长连接检测 监控的一点思考 java实现

大家好,我是烤鸭:

   怎么监控长链接服务器的稳定,除了探活服务之外,怎么保证长链接的收发正常,这篇文章考虑下这个。

问题来源

运营反馈部分直播间无法收到弹幕、点赞消息,第一时间进行复现,发现切换网络可以,但是不是所有人都可以。

怀疑是长连接服务器出问题了,重启后问题消失。

怎么监控呢,消息是否丢失?用户是否收到?

长链接实现

先谈谈实现方式,我们是基于nchan做的,之前也写过一篇文章。

https://blog.csdn.net/Angry_Mills/article/details/120068037

每次pub一条消息都会发布到redis,通过redis的发布订阅模式,不同的节点订阅后进行消息分发。

监控怎么加

客户端没收到消息的话,是建联的时候出错,还是建联成功一直没收到消息。

画一个简单的流程图,和监控可能加在哪里。

在这里插入图片描述

客户端加:
sub时候报错,进行错误上报,收到错误日志后进行报警。

服务端加:
发送到nchan服务器失败,进行报警。

发送到nchan服务器成功,redis中未有对应的消息,报警。

还有一种情况就是个人用户没收到消息,这种怎么监控。

建联了100个用户,只有1个用户没收到,网络原因?sub通道关闭了?nchan本身处理问题?

没什么好的方案,只能想办法记录当前建联了多少ip,以及发送了多少ip,进行比对,这种情况本身发生的几率不高。

服务端监控方案

pom中添加包

<dependency>
    <groupId>org.java-websocket</groupId>
    <artifactId>Java-WebSocket</artifactId>
    <version>1.3.5</version>
</dependency>

定时任务进行建联+消息发送和接收校验,看看是否有丢消息的情况,同时还可以探活长连接服务器

public WebSocketClient webSocketClient(String url, String vid) {
    try {
        WebSocketClient webSocketClient = new WebSocketClient(new URI(url), new Draft_6455()) {
            @Override
            public void onOpen(ServerHandshake handshakedata) {
                log.info("[websocket] 连接成功");
            }
            
            @Override
            public void onMessage(String message) {
                log.info("[websocket:" + url + "] 收到消息={}", message);
                // 放到 ConcurrentHashMap 一会和发送后的进行对比
                websocketPool.put(PREFIX_RECV_MSG + url, message);
            }
            
            @Override
            public void onClose(int code, String reason, boolean remote) {
                log.info("[websocket] 退出连接");
            }
            
            @Override
            public void onError(Exception ex) {
                log.info("[websocket] 连接错误={}", ex.getMessage());
                String msg = "[" + url + "][sub error]" + ex.getMessage();
                // 发送报警消息
            }
        };
        webSocketClient.connect();
        // 记录 WebSocketClient 对象,发送后进行 close
        websocketPool.put(url, webSocketClient);
        return webSocketClient;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

验证方法

    public void init() {
        String uri = "localhost:8080";
        // 随机生成群组id
        String cStr = UUID.randomUUID().toString();
        String protocol = "ws://";
        if ("prod".equalsIgnoreCase(envValue)) {
            protocol = "wss://";
        }
        // 1. 初始化 websocketclient
        String subUrl = protocol + uri + "/subscribe?integer=" + cStr;
        webSocketClient(subUrl, cStr);
        // 2. pub 消息
        String pubUrl = "http://" + uri + "/pubsub?integer=" + cStr;
        String message = UUID.randomUUID().toString();
        // 2.1 pub一次验证一次,pub就是https发送nchan负载
        //pub(pubUrl, message);
        try {
        	// 5秒后验证sub端是否和pub端结果一致
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 2.2 验证结果
        String subUrlMsg = PREFIX_RECV_MSG + protocol + uri + "/subscribe?integer=" + cStr;
        String recvMsg = (String) websocketPool.get(subUrlMsg);
        if (!message.equalsIgnoreCase(recvMsg)) {
            String msg = "[" + subUrl + "][sub error][message receive fail][send msg]=" + message
                    +"[recv msg]=" + recvMsg;
            // 不一致的话,报警
        }
        // 4. 销毁
        WebSocketClient webSocketClient = (WebSocketClient) websocketPool.get(subUrl);
        webSocketClient.close();
    }

报警截图:

可以看到确实有丢消息的情况,不过概率不高。

在这里插入图片描述

总结

nchan虽然是基于nginx的,性能和效率好,不过确实有些黑盒,不太好监控和二次开发。

以后还得考虑换一套框架,进行更完善的api和监控机制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烤鸭的世界我们不懂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值