问题1:使用jeromq的rep/req,一个服务(发送)同时向多个服务(接收)高频发送数据。为了提升各效率在我们把各个服务的zmq.socket都保存起来,分别使用线程发送数据。在一个接收方挂掉或者断开后。重连次数过多后,Jeromq就会出现emfile的问题,原因经过我们排查是由于socket在断开后再此发送时,重新建联,当建联数量超过1024个数量后(this.emptySlots.isEmpty()),再次建联就会报这个错。
我们现在的解决方案有两个
方案一:在创建是获取这个异常,然后在catch里面重新创建上下文,这里在关闭原上下文时(context.term())会一直卡死在这。
try {
socket = context.socket(ZMQ.REQ);
}catch (IllegalStateException e){//this.emptySlots.isEmpty()
context.term();
if(context.isClosed()||context==null)
context = ZMQ.context(1);
}
方案二:在断开后发送数据失败时,将原来的连接杀死;测试环境下没有发现问题,但是在生产环境下长时间运行依然会出现emfile报错。
socket.disconnect(addr);
socket.close();
socket.setLinger(0);
问题2:同样使用jeromq的rep/req,一个服务(发送)同时向多个服务(接收)高频发送数据。为了提升各效率在我们把各个服务的zmq.socket都保存起来,分别使用线程发送数据。在连续发送7天以上的数据后出现一个发送端向多个接收端高频发送消息时,出现发送给其中几个服务端出现收不到回复,重启接收端程序能够正常运行成功,运行7天以上后又会重复出现该情况。
TransferSocket socket = (TransferSocket)ConnectionSocket.SOCKETS.get(ip);
try
{
ZMsg recv = socket.send(zFrames);
if (recv == null) {
logger.error("传输失败,未收到" + ip + "回复");
destory(ip);
statusCode = 1;
} else {
logger.info("向[" + ip + "]发送数据成功");
try {
errorMessage = new String(base64.decode(recv.toArray()[4].toString()), "UTF-8");
logger.info("收到[" + ip + "]的响应:" + errorMessage);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
statusCode = 0;
recv.destroy();
}
} catch (Exception e) {
statusCode = 1;
errorMessage = "传输异常";
e.printStackTrace();
}
可能出现原因分析:
- 短暂的出现收不到回复,销毁ZMQ.Socket时,发送端Socket连接未断开,导致无论怎么新建socket都收不到回复。
- 出现一次收不到回复后,销毁了ZMQ.Socket,销毁后新建ZQM.Socket 未连接成功,所以出现收不到回复后一直不能恢复状态。
未找到合理的解决方案。