CentOS部署的Java服务的监听器收不到被监听设备发送的报文

背景:

交换机发送SNMP报文到CentOS服务器(线上环境)的162端口(SNMP默认TRAP端口),Java程序以UDP的方式监听162端口。

结论:

服务器防火墙没有放开162端口

排查过程:

  1. 线上环境程序包跟本地程序一致,本地开发环境整套流程跑起来没问题,但线上环境的程序收不到snmp包

  2. 检查交换机SNMP TRAP配置,没问题。

  3. 程序监听使用SNMP4J工具,使用idea debug本地环境的SNMP4J源码,发现负责监听的源码调用了java.net包的DatagramSocket类的receive方法。receive方法的源码注释:

    Receives a datagram packet from this socket. When this method returns, the DatagramPacket's buffer is filled with the data received. The datagram packet also contains the sender's IP address, and the port number on the sender's machine.
    This method blocks until a datagram is received. The length field of the datagram packet object contains the length of the received message. If the message is longer than the packet's length, the message is truncated.
    If there is a security manager, a packet cannot be received if the security manager's checkAccept method does not allow it.
    

    结合源码大意就是以BIO的方式与指定ip和port建立socket连接并阻塞等待数据返回。
    线上使用arthas工具trace命令监控SNMP4J监听方法的源码。发现trace异常栈打印到了上面提到的receive方法,说明程序正常进入监听。
    trace再监控receive方法,然后手动触发交换机的TRAP,trace没有打印代码栈,jdk的receive方法没有监听到报文,说明TRAP报文根本没有给到程序,那总不能jdk有bug吧。

  4. 继续追溯问题,在线上服务器使用tcpdump抓包,可以抓到TRAP报文,所以是服务器到程序这一步有问题。

  5. 数据包经由tcpdump和防火墙的先后顺序:

    进项的顺序 Wire -> NIC -> tcpdump -> netfilter/iptables
    出项的顺序 iptables -> tcpdump -> NIC -> Wire
    

    进项时,tcpdump是可以抓到防火墙过滤规则内要过滤的包的。
    于是排查防火墙,确实没有放开监听的162端口。

我的排查步骤是有问题的,排查问题应该先从简单的地方入手,先检查问题是否是低级错误引起的。

你可能感兴趣的:(java,centos)