java 集群im服务器消息路由,使用rabbitmq实现集群im聊天服务器消息的路由

单机系统的时候,客户端和连接都有同一台服务器管理。

format,png

image.png

在本地维护一份userId到connetciont的映射

服务器可以根据userId找出对应的连接,然后把消息push出去

format,png

image.png

但是集群环境下,连接分布在不同的机器,小明向小张发消息时跨了机器

format,png

image.png

小明向小张发的消息,需要小张的对应连接的服务器才能推送

要完成这个需求需要解决两个问题:

1、聊天服务器这么多,怎么才能知道小张连接了哪一台机器?

2、知道是哪一台服务器,怎么才能把消息精准发送到对应的机器?

format,png

image.png

有一种解决方案,就是把消息全量广播,然后每台机器自己去判断小张是不是在本机有连接,然后对应推送消息。但是这个方案明显不可取,因为这样会造成网络风暴,满天飞羽的消息在广播。

个人解决方案

一、对于第一个问题,怎么才能知道小张连接了哪一台机器,可以用redis去做一个map映射。

每台机器启动的时候都分配一个机器id,

当用户创建连接的时候,在redis放一个key-value,key值放的是userId,value放的是机器id。

这样就可以根据userId找对应的连接机器

format,png

image.png

二、对于第二个问题,怎么才能把消息精准发送到对应的机器,可以让每台机器启动的时候都有一个专属的mq和专属的routingkey,使用rabbitMq的TopicExchange交换器,这样消息就能精准投递到对应的机器,routingKey可以用上面定义的机器id。

同时queue的熟悉选专属队列,这样服务器重启后,连接断开后,旧的队列会自动删除

format,png

image.png

全过程就是:

1、小明要发消息给小张

2、根据小张userId找到小张所在的机器b

3、构建messageBody,把routingKey设置成b

4、向mq发送消息,rabbitMq根据routingKey把消息分发给机器b;

以下是代码:

1、新建springboot工程,maven如下

2、新建Constant做固定配置

3、配置RabbitmqConfig

4、配置消费者Consumer

5、设置UserController

6、实验环节,需要部署两个jar包

分别在2台服务器发起请求初始化连接。

在A服务器输入 curl localhost:8081//buildRoutingKey?recUserId=1

在B服务器输入 curl localhost:8082//buildRoutingKey?recUserId=2

然后发送消息

在任意一台服务器输入 curl localhost:8082/sendMsg?sendUserId=2&recUserId=1&msg=xiaozhangHello

在任意一台服务器输入 curl localhost:8082/sendMsg?sendUserId=1&recUserId=2&msg=xiaoMingHello

format,png

image.png

format,png

image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值