Carpe Diem

備忘録

bugsnagのWeb UIでスタックトレースを表示する方法

背景 サーバサイドでエラー検知・トラッキングのSaaSを利用する場合、bugsnagが候補に挙がると思います。 ただそのままerrorをNotify()してみてもスタックトレースがきちんと表示されない問題にぶつかります。 今回はGoでbugsnagを利用する場合に、bugsnagの…

fmt.Errorfとxerrors.Errorfと独自エラーと

Go

背景 エラーハンドリングでは エラーが発生した箇所を追うことができる スタックトレースが出力できればなお良し エラーの原因によって処理を分岐することができる といったことが重要です。 Go 1.13から入ったラップする仕組みにより、エラーメッセージにア…

VPC ネットワークピアリングで内部IPで疎通する

概要 前回はCloud VPNによる内部IPでの疎通方法を紹介しました。 christina04.hatenablog.com 今回はVPCピアリングを用いた疎通方法を紹介します。 VPCピアリングを用いて内部IPによる接続を行うと以下のメリットがあります。 レイテンシ 外部IPアドレスを使…

Cloud VPN (Classic VPN) を使ってみる

概要 GCPのVPCは物理ネットワークを仮想化したネットワークであり、異なるVPC同士は直接疎通することはできません。 通常であればExternal IP経由もしくはLBなどを用いてアクセスしますが、内部IPで疎通したい場合はVPNを構築する必要があります。 検証 事前…

gRPCのkeepaliveで気をつけること その2

背景 以前gRPCのkeepaliveについて説明しました。 christina04.hatenablog.com keepaliveの目的は idleコネクションを維持するため 死んだコネクション(TCPハーフオープン)があったら切断し、再接続するため と書きましたが、どちらの検証もアクティブなRP…

gRPCのChannelについて

背景 gRPCにはクライアントとサーバとの通信を抽象化したChannelという仕組みがあります。 GRPC_GO_LOG_SEVERITY_LEVEL=infoを有効にした際に出てくる [core] Channel Created [core] parsed scheme: "" [core] scheme "" not registered, fallback to defau…

Kubernetes Eventを保持したりSlack通知させたりする

背景 Kubernetesは宣言的で自己回復するシステムを提供しているため、おかしなコミットが入ったdocker imageをapplyしてCrashLoopBackOffが発生していたりしても前のPodが生きていて気づかなかったみたいなケースがあります。 またメモリが瞬間的に枯渇する…

CircleCIでのslack連携 (Slackアプリ版)

背景 以前CircleCIの新UI後のslack連携を書きました。 今見るとまたやり方が変わっている(Webhook URL→Slackアプリ)ので、やり方を説明します。 環境 CircleCI v2.1 circleci/slack v4.4.2 手順 大きく3ステップあります。 Slackアプリを作る CircleCIのC…

gcloud auth login と gcloud auth application-default login

GCP

概要 ローカルからGCPにアクセスする際に使う gcloud auth login gcloud auth application-default login について区別できるようまとめます。 環境 gcloud v340.0.0 gcloud auth login 用途 こちらはローカルで以下のようなGCP系CLIを実行する際の認証を得…

Slackアプリでチャンネルにメッセージを送信する方法

概要 Slackアプリでチャンネルにメッセージを送信する方法は主に以下の3つがあります。 Incoming Webhooksを使う Bot TokenでSlack API (chat.postMessage) を叩く User TokenでSlack API (chat.postMessage) を叩く それぞれのやり方を説明します。 メッセ…

特定のGCSバケットにのみアクセスできるサービスアカウントの作り方

概要 christina04.hatenablog.com の実践編です。 特定のGCSバケットにのみアクセスできるサービスアカウントを作ってみます。

関連と集約と合成集約の違い

概要 UML図における 関連 (Association) 集約 (Aggregation) 合成集約 (Composition) の違いをまとめます。 関係図 まずそれぞれを集合で表現すると以下のようになります。

GCPのIAMを使う上で理解しておくこと

背景 IAMはアクセス制御をする上で非常に重要な仕組みですが、一方で複雑になりがちです。 間違った理解のままだと必要以上の権限を与えてしまい、事故の原因となるので押さえておくべき点をいくつかまとめてみます。 リソース階層 GCPのIAMにはリソース階層…

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 今回は…

CodecovのBash Uploader問題の再発防止策

概要 コードカバレッジサービスのCodecovでは、カバレッジファイルをアップロードする際に以下のようにbash scriptを実行します。 bash <(curl -s https://codecov.io/bash) ref: Codecov Bash uploader しかし先日、このbash scriptが何者かに勝手に改竄さ…

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

Go

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

トランザクション分離レベルのケースと対応方法

背景 トランザクションの分離レベルで出てくる用語がぱっと頭に浮かぶよう、問題が発生するケースと対応方法をまとめます。 起きうる問題 基本的にどのDBも単一オブジェクトの原子性と分離性は保証します。 つまりデータ送信の途中でネットワーク接続が切れ…

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

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

OpenSSLコマンド備忘録

概要 よく忘れるので備忘録として。 環境 macOS v11.2.3 OpenSSL v1.1.1 秘密鍵、公開鍵 基本的にgenpkeyで作れるが、RSA、EC系は他のコマンドの方が短い記述で生成できる。 RSA /docs/man1.1.1/man1/openssl-genrsa.html /docs/man1.1.1/man1/openssl-rsa.h…

etcdを使った分散ロック

概要 前回のRedisを使った分散ロックでは、正確なロックを取るためにはZookeeperやetcdを使うと良い、とまとめていました。 なので今回はetcdを用いて分散ロックを実現します。 環境 etcd v3.4.15 pkg.go.dev/go.etcd.io/etcd v3.5.0 go 1.16.0 事前知識 分…

Redisを使った分散ロック (SETNX, Redlock)

概要 分散システムにおいて同じリソースにアクセスする際にロック(排他制御)する仕組みを分散ロックといいます。 ロックを用いる背景としては主に2つあり、 目的 説明 具体例 効率 同じ作業を不必要に複数回行わないため キャッシュのOriginへのリクエス…

NEG(Network Endpoint Group)を使った負荷分散

概要 従来のGKEのロードバランサーはNodeに到達後iptablesで再度負荷分散するという2段階ロードバランシングでした。 これによりレイテンシの増加、分散のばらつきといった問題が生じていました。 ref: Google Cloud Blog - News, Features and Announcemen…

セキュアなトークン管理方法

概要 クライアント↔サーバ間の認証・認可情報としてのトークン管理はWebサービスとしては必ずつきまとうものですが、一方できちんと実装しないとセキュアに管理はできません。 今回はそのトークン管理方法の一例を紹介します。 要件 今回の主な要件は以下で…

デッドロックとその対策

概要 複数のトランザクションが共通のリソースにアクセスする際に気をつけるものとしてデッドロックがあります。 例えばこのように一方はResource1, Resource2とロックしてアクセスし、もう一方はResource2, Resource1とロックしてアクセスする場合、うまく…

OAuth 2.0 Device Authorization Grant

概要 サービスのマルチデバイス対応をした際に、各デバイスで同じアカウントにログインするのはユーザにとっては非常に手間です。 例えばテレビデバイスに対応した場合にID&パスワードをリモコンで入力させるのはユーザにとって苦痛でしかありません。 なの…

SquidをForward Proxyサーバとして使う

概要 Forward Proxyを導入することで以下のメリットを得ることができます。 DNS lookupをキャッシュして名前解決を高速化 Targetからのレスポンスをキャッシュして高速化 TargetがIP制限している場合に、送信元IPを固定するサーバにする ↑と逆にTargetの制限…

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.…