いいものをつくろう

CTOの日記

network parallel programming protocol

akkaのmax-connectionやlinger-timeoutの設定とその挙動でRST(tcp reset)が送られる訳

投稿日:

akkaの設定でlinger-timeoutというものがあります。

そこをいじることになった時のメモです。

本質的には通信がsocket(ファイル)によって実現されること

そして、そのデータの送受信にはメモリとcpuが消費されること

をイメージしながら、システムを考えることです。

 

まず

クライアント -> ロードバランサー -> サバー

という構成で

クライアントがtimeoutと判断するリクエストが増えたとしよう

tcpdumpでおっかけて

RSTリクエストが異様に多い場合

https://doc.akka.io/docs/akka-http/current/common/timeouts.html

サーバーの設定でlinger-timeoutというものがある(linger-timeout)

サーバーがデータをネットワークレイヤーに投げてから、どれくらい待ったあとでconnectionを閉じるか?

という設定だ。

閉じる、はTCPのRSTを送ることで実現される。これが表題のresetが送られる、の意味です

ここをinfiniteにするとコネクションは閉じないので

最悪の場合connection leakにつながりかねない。

適当な値を設定する

例えば100msとか、

ネットワークレイヤーのバッファがつまっていると、転送まで時間がかかり、RSTで強制終了となるケースが

考えられる。

この場合、クライアントからすればtimeoutが発生したのを同じだ。

 

ちなみにdefaultでは1分

https://github.com/akka/akka-http/blob/master/akka-http-core/src/main/resources/reference.conf#L72

 

さらに延長で

httpclientのhttp-connection-pool.のmax-connection

max-open-requestsについても調べた。

これは、サーバーが別のapiが呼び出すとか、httpリクエストをする時の設定だ。

コネクションのpoolがあって

これを最大数はいくつにしますか?

という問いですが、

まずconnection-poolとは接続済のconnectionを貯めておく、というアイデアに成り立ちます。

理由は、通信の接続、切断のコストが高いので、おなじホストにつなぐなら、それを使いまわそう

という発想です。それ故にこの設定はhostごとに管理されるのです。

で、ひとつのホストにどれだけの並列、コネクションをもちますか?

singleRequestやcachedHostConnectionPoolをつかった実装によって挙動がすこし

違うことを

説明してくれています。https://www.gregbeech.com/2018/04/08/akka-http-client-pooling-and-parallelism/

さらにakkaは実際http1.1の仕様を実装しているだけで、この辺の制約、max-connectionsなどもHTTP/1.1から

来ていると理解することは、

新しい知見というか、見えてなかった森を発見させてくれるよな、気づきをあたえてくれます。

さらにhttp1.1であるpipeliningとかは残念ながらakka httpclientで実装できてないので

使えずに、それゆえにmax-connectionでおなじホストに立て続けにリクエストするとシーケンシャルに時間が

かかってしまう様子を実験とともに示してくれています。

 

 

HTTP/1.1のpersistent connectionは ConnectionPoolで対応していということや

akka httpclientではpipeliningが実装されてないこと、代わりにmax-connectionで、並列でのパフォーマンスは調整できること

などがポイントです。

また、もともとのlinger-timeoutについても、リクエストに対するレスポンスの大きさや、

ネットワークの帯域、hostのcpu, ramのリソースなども意識できて、初めて設定できる

ところです

と思います。

この辺の設定は、http通信はtcp通信で

tcp/ip通信はsocketで実現

socketとは単にファイルで、

アプリがtcp/ip通信したいときに、ネットワーク層の入り口、そのホストが線で別の誰かとやりとりするイメージをもてると

おもうが、これにソケットという総称のファイルがつかわれている

ただそれだけである。

ソケットとはファイルですか?の問いに

基本は"Everything is a file" in the UNIX World.で、ソケットもそうだよ。名前がなかったり、こんなとこ (e.g. /proc/net/tcp); にあったり。

あとこの回答もしっくり、それにc言語とかでsocketかくとき、もろファイルdescripterってなるし

#include <sys/socket.h>
int fd = socket(<domain>, <type>, <protocol>)

Sockets are a special file type, similar to TCP/IP sockets, providing inter-process networking protected by the file system's access control.

For example, when you open a listening socket in one terminal with netcat:

nc -lU socket.sock
then send data from another terminal by:

echo mytext | nc -U socket.sock
mytext appears on the first terminal.

By default nc stops listening after an End-of-File character.

https://askubuntu.com/questions/372725/what-are-socket-files

 

でようは

なにが言いたいのかというと

通信の根っこでは、ファイルを介してアプリが外の世界と通信している訳です。

それ故にulimitとかファイルを開ける上限数が通信とからんでいるし

このファイルの読み書きが発生するからI/O blockingも発生するし、

ファイルの読みかきだから、並列処理したときにcpuが頑張って、コンテキストスウィッチして、いろんあ

ソケット(ファイル)から読み書きしてアプリに連携してくれる

ということ想像せよ

することで全体像がよく見えるだろう

 

 

キーワード、

並列通信とソケットとファイル

 

 

以上です

 

-network, parallel programming, protocol

Copyright© CTOの日記 , 2020 All Rights Reserved.