1. 前言
前一阵子线上程序出了一个 Downtime,原来同事写的一段代码中间在读写 Redis 的时候没有做好异常处理。在关键流程上面因为读写 Redis 异常直接退出了,导致后续的流程没有处理完。
解决方法也很简单,从业务逻辑入手在读写失败的时候进行重试和降级即可。可是怎么模拟网络故障进行测试呢?
下面就要轮到 iptables 上场了。
2. 使用 iptables 模拟故障
使用 iptables 来模拟网络故障的时候,我们针对 Redis 写入进行处理。简单来说就是在 Redis Server 端口 OUTPUT 的网络包分别进行 REJECT 和 DROP 操作。
sudo iptables -D OUTPUT -p tcp --destination-port 22368 -j REJECT
sudo iptables -D OUTPUT -p tcp --destination-port 22368 -j DROP
异常信息:
Caused by: java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at redis.clients.jedis.Connection.connect(Connection.java:184)
测试过后虽然 Redis 写入数据有问题,但是主流程能够正常跑完,这就 OK 了。