Wizzercn / MqttWk

Java + Netty 实现的高并发高可用MQTT服务broker,轻松支持10万并发(有群友实现了130万在线)
Apache License 2.0
644 stars 231 forks source link

java.lang.NullPointerException报错 #17

Closed coolxbin closed 3 years ago

coolxbin commented 4 years ago

线上连接700台设备左右,频繁报空指针错误。有两个地方: 1、cn.wizzer.iot.mqtt.server.broker.protocol.DisConnect

    public void processDisConnect(Channel channel, MqttMessage msg) {
        String clientId = (String) channel.attr(AttributeKey.valueOf("clientId")).get();
        SessionStore sessionStore = sessionStoreService.get(clientId);
       // BUG:在极端条件下,redis中保存的session信息过期,导致sessionStore=null,此处报NullPointerException。
       // 判断条件修改为sessionStore != null && sessionStore.isCleanSession()
        if (sessionStore.isCleanSession()) {

        }
       // ...省略部分代码
    }

2、cn.wizzer.iot.mqtt.server.broker.handler.BrokerHandler

@Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
       // ...省略部分代码
    // 发送遗嘱消息
    if (this.protocolProcess.getSessionStoreService().containsKey(clientId)) {
        SessionStore sessionStore = this.protocolProcess.getSessionStoreService().get(clientId);
        // BUG:IdleStateHandler检测间隔与redis超时时间相同。极端条件下,containsKey=true,但是get返回null。
            // 判断条件修改为:null != sessionStore && sessionStore.getWillMessage() != null
            // 或者考虑仅使用this.protocolProcess.getSessionStoreService().get(clientId),然后判断null即可
        if (sessionStore.getWillMessage() != null) {
            this.protocolProcess.publish().processPublish(ctx.channel(), sessionStore.getWillMessage());
        }
      // ...省略部分代码
    }

另外,BrokerHandler.exceptionCaught()方法最好能将异常信息打印出来,方便从日志中查看异常详细。以上问题就是加了打印才发现了具体的代码,如果不加仅打印了Exception的message:

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if (cause instanceof IOException) {
            // 远程主机强迫关闭了一个现有的连接的异常
            ctx.close();
        } else {
            // FIX:打印异常信息
            logger.error("出现了异常", cause);
            super.exceptionCaught(ctx, cause);
        }
    }
wendal commented 4 years ago

我建议以pull request方式提供修正

coolxbin commented 4 years ago

@wendal 先等待作者回复吧,先听听他的建议,有可能有更好的修复方式

Wizzercn commented 3 years ago

已修改,忘记close了。