如何使用Cloudbees TcpSyslogMessageSender复用TCP-TLS通信会话与端口号
关于Cloudbees TcpSyslogMessageSender TCP-TLS连接复用的说明
Cloudbees TcpSyslogMessageSender 默认原生支持TCP-TLS场景下的连接、TLS会话、客户端端口复用,不需要额外配置组件参数。你当前代码每次通信都使用新客户端端口,是代码逻辑问题,和组件本身能力无关。
根因分析
你当前的代码存在两个直接导致连接无法复用的问题:
- 每次发送消息都新建一个全新的
TcpSyslogMessageSender实例,每个实例对应独立的TCP连接资源 - 发送完单条消息后立刻在
finally块调用close()方法主动断开连接,完全没给长连接留复用空间
这种实现下,每次发消息都会完整走一遍TCP三次握手、TLS握手、发消息、四次挥手断连的流程,操作系统每次新建TCP连接都会分配新的临时客户端端口,自然不可能实现复用。
复用实现方案
调整代码逻辑即可实现复用,不需要修改组件配置:
- 将
TcpSyslogMessageSender的初始化逻辑提前到应用启动阶段,做成全局单例复用,不要每次发消息都新建实例 - 不要在单条消息发送完成后调用
close(),组件内部会自动维护长连接状态,后续发送消息直接复用已建立的TCP连接和TLS会话,客户端端口自然会保持一致 - 仅在应用停机、后续不再需要发送syslog消息时,再调用
close()释放连接资源
参考实现代码:
// 应用启动阶段初始化全局唯一sender实例 private static final TcpSyslogMessageSender SYSLOG_SENDER; static { SYSLOG_SENDER = new TcpSyslogMessageSender(); SYSLOG_SENDER.setSyslogServerHostname("localhost"); SYSLOG_SENDER.setSyslogServerPort(6514); SYSLOG_SENDER.setMessageFormat(MessageFormat.RFC_5425); SYSLOG_SENDER.setDefaultMessageHostname(getHostName()); SYSLOG_SENDER.setDefaultAppName("test"); SYSLOG_SENDER.setDefaultFacility("local0"); SYSLOG_SENDER.setDefaultSeverity("notice"); SSLContext context = getSSLContext(); // 加载客户端证书、信任库生成SSL上下文 SYSLOG_SENDER.setSSLContext(context); SYSLOG_SENDER.setSsl(true); // 注册JVM停机钩子,应用退出时再关闭连接 Runtime.getRuntime().addShutdownHook(new Thread(() -> { try { SYSLOG_SENDER.close(); } catch (IOException e) { // 按需处理关闭异常 } })); } // 消息发送方法直接复用全局实例,不要每次新建、关闭sender public boolean sendSyslogMessage(String syslogMessage) { try { SYSLOG_SENDER.sendMessage(syslogMessage); return true; } catch (IOException e) { // 按需处理发送异常,组件在连接断开后会在下次发送时自动重连 return false; } }
补充说明
- 复用同一个sender实例的场景下,组件内部会自动维护TLS会话,不需要额外配置SSLContext参数或socket复用选项
- 如果担心长连接因空闲时间过长被中间网络设备、服务端断开,只需要在发送异常时按需加重试逻辑即可,组件本身具备连接断开后自动重连的能力
内容的提问来源于stack exchange,提问作者Arya Mohan
相关产品推荐
相关产品推荐

