Toxiproxy ネットワークとシステムの状態をシミュレートするプロクシーサーバのメモ


[Toxiproxy](https://github.com/Shopify/toxiproxy)は、Shopifyがオープンソースで公開しているプロキシーサーバ、ネットワークのテストなどに利用する。

## 用途

* 次のようなことを実現できる
  * SMTPクライントからSMTPサーバに接続する際に10秒間の遅延時間を入れる。

まだ使いかじめたばかり、他のツールがよければそちらを使おうと思う。

## インストール(OSXの場合)

```
brew tap shopify/shopify
brew install toxiproxy
```

これで``toxiproxy-server``とtoxiproxy-cliというコマンドが使える。


## 簡単な使い方

サーバを起動させる。には``toxiproxy-server``コマンドを実行する

```
toxiproxy-server 
INFO[0000] API HTTP server starting                      host=localhost port=8474 version=2.0.0
```

サーバが8474番ポートでListenする。

```
netstat -na | grep 8474
tcp4       0      0  127.0.0.1.8474         *.*                    LISTEN     
```

以降は``toxiproxy-cli``の説明

* localhost上の24220番ポートにSMTPサーバへ接続するプロクシーを立てる。
* このポートにアクセスがあった場合、ホストsmtp_serverの25番ポートに接続する
* プロクシーサーバの名前はsmtp_test

```
% toxiproxy-cli create smtp_test --listen localhost:24220 --upstream smtp_server:25
Created new proxy smtp_test
```

登録結果を確認

```
% toxiproxy-cli list
Listen		Upstream	Name	Enabled	Toxics
======================================================================
127.0.0.1:24220	smtp_server:25	smtp_test	true	None

Hint: inspect toxics with `toxiproxy-cli inspect <proxyName>`
```

smtp_testに、5秒間(5000ms)のレイテンシを付与する。


```
% toxiproxy-cli toxic add smtp_test -t latency -a latency=5000
Added downstream latency toxic 'latency_downstream' on proxy 'smtp_test'
```

リストを再度確認 Toxicsが1になっていることが確認できる。

```
% toxiproxy-cli list
Listen		Upstream	Name	Enabled	Toxics
======================================================================
127.0.0.1:24220	smtp_server:25	smtp_test	true	1

Hint: inspect toxics with `toxiproxy-cli inspect <proxyName>`
```

詳細をみるには``inspect``を使う。

```
% toxiproxy-cli i smtp_test
Name: smtp_test	Listen: 127.0.0.1:24220	Upstream: smtp_server:25
======================================================================
Upstream toxics:
Proxy has no Upstream toxics enabled.

Downstream toxics:
latency_downstream: type=latency stream=downstream toxicity=1.00 attributes=[ jitter=0 latency=5000 ]

Hint: add a toxic with `toxiproxy-cli toxic add`
```

これはつまり、下記Dのところの遅延時間を加えているということになる。
ToxiproxyはUpstream(おそらくBの部分)にも遅延時間を入れられるようだ。



```
SMTP   --- A --> Toxi  --- B --> SMTP 
CLIENT <-- D --- Proxy <-- C --- SERVER
```

telnetで接続を試して見る。

```
telnet localhost 24220
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
### 5秒間の遅延 ########
220 smtp_server ESMTP Postfix
```

プロクシーを削除するにはdコマンドで削除

```
% toxiproxy-cli d smtp_test
Deleted proxy smtp_test
```

削除できたか確認をする。

```
% toxiproxy-cli list
Listen		Upstream	Name	Enabled	Toxics
======================================================================
no proxies

Hint: create a proxy with `toxiproxy-cli create`
```





## Rubyクライアント導入

```
gem install toxiproxy
```

### 簡単な使い方

サーバを起動させる。には``toxiproxy-server``コマンドを実行する

```
toxiproxy-server 
INFO[0000] API HTTP server starting                      host=localhost port=8474 version=2.0.0
```

サーバが8474番ポートでListenする。

```
netstat -na | grep 8474
tcp4       0      0  127.0.0.1.8474         *.*                    LISTEN     
```

### クラインアントからプロキシー情報を登録する。

populate.rb

```ruby
require 'toxiproxy'
Toxiproxy.populate([
  {
    name: "smtp_test",
    listen: "127.0.0.1:24220",  # プロキシーを動かすアドレスとポート
    upstream: "smtp_server:25" # プロキシーが実際に接続するサーバとポート
  }
])
```

クライアントから、プロキシー情報を登録する

``ruby populate.rb``

サーバに次のようなログが出力される

```
INFO[0007] Started proxy                                 name=smtp_test proxy=127.0.0.1:24220 upstream=smtp_server:25
```

24220ポートでプロキシーサーバが動作する。

```
netstat -na | grep 24220
tcp4       0      0  127.0.0.1.24220        *.*                    LISTEN
```

Rubyのクライアントを動かしてみる。latencyで2000ms遅くする

```ruby
require 'socket'
require 'toxiproxy'

Toxiproxy[:smtp_test].downstream(:latency, latency: 2000).apply do
  bfr = Time.new
  s = TCPSocket.open('127.0.0.1',24220)
  puts s.gets 
  puts Time.now - bfr 
  
end
```


```
% ruby client.rb 
220 smtp_server ESMTP Postfix
7.013207
```

遅延が入っているが7秒かかった。

2回目

```
ruby client.rb
220 smtp_server ESMTP Postfix
2.009106
```

2秒間遅延している。

## 疑問(あとで調べる)

* Rubyクライアント最初の7秒間の遅延は、なぜ2秒じゃないのか？
* ~~telnetで接続して指定の秒数遅延させることはできるか？~~
* 他のツールだったらもっと簡単？