スッとGoを取り入れる

18,519 views

Published on

Go 1.6 Release Party
2016-02-17
Hatena Inc. Tokyo Office
Yusuke Wada a.k.a. yusukebe

Published in: Technology

スッとGoを取り入れる

  1. 1. スッとGoを取り入れる Go 1.6 Release Party 2016-02-17 Hatena Inc. Tokyo Office Yusuke Wada a.k.a. yusukebe
  2. 2. 自己紹介 • Yusuke Wada • @yusukebe • http://blog.yusuke.be/ • Wadit CEO / Omoroki CTO • Web Application Developer • Technical Advisor • Co-founder of bokete.jp • Perl書いてる...
  3. 3. 本日のテーマ
  4. 4. Goを本番投入するまでの 道のりとその他
  5. 5. 現在の主なGoプロダクト 2個
  6. 6. その1 bokete/webstamp
  7. 7. bokete.jp
  8. 8. お題画像+テキスト = ボケ
  9. 9. L○NEスタンプ風画像を
 ダウンロードできる
  10. 10. これ
  11. 11. その2 yusukebe/revealgo
  12. 12. Markdown driven presentation tool
  13. 13. revealgo コマンドを実行
  14. 14. 立ち上がったサーバをブラウザで開く
  15. 15. まさかの GitHub Trending 入り
  16. 16. \(^o^)/
  17. 17. ところがこのスライドは...
  18. 18. Keynote製
  19. 19. とはいえ... $ go get github.com/yusukebe/cmd/revealgo
  20. 20. Goを取り入れるため 最初にやったこと
  21. 21. ✕コードを書く https://flic.kr/p/81RqH3
  22. 22. ✕コードを読む https://flic.kr/p/aGjVq8
  23. 23. 答え...
  24. 24. ⃝bradfitzと話す http://twitter.com/bradfitz
  25. 25. 去年のYAPC::Asiaで bradfitzがボッチだったので...
  26. 26. ゆ:Hiぶらっど!君が書いたギアマンは最高にクールだね ぶ:どんな用途でギアマンを使ってるんだい? ...(中略)... ゆ:ところでGoはどうなんだ? ぶ:まさに今Goでプログラムを書いてるところだ ゆ:Goのいい所を教えてくれよ ...(中略)... ぶ:こうやればAndroid向けのバイナリもコンパイル出来るぜ ゆ:オーケー!Goを使ってみるよ!
  27. 27. 予めGo本体の開発メンバである bradfitz氏と「サシで」話して モチベーションが上がった
  28. 28. 2番目にやったこと
  29. 29. 3番目にやったこと
  30. 30. スクリプト的に Go言語を利用する
  31. 31. スクリプト的とは? • main.go に package main のみ • 単発のバッチスクリプトとか • 例えば... • MySQLのレコードを1つずつなめて... • ちょっとした処理を加えてカラムを変更するetc.
  32. 32. 例 for ;; { var results []Entry db.Select(&results, db.Where("flag","=","0"), db.Limit(limit)); if len(results) == 0 { break } var wg sync.WaitGroup for _, entry := range(results) { wg.Add(1) go func(e Entry) { work(e) wg.Done() }(entry) } wg.Wait() } goと書くだけで並行処理が走って DB接続処理もロックしないで便利!
  33. 33. そして調子に乗って...
  34. 34. goroutine走らせまくって 爆死 https://flic.kr/p/6TorAy
  35. 35. どこからGolang化 していくか?
  36. 36. ザックリな Boketeアーキテクチャ
  37. 37. Web API サーバ PC版Web スマホ版Web iOSアプリ Androidアプリ その他フロント... コアロジック 各種サービス APIサーバをGoで書き直す必要も無いので特化したサービスをGoで!
  38. 38. Web API サーバ PC版Web スマホ版Web iOSアプリ Androidアプリ その他フロント... コアロジック 各種サービス スタンプ画像生成サーバがあった! スタンプ
  39. 39. http://stamp.bokete.jp/{boke_id}.png
  40. 40. Web API サーバ スタンプサーバ TTL付きCDN クライアント URLのパスに基づきボケIDをゲット ボケ情報取得 お題画像も取得しつつ スタンプ 風に画像を生成しサーブ ボケが削除されることも考慮しつつ TTLを設定したCDNが画像を配信 シェア等してもらう
  41. 41. Perl製スタンプサーバを Goでリプレース
  42. 42. git log -p cpanfile -requires 'Lingua::JA::Fold'; -requires 'Imager'; -requires 'Imager::DTP::Textbox::Horizontal'; Lingua::JA::Fold - 禁則処理を含む日本語文字列の折り返し Imager - 画像処理モジュール Imager::DTP::Horizontal - テキスト画像の配置
  43. 43. じゃあレポジトリつくって 画像生成サーバ書くか
  44. 44. (´・ω・`)
  45. 45. 次にやったこと
  46. 46. 目的に合わせてそれを検証する スニペットを書いてく
  47. 47. 自信がついたらいよいよ スタンプサーバの実装
  48. 48. 出来た構成
  49. 49. $ tree ./ ./ !"" README.md !"" assets # !"" font-heavy.ttf # !"" font-medium.ttf # !"" stamp_404.png # !"" stamp_footer.png # !"" stamp_header.png # !"" stamp_panel.png # $"" transparent.png !"" assets.go !"" client.go !"" client_test.go !"" cmd # $"" stamp_server # $"" main.go !"" stamp.go !"" stamp_test.go !"" util.go $"" util_test.go go-bindataでassets.goに入れ込む アセットファイル達 WebAPIから情報とってくる peco/peco参考にした 画像オブジェクトをゴリゴリ頑張る utilとはいえ主にテキスト処理
  50. 50. ある程度検証後デプロイ
  51. 51. 結果こうなった • デプロイツールとしてAnsible • リモートレポジトリはGitHubのPrivate • Ansibleでgit cloneする時はローカルの をforward • GOPATHのsrc以下にAnsibleでプロジェクトをgit clone • go get [とってきたプロジェクトのパス] • GOPATHのbin以下に出来たバイナリを使って起動
  52. 52. リリースした結果
  53. 53. preforkしないからメモリ使用量少ない! CPUフルフルに使い切る! すごい!!
  54. 54. と思ったら...
  55. 55. メモリ膨れてる??
  56. 56. この時少しでも Goが悪いと考えてしまった 僕をお許し下さい...
  57. 57. 実は禁則処理ロジックで 無限ループを生む可能性があった (*ノω・*)テヘ
  58. 58. さらに改良
  59. 59. yusukebe/go-pngquant
  60. 60. gophper.png pngquant --speed 10 40.3KB 15.1KB!!
  61. 61. pngquantは標準入力からも 受け取れて標準出力にも 書き出せる
  62. 62. func CompressBytes(input []byte, speed string) (output []byte, err error) { cmd := exec.Command("pngquant", "-", "--speed", speed) cmd.Stdin = strings.NewReader(string(input)) var o bytes.Buffer cmd.Stdout = &o err = cmd.Run() if err != nil { return } output = o.Bytes() return }
  63. 63. \(^o^)/
  64. 64. GO引にまとめ
  65. 65. Goを取り入れる • 段階を追っていけばスッと取り入れられた • 結果スタンプサーバの画像サイズが縮小した • リソースの節約 • 最初は特化したサービスのリプレースから • 次は新アプリをGoで書いてみたい • たぶん... 悪いのはGoじゃない

×