问题: comet节点挂掉,zookeeper的node不能自动删除。 解决办法:在web模块,通过rpc 调用 comet Ping() 方法,返回err则删除该节点 安全验证 实现:在web模块开启http服务,通过rpc调用comet New()方法 创建token: comet->rpc.go->New() 添加 token 接口 在浏览器中打开: http://localhost:8090/1/token/add?k=Terry-Mao&t=0 成功返回: {"ret":0} 多个web服务:通过Nginx转发。 多个message服务:web模块获取message rpc 链接是随机的,redis地址是一致的。 多个comet服务:先根据用户的key通过http请求web获取连接节点,然后再根据对应的节点创建长连接。 http://localhost:8090/1/server/get?k=Terry-Mao&p=2 (参数p=1 websocket,p=2 tcp) web需要修改的配置: http.bind localhost:8090 # ip:端口 admin.bind localhost:8091 # ip:端口 [zookeeper] addr localhost:2181 # zkip:端口 comet.path /gopush-cluster-comet # zk comet path(与comet配置一致) message.path /gopush-cluster-message # zk message path(与message配置一致) migrate.path /gopush-migrate-lock # zk migrate path message需要修改的配置: rpc.bind localhost:9989 # ip:端口(多个用,隔开) node.weight 2 #权重 [redis.source] node2:2 tcp@localhost:6379 # 节点名:权重 redis地址 [zookeeper] addr localhost:2181 # zkip:端口 message.path /gopush-cluster-message # zk message path(与web配置一致) comet需要修改的配置: websocket.bind localhost:6968 # 多个用,隔开 tcp.bind localhost:6969 # 多个用,隔开 rpc.bind localhost:6970 # ip:端口(多个用,隔开) [zookeeper] comet.path /gopush-cluster-comet # zk comet path(与web配置一致) comet.node node1 # 节点名称 唯一 comet.weight 1 # 权重 大于0 message.path /gopush-cluster-message # zk message path(与web配置一致) addr localhost:2181 # zkip:端口 cometRing *ketama.HashRing type HashRing struct { defaultSpots int ticks tickArray length int } type tickArray []node type node struct { node string hash uint } 添加、删除comet节点 1.更新替换 cometNodeInfoMap、cometRing 2.rpc 到 comet 从删除 ChannelBucket.Data 不属于本节点的 key ,关闭key对应的链接Channel , 更新替换 CometRing、nodeWeightMap。 cometRing:是一个node的切片数组 每个comet的cometRing都是一致的,判断该用户是否属于该node,通过key获取node与Conf.ZookeeperCometNode比较(Conf.ZookeeperCometNode != node)来判断。 MessageRPC: comet和web模块: 启动程序 调用 myrpc.MessageRPC 的 init() 函数初始化 MessageRPC go watchMessageRoot() 监听节点变化 go handleMessageNodeEvent() 当节点有变化更新 MessageRPC 用二分法 随机获取 Message 节点链接 权重分配算法,将所有节点权重累加,然后每个节点的权重(除)/权重之和,生成一个节点对应的随机数。 comet模块 通过 go watchMessageRoot() 和 go handleMessageNodeEvent() 获取 message的信息保存到 MessageRPC 中。并监听节点变化 web模块 通过 go watchMessageRoot() 和 go handleMessageNodeEvent() 获取 message的信息保存到 MessageRPC 中。并监听节点变化 通过 go handleCometNodeEvent() 和 go watchCometRoot() 获取 comet 的 CometNodeInfo (RpcAddr、TcpAddr、WsAddr、Weight、Rpc)信息保存到 cometNodeInfoMap 中。 并监听节点变化 redis.source and mysql.source: 用户的key通过hash算法获取node,实现根据key来分库。 如果分库,redis存储room keys 信息,根据room Id来分配。