History of Go usage ▌2013-08 Start using Go to replace Python services ▌2014-02 First Go OSS: kintone Go SDK https://github.com/kintone/go-kintone ▌2016-02 Org. for Go OSS: https://github.com/cybozu-go
Why do we prefer Go? ▌Statically typed, yet compiles fast ▌Small and container-friendly executables ▌Concurrent programming made easy ▌Less to learn than C++, Java, …
Problem ▌We have a lot of Go products using a lot of third-party libraries to run in a production environment. ▌We should be able to: update third-party libraries easily, reproduce the executable reliably, and keep enough quality for production use.
Mono-repository ▌We maintain a single Git repository to share library packages between all programs used in-house ▌No package-local vendoring ▌Updating a library is just easy!
Mirroring ▌We use `git subtree` to mirror packages on Internet including ours. ▌By mirroring, we can: tolerate github.com failures, tolerate repository deletions, and reproduce the same executable.
Frameworks ▌No, it doesn’t mean Web frameworks. ▌We think production-grade programs should: leak no resources, output enough logs to shoot troubles, have proper timeouts, and exit / restart gracefully.
Frameworks (contd) ▌To help creating production-grade Go products, we have two frameworks: github.com/cybozu-go/log standardize log fields and formats. github.com/cybozu-go/cmd manage goroutines, logging, signals, etc. ▌Both are open source.
github.com/cybozu-go/log ▌Structured logging framework (≠ library) ▌Support three formats: plain, logfmt, JSON Lines ▌Simple and very fast 449K log/s in JSON Plain is a bit slow because it sorts fields.
github.com/cybozu-go/cmd ▌ This framework imposes the use of context in virtually all goroutines. ▌ Features Standardized signal handling Graceful restart of servers Logging using cybozu-go/log etc. https://ymmt2005.hatenablog.com/entry/2016/09/03/Making_well-behaved_programs_in_Go_with_cybozu-go/cmd
transocks and usocksd ▌github.com/cybozu-go/transocks Redirect outgoing TCP connections to a SOCKS or HTTP proxy transparently Use iptables instead of LD_PRELOAD works for programs independent of libc. ▌github.com/cybozu-go/usocksd SOCKS4/5 server (and library) Dynamic IP deselection using DNSBL https://ymmt2005.hatenablog.com/entry/2016/03/13/Transparent_SOCKS_proxy_in_Go_to_replace_NAT
github.com/cybozu-go/placemat ▌Virtual data center construction tool A product from Neco project to simulate CLOS & BGP network Under active development ▌Features Stateless (unlike libvirt) cloud-init & Ignition UEFI boot …
Vermeer ▌Not an OSS yet ▌Thumbnail generation service supports JPEG, GIF, TIFF, PNG, BMP ▌Pure Go implementation using github.com/disintegration/imaging to minimize vulnerabilities
What happened 1. Journald died. 2. Go got EPIPE and sent SIGPIPE to itself. 3. transocks died with SIGPIPE. 4. systemd did not restart transocks because it figured that exit with SIGPIPE is not a failure!!!
Journald dies ▌Journald is not PID 1. ▌So, the process may be killed, for example, by OOM killer. ▌Journald had bugs that killed it. One bug was fixed by us:
systemd and SIGPIPE ▌SuccessExitStatus directive defines what should be considered successful exit. ▌The default is exit code 0, SIGHUP, SIGINT, SIGTERM, and SIGPIPE!
Our recommendations ▌Output logs to files rather than journald. ▌Adjust OOM score of journald: ▌Add this line to your service unit files: $ cat /etc/systemd/system/systemd-journald.service.d/oom_score_adj.conf [Service] OOMScoreAdjust=-1000 RestartForceExitStatus=SIGPIPE