高性能C++ネットワークライブラリlibtnet実践:comet単機百万接続マウントテスト
最近go言語で大量の長接続をマウントしたプッシュサーバーを作っていますが、すでに完成していますが、メモリの使用状況があまり満足していないので、libtnetを使って再実現することを考えています.後でcometを使用してプッシュサーバを示す.
cometにとって,単機は大量の同時接続をサポートできることが最優先事項である.現在、業界にはすでに多くのデータがあり、単機で200 w、300 wをサポートしていると言っていますが、私はまず目標を100 wの上に決めて、主な原因は実際の運行の中で、cometはまた少量の論理機能があって、私は単機で100 wをマウントした上で、これらの論理を完全に無圧力で処理することができることを保証しなければなりません.
CometServer Test
まずlibtnetで簡単にcomet serverを書きました.httpリクエストを受け入れ、保留し、ランダムな時間が経過した後、200を返します.
comet serverは、長接続をマウントすることを担当しているだけで、メッセージのプッシュはありません.実際のプロジェクトでは、マウント接続とプッシュメッセージを2つのサービスに分けて完了しました.ここでcometは接続テストをマウントするだけです.
機械の準備をテストする
linuxシステムの上のNIC tcp接続ポートの数に制限があるため、ip_を調整します.local_port_rangeは、60000個のtcp接続をサポートします.
100 w接続には少なくとも16台のマシンが必要ですが、実際には4 Gメモリの仮想マシンが3台しかありません.だから、メンテナンスする子供靴は機械ごとに6枚のネットカードを入れました.これで100 wの接続を確立できます.
テストクライアントも非常に簡単で、毎秒1000個の接続をサーバに要求しますが、1台のマシンに複数のNICがあるため、socketを作成した後、socketをあるNICにバインドする必要があります.
実際のテストでは、メモリの問題で、1台あたり34 w程度のtcp接続を支えることができるのは、私には十分なので、チューニングもおっくうです.
CometServer Linuxチューニング
まず、最大オープンファイル数を調整する必要があります.私のマシンの上で、nr_Openの最大値は1048576で、私にとって十分なので、最大ファイル記述子の数を1040000に調整します.
次に、tcpのいくつかのシステムパラメータのチューニングです.
これらの値をどのように調整するかについては、ネット上ではそれぞれの説があり、直接man 7 tcpを提案しています.私も実際にはdmesg出力のtcpエラーを表示することで動的に調整します.ここで単独で説明する必要があるのはtcp bufferの設定で、私の最小とデフォルトは4 kです.これは主にプッシュサーバがあまり頻繁なデータインタラクションを必要としないことを考慮しているので、できるだけtcpのメモリ消費を減らす必要があります.
テスト結果
実際のテストは私を満足させた.
cometserver test 8プロセスのcpu消費はいずれも低く、輪訓timing wheelがあってから200を送信する論理があるため、鉄はcpu消費があると確信しており、マウントだけであればcpuはもっと低いはずだ.
socketの統計:
合計1017147個のtcpリンクがあり、4 G近く(1017167はページ数で4096を乗じる必要がある)のメモリを占有していることがわかります.
システムメモリの状況:
システムには16 Gメモリがあり、5 Gも利用できるので、意外にもシングルマシンはより多くのtcp接続を搭載できるはずです.
まとめ
libtnetを使用して開発された簡単なcomet serverは百万級の接続をサポートし、その応用に対する自信を深めました.
libnetアドレスhttps://github.com/siddontang/libtnetああ、見物を歓迎します.
cometにとって,単機は大量の同時接続をサポートできることが最優先事項である.現在、業界にはすでに多くのデータがあり、単機で200 w、300 wをサポートしていると言っていますが、私はまず目標を100 wの上に決めて、主な原因は実際の運行の中で、cometはまた少量の論理機能があって、私は単機で100 wをマウントした上で、これらの論理を完全に無圧力で処理することができることを保証しなければなりません.
CometServer Test
まずlibtnetで簡単にcomet serverを書きました.httpリクエストを受け入れ、保留し、ランダムな時間が経過した後、200を返します.
void onTimeout(const TimingWheelPtr_t& wheel, const WeakHttpConnectionPtr_t& conn)
{
HttpConnectionPtr_t c = conn.lock();
if(c)
{
c->send(200);
}
}
void onHandler(const HttpConnectionPtr_t& conn, const HttpRequest& request)
{
int timeout = random() % 60 + 30;
comet.wheel->add(std::bind(&onTimeout, _1, WeakHttpConnectionPtr_t(conn)), timeout * 1000);
}
int main()
{
TcpServer s;
s.setRunCallback(std::bind(&onServerRun, _1));
HttpServer httpd(&s);
httpd.setHttpCallback("/", std::bind(&onHandler, _1, _2));
httpd.listen(Address(11181));
s.start(8);
return 0;
}
comet serverは、長接続をマウントすることを担当しているだけで、メッセージのプッシュはありません.実際のプロジェクトでは、マウント接続とプッシュメッセージを2つのサービスに分けて完了しました.ここでcometは接続テストをマウントするだけです.
機械の準備をテストする
linuxシステムの上のNIC tcp接続ポートの数に制限があるため、ip_を調整します.local_port_rangeは、60000個のtcp接続をサポートします.
net.ipv4.ip_local_port_range = 1024 65535
100 w接続には少なくとも16台のマシンが必要ですが、実際には4 Gメモリの仮想マシンが3台しかありません.だから、メンテナンスする子供靴は機械ごとに6枚のネットカードを入れました.これで100 wの接続を確立できます.
テストクライアントも非常に簡単で、毎秒1000個の接続をサーバに要求しますが、1台のマシンに複数のNICがあるため、socketを作成した後、socketをあるNICにバインドする必要があります.
実際のテストでは、メモリの問題で、1台あたり34 w程度のtcp接続を支えることができるのは、私には十分なので、チューニングもおっくうです.
CometServer Linuxチューニング
まず、最大オープンファイル数を調整する必要があります.私のマシンの上で、nr_Openの最大値は1048576で、私にとって十分なので、最大ファイル記述子の数を1040000に調整します.
fs.file-max = 1040000
次に、tcpのいくつかのシステムパラメータのチューニングです.
net.core.somaxconn = 60000
net.core.rmem_default = 4096
net.core.wmem_default = 4096
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 4096 16777216
net.ipv4.tcp_wmem = 4096 4096 16777216
net.ipv4.tcp_mem = 786432 2097152 3145728
net.core.netdev_max_backlog = 60000
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_syn_backlog = 60000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_max_orphans = 131072
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_max_tw_buckets = 60000
net.netfilter.nf_conntrack_max = 1000000
net.netfilter.nf_conntrack_tcp_timeout_established = 1200
これらの値をどのように調整するかについては、ネット上ではそれぞれの説があり、直接man 7 tcpを提案しています.私も実際にはdmesg出力のtcpエラーを表示することで動的に調整します.ここで単独で説明する必要があるのはtcp bufferの設定で、私の最小とデフォルトは4 kです.これは主にプッシュサーバがあまり頻繁なデータインタラクションを必要としないことを考慮しているので、できるだけtcpのメモリ消費を減らす必要があります.
テスト結果
実際のテストは私を満足させた.
cometserver test 8プロセスのcpu消費はいずれも低く、輪訓timing wheelがあってから200を送信する論理があるため、鉄はcpu消費があると確信しており、マウントだけであればcpuはもっと低いはずだ.
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4685 root 20 0 187m 171m 652 S 19.9 1.1 2:19.20 cometserver_test
4691 root 20 0 191m 175m 656 S 16.6 1.1 2:17.80 cometserver_test
4686 root 20 0 170m 155m 652 S 16.3 1.0 2:09.54 cometserver_test
4690 root 20 0 183m 167m 652 S 16.3 1.1 2:11.44 cometserver_test
4692 root 20 0 167m 152m 652 S 16.3 1.0 2:11.29 cometserver_test
4689 root 20 0 167m 152m 652 S 15.3 1.0 2:03.08 cometserver_test
4687 root 20 0 173m 158m 652 S 14.3 1.0 2:07.34 cometserver_test
4688 root 20 0 129m 114m 652 S 12.3 0.7 1:35.77 cometserver_test
socketの統計:
[root@localhost ~]# cat /proc/net/sockstat
sockets: used 1017305
TCP: inuse 1017147 orphan 0 tw 0 alloc 1017167 mem 404824
UDP: inuse 0 mem 0
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0
合計1017147個のtcpリンクがあり、4 G近く(1017167はページ数で4096を乗じる必要がある)のメモリを占有していることがわかります.
システムメモリの状況:
[root@localhost ~]# free
total used free shared buffers cached
Mem: 16334412 11210224 5124188 0 179424 1609300
-/+ buffers/cache: 9421500 6912912
Swap: 4194296 0 4194296
システムには16 Gメモリがあり、5 Gも利用できるので、意外にもシングルマシンはより多くのtcp接続を搭載できるはずです.
まとめ
libtnetを使用して開発された簡単なcomet serverは百万級の接続をサポートし、その応用に対する自信を深めました.
libnetアドレスhttps://github.com/siddontang/libtnetああ、見物を歓迎します.