JMeterサーバークライアント構成でSQL Serverに負荷をかける

## はじめに

[前回記事](https://qiita.com/t13801206/items/d1d1a6d4c587e146ec52)では、ホストのJMeterから、DockerコンテナSQL Server 2019に接続した

今回は、Dockerネットワークを作り
そのネットワーク内にJMeterサーバ・JMeterクライアント・SQL Serverをつくる

そして閉ざされたDockerネットワーク内でJMeterからSQL Serverに負荷をかける

最後はその負荷の状況をWireSharkで観察する

## Dockerネットワークを作る

まずは検証環境となるネットワークをつくる
`172.20.0.0/16`はZabbixネットワークで占有しているので
今回は`172.21.0.0/16`をつかう

```powershell
docker network create --subnet 172.21.0.0/16 --ip-range 172.21.240.0/20 jmeter-net
docker network ls
```

## SQL Severをたてる

ホストからみて、`11433`ポートからアクセスできるよう設定する
また先ほどつくったネットワークに所属させる

```powershell
docker run --name jmeter-sqlserver --net jmeter-net --hostname sql -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=SqlPass1234' -p 11433:1433 -d mcr.microsoft.com/mssql/server:2019-latest
```

### データベースをつくる

`TestDB`をつくる
その中に`Students`テーブルをつくる

```sql
USE [TestDB]
GO

/****** Object:  Table [dbo].[Students]    Script Date: 2023/05/21 18:37:27 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Students](
	[Id] [int] NOT NULL,
	[Year] [varchar](100) NULL,
	[Industry_aggregation_NZSIOC] [varchar](100) NULL,
	[Industry_code_NZSIOC] [varchar](100) NULL,
	[Industry_name_NZSIOC] [varchar](100) NULL,
	[Units] [varchar](100) NULL,
	[Variable_code] [varchar](100) NULL,
	[Variable_name] [varchar](100) NULL,
	[Variable_category] [varchar](100) NULL,
	[Value] [varchar](100) NULL,
PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
```

### データを流し込む

ホストからコンテナにデータソースをコピーする
`d5ad`はコンテナID（docker psで調べる）

```powershell
docker cp .\student-data.csv d5ad:/etc/student-data.csv
```

`Students`テーブルにCSVファイルの中身をすべてインストールする

```sql
BULK INSERT
	[TestDB].[dbo].[Students]
FROM
	'/etc/student-data.csv'
WITH(
	FORMAT = 'CSV'
)
```

## JMeterサーバ（２つ）つくる

サーバ１個目

```powershell
docker container run -itd -v /d/200_Study/2305_JmeterServerClient:/mnt/jmeter --name jmeter-server1 --net jmeter-net --hostname JMServer1 justb4/jmeter:latest -s -n -D server_port=20000 -D server.rmi.localport=20000 -D server.rmi.ssl.disable=true -J mode=Statistical
```

サーバ２個目

```powershell
docker container run -itd -v /d/200_Study/2305_JmeterServerClient:/mnt/jmeter --name jmeter-server2 --net jmeter-net --hostname JMServer2 justb4/jmeter:latest -s -n -D server_port=20000 -D server.rmi.localport=20000 -D server.rmi.ssl.disable=true -J mode=Statistical
```

いずれも`/mnt/jmeter`をマウントしておく
マウント元フォルダに`mssql-jdbc-7.0.0.jre8.jar`を置いておく

### JMeterサーバの設定を変更する

`jar`ファイルが置いてあるパスを指定する

```bash:vi bin/user.properties
# jarファイルが格納されているパスを追記する
user.classpath=/mnt/jmeter
```

## JMeterクライアントをつくる

JMServer1,2をリモートホストに指定する
実行するファイルは、マウントしたフォルダにある`1.jmx`を使う

```powershell
docker container run -itd -v /d/200_Study/2305_JmeterServerClient:/mnt/jmeter --name jmeter-client --net jmeter-net --hostname JMClient justb4/jmeter:latest -D server.rmi.ssl.disable=true -D client.rmi.localport=20000 -J remote_hosts=JMServer1:20000,JMServer2:20000 -J mode=Statistical -t /mnt/jmeter/1.jmx -n -r
```

### `jmx`ファイルの中身

パラメータ|内容
-|-
Database URL | jdbc:sqlserver://sql:1433;database=TestDB
Query | select * from dbo.Students where Variable_name like '%s%' and Variable_category like '%s%';
スレッド数|180

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/b7ede5d4-73a5-be13-7de9-bb02d9827ef6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/e14b2993-f218-082e-43a6-11332c129f20.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/0441bdd8-4270-96ba-4331-a424322500e6.png)

### JMeterクライアントを実行する

JMeterクライアントを実行すると、勝手にJMeterサーバが動き出す

```powershell
2023-05-28 22:29:24 jmeter ALL ARGS=-Dlog4j2.formatMsgNoLookups=true -D server.rmi.ssl.disable=true -D client.rmi.localport=20000 -J remote_hosts=JMServer1:20000,JMServer2:20000 -J mode=Statistical -t /mnt/jmeter/1.jmx -n -r
2023-05-28 22:29:31 Creating summariser <summary>
2023-05-28 22:29:31 Created the tree successfully using /mnt/jmeter/1.jmx
2023-05-28 22:29:31 Configuring remote engine: JMServer1:20000
2023-05-28 22:29:32 Configuring remote engine: JMServer2:20000
2023-05-28 22:29:33 Starting distributed test with remote engines: [JMServer2:20000, JMServer1:20000] @ May 28, 2023 3:29:32 PM CEST (1685280572997)
2023-05-28 22:29:36 Remote engines have been started:[JMServer2:20000, JMServer1:20000]
2023-05-28 22:29:36 Waiting for possible Shutdown/StopTestNow/HeapDump/ThreadDump message on port 4445
2023-05-28 22:30:26 summary +      2 in 00:00:25 =    0.1/s Avg:  6772 Min:  3390 Max: 10155 Err:     0 (0.00%) Active: 65 Started: 65 Finished: 0
2023-05-28 22:31:05 summary +    600 in 00:01:04 =    9.4/s Avg: 13690 Min: 700410 Max: 1636316 Err:   467 (77.83%) Active: 288 Started: 296 Finished: 8
2023-05-28 22:31:05 summary =    602 in 00:01:29 =    6.8/s Avg: 13667 Min:  3390 Max: 1636316 Err:   467 (77.57%)
2023-05-28 22:31:34 summary +    600 in 00:00:29 =   20.7/s Avg: 14859 Min: 1472992 Max: 1506716 Err:   600 (100.00%) Active: 351 Started: 360 Finished: 9
2023-05-28 22:31:34 summary =   1202 in 00:01:58 =   10.2/s Avg: 14262 Min:  3390 Max: 1636316 Err:  1067 (88.77%)
2023-05-28 22:32:03 summary +    700 in 00:00:29 =   23.9/s Avg: 14730 Min: 1433782 Max: 1522632 Err:   700 (100.00%) Active: 343 Started: 360 Finished: 17
2023-05-28 22:32:03 summary =   1902 in 00:02:27 =   12.9/s Avg: 14434 Min:  3390 Max: 1636316 Err:  1767 (92.90%)
2023-05-28 22:32:32 summary +    700 in 00:00:30 =   23.7/s Avg: 14877 Min: 1460352 Max: 1521003 Err:   700 (100.00%) Active: 305 Started: 360 Finished: 55
2023-05-28 22:32:32 summary =   2602 in 00:02:57 =   14.7/s Avg: 14554 Min:  3390 Max: 1636316 Err:  2467 (94.81%)
2023-05-28 22:33:05 summary +    600 in 00:00:32 =   18.5/s Avg: 15083 Min: 1463071 Max: 1536315 Err:   600 (100.00%) Active: 166 Started: 360 Finished: 194
2023-05-28 22:33:05 summary =   3202 in 00:03:29 =   15.3/s Avg: 14653 Min:  3390 Max: 1636316 Err:  3067 (95.78%)
2023-05-28 22:33:51 summary +    398 in 00:00:47 =    8.5/s Avg: 15328 Min: 1521404 Max: 1531588 Err:   398 (100.00%) Active: 0 Started: 360 Finished: 360
2023-05-28 22:33:51 summary =   3600 in 00:04:16 =   14.1/s Avg: 14727 Min:  3390 Max: 1636316 Err:  3465 (96.25%)
2023-05-28 22:33:51 Tidying up remote @ May 28, 2023 3:33:51 PM CEST (1685280831949)
2023-05-28 22:33:56 ... end of run
2023-05-28 22:33:57 END Running Jmeter on Sun May 28 15:33:57 CEST 2023
```

180スレッドが２サーバなので、最大で360スレッドが動く

## SQLサーバでパケットをキャプチャする

JMeterからたくさん要求がきているときに
SQLサーバでどうみえるか？

```powershell
docker exec -it -u root jmeter-sqlserver /bin/bash
apt update && apt install -y tcpdump
tcpdump -w sample.pcap
```

### 各端末のIPアドレス

.1と.2がJMeterサーバで、.3がSQLサーバ

```powershell:docker network inspect jmeter-net
 "Containers": {
                "Name": "jmeter-server2",
                "IPv4Address": "172.21.240.2/16",
            },
                "Name": "jmeter-client",
                "IPv4Address": "172.21.240.4/16",
            },
                "Name": "jmeter-server1",
                "IPv4Address": "172.21.240.1/16",
            },
                "Name": "jmeter-sqlserver",
                "IPv4Address": "172.21.240.3/16",
            }
```

### WrireShark画面

TCP Zerowindow　受信バッファがいっぱいになっている様子がわかる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/01dbd153-2fa7-6fe7-de33-122ef14f0d9d.png)

## 参考

https://qiita.com/tatesuke/items/827e6190753964e46814

https://qiita.com/charon/items/4bcbd9d69e269d5e02b5

https://qiita.com/h-r-k-matsumoto/items/50b5d92a3edebb09a4fd

https://www.blazemeter.com/blog/jmeter-distributed-testing-with-docker

https://tm8r.hateblo.jp/entry/20120730/1343622646

https://satotech.hatenablog.com/entry/20141214/1418560404

## 糸冬了！！