タグ

ブックマーク / christina04.hatenablog.com (30)

  • 開発者ポータル Backstage とは - Carpe Diem

    背景 開発チームが抱えるよくある課題として システムが変化する一方でドキュメントは更新されず腐る メンバーの流入出によって口伝でかろうじて継承された知見も失われる 検索性が良くないと過去のドキュメントが気づかれず、同じような内容のドキュメントが新規量産される 後から参加したメンバーはどちらが正のドキュメントか分からず混乱する といったことが良くあります。 解決方法としては以下のように、GitHub&ルールベースで管理するといった例があります。 future-architect.github.io また組織・システムが大きくなってくると認知負荷を低減するためにドメインで区切るような形でチームの分割が始まりますが、 異なるチームによってシステムが管理され、システムの依存関係を全て知っている人がいなくなる CxOレイヤが大規模イベント前に現状を把握したいときに都度時間がかかってしまう チームごと

    開発者ポータル Backstage とは - Carpe Diem
  • IstioやEnvoyで発生するネットワーク系エラー - Carpe Diem

    背景 マイクロサービス環境でIstio(Envoy sidecar)を使っていると、いくつかのエラーに遭遇します。 それぞれどういった状況で発生しているエラーなのかを区別できないと、適切な対応にならないため各種エラーをまとめます。 環境 Envoy 1.22.0 Go 1.21 構成 次のようにclient appやserver appにsidecarが挟まるようにします。 エラー dial tcp 172.20.0.4:8001: connect: connection refused connection error: desc = "transport: Error while dialing: dial tcp 172.20.0.4:8001: connect: connection refused が発生するパターンです。 周辺ログも含めると次のようになります。 timeout-

    IstioやEnvoyで発生するネットワーク系エラー - Carpe Diem
  • gRPCで一時的なネットワーク断でのtransportエラーを回避する - Carpe Diem

    背景 gRPCを利用していると、デプロイを含む一時的なネットワーク断で以下のようなエラーが発生することがあります。 rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp xxx: connect: connection refused" rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp: lookup xxx: i/o timeout" これはgRPCがfail fastの思想になっており、ChannelがTRANSIENT_FAILUREの状態だとRPCを即座に失敗させるようにして

    gRPCで一時的なネットワーク断でのtransportエラーを回避する - Carpe Diem
  • Envoyで重み付き負荷分散を試してみる - Carpe Diem

    概要 christina04.hatenablog.com の中でconfig.route.v3.RouteActionに重み付き負荷分散(weighted load balancing)の設定がありました。 これを利用することで カナリアリリース リクエストのサンプリング 一部だけ詳細なログやstatsを出す Mountebankのようなリクエストをレコードしてリプレイできるモックサーバに流す といったことが容易に実現できます。 今回はこの機能を試してみます。 環境 v1.24.0 Weighted load balancing 設定 Listener 設定は簡単で、weighted_clusters.clustersに対象とするclusterとリクエストを振り分けする重みの設定を行うだけです。 以前はtotal_weightで重みの合計を指定する必要がありましたが、現在はdepreca

    Envoyで重み付き負荷分散を試してみる - Carpe Diem
  • EnvoyのVirtual hostを読み解く - Carpe Diem

    概要 EnvoyのルーティングはListener > Network filter chain > HCM(HTTP connection manager)のVirtual Hostで適用されます。 設定の一部は配列で複数設定することができますが、ものによっては 一致率が高いものから順に適用する(完全一致→部分一致→ワイルドカードなど) 先に設定した順で走査し、マッチしたものを適用する といった違いがあったりなど、きちんと理解していないとハマることがあるので1つ1つ読み解いていきます。 環境 Envoy v1.24.0 解説 例えば以下のような設定があるときに「これだけ知っておけばとりあえず大丈夫」な最低限理解しておく必要があるものを書いていきます。 route_config: name: local_route virtual_hosts: - name: local_service d

    EnvoyのVirtual hostを読み解く - Carpe Diem
  • FastAPIのメトリクスをマルチプロセスモードで収集する - Carpe Diem

    背景 PythonはGILがあるためマルチコアの恩恵を受けづらいです。そのためGunicornのようなプロセスマネージャを利用してマルチプロセスで稼働させ、パフォーマンスを上げるといった手法があります。 しかしマルチプロセスにした場合、Prometheusのメトリクス値が収集するプロセス毎に異なってしまい、来単調増加するはずの値が増減してしまいおかしなメトリクスになってしまいます。 単調増加せず途中途中で減少する ref: Strange drops in total requests · Issue #50 · trallnag/prometheus-fastapi-instrumentator · GitHub そこでPythonのPrometheus clientにはマルチプロセスモードが用意されており、外部共有ファイルにstatsを書き出すことで整合性を保証します。 今回はFas

    FastAPIのメトリクスをマルチプロセスモードで収集する - Carpe Diem
  • FastAPIでPath Operationに def と async def どちらを使うべきか - Carpe Diem

    背景 FastAPIでは以下のようにデコレータ関数を使うことでHTTPサーバのpathを設定することができ、これをPath Operationと呼びます。 from fastapi import FastAPI app = FastAPI() @app.get("/") async def read_root(): return {"Hello": "World"} @app.get("/items/{item_id}") async def read_item(item_id: int, q: str = None): return {"item_id": item_id, "q": q} このPath Operationでdefを使うべきかasync defを使うべきかの方針を説明します。 環境 Python 3.9.11 FastAPI 0.74.1 方針 結論から言うと以下の方針で

    FastAPIでPath Operationに def と async def どちらを使うべきか - Carpe Diem
  • EnvoyのYAMLの読み方 - Carpe Diem

    概要 Envoyyamlは非常に長大で初めて読む人からするととても分かりにくいです。 しかし実際は各要素の役割を理解するととてもシンプルに構成されていることが分かります。 そのための手助けとしてこちらで図を交えながら説明します。 環境 Envoy 1.22.0 要素の説明 まずは各要素を理解します。 downstreamとupstream 要素 説明 downstream Envoyからみたクライアント upstream Envoyがサービスに対するリクエストを転送する際に接続するエンドポイント(ネットワークノード) よくあるパターンで図示してみると以下です。 front proxyモデル sidecarで外部からリクエストを受ける sidecarでローカルアプリケーションからのリクエストを転送する このようにsidecarモデルのローカルアプリケーションは、downstreamにもup

    EnvoyのYAMLの読み方 - Carpe Diem
  • Cloud PubSubのOrdering Keyで考慮すること - Carpe Diem

    概要 以下のような購入時のドメインイベントをメッセージング基盤に非同期で渡してから順番通りに実行したい、となった時に便利なのが順序保証をしてくれるPubSubのordering keyです。 購入処理 各マイクロサービスへの状態変更リクエスト 行動ログ追記 購入完了メールの送信 ただordering keyを使う上での注意点はあまり見かけなかったのでこちらにまとめようと思います。 結論から言うとordering keyの粒度はなるべく細かくしないとスケールしないという話です。 環境 cloud.google.com/go/pubsub v1.19.0 考慮すべき点 同じordering keyのメッセージは同じパーティションにpublishされる Cloud PubSubはメッセージング基盤の概念であるパーティション(Kinesisでいうシャード)をカプセル化しており、ユーザが意識しなくて

    Cloud PubSubのOrdering Keyで考慮すること - Carpe Diem
  • GoのロギングライブラリzapのTips - Carpe Diem

    概要 zapを使っていて 書き込み先をio.Writerで自由に設定したい テストで時刻を固定値にしたい ログレベルによって標準出力、標準エラー出力を分けたい GCP Cloud Loggingのフォーマットでログ出力したい 全ログに付けたいフィールドがある 独自logパッケージでラップしたらcallerがおかしい とちょっとカスタマイズしたいケースのTipsです。 環境 Go 1.17 go.uber.org/zap v1.19.1 Tips 書き込み先をio.Writerで自由に設定したい zapのデフォルトの出力先は標準エラー出力ですが、期待通りのフォーマットでログが出力されているか確認したい時にio.Writerを渡してそこに書き込んでほしい場合です。 そんなときはzapcore.AddSyncを使います。 func NewWithWriter(w io.Writer) *zap.

    GoのロギングライブラリzapのTips - Carpe Diem
  • gRPCのChannelについて - Carpe Diem

    背景 gRPCにはクライアントとサーバとの通信を抽象化したChannelという仕組みがあります。 GRPC_GO_LOG_SEVERITY_LEVEL=infoを有効にした際に出てくる [core] Channel Created [core] parsed scheme: "" [core] scheme "" not registered, fallback to default scheme [core] ccResolverWrapper: sending update to cc: {[{localhost:8080 <nil> 0 <nil>}] <nil> <nil>} [core] Resolver state updated: {Addresses:[{Addr:localhost:8080 ServerName: Attributes:<nil> Type:0 Meta

    gRPCのChannelについて - Carpe Diem
  • gRPCのkeepaliveで気をつけること その2 - Carpe Diem

    背景 以前gRPCのkeepaliveについて説明しました。 christina04.hatenablog.com keepaliveの目的は idleコネクションを維持するため 死んだコネクション(TCPハーフオープン)があったら切断し、再接続するため と書きましたが、どちらの検証もアクティブなRPCがなくなってからのkeepaliveの例であり、リクエストが続く中での挙動は検証できてなかったので今回はそれを行います。 環境 grpc-go v1.38.1 Ubuntu 18.04 (Linux Kernel 4.15.0-147-generic) PINGフレームはいつ送信される? Client-side keepaliveのパラメータであるTimeで送信間隔は設定できますが、いつ条件を満たして発火する(タイマーが開始する)かについては説明していませんでした。 Proposalでは i

    gRPCのkeepaliveで気をつけること その2 - Carpe Diem
  • gRPCのkeepaliveで気をつけること - Carpe Diem

    概要 gRPCでは1つのHTTP/2コネクション上でstreamを多重化します。 しかしidleなコネクションは、LBなど間に介在するネットワーク機器によって気づいたら切断されているケースがあります。 そうならないよう、定期的にパケット(PINGフレーム)を流して「idleではないよ」とコネクションを維持しようとするのがいわゆるkeepaliveという仕組みです。 gRPCではデフォルトの設定では無効になっている&地味に設定が細かいので1つ1つ説明します。 gRPCのkeepaliveの役割 大きく2つあります。 1つ目は先に述べたようにidleコネクションを維持するためです。 2つ目は死んだコネクション(TCPハーフオープン)があったら切断し、再接続するためです。 例えばNLBでは350秒以上idleなコネクションが切断される仕組みがあり、これによって普段あんまりトラフィックの無いサービ

    gRPCのkeepaliveで気をつけること - Carpe Diem
  • GoのCLIで標準入力とファイル読み込みの両方に対応する - Carpe Diem

    概要 Goでは簡単にコマンドラインツールが作れますが、人によって引数やオプションといったインタフェースがバラバラになりがちです。 POSIX Utility Syntax Guidelinesというガイドラインがあるので、これに則るとUnixライクな統一されたインタフェースのCLIツールになります。 環境 golang/go v1.15.1 インタフェースのイメージ 例えば文字列の入ったファイルがあり $ cat sample.txt hogefuga 入力文字列をすべて大文字にするコマンドcapitalizeを作る場合、以下の3つのインタフェースをサポートするイメージです。 $ cat sample.txt | capitalize HOGEFUGA $ cat sample.txt | capitalize - HOGEFUGA $ capitalize sample.txt HOGE

    GoのCLIで標準入力とファイル読み込みの両方に対応する - Carpe Diem
  • CPU CFS Quotaを制限している場合の適切なGOMAXPROCS - Carpe Diem

    概要 christina04.hatenablog.com 以前上の記事でGOMAXPROCSはCPU数程度が適切に動くという話をしました。 これはこれで正しいのですが、一方でdockerのようにcgroupsでCPU Quotaを制限するケースではこれに当てはまらなくなります。 Kubernetesでいうと Kubernetesのresource requests, limits - Carpe Diem のようにlimitsを設定した場合ですね。 今回はその検証と対応方法についてまとめます。 環境 go 1.14.2 docker 19.03.8 CPU Quotaを制限してベンチマーク 以下の素数を算出するというCPUバウンドなプログラムを使います。 gotutorials/concprime at master · embano1/gotutorials · GitHub PCのC

    CPU CFS Quotaを制限している場合の適切なGOMAXPROCS - Carpe Diem
  • Prometheus でカスタムコレクタを用意する - Carpe Diem

    概要 以前↓の独自メトリクスを作る方法を紹介しました。 christina04.hatenablog.com これはdirect instrumentation(直接計装)というやり方で、アプリケーションサーバ自体がstatsを持ちprometheusにデータを渡すやり方です。 今回はそうではなく別プロセスや別サーバ、ホストOSのstatsを取り込んでコレクタとして登録する方法を紹介します。 イメージ的には各stats情報をprometheusフォーマットに変換するproxyを作る感じです。 環境 prometheus/client_golang 1.5.0 Collectorインタフェース GoではCollector interfaceを実装することでCustom Collectorを作れます。 Collector interfaceは以下の2つのメソッドを持っています。 Describ

    Prometheus でカスタムコレクタを用意する - Carpe Diem
  • PrometheusがStatsDより優れているところ - Carpe Diem

    概要 新しい技術というのは既存の技術にある課題を解決するために生まれてきます。 入門 監視 ―モダンなモニタリングのためのデザインパターン 作者:Mike Julianオライリー・ジャパンAmazon はStatsD&Graphiteを中心に説明されており、同時期に読んだ 入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング 作者:Brian BrazilオライリージャパンAmazon と比較して、メトリクス系ツールの古株であるStatsDより後発のPrometheusは、StatsD&Graphiteのどんな課題を解決しているかをまとめます。 Prometheusが優れているところ 大きく以下の3つが良いと思います。 ラベルベースの柔軟なメトリクス名 データ欠損しても推測可能 充実したExporter ラベルベースの柔軟なメトリクス名 メトリクス名など自由

    PrometheusがStatsDより優れているところ - Carpe Diem
  • gRPCのヘルスチェック - Carpe Diem

    概要 gRPCサーバのヘルスチェック方法として HTTPサーバを別途立ち上げてHTTPでチェック tcpでポートがopenしたかチェック といった方法がありますが、前者はgRPCサーバなのにHTTPサーバを用意しないといけなかったり、後者はtcpのopenは実際にServe開始したタイミングではないといった課題があります。 そこでKubernetesでは3番目の手段として何かしらのヘルスチェックのgRPCをコマンドラインから呼んでチェックする方法を推奨しています。 ref: Health checking gRPC servers on Kubernetes - Kubernetes 環境 go 1.13.5 grpc-go 1.27.1 Kubernetes v1.15.5 GRPC Health Checking Protocol 3番目の手段ですが、実はgRPCの方でヘルスチェック用

    gRPCのヘルスチェック - Carpe Diem
  • gRPCでのLoad Balancing - Carpe Diem

    背景 gRPCでは主に Proxy Model Balancing-aware Client External Load Balancing Service といったLBアプローチがあります。 それぞれの特徴や実装方法を調べてみました。 Load Balancingアプローチ こちらで定義されてます。 grpc/load-balancing.md at master · grpc/grpc · GitHub 主な負荷分散のアプローチとしては以下です。 Proxy Model LBと言われて最初に浮かぶイメージですね。 ref: https://grpc.io/blog/loadbalancing/ メリット クライアントと独立しているため、クライアントは自身のアプリケーション実装にのみ集中できます。シンプルでPolyglot向きでもあります。 またProxy側に様々な拡張ができます(メトリ

    gRPCでのLoad Balancing - Carpe Diem
  • GoのDIツールwireで知っておくと良いこと - Carpe Diem

    概要 christina04.hatenablog.com こういった設計のようにレイヤ間の依存関係を抽象化していると、DIの初期化処理が段々冗長になっていきます。 google/wireはそういったDIの初期化を自動的にやってくれるコード生成ツールです。 今回はwireを使う上で知っていると便利なところをまとめます。 環境 golang 1.13.5 wire 0.4.0 wireの使い方知らない人 以下のチュートリアルが非常に分かりやすいので一度やってみてください。 github.com 実務で知っておくと良いポイント Injectorの用意の手順 小さい依存関係であれば頭の中で把握できてサクッとかけますが、巨大なリポジトリになってくると何が何に依存しているか分からなくなってきます。 そういった場合まず最終的に用意するInjectorを生成するProviderだけwire.Build

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