先日行われた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)
GoのcontributorであるDave-sanのキーノート。
正直英語はあまりできないので、皆さんの翻訳ツイートから。
Go の map 実装を generics も boxing もなしで高速に実装する仕組みの解説。コンパイラが宣言された map の型ごとにアルゴリズム構造体を用意して、map 操作を syntax sugar として展開する際にアルゴリズムを渡すことでうまくやっている。なるほど。 #gocon
— ymmt (@ymmt2005) 2018年4月15日
keyもvalueもunsafe.Pointer ここ https://t.co/3DOwkSYAha #gocon
— そな太 (@sonatard) 2018年4月15日
type typeAlg struct { hash, equal }ってのが型に対応したハッシュ関数と同値比較の方法を保持する #gocon
— nasa9084@某某某某(0x19歳) (@nasa9084) 2018年4月15日
なるほどそういう方法にするとmapの実装を1つに出来てバイナリのサイズを小さくできるし速さもある程度両立できるということか. 賢いなぁ #gocon
— おりさの (@orisano) 2018年4月15日
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が作られること無くバイナリの誇大化を避けている。
channel
やselect
の実装も読んでためになる。
実際に解説を受けて背景を知ってから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はSIGPIPE
をSuccessExitStatus
として取り扱っているので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をつかう
- GCP Pub/SubはFakeサーバが提供されていたり。
- https://github.com/GoogleCloudPlatform/google-cloud-go/blob/master/pubsub/pstest/examples_test.go#L28
- 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も定期的に読んでおきたい。
- 愚者は経験に学び、賢者は歴史に学ぶ。
- どの記事が新しいのか、ちゃんとしているのか、鮮度などがよくわからない状態Goについて調べるならばやはり公式が一番。
- godoc
- wiki
余談?でthe Code Galaxiesというリポジトリの関連を可視化するサービスも紹介されていた。
https://anvaka.github.io/pm/#/?_k=cj0p80
GoらしいAPIを求める旅路
@lestrrat
https://www.slideshare.net/lestrrat/goapi-go-conference-2018-spring
pecoやBuilders Conの牧さんの発表。
- GoらしいAPIとは
- お題。 https://github.com/cenkalti/backoff
- lestrrat-sanが書き直したもの https://github.com/lestrrat-go/backoff
- 本系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 テーブル行をカプセル化したオブジェクトにドメインロジックのメソッドを生やすパターン
- https://www.martinfowler.com/eaaCatalog/activeRecord.html
- gormはレシーバが(
User
のような)テーブル行ではない
- 必要のないカプセル化をやめて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
SIGNAL
とcancel()
を受け取るcontext.Context
を内包した拡張構造体を定義した。close
をつかうとchannel
を持っているgoroutineに全てに通知ができる。が。。。context.Context
からキャンセルも受け取りたい。SIGANL
をハンドルするstruct
にcontext.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言語
- https://ja.wikipedia.org/wiki/Whitespace
- 空白、タブ、ラインフィードの三文字だけでプログラムを記述する
- いちおう実装は出来たがもろもろしんどかった
- Goで実装したのは初めてだと思っていたら結構先駆者がいた
swagもそうだけどパーサー作るの結構腕力が必要そう。だけど楽しそうだから自分も一度はやらないと。
LT2: クローラー実装で学ぶgo
川部 勝也
https://www.slideshare.net/katsuyakawabe/study-golang-by-developing-mini-crawler-93887152
- クローラを実装するとは
- 新しいプログラミング言語の勉強の題材にいい感じ
- 新人や学生のベンチマークによさそう
- 教授からクローラ作成の課題をもらった。
- シングルページのクローリングの第一段階から再帰的なクローリングの並列化(平行か?)まで。
- 以下のことが勉強できた
- Goを使ったソフトウェア設計
- 文字列処理(URI周りで泥臭くなる)
- 非同期処理(goroutine)
- ファイル入出力
- 完成したクローラはこちら
- https://github.com/Bo0km4n/avarus
- 600行くらい、一週間で書けるはず。
クローラの実装では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への追従は起きないらしい。
前から結構言ってるんだけど、go getで最新取られたくない場合は go1 というタグを切れば良いです #gocon
— Yoshifumi Yamaguchi (@ymotongpoo) 2018年4月15日
LT4: 学生版のGoConを開催したい!
@Yamashou
https://speakerdeck.com/yamashou/xue-sheng-ban-goconwokai-cui-sitai
- Aizu.Goという活動をしている。学生とゲストエンジニアの発表。
- https://twitter.com/hashtag/aizugo
- (connpass的なページが見つからなかった)
- 会津限定じゃなくて全国の学生Gopherと交流してGo学生で盛り上がりたい
- StudentGoという学生向けのSlackチームもある
- 現役Goエンジニアも学生と質疑応答、交流するために参加している
- ぜひJOINを
- https://docs.google.com/forms/d/e/1FAIpQLSdp6nGYN0sMgAQse7cV_YJKsdPpTzVoUasWXIldXSA0x72wdQ/viewform
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
heptio/contourのDockerfileがGoだ一番理想だと思うhttps://t.co/O1LemA30AZ #gocon
— Taichi Nakashima (@deeeet) 2018年4月15日
今自分で作っている開発用のコンテナは変更のたびに毎回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 clone
、git push
が2倍速くなった- アーキテクチャも変えているので一概には言えないが、golangいい感じ!
タイムオーバーだったので、最後のほうはスライドから読み取ったもの。ぜひ考察お聞きしたかった。