###前提・実現したいこと
RSTパケットがサーバー側の設定回数分、再送処理を行えること。
または、再送処理が指定回数されない理由を知りたい。
環境
クライアント側
PC1のVMWare上
CentOS
Linux release 7.4.1708 (Core)
Java
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-b12)
OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)
サーバー側
PC2のVMWare上
CentOS
Linux release 7.4.1708 (Core)
Java
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
JavaでのDB操作用パッケージ commons-dbcp2-2.1.jar org.apache.commons.dbcp2.BasicDataSource; MySQL mysqld Ver 5.7.20 for Linux on x86_64 (MySQL Community Server (GPL))
データ再送確認
wireshark
クライアントとサーバーの通信概要
クライアント側から送信し、サーバー側は受信したと同時に、必要であればDB処理を行い
即クライアント側へデータを送信する。
エコーサーバーみたいなもの。
検証中のクライアント側からの送信時の負荷の掛け方は クライアント側で1ユーザー分(ユーザー毎に送信、受信用の2スレッド)を 1000人分用意し、一斉にデータを送信させる。 ユーザー単体内ではwhileループで1000回分送信するなど。
###発生している問題・エラーメッセージ
Javaでクライアントとサーバーでソケット通信している際
TCPの「PSH,ACK」パケットの再送回数がサーバー側「tcp_retries2」の設定回数
に到達しないうちにRSTパケットが送信されて、コネクションがリセットされる。
firewalldで拒否した際のRSTパケット送信までの間隔合計約14分まで掛かるが
指定した再送回数分は再送されている。
早々にRSTパケットが発行される際は、6~9回「TCP Retransmission」を行った直後にRSTパケットが
サーバー側からクライアント側に送信されている。
データパケット送信からRSTパケット送信までの間隔合計100~110秒程度
クライアント側、サーバー側共に
「/proc/sys/net/ipv4/tcp_retries2」
15
サーバー側のMySQL
「show variables like '%timeout';」
+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| connect_timeout | 3600 |
| delayed_insert_timeout | 300 |
| have_statement_timeout | YES |
| innodb_flush_log_at_timeout | 1 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 3600 |
| net_write_timeout | 3600 |
| rpl_stop_slave_timeout | 31536000 |
| slave_net_timeout | 60 |
| wait_timeout | 28800 |
+-----------------------------+----------+
Java
1 JavaのBasicDataSourceの設定 2 bds.setMaxIdle(5000); 3 bds.setMinIdle(5); 4 bds.setMaxTotal(5000); 5 bds.setDefaultAutoCommit(false); 6 bds.setDefaultReadOnly(false); 7 bds.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 8 bds.setTimeBetweenEvictionRunsMillis(10*60*1000); 9 10 bds.setMaxConnLifetimeMillis(3600*1000); 11 bds.setMaxWaitMillis(3600*1000); 12 bds.setRemoveAbandonedTimeout(3600); 13 14 bds.setValidationQuery("select * from xxxx limit 1"); 15 bds.setTestOnBorrow(true); 16 bds.setTestWhileIdle(true); 17 bds.setMinEvictableIdleTimeMillis(6000000);
###試したこと
サーバー側でfirewalldで拒否した場合は、TCP再送回数は「tcp_retries2」の設定回数分
再送間隔の時間を倍々にしながら、最大120秒の間隔まで空けながら、再送処理を行った後に
RSTパケットを、サーバー側から送信してコネクションをリセット出来ていた。
クライアント側から、サーバー側でDB操作を必要としないデータを送信した場合は 送信量を増大させて負荷を上げていくと、最後はサーバー側のJavaがOutOfMemoryとなり 切断される。こちらは想定通り。 OutOfMemorryにならない状態であれば、処理負荷が高く、一括で受け取ったものを処理に20分 かかるものでも、クライアントの送信回数分が、正しくサーバー側から返却される。 だが、サーバー側でDB操作を必要とするデータをクライアント側から大量に送る場合 前述の処理よりCPUの論理コアの使用率が半分程度でも、早々に再送回数の指定より少ない状況で RSTパケットが送信されて、コネクションがリセットされる。 DB操作のデータを含むものでも、一括で送られるデータが「1000ユーザーが300回ずつ」では問題なく 処理が出来ていて、1ユーザーあたりの送信回数を500や1000程度の処理になると、RSTパケットが 発生して、切断される。
どのようなことでも結構ですので、お教え頂ければと思います。
よろしくお願いします。
あなたの回答
tips
プレビュー