春天整合超时客户

时间:2014-06-25 10:50:41

标签: java multithreading spring tcp spring-integration

我的Spring集成方案是:

  1. 使用自定义协议(大小和内容)发送数据的生产者
  2. 我必须解码此自定义协议,然后处理结果。
  3. 所以我尝试了很多配置,目前最好的是以下内容:

    <bean id="serializer" class="com.MySerializerDeserializer" />
    <task:executor id="myTaskExecutor" pool-size="5-300" queue-capacity="500000"/>
    <int-ip:tcp-connection-factory id="serverTcpConFact"
        type="server"
        port="5566"
        using-nio="true"
        single-use="false"
        so-timeout="5000"
        task-executor="myTaskExecutor"
        deserializer="serializer" 
        serializer="serializer"/>
    
    <int-ip:tcp-inbound-channel-adapter id="tcpInboundAdapter"
        channel="tcpInbound"
        connection-factory="serverTcpConFact" />
    
    <int:channel id="tcpInbound" />
    
    <int:service-activator input-channel="tcpInbound"
        ref="importService"
        method="handler" />
    
    <bean id="importService" class="com.MyImportService" />
    

    序列化类是:

    public class MySerializerDeserializer implements Serializer< MyMessage >, Deserializer< MyMessage > {
    
        @Override
        public MyMessage deserialize(InputStream inputStream) throws IOException {
            DataInputStream dis = new DataInputStream(inputStream);
            int size = dis.readInt();
            byte[] b = new byte[size];
            dis.read(b);
            MyMessage s = new MyMessage ();
            String value = new String(b);
            s.setTest(value);
            return s;
    

    我将此代码用于服务器:

    class SimpleThread extends Thread {
        public void run() {
            try {
                String id = java.util.UUID.randomUUID().toString();
                try (Socket echoSocket = new Socket("localhost", 5566)) {
                    DataOutputStream dos = new DataOutputStream(echoSocket.getOutputStream());
                    for (int i = 0; i < 500; i++) {
                        String s = id + " " + i;
                   dos.writeInt(s.length());
                        dos.write(s.getBytes());
                        dos.flush();
                        System.out.println(id + " - " + i + " - " + s.length());
                    }
                }
    

    当我尝试执行多个线程时,单个线程执行此操作时效果正常如下:

      for (int i = 0; i < 5; i++) {
     new SimpleThread().start();
     }
    

    Spring集成服务器卡住了,我有以下警告:

    WARN _[m [THREAD ID=myTaskExecutor-1] 2014-06-25 12:42:18 WARN  org.springframework.integration.ip.tcp.connection.AbstractConnectionFactory:566 - Timing out TcpNioConnection 127.0.0.1:56273:5566:4e3caf61-1101-4881-a1cf-1c31610b33f3
    

    它不起作用,服务器无法收到消息。

    出现此错误: enter image description here

    我哪里错了? 谢谢。

    修改

    我用这种方式修改了线程轮询:

    <bean id="myTaskExecutor" class="org.springframework.integration.util.CompositeExecutor">
        <constructor-arg>
            <bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
                <property name="threadNamePrefix" value="io-" />
                <property name="corePoolSize" value="4" />
                <property name="maxPoolSize" value="8" />
                <property name="queueCapacity" value="50000" />
                <property name="rejectedExecutionHandler">
                    <bean class="org.springframework.integration.util.CallerBlocksPolicy">
                        <constructor-arg value="10000" />
                    </bean>
                </property>
            </bean>
        </constructor-arg>
        <constructor-arg>
            <bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
                <property name="threadNamePrefix" value="assembler-" />
                <property name="corePoolSize" value="4" />
                <property name="maxPoolSize" value="10" />
                <property name="queueCapacity" value="50000" />
                <property name="rejectedExecutionHandler">
                    <bean class="org.springframework.integration.util.CallerBlocksPolicy">
                        <constructor-arg value="10000" />
                    </bean>
                </property>
            </bean>
        </constructor-arg>
    </bean>
    

    服务器响应更快,但我仍有问题

    **编辑*****

    导入服务是:

    public class ImportService {
    
        public void handler(MyMessage inp) {
            System.out.println(Thread.currentThread().getName() + "******" + inp.getTest());
    
        }
    

2 个答案:

答案 0 :(得分:1)

我刚刚按照描述运行了您的测试(复制了您的代码),并且所有工作都按预期工作。 500条消息传递到另一方。

我建议您打开TRACE级别日志记录,并可能在解串器中添加一些调试日志记录。

答案 1 :(得分:0)

@JR您可能想看看这个与您类似的示例。

https://github.com/rajeshgheware/spring-integration-samples/tree/master/spring-integration-samples-tcp-concurrent-server

我成功测试了3900个并发客户端的这段代码。