LoginSignup
2
1

More than 3 years have passed since last update.

シナリオから学ぶ連携テスト

Last updated at Posted at 2020-10-01

シナリオ背景

連携API(VPC A)とAPIを使うサービス(VPC B)はAWSの違うVPCに存在する。
2つのシステムはPeering設定されて通信できる状況。
連携APIのVPCは
マルチAZ構成*になっている(2つのAZ)

Peering2つのVPC間の通信を外部ネットワーク経由でなくL3ネットワーク経由で、でVPC間の相互に通信ができるサービスです。

マルチAZ構成クラウド上で構築・運用されるシステムの可用性を高めるためのベストプラクティスの一つであり

peering-intro-diagram.png
VPCピア機能についてはこちらを参考してください。

シナリオ概要

サービス運用途中急に連携APIの1/3のResponseがTimoutになった。
「VPC A」環境からの接続には問題なし。

原因調査準備

「VPC B」の環境に新しいEC2インスタンスを作ってテスト環境を用意

APIの負荷テスト

vegeta・ApacheBenchを使ってAPIサーバーの性能に問題があるのかを調査。
負荷テストを行なったが特に性能上問題はなかった。

vegetaテスト方法

{API URL} に向けて 10 request/sec のレートで 30秒間 負荷をかけ続ける場合

vegeta実行(Sample)
$ echo "GET {API URL}" | vegeta attack -rate=10 -duration=30s | tee results.bin | vegeta report

vegeta実行結果
Requests      [total, rate, throughput]         300, 10.03, 10.03
Duration      [total, attack, wait]             29.908s, 29.9s, 8.468ms
Latencies     [min, mean, 50, 90, 95, 99, max]  2.424ms, 9.616ms, 8.06ms, 15.127ms, 23.502ms, 29.709ms, 88.864ms
Bytes In      [total, mean]                     60000, 200.00
Bytes Out     [total, mean]                     0, 0.00
Success       [ratio]                           100.00%
Status Codes  [code:count]                      200:300  
Error Set:

Vegetaの使い方についてはこちらを参考

ApacheBenchテスト方法

10ユーザがそれぞれ10回リクエストした場合

ab実行
ab -n 100 -c 10 {API URL}
option
n: 生成するリクエスト数を指定します
c: 並列実行する数(コネクション数)を指定します
実行結果(Sample)
This is ApacheBench, Version 2.3 <$Revision: 1874286 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking xxxxxxxxxx (be patient).....done


Server Software:        nginx/1.15.12
Server Hostname:        xxxxxxxxxxxxx
Server Port:            80

Document Path:          /api
Document Length:        25 bytes

Concurrency Level:      10
Time taken for tests:   0.148 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      15300 bytes
HTML transferred:       2500 bytes
Requests per second:    676.97 [#/sec] (mean)
Time per request:       14.772 [ms] (mean)
Time per request:       1.477 [ms] (mean, across all concurrent requests)
Transfer rate:          101.15 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    2   2.3      1      14
Processing:     2   11   7.2      9      31
Waiting:        2   11   7.2      9      30
Total:          3   13   8.4     10      35

Percentage of the requests served within a certain time (ms)
  50%     10
  66%     16
  75%     20
  80%     21
  90%     26
  95%     30
  98%     34
  99%     35
 100%     35 (longest request)

ABの使い方についてはこちらを参考

連携APIサーバーの疎通テスト

curlを使ってテストサーバーからAPIを直接実行して疎通確認した結果、Timeoutが再現できました。
Timeoutの原因調査のため、curlのTraceオプションをつけて実行

curl_trace実行
$curl -sS {API URL} --trace-ascii trace.log -o /dev/null

DNS名前解決ができなかったのが原因でTimeoutになったのが分かりました。

trace(Traceのドメイン名・IPアドレスは編集)
== Info:   Trying xx.xxx.xx.xx...
== Info: TCP_NODELAY set
== Info: connect to xx.xxx.xx.xx port 80 failed: Connection timed out
== Info:   Trying xx.xxx.xx.x...
== Info: TCP_NODELAY set
== Info: Connected to {API URL} (xx.xxx.xx.x) port 80 (#0)
=> Send header, 169 bytes (0xa9)
0000: GET /api HTTP/1.1
0032: Host: {API URL}
0072: amazonaws.com
0081: User-Agent: curl/7.61.1
009a: Accept: */*
00a7:
<= Recv header, 15 bytes (0xf)
0000: HTTP/1.1 200
<= Recv header, 37 bytes (0x25)
0000: Date: Wed, 02 Sep 2020 06:59:42 GMT
<= Recv header, 32 bytes (0x20)
0000: Content-Type: application/json
<= Recv header, 28 bytes (0x1c)
0000: Transfer-Encoding: chunked
<= Recv header, 24 bytes (0x18)
0000: Connection: keep-alive
<= Recv header, 23 bytes (0x17)
0000: Server: nginx/1.15.12
<= Recv header, 2 bytes (0x2)
0000:
<= Recv data, 209 bytes (0xd1)
0000: c6
0004: {"result":{""}}]}}
00cc: 0
00cf:
== Info: Connection #0 to host {API URL} left intact
~                                                                                                                                                                                                           
~                                                                                                                                          

curlのTraceについての詳細はこちらを参考

その後nslokupでDSNが3つに増えてその1つに接続できなくてTimeoutになったのが判明しました。

結論

背景で連携APIサーバーのマルチAZ構成は2つだと説明したと思います。
APIサーバー(VPC A)のAZ構成を3つに増やしたけど連携APIを使うサーバー(VPC B)のPeering設定は2つのAZを許可したままになっているので新しいAZのDNSに接続できないためエラーになります。
「VPC B」のPeering設定に新しく追加されたAZサブネットのCIDRを追加することで解決。

Amazon API Gatewayを使って連携すれば上記のような設定変更の影響は無くなる。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1