我使用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