spring boot websocket 集群环境处理

        开发中迎来一个功能重构,需要在后台系统给指定用户发送whatsApp消息。验证用户关系,用户回复后进行其他提问。原先开发这个功能负责人是基于轮询实现,看着频繁刷mongodb的日志心里不爽,决定尝试使用websocket 进行推送。

        通常实现websocket 方式有几种原生注解,spring 封装,及netty实现。 具体实现可以参考下此文https://www.cnblogs.com/kiwifly/p/11729304.html

       相信简单实现通信对工作1-2年之后的人并不是什么难事,哈哈 不就是使用api吗。具体通信代码就不贴了,没啥意思。主要是想记录一下,开发过程遇到的问题。了解websocket的相信都知道websocket中的session无法持久化,不像http中的session能持久化到redis之类。这对集群环境显然不是很美好,例如发送whatsApp消息后台操作人员连接到A服务器,给用户发送消息。A服务器收到发送消息请求,马上调用第三方消息接口发送。由于用户回复消息不是实时的,只能是提供一个回调地址给第三方。当今项目架构想必单机的情况基本不存在了吧,若是第三方回调A服务器上,则通过websocket正常推送。若回调到B服务,那么会话就不存在了。怎么解决呢?有人会说可以用nginx把用户请求都落到一个节点上,这样就使得程序失去负载均衡的意义了。反过来想想既然消息落到某台机器,是不是可以把消息分发到其他机器呢?广播一下消息即可。dubbo redis mq 都可以做相应的事。

     鉴于我们项目使用了RabbitMq,决定使用RabbitMq方式广播消息。用过RabbitMq肯定知道有种FanoutExchange模式的交换机,问题又来了FanoutExchange只会把消息广播到不同queue里。这时候心里又嘀咕了,同一套代码跟配置都是一样的。怎么搞呢?有没有法子呀,答案肯定是有的咯。可以声明queue的时候获取本机ip及进程id,这样就能产生不同的queue的名字了。动态创建queue及绑定交换机即可贴出部分代码

 

@Bean("webSocketFanoutExchange")
    FanoutExchange webSocketFanoutExchange() {
        return new FanoutExchange("webSocketFanoutExchange");
    }

    @Bean("webSocketQueue")
    public Queue webSocketQueue() {
        String name = "message.websocket.";
        try {
            String ip = InetAddress.getLocalHost().getHostAddress();
            RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
            final String info = runtime.getName();
            final int index = info.indexOf("@");
            if (index != -1) {
                name = name + ip + "_" + info.substring(0, index);
            }
        } catch (UnknownHostException e) {
            log.warn("获取本地ip失败", e);
            name = name + UUID.randomUUID().toString().replace("-", "");
        }
        name = name + ".queue";
        return new Queue(name, false, false, true, null);
    }

    @Bean("bindingWebSocketExchange")
    Binding binding WebSocketExchange(@Qualifier("webSocketQueue") Queue  webSocketQueue,
                                             @Qualifier("webSocketFanoutExchange") FanoutExchange  webSocketFanoutExchange) {
        return BindingBuilder.bind(webSocketQueue).to(webSocketFanoutExchange);
    }

    @Bean(" WebSocketMessageContainer")
    public SimpleMessageListenerContainer  WebSocketMessageContainer(ConnectionFactory connectionFactory,
                                                                            @Qualifier("webSocketQueue") Queue  webSocketQueue,
                                                                            WebSocketMqListener webSocketMqListener) throws AmqpException {
		//WebSocketMqListener 你的消费处理
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.addQueues(webSocketQueue);
        container.setMessageListener(webSocketMqListener);//监听处理类
        return container;
    }
 
Spring Cloud WebSocket集群是一种基于Spring Cloud框架的分布式应用方案,用于在多个节点之间实现WebSocket通信。在传统的单节点应用中,WebSocket通信很容易实现,但在集群环境下,由于多个节点的存在,需要特殊处理来确保消息的正确传递和一致性。 为了实现Spring Cloud WebSocket集群,可以采用以下几个步骤: 1. 在Spring Cloud项目中引入WebSocket技术。可以使用Spring Boot提供的WebSocket支持,通过注解和配置类实现WebSocket的连接和消息处理等功能。 2. 使用消息中间件。在集群环境下,不同节点之间需要实现消息的传递和同步。因此,可以选择一个合适的消息中间件,比如RabbitMQ或Kafka等,在各个节点之间建立消息队列和订阅机制,实现消息的分发和同步。 3. 编写WebSocket控制器。根据业务需求编写WebSocket控制器,处理客户端的连接、断开和消息发送等事件。在控制器中,可以使用消息中间件发送和接收消息,保证节点间的通信。 4. 配置负载均衡和集群管理。在集群环境下,可以使用负载均衡软件(如Nginx等)来实现请求的分发和负载均衡。同时,需要配置好集群管理工具,比如使用Spring Cloud的Eureka服务注册与发现来管理多个节点。 5. 测试和监控。完成以上步骤后,需要进行系统的测试和监控。可以使用一些性能测试工具来模拟多节点并发连接,并观察系统的表现。同时,使用监控工具来监测系统的运行状况,并实时发现和解决可能的问题。 通过以上步骤和措施,就可以实现Spring Cloud WebSocket集群,并确保多个节点之间的WebSocket通信的可靠性和一致性。在实际应用中,还可以根据具体需求进行优化和扩展,以适应不同规模和复杂度的分布式应用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值