Carpe Diem

備忘録

Go

Go modulesで依存モジュールのメジャーバージョンがv2以上の時の対応

Go

背景 依存するモジュールのメジャーバージョンがv2以上の場合に、以下のようにバージョン指定すると $ go get github.com/xxx/yyy@v2.0.1 次のように怒られます。 require github.com/xxx/yyy: version "v2.0.1" invalid: should be v0 or v1, not v2 今回は…

ユースケースに応じたユニークなIDの生成

Go

概要 ユニークなID生成をしたい場面は多々ありますが、ユニークIDにはユースケースによって以下のような要件が出てきます。 ユニーク 短い(=データ量が少ない) 推測困難 分散性(ランダム性) 順序性(Lexicographical) 生成速度 それぞれの観点について…

JWTの署名検証で使う公開鍵をX.509証明書で管理する

概要 JWTをアクセストークンとして利用する場合、署名(秘密鍵)は認証サーバで、署名検証(公開鍵)はリソースサーバで行うのが良いです。 そのため認証サーバは公開鍵をリソースサーバに公開する必要があります。 Googleなどの大規模サービスを見ると、生…

http clientでHTTP/2を使う方法

背景 外部APIを叩く時に利用するhttp clientですが、サーバ側がHTTP/2対応しているのであればコネクションの有効活用ができるようHTTP/2を使いたいものです。 その際にhttp client側で設定する点、気をつける点を説明していきます。 環境 Go 1.15.6 curl 7.6…

WARNING: Missing 'go_package' option が出る時の対処法

背景 いつの間にかprotocでprotoc-gen-goプラグインを使うと以下のようなエラーが出るようになりました。 2021/01/05 06:19:01 WARNING: Missing 'go_package' option in "xxx/xxx.proto", please specify it with the full Go package path as a future rel…

ポインタを図で理解する

Go

概要 Goのポインタを図で理解することで ダブルポインタとは Goは全て値渡し ポインタレシーバと値レシーバの違い がどういうことかを理解でき、参照渡しの時に x = y だと更新されず *x = *y だと更新される理由が分かります。

structのメモリ割り当て

Go

概要 Goにおけるstructのメモリ構造を知ることでフィールド順序に対する意識が変わったり、なぜunsafe.Sizeof(string)が16bytesでunsafe.Sizeof(slice)が24bytesになるかが理解できます。 環境 Go 1.15.6 darwin 20.1.0 x86_64 各型のメモリ割り当て unsafe.…

GoでShutdown Hook

Go

背景 以前Graceful shutdown機能の使い方を紹介しました。 christina04.hatenablog.com これによって処理途中のリクエストが残っていても、きちんと完了するまで待ってからプロセスを終了してくれます。 しかしPubSubのPublish()のような非同期処理であれば…

継続的プロファイリング

背景 過去にいくつかpprofの使い方を紹介しましたが、実際に運用する上では以下の課題があります。 何かしら問題が発生して初めてプロファイリング開始するという後手になりがち 問題の再現が難しく、再び発生するまで様子見という流れになりがち プロファイ…

GCPのCloud PubSubで考慮すること

概要 GCPのCloud PubSubはメッセージング基盤として非常に有用です。 ただし利用する上で考慮すべきことも多々あるのでまとめておきます。 パラメータに関しては主にGoのクライアントライブラリをベースに説明します。 環境 Go 1.15.2 google-cloud-go v0.72…

データ暗号化で考慮すること(鍵編)

概要 前回の続きです。 christina04.hatenablog.com 今回は暗号化における鍵(共通鍵)について説明します。 前提知識 鍵とは 鍵とはとても大きな数です。 鍵のビット長が大きい=鍵空間が大きいことを意味します。つまり可能な鍵の総数が大きいため総当り攻…

データ暗号化で考慮すること(暗号アルゴリズム編)

概要 ユーザのメールアドレスといった機密情報を暗号化・復号したいユースケースがあるとします。 メール送信などに利用するためパスワードのようにハッシュ化するのでなく、復号して利用したいケースです。 機密情報の管理全般については以前↓で話しました…

GoのCLIで標準入力とファイル読み込みの両方に対応する

Go

概要 Goでは簡単にコマンドラインツールが作れますが、人によって引数やオプションといったインタフェースがバラバラになりがちです。 POSIX Utility Syntax Guidelinesというガイドラインがあるので、これに則るとUnixライクな統一されたインタフェースのCL…

gRPCのkeepaliveで気をつけること

概要 gRPCでは1つのHTTP/2コネクション上でstreamを多重化します。 しかしidleなコネクションは、LBなど間に介在するネットワーク機器によって気づいたら切断されているケースがあります。 そうならないよう、定期的にパケット(PINGフレーム)を流して「id…

GoGo Protobufのメリット・デメリット

概要 Goでprotobufのコードを生成する際には公式のgolang/protbuf以外にgogo/protobufが候補に挙がると思います。 メリット 大きなメリットはパフォーマンスとカスタマイズ性です。 marshalling と unmarshalling が高速 去年のベンチマークですが、公式より…

Go でサーバレスポンスの内容を表示

Go

概要 開発中にサーバレスポンスの内容を表示したい時があると思いますが クライアントが受け取ったレスポンス サーバが送ったレスポンス のそれぞれをログなどで表示する方法を紹介します。 環境 go 1.14.3 クライアントが受け取ったレスポンスを表示 クライ…

Goのioパッケージのメソッドを図示

Go

概要 Goのioパッケージにはio.Reader、io.Writerのインタフェースを有効活用するため以下のような便利なメソッドが用意されています。 io.Copy io.Pipe io.MultiReader io.MultiWriter io.TeeReader しかし普段から使っていないと、これらメソッドの方が簡単…

CPU CFS Quotaを制限している場合の適切なGOMAXPROCS

概要 christina04.hatenablog.com 以前上の記事でGOMAXPROCSはCPU数程度が適切に動くという話をしました。 これはこれで正しいのですが、一方でdockerのようにcgroupsでCPU Quotaを制限するケースではこれに当てはまらなくなります。 Kubernetesでいうと Kub…

Go Module MirrorとChecksum Database

Go

概要 Go 1.13から、goコマンドはデフォルトでGo Module MirrorとChecksum Databaseを使用してモジュールをダウンロード&認証するようになりました。 環境 go 1.14.1 Module Mirror (Module Proxy) Module Mirrorは公開モジュールをキャッシュし、go modでの…

go generateでモックを生成する

Go

背景 Clean Architecture に則ってレイヤ間をプラガブルにするためにインタフェースを使っていくと、テストのために各インタフェースのモックが欲しくなります。 そのモックを生成する際にgolang/mockを使用するわけですが、毎回 $ mockgen -source user.go …

gRPCでのLoad Balancing

背景 gRPCでは主に Proxy Model Balancing-aware Client External Load Balancing Service といったLBアプローチがあります。 それぞれの特徴や実装方法を調べてみました。 Load Balancingアプローチ こちらで定義されてます。 grpc/load-balancing.md at ma…

gRPCでのClient-Side LB実装の変遷

概要 gRPCでのバランシングをClient-Sideで直接実装する方法の紹介です。 gRPCはPolyglot(様々な言語で扱う)を意識しているので、gRPC自体の仕様が策定→各言語がそれに則って実装となります。 なので「元々はこういう実装だったけど、他の言語と統一してこ…

go modulesでコマンドラインツールのバージョン管理をする

Go

概要 goはModulesでリポジトリのライブラリのバージョン管理を行えます。 ただコマンドラインツールに関してはgo getしてgo.modに追加されても、goファイルで扱っているわけではないのでgo mod tidyすると消えてしまいます。 しかしながら「この機能は最新の…

GoのDIツールwireで知っておくと良いこと

Go DI

概要 christina04.hatenablog.com こういった設計のようにレイヤ間の依存関係を抽象化していると、DIの初期化処理が段々冗長になっていきます。 google/wireはそういったDIの初期化を自動的にやってくれるコード生成ツールです。 今回はwireを使う上で知って…

vim-goからvim-lspへ移行しました

概要 vim-goからvim-lspへ移行する時に問題になってたところを全部mattnさんが解決してくださってたのでようやく完全移行したという話です。 環境 vim 8.2 go 1.13.5 これまでの課題 vim-goの問題点 2014年からgoを触っていましたが当時はvim-go一択で、しか…

cgoを使わないGoのクロスコンパイル時に -installsuffix cgo が不要になってた

背景 以前Docker multi stage buildなどビルド環境と実行環境が異なる(クロスコンパイル)時に、単純にGOOSやGOARCHをセットするだけではなく $ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ go build -a -installsuffix cgo -o main main.go のように CGO_ENA…

Go の http.Server は各種 Timeout をセットした方が良い

Go

概要 以前↓の記事を紹介しましたが、 christina04.hatenablog.com http.Serverの各Timeoutを使わないと TCPハンドシェイクをしたあと全くリクエストを送ってこないクライアント Slowloris DDoS attack による大量接続攻撃を受けた時に困るので注意してくださ…

pipeエラーのハンドリング

概要 write: broken pipeといったクライアント側の強制的なコネクション切断でのエラーハンドリングをする際の知見まとめ。 環境 golang/go 1.13.3 事前知識 知っておくと良い知識を先に説明します。 そもそもpipeとは pipeはプロセス間通信をするための単方…

Goのnet/httpのkeep-aliveで気をつけること

概要 Idle connectionをプールするkeep-aliveの仕組みですが、Goで適切に使用するためにはいくつか注意があります。 環境 golang/go 1.13.1 TCP Keep-Aliveの挙動をパケットキャプチャで確認する 例えば以下のようにDefaultTransportの一部の設定(①、②)を…

Goのnet/httpのtimeoutについて

Go

概要 タイムアウトと一口に言ってもサーバ・クライアント、そして各フェーズによって細かく設定があります。 今回はGoのnet/httpのtimeoutについて1つ1つ説明していきます。 環境 golang/go 1.13 Server 全体図 サーバ系timeoutと各フェーズは以下の関係に…