我使用Spring集成TCP服務器,它保持連接到幾千客戶端。我需要服務器來限制客戶端在負載過重的情況下不會丟失消息。春季集成 - 可靠的TCP高容量應用程序
我的服務器配置:
<task:executor id="myTaskExecutor"
pool-size="4-8"
queue-capacity="0"
rejection-policy="CALLER_RUNS" />
<int-ip:tcp-connection-factory id="serverTcpConFact"
type="server"
port="60000"
using-nio="true"
single-use="false"
so-timeout="300000"
task-executor="myTaskExecutor" />
<int-ip:tcp-inbound-channel-adapter id="tcpInboundAdapter"
channel="tcpInbound"
connection-factory="serverTcpConFact" />
<channel id="tcpInbound" />
<service-activator input-channel="tcpInbound"
ref="myService"
method="test" />
<beans:bean id="myService" class="org.test.tcpserver.MyService" />
由於連接工廠默認任務執行者是無界的,我用一個彙集任務執行,以防止內存不足的錯誤。
一個簡單的客戶端負載測試:
public class TCPClientTest {
static Socket socket;
static List<Socket> sl = new ArrayList<>();
static DataOutputStream out;
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10000; i++) {
socket = new Socket("localhost", 60000);
sl.add(socket);
out = new DataOutputStream(socket.getOutputStream());
out.writeBytes("connection " + i + "\r\n");
System.out.println("Using connection #" + i);
}
System.in.read();
}
}
當我運行它,服務器只接收大約10-20消息,然後客戶端獲得「連接被拒絕:連接」異常。之後,即使在連接超時之後,服務器也不能再接受任何新的連接。增加池大小僅有助於獲得更多的消息。
編輯
我使用Spring集成3.0.2.RELEASE。對於生產,我使用8-40個線程,但它僅在幾百次連接之後纔會使此測試失敗。
MyService.test()並沒有做太多......
public class MyService {
public void test(byte[] input) {
System.out.println("Received: " + new String(input));
}
}
Here is the log with trace level logging.
什麼版本的Spring Integration? 'MyService.test()'做了什麼?由於你只是在每個套接字上發送一條短消息,所以我不希望這個測試用例有任何線程問題(儘管4-8個線程可能完全不適合具有這個套接字數量的實際應用程序)。我建議你打開服務器端的跟蹤級日誌記錄。 –
@Gary Russell編輯我的問題。 – John29