20211129のGoに関する記事は5件です。

1つのKubernetesクラスタで複数のシングルテナント向けの証明書を取り扱う

背景 あるところに、Azure Kubernetes Serviceを用いたWebサービス公開に携わる一人のエンジニアがおりました。 ある日彼はこんなことを考えました。 (-"-)「今開発中の機能はサーバー負荷がかなり大きい…」 (-"-)「利用が集中すると他のユーザーに影響する恐れがある…」 (-"-)「でもユーザーによってはそういった形での業務影響が許されない…」 (・_・)!「よし、シングルテナント構成を取れるようにしよう」 そこで彼はハイパフォーマンスを要求するユーザー向けに個別のクラスタ構成を定義し、それぞれを別のnamespaceで動かすことを考えました。また各ユーザー向けには専用のサブドメインを切り、Azure DNSを用いてドメイン毎に別のクラスタが利用されるよう振り分けを行うことにしました。 めちゃ雑に図にするとこんな感じです。 本題 さて、もはや常時HTTPSが当たり前の時代で、彼のWebサービスでもHTTPS越しにサービスを公開しています。ドメインが増えればその当然そのサーバー証明書が必要になります。 証明書はお金で買うことも出来ますし、買った証明書はKubernetesのsecretを経由することで比較的に各Podへの配布ができます。しかし彼はケチでものぐさなエンジニアだったので、証明書を買うのにお金をかけることはしたくなかったし、証明書の期限が切れるたびにsecretを更新する手間をかけたくもなかったのです。 無料の証明書と言えばそう、Let's Encryptの出番です。幸い世の中にはLet's Encryptからの証明書取得を行うためのKubernetesアドオンがありましたし、親切にもAzureにはこれを利用するための公式ドキュメントがありました。 jetstack/cert-manager Azure Kubernetes Service (AKS) で HTTPS イングレス コントローラーを作成する 壁その1: Let's Encryptのレート制限 Let's Encryptに関して彼は全くの素人でしたが、ネット上のサンプルを参考に証明書の取得をすることは簡単にできました。 issuer.yml apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: letsencrypt spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: hoge@example.com privateKeySecretRef: name: letsencrypt-key http01: {} certificate.yml apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: example-certificate spec: secretName: certs-example issuerRef: kind: Issuer name: letsencrypt commonName: "a.example.com" dnsNames: - "a.example.com" たったこれだけで a.example.com 向けの証明書が取得できたので、意気揚々と各名前空間上に同様のオブジェクトをデプロイしました。これはとても上手く行きました。 しかし価値を確信した刹那、とある記事が彼の目に留まりました。 レート制限 -Let's Encrypt- その記事にはこうあります。 主なレート制限としては、登録ドメインごとの証明書数 (1週間に50個まで) があります。登録ドメインとは、一般に言うと、あなたがドメイン名レジストラから購入したドメインの一部のことです。たとえば、www.example.com の場合、登録ドメインは example.com です。new.blog.example.co.uk の場合、登録ドメインは example.co.uk になります。 これは今後ユーザーが増え続けたとき、名前空間の数だけ証明書のリクエストが発生することでレート制限に引っ掛かる可能性を意味していました。 彼は詰みました。 解決策 ユーザー数が増えるにつれて大量のドメインが要るとは言っても、所詮は example.com のサブドメインが増えるに過ぎません。 ならば、ワイルドカード証明書 *.example.com を使うことができれば証明書を1つにまとめることができるはずです。 軽く調べてみるとLet's Encryptはワイルドカード証明書に対応していることがわかりました。 やったね! 壁その2: ワイルドカード証明書の取得に関する制限 早速、取得する証明書をワイルドカード形式にしてみることにしました。 certificate.yml apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: example-certificate spec: secretName: certs-example issuerRef: kind: Issuer name: letsencrypt commonName: "*.example.com" dnsNames: - "*.example.com" 結果、これまで上手くいっていた証明書取得は謎のエラーにより動かなくなりました。 彼はふたたび詰みました。 解決策 どうやらLet's Encryptでのワイルドカード証明書の取得には、よりセキュアなチャレンジ方式を用いる必要があるようでした。 彼が使っていたのは最もベーシックな HTTP-01 でしたが、これをより信頼性の高い DNS-01 チャレンジにすることで解決することがわかりました。 cert-managerにはAzure DNSを用いて DNS-01 チャレンジを行うための仕様が用意されていたので、設定してみることにしました。 issuer.yml apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: letsencrypt spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: hoge@example.com privateKeySecretRef: name: letsencrypt-key solvers: - dns01: azureDNS: environment: AzurePublicCloud subscriptionID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx resourceGroupName: hogehoge hostedZoneName: example.com tenantID: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy clientID: zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz clientSecretSecretRef: name: azuredns key: azure-client-secret この設定は見事に動き、生成されたワイルドカード証明書がSecretとして保存されました。 よかったね! 壁その3: Secretのスコープ しかしここで彼は気づきました。 「Secretって他の名前空間で使いまわせなくね?」 そう、せっかく作った証明書のSecretですが、これを各名前空間で共通して使うことができないと意味がなかったのです。そして、そんな仕組みは今のKubernetesにはありませんでした。 彼は三たび詰みました。 解決策 彼に残されたのは、たった1つのシンプルな答えでした。 「複数の名前空間で使いまわせなければ、Secretをコピーすればいいじゃない」 そして もはやヤケクソになった 彼は クソ雑な コードを書き上げました。 そう、彼を最後に助けたのはコードを書く腕力でした。 あとはCronJobによる定期実行が全てを解決してくれました。 世界に平和が訪れたのです。 がんばったね! まとめ そんなわけで、ユーザーごとに異なるコンテナを異なるドメインで提供するようなサービス構成を作ってみたら思いのほか苦労したよ!というお話でした。 苦心した甲斐あって今では証明書の調達に悩まされることもなく、安定してサービス提供が出来ていて万々歳です。 ……そして彼はのちに複数の名前空間に分かれた各環境のバージョン管理や運用にてもっと苦労することになるのですが、それはまた別のお話ということで。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「IDOLY PRIDE」でGo、gRPC、Cloud Spannerに挑戦してみた

QualiArts AdventCalendar 2日目の記事は、「IDOLY PRIDE」のバックエンドエンジニアをしている朝倉が担当します。 はじめに 2021年6月にリリースした「IDOLY PRIDE」では、QualiArtsのゲームバックエンドとしては初めてGo、gRPC、Cloud Spannerを採用しました。本記事では、それらの技術に挑戦した理由やリリース・運用を経験してそれぞれの技術の良かった点・苦労した点をまとめたいと思います。 それぞれの技術に対してバックエンドメンバーにアンケートを記入してもらい、そのアンケートをもとに(ゲームバックエンドでのユースケースにおける)良かった点・苦労した点を振り返りしました。次章から振り返りで話し合った良かった点・苦労した点を品質特性の軸で紹介していきます。 アンケートの内容 それぞれの技術に対して、次の項目を記入してもらいました。 5段階評価とその理由(1:次は採用しない、5:次も採用する) 良かった点 苦労した点 品質特性とは ソフトウェア品質の評価に関する国際規格(ISO/IEC 9126)で、6つの特性とそれぞれの品質特性をさらに細分化した副特性が定められています。 品質特性 副特性 説明 機能性 合目的性,正確性,相互運用性,標準適合性,セキュリティ 求められる機能が満たせているか 信頼性 成熟性,障害許容性,回復性 正常に動作するか、障害が起こりにくいか 使用性 理解性,習得性,運用性 理解しやすいか、使いやすいか 効率性 時間効率性,資源効率性 開発効率がよいか、リソース効率がよいか 保守性 解析性,変更性,安定性,試験性 改修しやすいか、運用しやすいか 移植性 環境適用性,設置性,規格適合性,置換性 他の環境へ移しやすいか Go 挑戦した理由 「IDOLY PRIDE」のバックエンドエンジニアはJavaのプロジェクト経験者が多かったのですが、下記の理由からGoに挑戦しました。 言語仕様がシンプルなので長期運用でメンバーの入れ替えなどがあっても学習コストを低く抑えらる。 静的型付け言語でコードが追いやすいので運用開発においても品質が担保できる。 起動が早いなどDocker、Kubernetesなどのコンテナ技術との相性が良い。 単純にJavaに飽きたので別言語をやってみたかった。 リリース・運用してみた所感 品質特性 良かった点 苦労した点 機能性 標準パッケージが充実+サードパーティライブラリでゲームバックエンドで求められる要件は満たすことができた。ベンチマーク、プロファイルが標準で入っていて簡単に使える。並行処理が書きやすい。ダックタイピングのinterface仕様も使いやすい。 信頼性 使用性 言語仕様がシンプルで学習コスト低めでキャッチアップしやすかった。情報が多い。コミュニティも活発で勉強会や資料も豊富にある。調べるとだいたい情報が見つかった。スクリプト言語的な用途でも利用できる。言語自体の人気があり採用でメリットがあった。 ジェネリクスがなく、コレクション操作が冗長になりがち。エラーハンドリングがめんどくさい。三項演算子がほしい。 効率性 コード量が多くなる。処理が長くなる。自動生成でカバー必要だった。 保守性 fmtが標準であり、言語仕様的にもコードが統一されやすい。静的型付けでコードを追いやすい。レビューしやすい。エラーハンドリングも処理が明確になってよい。標準パッケージやライブラリのコードもシンプルなので読んで動きを理解できる。 移植性 ワンバイナリにコンパイルできたり、起動速度が早いなどコンテナ環境との相性良い。バージョンアップ時の互換性が高い。 太字は多かった意見。 総評 強くデメリットを感じる場面はなく高評価でした。 複数人かつ長期運用での開発でメリットを感じる意見が多くありました。 API以外のユースケースでも利用しやすく、スクリプト的な用途でも利用しています。 コードが長くなりがちなので、DB周りのコードなどを自動生成するなどで開発効率を上げる工夫をしていました。 (コードは長くなるけど、思考がシンプルなので開発スピードは早いとの意見もありました。) gRPC 弊社エンジニアの簗瀬が執筆した「IDOLY PRIDE」のgRPC利用に関する記事記事も合わせてご覧ください 「IDOLY PRIDE」におけるgRPC利用とカスタマイズ 挑戦した理由 「IDOLY PRIDE」までのゲームタイトルでは、各ゲームタイトルごとにクライアント・サーバー間の通信仕様を決めて通信基盤や自動生成ツールなどを開発していました。タイトルごとの通信仕様を共通化していきたいという理由からgRPCに挑戦しました。 IDL(protoファイル)を利用して、クライアント・サーバー間の通信内容を定義し共有することで開発スピードが上げられる。 REST APIと比較して通信速度が速いので、ユーザ体験が良くなる。 これまでも、Bodyサイズの削減やシリアライズ・デシリアライズの速度の向上のために、REST APIでBodyをProtocolBuffersでシリアライズすることが多かったため慣れている。 リリース・運用してみた所感 品質特性 良かった点 苦労した点 機能性 option、プラグイン拡張、protoのリフレクションなどでカスタマイズ、自動生成やりやすい。RESTに比べて通信が高速でユーザ体感がいい。 ストリーミング通信を使う機会はなかった。 信頼性 (静的型付け言語だと)サーバー、クライアントでコードがずれることない。 使用性 マネージドのLB、WAFが使えなかったり、(istioでLoadBalancingするなど)インフラ面の考慮が必要で導入コストが高かった。 効率性 クライアントとの意思疎通や繋ぎ込みがやりやすい。 負荷試験、脆弱性診断の準備などHTTPと比較して導入コストが高かった。RESTに比べると周辺環境が整っておらず、APIのデバッグなどがやりにくかった。 保守性 IDLで情報が共有しやすい。 移植性 太字は多かった意見。 総評 クライアントとの意思疎通やカスタマイズ性の高さでAPI開発がやりやすくなったとの意見が多くありました。 一方、技術検証や基盤の準備、インフラ面の考慮など導入コストはかなり大きかったです。 GCP、AWSのマネージドサービスでも、徐々にgRPC対応されているので導入の閾値は下がってきていると感じます。 Cloud Spanner 弊社エンジニアの島田が執筆した「IDOLY PRIDE」のCloud Spaner利用に関する記事も合わせてご覧ください 「IDOLY PRIDE」におけるGoogle Cloud Spannerの活用 挑戦した理由 これまではMySQLを採用することが多かったのですが、テーブルの分割やマスター/スレーブ構成などをしてスケーラビリティを確保したり、アップデート作業が必要だったり運用負荷が高いのが課題でした。データベースの運用負荷を減らしたいという理由でCloud Spannerに挑戦しました。 フルマネージドのサービスで、設定項目もリージョンとノード数くらいで運用負荷が少ない。 ノード数を増やすことでスループットを増加させることができる。ノード数はオンラインで増やすことができるので負荷に応じて柔軟に運用できる。 トランザクションが利用できるのでデータの整合性を保ちやすい。 RDBと同じように、スキーマ定義やSQLクエリが利用でき、スキーマ変更はオンラインで適応可能。 リリース・運用してみた所感 品質特性 良かった点 苦労した点 機能性 周辺環境が整ってきている。(エミュレータやプロセッシングユニット等)インターリーブでデータ取得を効率化できる。 信頼性 スケールとトランザクションが両立していて、レイテンシも問題になってない。 使用性 DB設計時の考慮やウォームアップなどでホットスポットへの考慮が必要。複数ユーザで同一レコードの同一カラムを同時更新するとトランザクションリトライが発生しスループットが悪化する。トランザクションリトライを意識した実装(冪等性の担保)が必要。バッチ処理などではミューテーション上限の意識が必要。RO、RWトランザクションの使い分けを意識。採用事例がまだまだ少なく。情報が少ない。 効率性 エミュレータでローカル開発ができる。 料金が高い 保守性 自動スプリット分割やノード数の調整でスケールが簡単にできる。CPUなど監視の指標がシンプル。 移植性 GCPでしか使えない 太字は多かった意見。 総評 パフォーマンス、スケール、監視などの面でとても快適に運用できています。 インスタンス料金は高いですが、負荷に応じて柔軟にノード数を調整できるため実際の料金はMySQLと比較してもそれほど高くはなっておりません。プロセッシングユニットの登場により、開発環境などの小規模環境でも安く利用できるようになりました。 「IDOLY PRIDE」の開発初期(2019年頃)と比較し現在は周辺環境がかなり整ったので使いやすくなりました。直近でもプロセッシングユニット、TTL、BigQuery連携など便利な機能が追加されより使いやすくなっています。 ただ、ホットスポットの考慮やトランザクションリトライ、ミューテーション上限などの特性をきちんと理解してゲーム要件にマッチするか十分検討が必要だと感じています。 まとめ 今回は「IDOLY PRIDE」でのGo、gRPC、Cloud Spannerに挑戦した理由と実際に利用してみて良かった点・苦労した点を簡単にですが紹介させていただきました。リリースから半年経ちますが、大きな問題なく運用できておりそれぞれの技術のメリットも感じています。本記事がGo、gRPC、Cloud Spanner導入の参考になれば幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

独自KVSデータベースを作ってみた

初めに オークファンの開発部に2021年新卒入社した@isodaです。 題名の通り、独自KVSデータベースの設計と開発(実装は途中)を行いました。 経緯 通信プロトコル、ファイルシステム、バイナリなどの理解。 Goを使用した開発や1から設計を行う経験の為、研修の一環として、今回の独自KVSデータベースの設計と開発を行わせて頂きました。 通信プロトコルの設計 通信はTCPを使用し、バイナリデータでのやり取りを行います。 DBサーバーへのリクエスト KeyとValueを送る際に、どこまでがKeyでどこまでがValueなどを識別するために、識別文字を入れる方法もありますが、 今回はバイナリセーフにしたいためKeyとValueのサイズを通信に内包する方法にしました DBサーバーからのレスポンス Create/Update/Deleteの際は正常を示す値(0x00) or 異常ならエラーコード Readの際は正常系はリクエストのKeyに対応するValueの値 or 異常ならエラーコードが返ってくる Create/Update(Request) CreateとUpdateは以下のよう定義します。 Mode + KeySize + Key + ValueSize + Value 具体例:key=hoge value=fugaでcreateを行った時のイメージ echo "\x00\x05hoge\x00\x04fuga" | hexdump -C 00000000 00 05 68 6f 67 65 00 04 66 75 67 61 0a |..hoge..fuga.| 開始アドレス サイズ(byte) 値 Mode 0x00 0x01 0x00(C) or 0x02(U) KeySize 0x01 0x01 0x01 ~ 0xFF Key 0x02 0x01 ~ 0xFF KeySizeの値と同じバイト数の任意の値 ValueSize 0x02 + Keyのサイズ 0x02 0x0001 ~ 0xFEFD Value 0x04 + Keyのサイズ 0x0001 ~ 0xFEFD ValueSizeの値と同じバイト数の任意の値 Read/Delete(Request) ReadとDeleteは以下のよう定義します。 Mode + KeySize + Key 具体例:key=hogeでreadを行った時のイメージ echo "\x01\x05hoge" | hexdump -C 00000000 01 05 68 6f 67 65 0a |..hoge.| 開始アドレス サイズ(byte) 値 Mode 0x00 0x01 0x01(R) or 0x03(D) KeySize 0x01 0x01 0x01 ~ 0xFF Key 0x02 0x01 ~ 0xFF KeySizeの値と同じバイト数の任意の値 ファイルシステムの設計 ファイルに実際どのように、読み書きされるかを設計しました。 バイナリファイルの中身はこんなイメージです。 バイナリファイルへの読み書きはビッグエンディアン KeyとValueとそのサイズを1つのセットとして、1ブロック0x10000byteでファイルに書き込まれる KeyとValueも0埋めを行い固定長で保存 KeySizeに0x00が入っている場合は論理削除とする 実装 Goで実装を行なっています。 Client 入力した値を通信プロトコルに沿ったバイナリ形式に変換してServerへ送信 ClientでServerから受け取ったレスポンスを表示 Server 受け取った値をGolangの構造体に入れて、その構造体をバイナリファイルへ読み書きする処理を行い、Clientにレスポンスを返す。 ServerのCreate処理部分のソースコード package crud import ( "bytes" "encoding/binary" "fmt" "os" ) func (b *Block) Create() error { // キーの存在確認 bf, err := b.Read() if err != nil { return err } if bf.Ks != nil { return fmt.Errorf("key already exist") } buf := new(bytes.Buffer) var data = []interface{}{ b.Ks, b.Vs, b.K, b.V, } for _, v := range data { err := binary.Write(buf, binary.BigEndian, v) if err != nil { fmt.Println("binary.Write failed:", err) } } file, err := os.OpenFile(b.Cnf.FILE.Path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if err != nil { return err } defer file.Close() _, err = file.Write(buf.Bytes()) if err != nil { return err } err = file.Close() if err != nil { return err } return nil } 終わりに 今回の経験を通して、設計では、どの様に通信プロトコルを定義すれば、バイナリセーフになるのか。 どの様な形でバイナリファイルに書き込みば、読み書きがしやすいかなどを考える良い機会になりました。 また設計をするのは殆ど初めての経験だったのですが、とても大変だが大切な工程であると感じました。 実装ではGoでの開発が初めてなので、戸惑うことも多かったのですが、今後業務でGoを使う機会もあるので勉強になりました。 設計でも実装でも先輩にレビューを頂いたり、レクチャーをして頂いたりしたのでスムーズに進めることができ、感謝しております。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

チームで内部API開発をするときのツール

まえがき 最近はBFFアーキテクチャの採用により、サーバサイドは内部(Internal)APIとしてAPIを作成することが多い チームで開発するために、どのAPIが何を示しているかはわかりやすくしておきたい サーバ・フロントどちらを触るときでもAPI定義を見れば実装できるようにしたい 各エンドポイントが何をしているか、コードを見ればわかるけど毎回したくはない チーム開発でAPI開発をするときにどのようなツールを利用していたかについて記載する。 前提 いわゆるREST APIを採用 (gRPCではない) OpenAPI3.0 を仕様 VSCode拡張機能 Swagger Viewer API定義をプレビューできる拡張機能 拡張機能名はSwaggerとついているが、OpenAPI3.0でも問題なくプレビューが可能 いわゆるライブリロード機能があり、編集→反映がスムーズに行えるのが良い 図はサンプルなAPIを表示した例 OpenAPI extension for Visual Studio Code OpenAPI extension for Visual Studio Code 新規作成時にテンプレートから生成が可能 一方previewのような形では使えないのでそこまでは利用していない。 Redoc Redoc デモはこちら : https://redocly.github.io/redoc/ OpenAPIの定義からPreviewを生成するOSS example にあるように、API定義と、cdnの読み込みさえ書けば良い <body> <redoc spec-url='http://petstore.swagger.io/v2/swagger.json'></redoc> <script src="https://cdn.jsdelivr.net/npm/redoc@latest/bundles/redoc.standalone.js"> </script> </body> oapiの場合 sepc.yamlを指定すれば良い。 実運用上は GitHub Pagesのようなところにホスティングして開発者が確認できるようにしている 図はサンプルAPIを表示した例 oapi-codegen oapi-codegen Goでサーバサイドを書くために、oapi-codegenを利用してサーバサイドのコードを生成している まとめ 各種ツールを利用することで、内部API開発を効率的にできるようになった。 API定義があることで、サーバー <-->フロント間でやり取りする際の共通言語として利用できるようになった。 また、サーバーサイドを主としていた人がフロント側を行う際にもよい取っ掛かりとなった。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ghzでgRPCの負荷試験(Benchmark Test)を行います hz

はじめに gRPCの負荷試験の為にghzというツールを使おうと思うのですが、「hz」の意味がわからず読み方がわかりません。? ちょっと洋式トイレにも見えます。 基本的な使い方 インストール方法 githubのどトップに書いてあるので説明するまでも感がありますが、一応。 MACerなのでbrewでインストールしております。 brew install ghz 実行コマンド ghz --config=./config.json configファイルの中身 config.json { "name": "Otsuka Test", "call": "akame.Linebot.ReplyMessage", "host": "0.0.0.0:50051", "total": 15000, "concurrency": 300, "connections": 300, "rps": 3000, "data": { "line_id": "azusa", "text": "{{randomString 10 }}", "nonce": "hogehoge" }, "format": "html", "output": "report.html", "insecure": true, "load-schedule": "const", "load-start": 0, "load-end": 0, "load-step": 0, "load-step-duration": 0, "load-max-duration": 0, "concurrency-schedule": "const", "concurrency-start": 1, "concurrency-end": 0, "concurrency-step": 0, "concurrency-step-duration": 0, "concurrency-max-duration": 0, "timeout": "20s", "binary": false } 今回使用した彼女 (gRPCアプリケーション) configの中身を解説 name テストの名称です。(一応解説) call コールするメソッド名です。 ※ reflectionを使用していない場合、追加で--protoオプションを指定する必要があります。 host (略) total リクエストの合計数です。 例えば1秒3,000リクエストで5秒間負荷をかけたい場合、合計は15,000となります。 concurrency 並行(同時)実行数です。 ※ 同時接続数ではありません。 connections gRPCの同時接続数を指定できます。 concurrencyオプションの数を超えることは出来ません。 rps 秒間リクエストの数です。 rps=10, total=100 だと1秒10リクエストなので、負荷テストが完了するまで10秒かかる計算となります。 data gRPCで送るbody部分です。 {{randomString 10 }}の記述は10桁(指定した桁)でランダムな文字列を生成してくれます。 他にも色々便利なParamがありますが割愛します。 データを固定データではなく、いくつかのパターンに分割してリクエストしたいという場合があると思います。 そういう時は、[]配列形式 ↓ でデータを飛ばしてあげると動作します。 [ { "line_id": "azusa", "text": "{{randomString 10 }}", "nonce": "hogehoge" }, { "line_id": "yui", "text": "{{randomString 10 }}", "nonce": "fugafuga" } ] なので [ { "line_id": "azusa", "text": "{{randomString 10 }}", "nonce": "hogehoge" } ] ↑これと ↓これは同義となります。 { "line_id": "azusa", "text": "{{randomString 10 }}", "nonce": "hogehoge" } format reportの形式を選べます。 指定がない場合コンソールに出力されます。 形式の一覧は以下です。 csv, json, pretty, html, influx-summary, influx-details, prometheus influxDBを指定できるためinfluxDB => Grafanaや、prometheus => Grafanaの接続も可能となります。 HTMLレポートはこんな感じで表示されます。↓ load-***オプション rpsを時間経過ともに増減できるオプションです。 load-scheduleはconst・step・lineの何れかから選べます。 load-scheduleの種別ごとの設定は以下です。 const rpsで指定した秒間リクエストがそのまま実行されます。 step startからendにかけてstep-durationで設定した時間ごとにstep数分rpsが増加or減少します。 max-durationはendに訪れる前にこの時間を経過すると、その時点でのrpsで負荷テストを続行し、それ以上rpsは増減しません。 line startからendにかけて1秒ごとにstep数分rpsが増減します。 concurrency-***オプション 並行(同時)実行数を時間経過ともに増減できるオプションです。 concurrency-scheduleはconst・step・lineの何れかから選べます。 concurrency-scheduleの種別ごとの設定は以下です。 const concurrencyで指定した秒間リクエストがそのまま実行されます。 step startからendにかけてstep-durationで設定した時間ごとにstep数分concurrencyが増加or減少します。 max-durationはendに訪れる前にこの時間を経過すると、その時点でのconcurrencyで負荷テストを続行し、それ以上concurrencyは増減しません。 line startからendにかけて1秒ごとにstep数分concurrencyが増減します。 あとがき いっぱいまとめて、疲れたので今日はいいお肉でも食べたいなと思います。 採用PR gRPCやマイクロサービス化・二次元コンテンツに興味がある、もしくはチャレンジしてみたいという方は是非一緒に働きましょう!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む