Upgrade to Pro — share decks privately, control downloads, hide ads and more …

5ヶ月でプロダクションにGoを導入したお話

DMM.com
October 05, 2016

 5ヶ月でプロダクションにGoを導入したお話

3社合同勉強会にて、Go言語を導入した事例を紹介しました。

DMM.com

October 05, 2016
Tweet

More Decks by DMM.com

Other Decks in Technology

Transcript

  1.  Segment Platform  Consumer DB MPP DWH AMQP API

    ビッグデータを用いて任意のユーザーを抽出
  2.  Segment Platform  Consumer DB MPP DWH AMQP API

    リクエストをAPIで受け付け SQLを生成 API ビッグデータを用いて任意のユーザーを抽出
  3.  Segment Platform  Consumer DB MPP DWH AMQP API

    DB AMQP API - キューにMessageをPublish - 処理開始レコード登録 ビッグデータを用いて任意のユーザーを抽出
  4.  Segment Platform  Consumer DB MPP DWH AMQP API

    DaemonがMessageをConsume ビッグデータを用いて任意のユーザーを抽出
  5.  Segment Platform  Consumer DB MPP DWH AMQP API

    SQL(Create table as select 〜) を実行 ビッグデータを用いて任意のユーザーを抽出
  6.  Segment Platform  Consumer DB MPP DWH AMQP API

    PrestoにてDWHから抽出し、DB の一時テーブルへ書き出し ビッグデータを用いて任意のユーザーを抽出
  7.  Segment Platform  Consumer DB MPP DWH AMQP API

    進捗状況を非同期に更新 ビッグデータを用いて任意のユーザーを抽出
  8.  Docker Swarm Segment Platform  Consumer DB MPP DWH

    AMQP API / AMQP / Consumerを Dockerコンテナ内で起動 API ビッグデータを用いて任意のユーザーを抽出
  9.  ナウい開発をしたい • ORMapper使いたい - Gorm • 煩雑な処理を自動化したい - Godo

    • テストデータも管理したい - Fixture • Packageのバージョン管理したい- Glide 
  10.  Fixtureとは ? • DB用テストデータをymlで定義 • テスト実行時に、DBへデータをインサート  EJNFOTJPOTZNM 

    JE EJTQ@OBNFTBNQMFEJNFOTJPO CJHJOU  GVODUJPO EJNFOTJPO@UZQFCJHJOU BMMPX@PQFSBUPST   CFUXFFO EFTDSJQUJPOTBNQMFEJNFOTJPO FOBCMF@GMH
  11.  1. glide create SPPU!HPQIFSHPTSDBQQHMJEFDSFBUF <*/'0> (FOFSBUJOHB:".-DPOGJHVSBUJPOGJMFBOEHVFTTJOHUIFEFQFOEFODJFT <*/'0> "UUFNQUJOHUPJNQPSUGSPNPUIFSQBDLBHFNBOBHFST VTFTLJQJNQPSU

    UPTLJQ  <*/'0> 4DBOOJOHDPEFUPMPPLGPSEFQFOEFODJFT <*/'0> 8SJUJOHDPOGJHVSBUJPOGJMF HMJEFZBNM  <*/'0> 8PVMEZPVMJLF(MJEFUPIFMQZPVGJOEXBZTUPJNQSPWFZPVS HMJEFZBNMDPOGJHVSBUJPO  <*/'0> *GZPVXBOUUPSFWJTJUUIJTTUFQZPVDBOVTFUIFDPOGJHXJ[BSE DPNNBOEBUBOZUJNF <*/'0> :FT : PS/P /  / <*/'0> :PVDBOOPXFEJUUIFHMJEFZBNMGJMF$POTJEFS <*/'0> 6TJOHWFSTJPOTBOESBOHFT4FFIUUQTHMJEFTIEPDTWFSTJPOT <*/'0> "EEJOHBEEJUJPOBMNFUBEBUB4FFIUUQTHMJEFTIEPDT HMJEFZBNM <*/'0> 3VOOJOHUIFDPOGJHXJ[BSEDPNNBOEUPJNQSPWFUIFWFSTJPOTJO ZPVSDPOGJHVSBUJPO 
  12.  2. glide get <package> SPPU!HPQIFSHPTSDBQQHMJEFHFUHJUIVCDPNOMPQFTTMBDL <*/'0> 1SFQBSJOHUPJOTUBMMQBDLBHF <*/'0> "UUFNQUJOHUPHFUQBDLBHFHJUIVCDPNOMPQFTTMBDL

    <*/'0> (BUIFSJOHSFMFBTFJOGPSNBUJPOGPSHJUIVCDPNOMPQFTTMBDL <*/'0> 5IFQBDLBHFHJUIVCDPNOMPQFTTMBDLBQQFBSTUPIBWF4FNBOUJD7FSTJPO SFMFBTFT IUUQTFNWFSPSH  <*/'0> 5IFMBUFTUSFMFBTFJTW:PVBSFDVSSFOUMZOPUVTJOHBSFMFBTF 8PVMEZPVMJLF <*/'0> UPVTFUIJTSFMFBTF :FT : PS/P /  / <*/'0> "EEJOHHJUIVCDPNOMPQFTTMBDLUPZPVSDPOGJHVSBUJPO <*/'0> %PXOMPBEJOHEFQFOEFODJFT1MFBTFXBJU <*/'0> 'FUDIJOHHJUIVCDPNOMPQFTTMBDL <*/'0> 3FTPMWJOHJNQPSUT <*/'0> %PXOMPBEJOHEFQFOEFODJFT1MFBTFXBJU <*/'0> &YQPSUJOHSFTPMWFEEFQFOEFODJFT <*/'0> &YQPSUJOHHJUIVCDPNOMPQFTTMBDL <*/'0> 3FQMBDJOHFYJTUJOHWFOEPSEFQFOEFODJFT 
  13.  About Echo  • labstack/echo • 軽量・高速なフレームワーク ➡ RESTful

    APIを作りたいならオススメ • 非常に活発に開発されている ➡ v2系を利用中
  14.  ディレクトリ構成  SPPU!HPQIFSHPTSDTBNQMFBQJUSFF-$  ](PEPEJSԧԡԗՑ՛ԲդHPEPӘԯԋՔԗ԰Ւ ]BQJ൵FOEQPJOUӘԯԋՔԗ԰Ւ ]DPNNPOஈ㉊௡ⅈ ]DPOG⼀ᇰԽԉԌՓ ]GJYUVSFԮԡ԰ԯդԧ

    ]HMJEFMPDL ]HMJEFZBNM7FOEPSJOHԬդՓǒHMJEFӘQBDLBHF☛ⅈԽԉԌՓ ]NBJOHP ]NJEEMFXBSF⽇⼊௡ⅈӔӓ஁SFRVFTUӕሽӁӐᇴᢇӃӵஈ㉊௡ⅈ ]SPVUFS"1*ӘՓդԮԋ՛Ԙ AWFOEPSਜ⇹QBDLBHFӼ☛ⅈӃӵԯԋՔԗ԰Ւ
  15.  Vendoring (api)  QBDLBHFCJUCVDLFUYYYDPNTBNQMFTBNQMFBQJ JNQPSU QBDLBHFHJUIVCDPNMBCTUBDLFDIP WFSTJPO? TVCQBDLBHFT FOHJOFTUBOEBSE

    QBDLBHFCJUCVDLFUYYYDPNTBNQMFTBNQMFDPSF TVCQBDLBHFT NPEFMTTBNQMF WDTHJU SFQPTTIHJU!CJUCVDLFUYYYDPN999TBNQMFTBNQMFDPSFHJU EFW*NQPSU QBDLBHFHJUIVCDPNHPUFTUGJYUVSFTUFTUGJYUVSFT
  16.  1. Package Common  BQJHP QBDLBHFBQJ HMPCBMႁᡔ WBS 

     DPOGJHDPNNPO(FU$POGJH   MPHHFSDPNNPO(FU-PHHFS BQQ   ஈ㉊௡ⅈ GVODDPNNPO'VOD \  ^ package内の共通変数や関数を定義 ←private (※小文字始まり)
  17.  1. Package Common  SFTPVSDFHP QBDLBHFBQJ GVOD(FU3FTPVSDF DFDIP$POUFYU \

     MPHHFS8JUI'JFMET MPHSVT'JFMET\NFUIPE NFUIPE^ %FCVH 4UBSU   EFGFSGVOD \   MPHHFS8JUI'JFMET MPHSVT'JFMET\NFUIPE NFUIPE^ %FCVH &OE   ^   DPNNPO'VOD  ^ loggerやcommonFunc()を使用
  18.  2. Using `json:"omitempty"`  UZQF$PMMFDUJPO3FTVMUTUSVDU\ $PVOUJOUAKTPODPVOUA -JTU<>*UFNAKTPOMJTUA /FYU63-TUSJOHAKTPOOFYU@VSM PNJUFNQUZA

    ^ UZQF*UFNTUSVDU\ *%JOUAKTPOJEA /BNFTUSJOHAKTPOOBNFA ^ JSONレスポンスに不要な要素を含めない
  19.  \  TUBUVT   EBUB\   DPVOU

       MJTU<    \     JE      OBNFQIQ    ^   >  ^   OFYU@VSM ^ 2. Using `json:"omitempty"`  \  TUBUVT   EBUB\   DPVOU    MJTU<    \     JE      OBNFQIQ    ^   >  ^ ^ omitempty not omitempty JSONレスポンスに不要な要素を含めない
  20.  3. Transaction  GVOD4PNF'VOD DFDIP$POUFYU FSSPS\  FSST<>FSSPS\^ 

    UYE#FHJO   EFGFSEC'JOJTI5SBOTBDUJPO UY FSST   FSSTIPHF   JGMFO FSST \   SFUVSOFDIP/FX)551&SSPS  IUUQ4UBUVT*OUFSOBM4FSWFS&SSPS  FSST<>&SSPS    ^ ^ GVOD'JOJTI5SBOTBDUJPO UY HPSN%# FSSPST <>FSSPS \  JGMFO FSSPST \   UY3PMMCBDL   ^FMTF\   UY$PNNJU   ^ ^
  21.   GVOD4PNF'VOD DFDIP$POUFYU FSSPS\  FSST<>FSSPS\^  UYE#FHJO 

     EFGFSEC'JOJTI5SBOTBDUJPO UY FSST   FSSTIPHF   JGMFO FSST \   SFUVSOFDIP/FX)551&SSPS  IUUQ4UBUVT*OUFSOBM4FSWFS&SSPS  FSST<>&SSPS    ^ ^ GVOD'JOJTI5SBOTBDUJPO UY HPSN%# FSSPST <>FSSPS \  JGMFO FSSPST \   UY3PMMCBDL   ^FMTF\   UY$PNNJU   ^ ^
  22.   GVOD4PNF'VOD DFDIP$POUFYU FSSPS\  FSST<>FSSPS\^  UYE#FHJO 

     EFGFSEC'JOJTI5SBOTBDUJPO UY FSST   FSSTIPHF   JGMFO FSST \   SFUVSOFDIP/FX)551&SSPS  IUUQ4UBUVT*OUFSOBM4FSWFS&SSPS  FSST<>&SSPS    ^ ^ GVOD'JOJTI5SBOTBDUJPO UY HPSN%# FSSPST <>FSSPS \  JGMFO FSSPST \   UY3PMMCBDL   ^FMTF\   UY$PNNJU   ^ ^ defer 関数からreturn時の処理を予約
  23.   GVOD4PNF'VOD DFDIP$POUFYU FSSPS\  FSST<>FSSPS\^  UYE#FHJO 

     EFGFSEC'JOJTI5SBOTBDUJPO UY FSST   FSSTIPHF   JGMFO FSST \   SFUVSOFDIP/FX)551&SSPS  IUUQ4UBUVT*OUFSOBM4FSWFS&SSPS  FSST<>&SSPS    ^ ^ GVOD'JOJTI5SBOTBDUJPO UY HPSN%# FSSPST <>FSSPS \  JGMFO FSSPST \   UY3PMMCBDL   ^FMTF\   UY$PNNJU   ^ ^ transactionを開始し、deferにて 終了処理を呼び出し
  24.   GVOD4PNF'VOD DFDIP$POUFYU FSSPS\  FSST<>FSSPS\^  UYE#FHJO 

     EFGFSEC'JOJTI5SBOTBDUJPO UY FSST   FSSTIPHF   JGMFO FSST \   SFUVSOFDIP/FX)551&SSPS  IUUQ4UBUVT*OUFSOBM4FSWFS&SSPS  FSST<>&SSPS    ^ ^ GVOD'JOJTI5SBOTBDUJPO UY HPSN%# FSSPST <>FSSPS \  JGMFO FSSPST \   UY3PMMCBDL   ^FMTF\   UY$PNNJU   ^ ^ err有無に応じて commit or rollbackを切り替え
  25.   GVOD4PNF'VOD DFDIP$POUFYU FSSPS\  FSST<>FSSPS\^  UYE#FHJO 

     EFGFSEC'JOJTI5SBOTBDUJPO UY FSST   FSSTIPHF   JGMFO FSST \   SFUVSOFDIP/FX)551&SSPS  IUUQ4UBUVT*OUFSOBM4FSWFS&SSPS  FSST<>&SSPS    ^ ^ GVOD'JOJTI5SBOTBDUJPO UY HPSN%# FSSPST <>FSSPS \  JGMFO FSSPST \   UY3PMMCBDL   ^FMTF\   UY$PNNJU   ^ ^ 以降の処理では、 transactionを意識しないコード
  26.  Consumer • AMQPをConsumeして処理を行うDaemon • Graceful Shutdown • SIGHUP /

    管理channel • Proxy経由でのアクセス • 処理状況の非同期更新 
  27.  1. Graceful shutdown  JNQPSUTZOD WBSXHTZOD8BJU(SPVQ GVODNBJO \ 

    NBJONBLF DIBOCPPM   HPGVOD \   GPS\    TFMFDU\    DBTFTIVU%PXO$IBO     NBJOUSVF CSFBL    DBTFEEFMJWFSZ$IBO     XH"EE       HPGVOD EBNRQ%FMJWFSZ \      EFGFSXH%POF  ՉԫԣդԠӘ௡ⅈ     ^    ^   ^  ^  NBJOՓդԿ✳६ൺᦆ  NBJO  MPHHFS*OGP 'JOJTIJOHDPOTVNFSHSBDFGVMMZ     XH8BJU   MPHHFS*OGP 'JOJTIFE  ^
  28.   JNQPSUTZOD WBSXHTZOD8BJU(SPVQ GVODNBJO \  NBJONBLF DIBOCPPM 

     HPGVOD \   GPS\    TFMFDU\    DBTFTIVU%PXO$IBO     NBJOUSVF CSFBL    DBTFEEFMJWFSZ$IBO     XH"EE       HPGVOD EBNRQ%FMJWFSZ \      EFGFSXH%POF  ՉԫԣդԠӘ௡ⅈ     ^    ^   ^  ^   NBJONBJOՓդԿ✳६ൺᦆ  MPHHFS*OGP 'JOJTIJOHDPOTVNFSHSBDFGVMMZ   XH8BJU XHҶӕӔӵӨӑൺᦆ  MPHHFS*OGP 'JOJTIFE  ^
  29.   JNQPSUTZOD WBSXHTZOD8BJU(SPVQ GVODNBJO \  NBJONBLF DIBOCPPM 

     HPGVOD \   GPS\    TFMFDU\    DBTFTIVU%PXO$IBO     NBJOUSVF CSFBL    DBTFEEFMJWFSZ$IBO     XH"EE       HPGVOD EBNRQ%FMJWFSZ \      EFGFSXH%POF  ՉԫԣդԠӘ௡ⅈ     ^    ^   ^  ^   NBJONBJOՓդԿ✳६ൺᦆ  MPHHFS*OGP 'JOJTIJOHDPOTVNFSHSBDFGVMMZ   XH8BJU XHҶӕӔӵӨӑൺᦆ  MPHHFS*OGP 'JOJTIFE  ^ TZODύοέʔδ
 8BJU(SPVQΛར༻
  30.   JNQPSUTZOD WBSXHTZOD8BJU(SPVQ GVODNBJO \  NBJONBLF DIBOCPPM 

     HPGVOD \   GPS\    TFMFDU\    DBTFTIVU%PXO$IBO     NBJOUSVF CSFBL    DBTFEEFMJWFSZ$IBO     XH"EE       HPGVOD EBNRQ%FMJWFSZ \      EFGFSXH%POF  ՉԫԣդԠӘ௡ⅈ     ^    ^   ^  ^   NBJONBJOՓդԿ✳६ൺᦆ  MPHHFS*OGP 'JOJTIJOHDPOTVNFSHSBDFGVMMZ   XH8BJU XHҶӕӔӵӨӑൺᦆ  MPHHFS*OGP 'JOJTIFE  ^ main loop終了同期用channel
  31.   JNQPSUTZOD WBSXHTZOD8BJU(SPVQ GVODNBJO \  NBJONBLF DIBOCPPM 

     HPGVOD \   GPS\    TFMFDU\    DBTFTIVU%PXO$IBO     NBJOUSVF CSFBL    DBTFEEFMJWFSZ$IBO     XH"EE       HPGVOD EBNRQ%FMJWFSZ \      EFGFSXH%POF  ՉԫԣդԠӘ௡ⅈ     ^    ^   ^  ^   NBJONBJOՓդԿ✳६ൺᦆ  MPHHFS*OGP 'JOJTIJOHDPOTVNFSHSBDFGVMMZ   XH8BJU XHҶӕӔӵӨӑൺᦆ  MPHHFS*OGP 'JOJTIFE  ^ mainループ shutDown/deliveryを無限ループで 待ち受ける
  32.   JNQPSUTZOD WBSXHTZOD8BJU(SPVQ GVODNBJO \  NBJONBLF DIBOCPPM 

     HPGVOD \   GPS\    TFMFDU\    DBTFTIVU%PXO$IBO     NBJOUSVF CSFBL    DBTFEEFMJWFSZ$IBO     XH"EE       HPGVOD EBNRQ%FMJWFSZ \      EFGFSXH%POF  ՉԫԣդԠӘ௡ⅈ     ^    ^   ^  ^   NBJONBJOՓդԿ✳६ൺᦆ  MPHHFS*OGP 'JOJTIJOHDPOTVNFSHSBDFGVMMZ   XH8BJU XHҶӕӔӵӨӑൺᦆ  MPHHFS*OGP 'JOJTIFE  ^ shut down channelに入力があった場合 - mainループの同期channelに入力し終了
 (以降のchannelのconsumeしない)
  33.   JNQPSUTZOD WBSXHTZOD8BJU(SPVQ GVODNBJO \  NBJONBLF DIBOCPPM 

     HPGVOD \   GPS\    TFMFDU\    DBTFTIVU%PXO$IBO     NBJOUSVF CSFBL    DBTFEEFMJWFSZ$IBO     XH"EE       HPGVOD EBNRQ%FMJWFSZ \      EFGFSXH%POF  ՉԫԣդԠӘ௡ⅈ     ^    ^   ^  ^   NBJONBJOՓդԿ✳६ൺᦆ  MPHHFS*OGP 'JOJTIJOHDPOTVNFSHSBDFGVMMZ   XH8BJU XHҶӕӔӵӨӑൺᦆ  MPHHFS*OGP 'JOJTIFE  ^ 通常処理channelに入力があった場合 - 開始時にAdd - go routine内でdefer done
  34.   JNQPSUTZOD WBSXHTZOD8BJU(SPVQ GVODNBJO \  NBJONBLF DIBOCPPM 

     HPGVOD \   GPS\    TFMFDU\    DBTFTIVU%PXO$IBO     NBJOUSVF CSFBL    DBTFEEFMJWFSZ$IBO     XH"EE       HPGVOD EBNRQ%FMJWFSZ \      EFGFSXH%POF  ՉԫԣդԠӘ௡ⅈ     ^    ^   ^  ^   NBJONBJOՓդԿ✳६ൺᦆ  MPHHFS*OGP 'JOJTIJOHDPOTVNFSHSBDFGVMMZ   XH8BJU XHҶӕӔӵӨӑൺᦆ  MPHHFS*OGP 'JOJTIFE  ^ mainループ終了同期が取れたら、 graceful shutdown開始
  35.   JNQPSUTZOD WBSXHTZOD8BJU(SPVQ GVODNBJO \  NBJONBLF DIBOCPPM 

     HPGVOD \   GPS\    TFMFDU\    DBTFTIVU%PXO$IBO     NBJOUSVF CSFBL    DBTFEEFMJWFSZ$IBO     XH"EE       HPGVOD EBNRQ%FMJWFSZ \      EFGFSXH%POF  ՉԫԣդԠӘ௡ⅈ     ^    ^   ^  ^   NBJONBJOՓդԿ✳६ൺᦆ  MPHHFS*OGP 'JOJTIJOHDPOTVNFSHSBDFGVMMZ   XH8BJU XHҶӕӔӵӨӑൺᦆ  MPHHFS*OGP 'JOJTIFE  ^ graceful shutdown中… wgが0になるまで同期
  36.   JNQPSUTZOD WBSXHTZOD8BJU(SPVQ GVODNBJO \  NBJONBLF DIBOCPPM 

     HPGVOD \   GPS\    TFMFDU\    DBTFTIVU%PXO$IBO     NBJOUSVF CSFBL    DBTFEEFMJWFSZ$IBO     XH"EE       HPGVOD EBNRQ%FMJWFSZ \      EFGFSXH%POF  ՉԫԣդԠӘ௡ⅈ     ^    ^   ^  ^   NBJONBJOՓդԿ✳६ൺᦆ  MPHHFS*OGP 'JOJTIJOHDPOTVNFSHSBDFGVMMZ   XH8BJU XHҶӕӔӵӨӑൺᦆ  MPHHFS*OGP 'JOJTIFE  ^ 処理終了
  37.  2. Access via proxy  JNQPSU   GNU

     OFUIUUQ  QSPYZ63- FSSVSM1BSTF GNU4QSJOUG IUUQTT QPSU  IPTU  IUUQ%FGBVMU5SBOTQPSUIUUQ5SBOTQPSU\1SPYZ IUUQ1SPYZ63- QSPYZ63- ^ defaultTransportにProxyURLを セットし、全てのアクセスを proxy経由にする
  38.  Test automation • CIはJenkinsで • 下記パッケージで実現 • gocov +

    gocov-xml + go-junit-report • テスト実行時には、テストのためのコンテナ を立てて毎回クリーンな状態にしている 
  39.  How to Unit test? • gocovを利用し、テスト & カバレッジ取得 •

    開発時は、gocov + gocov-htmlを使って、ブ ラウザからカバレッジレポートを閲覧