2015.03.11 Gunosy.Go

2015.03.11 Gunosy.Go

よろしくお願いします。

まず、お前だれよということについて話します。
3: 吉田昂平といいます。インターネットでは yosida95 で活動しています。詳しく知りたい方は yosida95.com にアクセスしてください。

Go at Gehirn というタイトルでお話させていただきますが、

ゲヒルン。

ゲヒルンとはインフラ・セキュリティ・防災をやっている会社で、わたしは 2013 年 8 月、高校生 3 年の夏休みからソフトウェアエンジニアとしてゲヒルンが提供するインフラサービスのバックエンドの開発をしています。

ゲヒルンはインフラサービスの一環として Gehirn Web Services (新宿) を現在提供しています。

その Gehirn Infrastructure Services (新宿) ですが、この春

Go をバックエンドの開発言語に採用して、大規模なリニューアルを計画しています。

こちらが提供予定のサービス、 Gehirn Infrastructure Services の開発中の画面です。

このリニューアルでは新たに EDJ, MTA, KVS を提供し、また現在提供している RS2, DNS も刷新します。

では、どのサービスに Go が使われているのか、

これらのサービスの内、

これだけ、つまり DNS を除いたすべてのサービスで Go が何らかの形で使われます。

その中でも特に、

EDJ と MTA は 100% Go で開発しました。

EDJ は Event Delivery Junction の略で、ゲヒルンが提供しているサービスからのお知らせ、例えばメンテナンス情報や障害情報、また各サービスで発生したイベントをまとめて受け取るためのサービスです。

これらのイベントは HTTP Hook, IRC, Slack, Pushover SMS, E-Mail などユーザーが任意に指定した宛先に配送されます。

技術的には、単純に AMQP を Pub/Sub しています。配送したいイベントがサービスで発生したら Publisher が AMQP にメッセージを流し、それを Subscriber が指定された宛先に配送する仕組みです。

MTA は Mail Transfer Agent の略で、 プログラマブルなメール API です。 HTTP か SMTP によってメールを配送することができます。また、メールを受信することもできます。受信したメールは先程の EDJ のイベントとして扱われます。さらに、 Delivery Status Notification という SMTP の拡張をサポートしているため、メールが正常に配送された、一時的なエラーによってメールが遅配される、メールの配送に失敗したなどのイベントも同様に EDJ のイベントとして受け取ることができます。

MTA は上記に上げるような RFC を実装した SMTP サーバーをフルスクラッチしました。

この MTA と EDJ を組み合わせることによって、受信したメールを HTTP や IRC, Slack, Pushover, SMS などに通知することができます。例えばメーリングリストを購読しているメールアドレスの受信サーバーを MTA にすることによって、 Slack にいち早く情報が通知されチームに共有されると言った使い方ができると思っています。

さらに、 EDJ のイベント配送先にメールアドレスを指定することで、受信したメールを別のメールアドレスに転送するような使い方もできます。

ではなぜ Go なのか、

Go の利点は開発がのしやすさとデプロイのしやすさにあると思っています。

まず、開発のしやすさ。

これは、シンプルで習得しやすい言語仕様と、 Goroutine, Channel, Select 構文による並列処理の扱いやすさ、

そして bufio や crypto などのパワフルな標準ライブラリ、豊かなサードパーティライブラリがある点です。

そしてデプロイ。

まず、 Gehirn のプロダクトは Pull Request をマージすることによって指定した Git のブランチに変更があった場合に CircleCI でビルドが走り、テストが通った場合にデプロイされます。

Go 言語は簡単にクロスコンパイルできて、ダイナミックリンクを必要としないため、まっさらなサーバーでもバイナリひとつを置くだけでデプロイが完了します。

そのため、 CircleCI のテストコンテナの中でデプロイ先のアーキテクチャ向けにコンパイルをして、これによって生成されたバイナリをそれぞれのサーバーに置く。そして、 supervisor によってプロセスを起動するというとてもシンプルなしくみでデプロイできます。

ここまで利点を紹介してきましたが、では Go にある課題はなにか。

それはなんといっても依存パッケージの管理の面倒臭さにあると感じています。サードパーティライブラリを取得してくる `go get` コマンドですが、このコマンドはライブラリのバージョンという概念を持っていません。また、これはぼくが Python などの Lightweight Language に慣れ親しんでいるから感じるのかもしれませんが、オフィシャルなパッケージインデックスを持っていないため、特定のバージョンを指定することができません。バージョンの概念を持っていないと何が面倒くさいかというと、依存先のライブラリに後方互換性を壊す破壊的な変更が入った場合にある日突然ビルドできなくなるといった問題が発生します。自分の手元ではビルドできるコードが、新たにアサインされたメンバーの手元では動かないといった自体も発生します。これについては Gehirn Infrastructure Services を開発しているチームはとても小さく、バックエンドを開発しているのは最初から最後までぼくしかいないため大きな問題とはなりませんでしたが、大きな開発になればなるほど発生する問題だと思います。

ちなみに、 gopkg.in など他のソリューションもありますが、わたしは godep を使っています。

それでは本日のまとめです

Gehirn で実際に Go によって開発したサービスを紹介することによって、 Go すでにプロダクションレディーであるということをおはなししました。また、 Gehirn ではわたしが担当している Gehirn Infrastructure Services 以外にも Go で開発したシステムを提供しています。

また、わたしは MTA のために実用的な SMTP サーバーを開発しました。もし SMTP やその周辺のテクノロジーのご興味をお持ちの方がいらっしゃいましたら、ぜひわたしとお友達になりましょう。

以上です。何かご質問がありましたら twitter @yosida95 まで遠慮なく聞いてください。ありがとうございました。

D12b0581b8218af98bf3014af3eeaac3?s=128

Kohei YOSHIDA

March 11, 2015
Tweet