Code Monkey home page Code Monkey logo

im's Introduction

分布式IM

一、概述

使用netty开发分布式Im,提供分布netty集群解决方案。服务端通过负载均衡策略与服务集群建立连接,消息发送通过服务间集群的通信进行消息转发。

二、自定义协议

1.自定义协议要素

  • 魔数,用来在第一时间判定是否是无效数据包
  • 版本号,可以支持协议的升级
  • 序列化算法,消息正文到底采用哪种序列化反序列化方式,可以由此扩展,例如:json、protobuf、hessian、jdk
  • 指令类型,是登录、注册、单聊、群聊… 跟业务相关
  • 请求序号,为了双工通信,提供异步能力
  • 正文长度
  • 消息正文

三、集群架构

架构图

1.客户端

用户聊天客户端,客户端连接IM服务需要进行用户认证。用户认证成功之后,开始连接上线。

2.服务路由

服务路由负责将客户端的连接请求按照不同的负载均衡策略路由到不同的IM服务,建立长链接。负载均衡策略分为以下四种:

  • 一致性HASH负载均衡策略
  • 最少活跃数负载均衡策略
  • 随机调用负载均衡策略
  • 轮询调用负载均衡策略

3.IM服务集群

为了避免单节点故障,IM服务采用集群模式。集群内各个IM服务又互为对方的客户端,用于转发远程消息(消息接收客户端连接其他IM服务节点)。

4.ZK集群

ZK集群作为IM服务的注册中心,用户IM服务的注册与发现以及服务上线、下线的事件监听通知。通过node事件,控制IM服务之间连接的建立与断开。

5.消息队列

消息队列用户发送离线消息、聊天消息。

6.MongoDB集群

存储离线消息及聊天消息。

7.Redis集群

存储客户端的连接session信息(客户端与服务端连接的信息)

四、netty集群方案

首先需要明确一个问题,netty的channel是无法存储到redis里面的。netty的channel是一个连接,是和机器的硬件绑定的,无法序列化,计算存到redis里面,取出来也无法使用。

1.ZK作为注册中心实现

(1)channel无法存储的问题

channel是无法存储到redis里面的,但是客户端和服务端的连接信息(例如:127.0.0.1:8080的服务端是127.0.0.1:9090)是可以存储到redis里面的,因此可以通过redis存储连接信息。key为客户端标识,value为服务端地址信息,获取客户端的连接时,直接通过客户端信息即可获取其服务信息。

channel存储

(2)服务端连接的问题

客户端连接服务端时,客户端如何知道当前服务端有哪些,需要要连接哪个?这个问题可以通过ZK解决。使用ZK作为注册中心,服务端上线后在ZK中创建node,连接服务端时,从ZK获取在线节点信息,根据负载均衡策略选择服务端连接。

ZK注册中心

(3)消息转发的问题

连接相同服务的客户端,可以直接通过获连接当前服取客户端信息进行消息的转发,那连接不同服务端消息如何转发?我们可以通过监听ZK中node的事件(node创建代表新的服务上线,node销毁代表服务下线),通过不同的事件方法,实现服务端之间的互相连接。

消息转发

2.redis订阅与广播实现(可替换为消息队列进行处理)

redis支持消息订阅与发布机制机制(消息队列),可以使用该机制实现不同服务间的消息转发。在广播消息时,需要携带能唯一标识接收者身份的字段(例如clientId)。消息广播结束后,所有服务端会 收到该消息,服务端仅仅需要判断该消息接收者的是否是连接的自己作为服务端。若发现该接收者正是连接的自己,则直接将消息转发到该客户端即可。

消息转发

五、核心功能

1.netty服务节点的注册与发现

2.netty服务节点的负载均衡策略

2.netty服务节点的消息转发

im's People

Contributors

beardlesscat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

im's Issues

有个不明白的地方想请教一下.

1.集群情况下,其中的每一个server服务要别所有的server建立连接吧.集群项目启动的时候只能一个一个启动吧,如果同时启动会出现有的server和server之间的连接建立会漏掉.

2.横向扩容的时候也只能一台一台的扩容吧.

3.如果在消息发送的时候一台server突然挂掉了.那这个消息从client到server就失败了.消息就会丢掉.(这个可以从链路上做分段ack缓存失败的消息)

4.如果在消息发送的时候一台server突然挂掉了,已经到达当前server的消息就会丢失.

关于随机的方式选择服务器节点的疑问

hi,master分支下面的随机选择节点有点疑问请教一下:

protected ServerNode doSelect(List<ServerNode> serverNodes) {
    int size = serverNodes.size();
    int[] weights = new int[size];
    int total = 0 ;
    for(int i=0;i<size;i++){
	    Integer weight = serverNodes.get(i).getWeight();
	    total+=weight;
	    weights[i] = total;
    }
    //类似于抽奖算法
    int randomIndex = ThreadLocalRandom.current().nextInt(weights[size - 1]);
    for(int index = 0;index<size;index++){
	    if(randomIndex < weights[index]){
		    return serverNodes.get(index);
	    }
    }
    return serverNodes.get(ThreadLocalRandom.current().nextInt(serverNodes.size()));
}

0客户端的时候启动2个服务节点,此时2个服务节点的权重weight是不是都是0?
如果是的话

    int randomIndex = ThreadLocalRandom.current().nextInt(weights[size - 1]);

这个里面的nextInt一直时0,会报错吧?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.