Carpe Diem

備忘録

Envoyで自動リトライ

概要

ネットワーク越しの通信は基本的に不安定であるため、外部APIとの通信で発生したエラーを都度クライアントに返すとエラー率が上がってしまいユーザ体験が悪くなってしまします。

そこでクライアントに返す前に何度かリトライすることで、エラー率を下げるようにするという実装を行うことが多いです。
例えばGCPSDKではgax-goというライブラリがそこを保証してくれています。

google-cloud-go/invoke.go at 20e9b2acf7766594da827da62858d83cb03fed81 · googleapis/google-cloud-go · GitHub
gax-go/invoke.go at ce75229dd089591008bbaf03b1518474f9830646 · googleapis/gax-go · GitHub

しかしこういった処理は本来アプリケーションで表現したいドメイン部分ではないので、できればEnvoyやIstioといったソリューションで解決したいです。

今回はEnvoyでの設定方法を説明します。

環境

  • Envoy 1.22.0

構成

以下のように前段にEnvoyを挟んでバックエンドのリトライを自動化します。

続きを読む

Bazel で multiple copies of package passed to linker の対応方法

概要

Bazelでビルド時に

multiple copies of package passed to linker: @io_bazel_rules_go//proto/wkt:field_mask_go_proto @org_golang_google_genproto//protobuf/field_mask:field_mask

のようなエラーが出た時の対応です。

環境

  • Bazel 5.0.0
  • gazelle 0.25.0
  • grpc-gateway 2.10.3

原因

protobufのWKT(Well Known Types)は複数のルールで提供されています。

複数のライブラリが同じproto(今回だとgoogle.golang.org/genproto/protobuf/field_mask)に依存している状態で、けれど依存するルールが異なる場合にこの問題が発生します。

よく起きるケースとしては以下の両方を満たす場合です。

  • あるライブラリは事前に生成された.pb.goに依存している
  • 別のライブラリはBazelビルド時に.protoから生成される
続きを読む

Adaptive Concurrency

概要

christina04.hatenablog.com

で説明したように、Circuit Breakerのパラメータ調整は大変です。

実際のキャパシティよりパラメータを小さくしてしまうと、リソースはまだ余裕があるのにOpenしていまいます。
逆にパラメータが大きすぎると、Openが遅れサービス側に過負荷がかかってしまいます。

また一度適切に設定してからも、実装によってキャパシティが変更されればそれに合わせてCircuit Breaker側も変更が必要になります。

そのようなCircuit Breakerの課題を解決するものとしてAdaptive Concurrencyというものがあるので紹介します。

環境

  • Envoy v1.22.0
続きを読む

EnvoyのYAMLの読み方

概要

Envoyのyamlは非常に長大で初めて読む人からするととても分かりにくいです。

しかし実際は各要素の役割を理解するととてもシンプルに構成されていることが分かります。

そのための手助けとしてこちらで図を交えながら説明します。

環境

  • Envoy 1.22.0

要素の説明

downstreamとupstream

要素 説明
downstream Envoyからみたクライアント
upstream Envoyがサービスに対するリクエストを転送する際に接続するエンドポイント(ネットワークノード)
続きを読む

外部サービスへのリクエストにEnvoyのCircuit Breakerを設定する

概要

サービスの信頼性を高めるため、依存するマイクロサービスが落ちても障害範囲をそこだけに留め、それ以外のマイクロサービスは稼働し続けるのが理想です。

自分たちのサービスであれば各マイクロサービスにCircuit Breakerを設定することで、スローダウンした際に即座に503を返しリクエストをスタックさせずに迅速に返すことが可能です。

一方外部サービスの場合はCircuit Breakerを備えているかはサービスによって異なります。場合によってはスローダウンした場合ずっとリクエストが返らず、依存しているマイクロサービスはリクエストがどんどんスタックしてOOMが発生する可能性があります。

Envoyを使うと外部サービスへのリクエストに対しても簡単にCircuit Breakerを設定することが可能です。

環境

  • Envoy v1.22.0
  • Go v1.18.3
続きを読む

Envoy Circuit Breakerの挙動を確認する

背景

EnvoyにはCircuit Breakerがあり、依存するサービスがスローダウンした際にそれ以上リクエスト送らず即座に503を返すことでサービスが死なないようにする仕組みがあります。

しかしパラメータの調節が難しく、期待した挙動にならないことが多いため1つ1つのパラメータの挙動をメトリクスとともに書いておきます。

環境

  • Envoy v1.22.0

構成図は以下です。

続きを読む

MongoDBでindexを整理する際に使ったコマンド

概要

MongoDBで使っていないindexを整理する際に使ったコマンドのチートシートです。

バックアップ用途の吐き出しコマンドとスプレッドシートで確認しやすくするためのコマンドを主に書きます。

環境

  • MongoDB v3.6.23

コマンド

以下にそれぞれのケースでのスクリプトを書きます。実行時は

$ mongo mongodb://{YOUR_HOSTNAME}:27017/{YOUR_DB_NAME} < script.js > output.txt

といった形で行います。

続きを読む