私がGoを選択する理由 / Geek Salon Vol.7

私がGoを選択する理由 / Geek Salon Vol.7

5d74d743eabd2bf7d4d2f68b9d3c727d?s=128

Tatsuhiko Kubo

May 29, 2015
Tweet

Transcript

  1. ࢲ͕GoΛબ୒͢Δཧ༝ Tatsuhiko Kubo@cubicdaiya Geek Salon vol.7@2015/05/29

  2. ࣗݾ঺հ • ٱอୡ඙(Tatsuhiko Kubo) • bokko@cubicdaiya • Software Engineer in

    Infrastructure Engineering • Mercari, Inc. • Favorites: Go, C, Lua, nginx
  3. GoͰ৭Μͳ΋ͷͭͬͯ͘·͢ • nginx-build - nginxͷϏϧυπʔϧ • cachectl - OSͷϖʔδΩϟογϡ੍ޚπʔϧ •

    slackboard - SlackϓϩΩγαʔό • gaurun - ϓογϡ௨஌ϓϩΩγαʔό શ෦ϝϧΧϦͷதͰ࢖ΘΕ͍ͯ·͢
  4. GoҎ֎Ͱར༻ܦݧͷ͋Δݴޠ • ϓϩμΫγϣϯͰͷར༻ܦݧ͋Γ • C, C++, Lua, PHP, Python, JavaScript

    • JavaScriptͱC++͸΋͏΄ͱΜͲ๨Ε·ͨ͠… • ৮ͬͨ͜ͱ͋ΔϨϕϧ • Perl, Ruby, Scheme, Haskell, Erlang, Scala, etc…
  5. C, C++Ͱͷ։ൃܦݧ • neoagent - memcachedϓϩΩγαʔό • ngx_small_light - ը૾ม׵༻nginxϞδϡʔϧ

    • dtl - diffϥΠϒϥϦ • OSSʹͳͬͯͳ͍ੲͷ͓࢓ࣄ • e.g. ϨίϝϯυΤϯδϯɺ૊ΈࠐΈιϑτ΢ΣΞɺ ޿ࠂ഑৴γεςϜɺetc…
  6. LLͰͷ։ൃܦݧ • WebαʔϏεͷ։ൃɾӡ༻ • e.g. ϑΥτଂ, ·ͪͭ͘, pixiv, ϝϧΧϦ •

    PHP͕ϝΠϯ • ͦͷଞࡉʑͱͨ͠CLIπʔϧΛͨ·ʹPython΍ Ruby౳Ͱॻ͍ͯ·ͨ͠
  7. ݱࡏͷཱͪҐஔͱ͍͏͔ओͳ࢓ࣄ • ϛυϧ΢ΣΞͷ։ൃɾӡ༻ • ֤ॴʹnginxͱGoΛಋೖͯ͠༡Ϳ࠷దԽ • Ansible, Fluentd, Elasticsearch, etc…

    • ͦͷଞࡶଟͳӡ༻޲͚CLIπʔϧͷ։ൃ • rootݖݶ͕ඞཁͳ࢓ࣄશൠ • ҰൠʹΠϯϑϥΤϯδχΞͱݺ͹ΕΔ࢓ࣄ
  8. CͰ͸ͳ͘GoΛબ୒͢Δཧ༝ • (গͳ͘ͱ΋CΑΓ͸)ੜ࢈ੑ͕ߴ͍ • ϝϞϦ؅ཧͷ༰қ͞(ΨϕʔδίϨΫγϣϯ) • ڧྗͳฒߦॲཧͷαϙʔτ(ΰϧʔνϯ) • ΋͏ϚϧνεϨουϓϩάϥϜͷσόοά͢ΔͷźŦƄɾɾɾ •

    Ϗϧυ͕؆୯ • े෼ͳύϑΥʔϚϯε(جຊCͷํ͕଎͍͕ɺGoͰे෼ͳ৔߹΋ ଟ͍)
  9. LLͰ͸ͳ͘GoΛબ୒͢Δཧ༝ • ߴ͍ύϑΥʔϚϯε & ϑοτϓϦϯτ͕খ͍͞ • LLͱൺ΂Δͱ͔ͳΓ଎͍ • ڧྗͳฒߦॲཧͷαϙʔτ(ΰϧʔνϯ) •

    ഑෍ͷ༰қ͞(ΫϩείϯύΠϧɺ୯ҰόΠφϦ) • CLIπʔϧͷ࡞੒ɾ഑෍ɾӡ༻ָ͕
  10. ࣮ྫ

  11. nginx-build

  12. nginx-build • nginxͷϏϧυπʔϧ • nginxͷϏϧυʹ·ͭΘΔ໘౗ࣄΛࣗಈԽ • ιʔείʔυ΍ґଘϥΠϒϥϦͷμ΢ϯϩʔυ • 3rd PartyϞδϡʔϧͷμ΢ϯϩʔυɺ૊ΈࠐΈ

    • https://github.com/cubicdaiya/nginx-build
  13. Why is nginx-build written in Go? • ࠷ॳ͸shͰॻ͍ͯͨ • ੲ͍ͨձࣾʹ͸શࣗಈԽsh͕͋ͬͨ

    • స৬ͯ͠࢖͑ͳ͘ͳͬͨ • ·ͨshॻ͘ͷͭΒ͍͠ɺϝϯς΋ͨ͘͠ͳ͍ • ͦ͏ͩɺGoͰॻ͜͏ʂ
  14. Why is nginx-build written in Go? • ϙʔλϒϧ • ϝϯςָ͕

    • ഑෍΋ָ • ΫϩείϯύΠϧ͕؆୯ • ฒྻॲཧ͕؆୯
  15. nginx-buildͷ࣮ߦ෩ܠ $ nginx-build -d work -pcre -zlib -openssl nginx-build: 0.3.1

    Compiler: gc go1.4.1 2015/03/10 02:04:23 Download pcre-8.36..... 2015/03/10 02:04:23 Download zlib-1.2.8..... 2015/03/10 02:04:23 Download openssl-1.0.2..... 2015/03/10 02:04:23 Download nginx-1.7.10..... 2015/03/10 02:04:28 Extract zlib-1.2.8.tar.gz..... 2015/03/10 02:04:28 Extract nginx-1.7.10.tar.gz..... 2015/03/10 02:04:35 Extract openssl-1.0.2.tar.gz..... 2015/03/10 02:04:39 Extract pcre-8.36.tar.gz..... 2015/03/10 02:04:39 Generate configure script for nginx-1.7.10..... 2015/03/10 02:04:39 Configure nginx-1.7.10..... 2015/03/10 02:04:45 Build nginx-1.7.10..... 2015/03/10 02:07:34 Complete building nginx! ɾ ɾ ɾ $ ฒྻͰ࣮ߦ͞Ε·͢
  16. ͜Μͳײ͡ parallels := 0 done := make(chan bool) (தུ) if

    *pcreStatic { parallels++ go downloadAndExtractParallel(&pcreBuilder, done) } if *openSSLStatic { parallels++ go downloadAndExtractParallel(&openSSLBuilder, done) } if *zlibStatic { parallels++ go downloadAndExtractParallel(&zlibBuilder, done) } parallels++ go downloadAndExtractParallel(&nginxBuilder, done) (தུ) for i := 0; i < parallels; i++ { <-done }
  17. shΑΓͣͬͱָͰ͢

  18. cachectl

  19. cachectl • OSͷϖʔδΩϟογϡ֬ೝɾ࡟আπʔϧ • ແବͳϖʔδΩϟογϡΛղ์͢Δͷʹར༻ • cachectld͍ͬͯ͏σʔϞϯ΋෇͍ͯΔ • https://github.com/cubicdaiya/cachectl

  20. Why is cachectl written in Go? • طଘͷπʔϧ͕࢖͍ʹ͔ͬͨ͘ • e.g.

    σΟϨΫτϦࢦఆ͕Ͱ͖ͳ͍ • σʔϞϯԽͯ͠ఆظతʹ࣮ߦ͔͚ͨͬͨ͠ͲɺͦΜͳػ ೳ࣋ͬͯΔπʔϧ͕ͳ͔ͬͨ • γεςϜίʔϧ͕cgo΍syscallͰ؆୯ʹݺͼग़ͤΔ • ϖʔδΩϟογϡͷ৘ใऔಘ΍ղ์ʹ͸mmap΍ mincoreɺposix_fadvise౳ͷγεςϜίʔϧ͕ඞཁ
  21. cachectlͰϖʔδΩϟογϡͷ ར༻۩߹ΛνΣοΫ $ cachectl -f /var/log/nginx/access.log 2015/03/10 03:08:37 /var/log/nginx/ access.log

    's pages in cache: 1323464/1323464 (100.0%) [filesize=5293852.1K, pagesize=4K] $ 5GBͷϩάϑΝΠϧͷத਎͕ શ෦ϖʔδΩϟογϡʹࡌͬͯΔ
  22. ফͯ͠ΈΔ $ # ϖʔδΩϟογϡΛ࡟আ $ cachectl -f /var/log/nginx/access.log -op purge

    2015/03/10 03:13:03 purging /var/log/nginx/ access.log 's page cache $ $ # ࠶౓ϖʔδΩϟογϡͷར༻۩߹ΛνΣοΫ $ cachectl -f /var/log/nginx/access.log 2015/03/10 03:13:07 /var/log/nginx/access.log 's pages in cache: 94/1325181 (0.0%) [filesize=5300722.2K, pagesize=4K] $ 5GBͷϝϞϦ͕ղ์͞Ε·ͨ͠
  23. ࢦఆͨ͠ϑΝΠϧͷϖʔδΩϟογϡΛղ์͢ΔCͷؔ਺ /* #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h>

    int fadvise(const char *path, float r) { int fd; struct stat st; off_t l; fd = open(path, O_RDONLY); if(fd == -1) { return -1; } if(fstat(fd, &st) == -1) { goto error; } l = (off_t)(st.st_size * r); if(posix_fadvise(fd, 0, l, POSIX_FADV_DONTNEED) != 0) { goto error; } close(fd); return 1; error: close(fd); return -1; } */ import "C"
  24. Go͔Βͷݺͼग़͠ func purgePages(fpath string, fsize int64, rate float64) error {

    if rate < 0.0 || rate > 1.0 { return errors.New(fmt.Sprintf("%f: rate should be less than 1.0\n", rate)) } cs := C.CString(fpath) defer C.free(unsafe.Pointer(cs)) result := C.fadvise(cs, C.float(rate)) if result == -1 { return errors.New(fmt.Sprintf("failed to purge page cache for %s", fpath)) } return nil } C.(ؔ਺໊)Ͱݺͼग़ͤΔ
  25. slackboard

  26. slackboard • SlackϓϩΩγ • clientίϚϯυ(slackboard-cli)෇ଐ • ࠷ۙcronlogͬΆ͍ͷΛ௥Ճ(slackboard-log) • https://github.com/cubicdaiya/slackboard

  27. Why is slackboard written in Go? • net/httpͰ؆୯ʹHTTPαʔό/ΫϥΠΞϯτ͕ॻ ͚Δ •

    slackboard-cli͸શαʔόʹ഑ஔ͍ͨ͠ • GoͳΒ഑෍ָ͕ • LLΈ͍ͨʹ֤αʔόʹ࣮ߦ؀ڥ༻ҙ͠ͳ͍͍ͯ͘
  28. ࣮ߦΠϝʔδ

  29. gaurun

  30. gaurun • ൚༻ϓογϡ௨஌αʔό • ୹࣌ؒͰ਺ेɺ਺ඦສ݅ͷϓογϡ௨஌͕Մೳ • HTTPͱJSONΛϕʔεʹͨ͠γϯϓϧͳAPI • https://github.com/mercari/gaurun

  31. ϝϧΧϦͷϓογϡ௨஌γεςϜ PS CBUDIαʔό

  32. Why is gaurun written in Go? • net/httpͰ؆୯ʹHTTPαʔό/ΫϥΠΞϯτ͕ ॻ͚Δ •

    ڧྗͳฒߦॲཧͷαϙʔτ • ୹࣌ؒͰޮ཰Α͘ϓογϡ௨஌͢Δʹ͸ฒ ߦੑͷߴ͍ݴޠ͕ඞཁ
  33. ·ͱΊ • ੲ͸C΍LLͰॻ͍ͯͨ΋ͷ΋ࠓͰ͸GoͰॻ͘Α͏ʹͳ Γ·ͨ͠ • ҎԼͦͷཧ༝ • े෼ͳύϑΥʔϚϯεͱϑοτϓϦϯτͷখ͞͞ • ڠྗͳฒߦॲཧͷαϙʔτ(ΰϧʔνϯ)

    • Ϗϧυɾ഑෍ͷ༰қ͞