My External Storage

Apr 17, 2018 - 14 minute read - Comments - go report

Go Conference 2018 Spring 参加メモ #gocon

先日行われたgoconの参加メモ。今回は2トラック制だったので、自分が見たものだけ。 公開されているスライド資料などは以下のリンクに添付されている。

Go Conference 2018 Springイベント資料一覧
https://gocon.connpass.com/event/82515/presentation/

runtimeのコードを見たり、API設計や公式の歩き方、gRPCマイクロサービスにおけるテストの話まで、非常に幅広い技術スタックの知見を得ることができた。 また、学生エンジニア・新卒エンジニアの方々の熱意や技術力を目の当たりにすることも出来て、アラサーエンジニアとしては畏怖と尊敬を覚えた。
技術的にもパッション的にも(英語的にも…)、もっとスキルを磨いていかないと感じた一日になった。以下、発表メモと若干の覚え書き。

URL https://gocon.connpass.com/event/82515/
会場 サイボウズ株式会社 東京オフィス (東京日本橋タワー)
日時 2018/04/15(日) 09:00 〜 18:00
資料 https://gocon.connpass.com/event/82515/presentation/
ハッシュタグ #gocon
Toggeter https://togetter.com/li/1218219

How the Go runtime implements maps efficiently (without generics)

Dave Cheney

GoのcontributorであるDave-sanのキーノート。

正直英語はあまりできないので、皆さんの翻訳ツイートから。

mapの実装の話。基本的なHashMapのアルゴリズムから、C++, JavaのMapの実装との比較も解説されていた。

  • Goはhashmapの実装にinterface{}をつかっていない。
  • コンパイルするとmap操作はruntime.mapaccess1といった関数に展開されている。
  • HashMapの実装はsrc/runtime/hashmap.goに全部入っている。
  • mapの実装はKey/Valueをunsafe.Poointerで持つ。
  • じゃあどうやってmap操作を行っているかというと、maptype型にもつ情報から値の比較などを行っている。
  • たとえはmap[key]で値を取得する実装はここ。
  • 実行時にアルゴリズムを渡せるので、型ごとのmapが作られること無くバイナリの誇大化を避けている。
  • channelselectの実装も読んでためになる。

実際に解説を受けて背景を知ってからruntimeパッケージを見るの非常におもしろい。
また標準パッケージを読む楽しさを知ってしまった。
単純なアルゴリズムこそ最適化のためにいろいろされているんだなと感じた。

codehexさんがブログに懇親会でDave-sanから聞いた情報も書いてくださっている。

Go at Cybozu

サイボウズ株式会社 @ymmt
https://speakerdeck.com/ymmt2005/go-at-cybozu

スポンサーセッション。
今回のgoconはサイボウズさんの会場だったのだが、すごいキレイだった!!
会場の部屋もイベント規模ごとに変えられるようだし、懇親会も出来るバースペースもあってすごい。。。!

  • サイボウズでは2013年くらいからGoを使っている。
  • OSSとして2014年にはkintone Go SDK、2016年からはcybozu-go org(10 repo)としてもいろいろ公開している。
  • Kintone on AWSのYakumoは50%がGo。
  • Monorepo構成。vendorを使わず全てのコードをgit repoに入れている。
  • journaldとgoは相性が悪いので対策としてはjournald使わないほうがよい。
  • Goがエラー時にSIGPIPEをシグナルしてもjornaldはSIGPIPESuccessExitStatusとして取り扱っているのでRestart=on-failureしないらしい。

サイボウズがこんなにもGoを使っているとは知らなかったのでお話を聞けて非常によかった。
あまりメジャーではない(?)Monorepo構成をしていたり、積極的な技術チャレンジしていそうだった。

Testing with microservices in merpay

株式会社メルカリ @kazegusuri

https://speakerdeck.com/kazegusuri/testing-with-microservices-in-merpay

メルカリさんはスカラーシップとして地方学生を無料招待されていた。
社会人でもあまり行動圏外のイベントには参加できないので、こういう取り組みはすばらしいなあ

Go Conference 2018 Spring スカラーシップのご案内
http://tech.mercari.com/entry/2018/03/19/164252

gRPC王と噂のkazegusuriさんの発表。
自分もよくmercari/go-grpc-interceptorを見ている。
https://github.com/mercari/go-grpc-interceptor

  • メルカリでは2015年末頃にgRPC導入。
  • Go + gRPC/k8s(GKE + EKS?)/Circle CI + Spinnaker/Stack Driver Logging, Profiler/Datadog/Pagerduty, Sentry
  • メルペイで決済システムを作るうえでの難しさ
    • 一貫性とクリティカル。
    • 0.1%のエッジケースを考慮したシステム
    • マイクロサービスの中でトランザクションが分離していくなかでどうするのか。
  • メルペイの決済システムは中核となる決済システムが各マイクロサービス間の処理の流れを状態遷移モデルで監視している。
  • 共通テストフレームワークを作成し、状態遷移中の様々な異常状態を定義してテストしている。
  • Failure Injection(MySQL)。MySQLの結果にエラーを注入する
  • Failure Injection(HTTP)はRoundTripper
  • gRPCへのFailure Injectionはインターセプターで
  • テストの中でエラーをわざと発生させるが、ランダムでエラーを発生させるとテストが不安定になる。
  • エラーの発生は決定的に行いたいので、stacktrace(runtime.Callers)で一度発生したパスでは二度と発生させない。
  • 外部・内部サービスのテストはFakeをつかう
  • Fakeが本物と同じ動きをしてくれるのかもテストしている。本物とFakeに対して同じ処理を行って再現度が完璧なのか見ている。
  • データベースを接続するようなテストではTestMainでschemaファイルを読みこんでテスト毎にDBを起動している。
  • E2EテストではgRPCサーバを起動してクライアントからテストしている。
  • Chaos TestではShopify/toxiproxyをつかって遅延させたり帯域制限したり落としたり。
  • PostManでテストケースをGitHubで管理してQAテスト

具体的なOSSなどの紹介もあり、マイクロサービスにおけるテストについてものすごい情報量だった。
そこまでテストできるのか!?というくらいのアプローチ、全部やるのか(やれるのか)は別として手札として取り込みたい。

How to write Go code

@kaneshin
https://speakerdeck.com/kaneshin/how-to-write-go-code

エウレカCTOのkaneshinさんの発表。
発表のほぼ大半は実際にライブサーフィン?ライブブラウジング?で公式めぐりをされていた。
Goはgodoc上でExampleがそのまま動かせたりするし、実コードにも補足コメントが色々書いてあって、 本当に公式だけで大半の調査ができるところが魅力だと思う。
たしか発表中には出てこなかったと思うが、WikiのCodeReviewCommentsも定期的に読んでおきたい。

余談?でthe Code Galaxiesというリポジトリの関連を可視化するサービスも紹介されていた。
https://anvaka.github.io/pm/#/?_k=cj0p80

GoらしいAPIを求める旅路

@lestrrat
https://www.slideshare.net/lestrrat/goapi-go-conference-2018-spring

pecoBuilders Conの牧さんの発表。

  • GoらしいAPIとは
  • 本系backoffのAPIはfunc Retry(f func() error, b BackOff) error
  • シグネチャ(引数や戻り値)合わせないといけないしそのために毎回クロージャをつくるのはGoっぽくない。。。
  • その言語の自然な書き方が出来るようにAPIを作る
  • Goでいうと必ずしも実装をひとつの構造体に隠蔽することが良いわけではない。

実際に再設計されたAPIはlestrrat-go/backoffのREADMEで見ることができる。
本当に自然な感じのGoのコードになっている。 自分も設計を考えるときにとりあえずひとつのstructに入れてレシーバメソッド生やす、というような考え方をよくしてしまうので、とても参考になった。

コードジェネレートとの付き合い方

@pei0804
https://www.slideshare.net/JumpeiChikamori/go-conference-2018-spring

goのコードからswagger定義を生成するswaggo/swagを開発されている方。
[swaggo]GoのGoDocを書いたら、Swaggerを出せるやばいやつ

  • コードを自動生成するOSSは多い。が、気になるときもある。
  • Categoryを元にジェネレートした時、メソッド名はCategoriesになってほしいとか
  • swaggo/swagを作っている。goaみたいなことをgoa以外でもswaggerドキュメントを作りたかった。
  • ASTを作ってごりごりしている。必須と任意項目が混ざると大変。
  • 構造体のパースをするときに何も意識していないと、相互参照体があったとき無限ループに…
  • 実際にジェネレータを開発してみて感じたメリット
    • 機械的に生成できる効率化
    • 同じ書き方が保証できて品質担保
  • 実際に開発してみて感じたデメリット
    • 結局パーサーなので、小さい変更でも実装コストがデカイ。生産性をペイできないときもありそう。
  • 作るときは泥臭くがんばる
  • 使う側の付き合い方としては自分もコミットするくらいの気持ちのが良い

Gormの気持ちになってGormを使う

@linyows
https://speakerdeck.com/linyows/become-a-gorm-feeling-and-use-gorm

  • gormはgoで使うORMのライブラリ
  • goでは珍しくメソッドチェーンをする。 -メソッドチェーンようなのは他にはgomockとか?
  • gorm使っているとメソッドが乱立する問題。
  • goの言語思想(コンセプトの分離)とActive Recordパターンは相性がよくない
  • Active Record pattern テーブル行をカプセル化したオブジェクトにドメインロジックのメソッドを生やすパターン
  • 必要のないカプセル化をやめてDB操作はGormに任せることで処理をシンプルにする
  • DBコネクションとデータ、ドメインロジックの分離をメリットと捉える
  • いつも使うクエリはGORMのScopesに登録しておけば良い

クリーンアーキテクチャというかレイヤーを意識しようとしたらDB操作をAPI層に直に書きたくない気もするし、どうしたら良いのだろう?
Tweetを見ても「grom…」というつぶやきが多かった気がする。

Goroutine meets a signal

@codehex
https://speakerdeck.com/codehex/goroutine-meets-a-signal

Golet (https://github.com/Code-Hex/golet)
Go Conference 2018 Spring へ登壇しました
GoCon に参加して本当に良かった話

  • 元ネタはPerlのProcletをGoに移植したgolet
  • SIGNALcancel()を受け取るcontext.Contextを内包した拡張構造体を定義した。
  • closeをつかうとchannelを持っているgoroutineに全てに通知ができる。が。。。
  • context.Contextからキャンセルも受け取りたい。
  • SIGANLをハンドルするstructcontext.Contextを含める
  • context.Contextをラップしているので、contextとしても機能する
  • SIGNALも受け取るので両方をselectで待機できる
  • ただ、contextパッケージにはDo not store Contexts inside a struct type;と書いてある…

ちょうどcontext.Contextを構造体に含めちゃいけない理由を会社の人と話していた。
その時は構造体のレシーバメソッドに呼び出し元からcontext.Contextがあったとき、

  • 構造体に内包したcontext.Context
  • メソッドの引数で受け取ったcontext.Context

どちらにどう従うのかが曖昧になってしまうから構造体に内包するのは良くないのでは、だと話になった。
あと、構造体に含めるときは構造体オブジェクトとcontext.Contextのライフサイクルが同じであることが前提なのも懸念事項にある?

Why context.Context not in structs ?
https://gist.github.com/cia-rana/2ef3d6c33f93ce9add633989f9b8926e

[Blog] Context should go away for Go 2
https://groups.google.com/forum/#!topic/golang-nuts/eEDlXAVW9vU

この辺読んだ気がする。曖昧な判断で構造体に内包するのはよくないのは確かそう。
なお、発表のあと牧さんと別のアプローチの話をされていたそう。

Dgraph - A high performance graph database written in pure Go

@munisystem
https://speakerdeck.com/munisystem/dgraph-a-high-performance-graph-database-written-in-pure-go

DGraphというGo実装の分散グラフデータベースの紹介

https://github.com/dgraph-io/dgraph

  • たくさんのWebアプリはグラフで表現できる関係をもっている
  • が、グラフをRDBMSで表現するのはむずかしい。リレーションか新しい型が必要になるから。
  • Wantedlly Peopleのようなユースケース(名刺を大量にWriteする)でパフォーマンスがでるような既存のサービスがない。
  • そこでDGraphを採用した。
    • https://github.com/dgraph-io/dgraph
    • graphQLライクなクエリシンタックス
    • gRPCやHTTPもサポートしている。
    • Writeがハイパフォーマンス
    • 水平スケーリングも得意
  • golangで書いてあるので読めばなんとかなるのではというところもDgraphの魅力。

LT1: Whitespace言語処理系をGoで実装してみた

@snowcrush
https://tanstaafl.0pt.jp/slides/whitespace.v2/#1

  • Whitespace言語をGoで実装した話。
    • github.com/minoritea/whitespace
  • Whitespace言語
  • いちおう実装は出来たがもろもろしんどかった
  • Goで実装したのは初めてだと思っていたら結構先駆者がいた

swagもそうだけどパーサー作るの結構腕力が必要そう。だけど楽しそうだから自分も一度はやらないと。

LT2: クローラー実装で学ぶgo

川部 勝也
https://www.slideshare.net/katsuyakawabe/study-golang-by-developing-mini-crawler-93887152

  • クローラを実装するとは
    • 新しいプログラミング言語の勉強の題材にいい感じ
    • 新人や学生のベンチマークによさそう
  • 教授からクローラ作成の課題をもらった。
  • シングルページのクローリングの第一段階から再帰的なクローリングの並列化(平行か?)まで。
  • 以下のことが勉強できた
    • Goを使ったソフトウェア設計
    • 文字列処理(URI周りで泥臭くなる)
    • 非同期処理(goroutine)
    • ファイル入出力
  • 完成したクローラはこちら

クローラの実装ではhtnl、cssやjs内のURLの置換もしてローカルでページを再現していたらしいので、 正規表現やフロントエンド言語の構造解析の勉強になりそう。

LT3: go-selfupdate-github でツールを「自己アップデート」できるようにする

ドッグ
https://speakerdeck.com/rhysd/go-selfupdate-github-de-turuwozi-ji-atupudetosuru

  • goのCLIツールのアップデートはどうするのか?
    • go get -u
    • brewなどのパッケージマネージャ
    • リリースページから直接ダウンロード
  • どれも一長一短なので自動アップデートツールを作った
  • リリースページから最新のバイナリを自動検出。
    • https://github.com/rhysd/go-github-selfupdate
    • CLIに組み込むことで以下を実現できる
    • GitHubのリリースページから最新のバイナリを自動検出
    • 自動ダウンロード
    • 実行ファイルの自動置き換え
    • ユーザーに確認して更新することも可能

GoのCLIツールに関わらず、自動更新機能がほしいときはあるのですごい嬉しいライブラリ!
なお、go getに関して言うとブランチかtagにgo1がつけて公開しておくとHEADへの追従は起きないらしい。

LT4: 学生版のGoConを開催したい!

@Yamashou
https://speakerdeck.com/yamashou/xue-sheng-ban-goconwokai-cui-sitai

LT5: Goで始めるdockerとcontainerd

@sakajunquality
https://speakerdeck.com/sakajunquality/starting-docker-with-go

  • Dockerというコンテナ技術
  • 普通にDockerコンテナでgolangアプリ用のコンテナを作ると案外でかくなる
  • multistage buildでgo buildを前処理として終わらせて、実行するコンテナとは別にする。
  • サンプルコードだと、380MBあったコンテナのサイズが11MBまで縮小した。

deeeetさんがおすすめしていたDockerfileの構成はこちらだった。

https://github.com/heptio/contour/blob/master/Dockerfile

今自分で作っている開発用のコンテナは変更のたびに毎回docker buildするのがめんどくさくて、 ソースコードマウントしてgo runで動かすように作っている。(コンテナリビルドしなくてもリスタートで変更が反映できる)
本番用はちゃんとマルチステージで組まないと。

LT6: Replaced Backlog Git Server from Perl to Go

Yuichi Watanabe
https://slides.com/vvatanabe/replaced-backlogs-git-server-from-perl-to-go

  • nulabのbacklogのgit serverをgolangにリプレースした話。
  • Perl版とgo版を比較して
    • リクエスト処理は4倍くらい速くなった
    • CPU負荷は4割ほど削減
    • git clonegit pushが2倍速くなった
    • アーキテクチャも変えているので一概には言えないが、golangいい感じ!

タイムオーバーだったので、最後のほうはスライドから読み取ったもの。ぜひ考察お聞きしたかった。

関連記事