问题引入:
服务器A、B、C、D,客户端:C1,C2,C3,C4;
客户端基于集群聊天服务器的负载均衡分配;
C1 被分配到A,C2 被分配到B,C3 被分配到C,C4 被分配到D;
C1->C3; C3->C1;
C2->C3; C4->C1;
跨服务器间的消息通信问题,使用Redis 发布订阅,
则无需多服务器强连接(服务器机数量*(服务器机器数量-1)次连接,且不便于服务器扩展)浪费资源;
底层结构:
发布订阅:基于哈希表与链表结构实现
map结构key值保存用户订阅的兴趣事件,而value保存发布者对象信息,以链表的形式连接对同一事件感兴趣的对象,当消息队列中出现关于订阅事件的发布信息时,Redis可以快速的将该信息按照以key值对应的value链表为订阅的转发顺序;
基于上述情况:
服务器A、服务器B将订阅(SUBSCRIBE) C3 事件;
服务器C、服务器D将订阅(SUBSCRIBE) C1事件;
订阅:Redis 在内部map结构中查找订阅事件,找到则将订阅对象加入链表序列,否则创建该key值,并将服务器加入value链表
eg: 服务器A 订阅C3 对象的事件,Redis先在Map结构查找C3事件是否存在,不存在创建C3 为key,并将服务器A 插入value中的链表结构
发布:
当某服务器在Redis消息队列中发布(PUBLISH)事件时,Redis将在map结构中找到订阅该事件对应的服务器链表,进行转发。
eg:当消息队列中由服务器发布关于C1 事件,Redis 查找C1为key对应的value 链表,并将C1事件转发给链表中的服务器C、服务器B。
观察者模式:
定义一种(被观察类)对多(观察类)的关系,让多个观察对象同时监听一个被观察对象,被观察 对象状态发⽣变化时,会通知所有的观察对象,使他们能够更新自己的状态。
观察者模式中存在两种角色:
观察者:内部包含被观察者对象,当被观察者对象的状态发⽣变化时,更新状态。
接收通知更新状态->被观察者:内部包含了所有观察者对象,当状态发生变化时通知所有的观察者更新自己的状态。
场景: 当⼀个对象的改变需要同时改变其他对象,且不知道具体有多少对象有待改变时,应该考虑观察者模式; 一个抽象模型其中一方面依赖于另一方面,这时以观察者模式将这两者封装在独立的对象中使它们各自地改变和复用