Spring TCP支持高CPU利用率

时间:2018-03-21 09:06:00

标签: java spring-boot spring-integration

我正在使用spring TCP support来创建TCP服务器。

我注意到当我只发送一个请求时,CPU的运行率为91%。 这是我的代码

    let myString = "abcde."
    let op1 = myString.removeTheSpecialCharAtLast(char: "cd")
    let op2 = myString.removeTheSpecialCharAtLast(char: ".")
    let op3 = myString.removeTheSpecialCharAtLast(char: "de")
    let op4 = myString.removeTheSpecialCharAtLast(char: "de.")
    print(op1)   //abcde.
    print(op2)   //abcde
    print(op3)   //abcde.
    print(op4)   //abc

这就是我如何转换和记录消息

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.ip.tcp.TcpInboundGateway;
import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;
import org.springframework.integration.ip.tcp.connection.MessageConvertingTcpMessageMapper;
import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory;
import org.springframework.integration.ip.tcp.serializer.AbstractByteArraySerializer;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.converter.ByteArrayMessageConverter;
import org.springframework.messaging.converter.MessageConverter;

@Configuration
@IntegrationComponentScan
public class TCPServerConfig {

  @Value("${tcp.listener.port}")
  private int port;

  @Bean
  public MessageConvertingTcpMessageMapper mapper(final MessageConverter messageConverter) {
    return new MessageConvertingTcpMessageMapper(messageConverter);
  }

  @Bean
  public MessageConverter messageConverter() {
    return new ByteArrayMessageConverter();
  }


  @Bean
  public TcpInboundGateway tcpInGate(final AbstractServerConnectionFactory connectionFactory) {
    final TcpInboundGateway inGate = new TcpInboundGateway();
    inGate.setConnectionFactory(connectionFactory);
    inGate.setRequestChannel(fromTcp());

    return inGate;
  }

  @Bean
  public MessageChannel fromTcp() {
    return new DirectChannel();
  }

  @Bean
  public AbstractServerConnectionFactory serverCF(
      final AbstractByteArraySerializer byteArraySerializer) {
    final TcpNetServerConnectionFactory connectionFactory =
        new TcpNetServerConnectionFactory(this.port);
    connectionFactory.setDeserializer(byteArraySerializer);
    connectionFactory.setSerializer(byteArraySerializer);
    return connectionFactory;
  }

  @Bean
  public AbstractByteArraySerializer byteArraySerializer() {
    return new ByteArrayCustomeSerializer();
  }
}

我添加了日志记录,发现一旦应用程序收到第一个请求,它就会正确地提供它,然后每秒多次使用空字节数组的输入流调用import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.apache.commons.lang3.StringUtils.isBlank; import java.nio.charset.Charset; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; import org.springframework.integration.annotation.MessageEndpoint; import org.springframework.integration.annotation.ServiceActivator; import org.springframework.integration.annotation.Transformer; @Slf4j @MessageEndpoint class TCPMessageProcessor { @Transformer(inputChannel = "fromTcp", outputChannel = "toProcess") public String convertInput(final byte[] bytes) { if(ArrayUtils.isEmpty(bytes)){ return EMPTY; } String inboundMessage = new String(bytes, Charset.forName("ASCII")); log.info("Converted the message to string: '{}'. Handing it processor", inboundMessage); return inboundMessage; } @ServiceActivator(inputChannel = "toProcess") public String process(final String message) { if(isBlank(message)){ return EMPTY; } log.info("Started processing message '{}'", message); return "some response"; } } 。任何人都可以提供有关为什么会发生这种情况以及如何避免这种行为的见解?

这来自ByteArrayCustomeSerializer#doDeserialize

org.springframework.integration.ip.tcp.connection.TcpNetConnection

1 个答案:

答案 0 :(得分:1)

这很可能是您ByteArrayCustomeSerializer中的错误 - 编辑问题以显示代码。

很可能你没有检测到流的结束。

如果流在消息之间关闭,则需要抛出SoftEndOfStreamException以表示套接字已以“预期”方式关闭。如果在消息反序列化期间流关闭,则抛出一些其他异常。