一、背景介绍
系统使用过程中需接收长度特别长的syslog日志,debug发现之前使用UnicastReceivingChannelAdapter接收UDP消息会导致接收的数据不全,因此猜测UnicastReceivingChannelAdapter默认配置的接收字节有限制。
参考TCP and UDP Support (spring.io)的Table 2. UDP Inbound Channel Adapter Attributes,发现有一个属性为receive-buffer-size,意为缓冲区大小设置,缓冲区的大小用于接收datagrampackets。通常设置为最大传输单元(MTU)大小。如果使用较小的缓冲区,则可能会发生截断。文章提到也可以使用检查长度属性(check-length)来检测到这一点。
笔者通过设置check-length为true试了下效果。代码如下:
- UnicastReceivingChannelAdapter channelAdapter = new UnicastReceivingChannelAdapter(514);
- channelAdapter.setLengthCheck(true);
全部代码可参考使用UnicastReceivingChannelAdapter多线程接收UDP消息的方法,测试发现这个长度检查对接收超长字节消息只会告警,日志如下。
- 2022-07-05 11:07:16 ERROR [processUniCastUdpMessage.ip:udp-inbound-channel-adapter#0-ip:udp-inbound-channel-adapter] o.s.i.ip.udp.UnicastReceivingChannelAdapter Failed to map packet to message
- org.springframework.integration.mapping.MessageMappingException: Incorrect length; expected 175334770, received 2048
- at org.springframework.integration.ip.udp.DatagramPacketMessageMapper.toMessage(DatagramPacketMessageMapper.java:227)
- at org.springframework.integration.ip.udp.DatagramPacketMessageMapper.toMessage(DatagramPacketMessageMapper.java:213)
- at org.springframework.integration.ip.udp.UnicastReceivingChannelAdapter.doSend(UnicastReceivingChannelAdapter.java:199)
- at org.springframework.integration.ip.udp.UnicastReceivingChannelAdapter.lambda$asyncSendMessage$0(UnicastReceivingChannelAdapter.java:184)
- at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
- at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
- at java.lang.Thread.run(Thread.java:748)
二、解决方法
根据需要设置缓冲区大小,代码如下:
- UnicastReceivingChannelAdapter channelAdapter = new UnicastReceivingChannelAdapter(514);
- channelAdapter.setReceiveBufferSize(2048000);
缓冲区默认大小是2048。