一、序言

近几个月一直从事一个分布式异步通信系统,今天就整理并blog一下.

这是一个全国性的通信平台,对性能,海量数据,容错性以及扩展性有非常高的要求,所以在系统的架构上就不能简单的采用集中式.简单的总结一下就是:

  1.数据分布式存储

       2.请求分布式调度

       3.多结点分布式部署

       4.双重备份,热切换

系统的核心无非就是网络架构,分布式算子和通信,要求如下:

  分布式算子:

               1.对于任意输入,输出均匀分布

               2.输出结果数可控

       通信:

               1.高并发量

               2.多线程

分布式算子我们选择的是sun公司的hash函数,通信用的则是cindy socket通信.网络架构以及具体的描述会在后面的blog中逐步给出.

二、网络架构

整个系统的架构如图所示,包括四层,每一层可以由若干结点来对数据和请求分流:

1.接口服务器(Interface Server):

1).对外提供访问接口并接受请求,考虑到HTTP的广泛性,一般内置一个http服务器进程

2).监控各dispatcher server的工作状态

3).转发请求到其中的一个最优dispatcher中,这里的最优性判断以各dispatcher server的工作状态为依据,当然在这一层上不心请求的具体内容可以简单地采用轮询或随机算法.

2.消息分发服务器(Dispatcher Server):

1).接受来自于接口服务器的请求

2).解析请求,提取特征参数(一般是类似于用户帐号之类的东西,一个帐号下的数据会被分布到同一个结点上),然后对该参数执行hash函数,计算出目标数据所在的App Server,然后将请求转发给该App Server.

3).事实上,在实际的项目中的处理比上面的介绍要更复杂一些,但伸缩性大大加强了.

3.应用服务器(App Server):

1).执行业务逻辑,等同于集中式系统中的应用服务器,已经不存在分布式的特征了.所处理的数据就是自己数据库中的数据,与网络上的其他结点无关.

2).被划分为多个逻辑组(group),同一个组中的服务器负载均衡

3).考虑到数据库的双重备份,热切换和负载均衡,才用了多数据库单读多写策略.对于读,监控各数据库工作状态,选择一个最优数据库来提供数据;对于写,同时写所有的数据库,因此必须保证操作的事务性.

4.数据库服务器(DB Server):

1).提供数据访问,没什么好说的,对于非事务性数据库需要在App Server层提供辅助措施;

5.结点之间的通信

1).数据(请求,响应,异常)以网络格式异步并发传输

三、分布式算法

接口服务器(Interface Server)和消息分发服务器(Dispatcher Server)在分发请求的策略上有所不同.

辅助函数和变量:

 

 public String[] getTargetServerIps();//目标服务器的ip,如193.243.15.45:8080

      public int[] getTargetServerIds();//目标服务器ID,与上述服务器ip一一对应,可以自由配置

      public boolean isServerWorking(index);//判断目标服务器的状态

      int currentTargetServerIndex=0;//当前的目标服务器在targetServerIds中的index

接口服务器(Interface Server)采用轮询算法:

       public String getTargetServerIp(){//获取该次请求所要分发的目标服务器

                 String[] targetServerIps=getTargetServerIps();

                 int[] targetServerIds=getTargetServerIds();

                 int index=currentTargetServerIndex;

                 boolean isWorking=false;

                 while(!isWorking){

           index=targetServerIds.length()%(currentTargetServerIndex+1);

                    isWorking=isServerWorking(index);

                        if(!isWorking&&index==currentTargetServerIndex){//无任何目标服务器可用

                                    return "0:0";

                        }

              }

                  currentTargetServerIndex=index;

                  return targetServerIps[index];

        }

消息分发服务器(Dispatcher Server)分发请求采用的hash算法

 // hash algrithm from JDK's String,来自于jdk的hash算法

    public int hash(byte[] bs) {

        int hash = 0;

        for (int i = 0; i < bs.length; i++) {

            hash = 31 * hash + bs[i];

        }

        return hash;

    }

    public int getTargetServerGroupIndexByHash(String hashParam) throws BtirException {//返回根据hash计算出的目标服务器群组

         byte[] hashinfo=hashParam.getBytes("utf-8");

         int frameCount=2://由hash值的后两位进行分段的数目 ,即hash结果数,目标服务器群组的数量

   int step = 100 / frameCount;

         int hash = Math.abs(hash(hashParam) % 100);

        for(int i=0, beg=0, end=step; i<frameCount; i++) {

            if(beg <= hash && hash < end )

                return 2*i;

            beg = end;

            end += step;

        }

        return 2*(frameCount-1); //如果设置得好,应该不会走到这里

    }

    public String getTargetServerIpInGriuo(int groupIndex){//根据轮询算法,计算服务器群组中的最优服务器

               String[] targetServerIps=getTargetServerIps();//组内的轮询算法,代码略

                int[] targetServerIds=getTargetServerIds();

      int index=getTargetServerIndexInGroup(groupIndex);//轮询算法代码略

                return targetServerIps[index];

 }

四、通信节点设计模型

通信是请求响应的方式,这对于接口服务器,消息分发服务器和应用服务器来说都是一直的,所以三者可以采用一致的模型来描述.

包括两个部分:client和server.这里描述一下二者的结构和网络通信.

client构造并发送请求,在异步系统里可以将构造和发送解偶,如图

RequestBuilder生成Request
     将Request投入到Request队列(RequestQueue)中
     独立线程RequestScanner扫描Request队列并调用RequestSender发送请求.
     针对不同类型的请求可以构造不同的队列和不同的sender,队列中Request的优先级策略可以根据需要来定制.
server接收请求并处理,如图

server接收请求并处理,如图

       RequestAccepter接收请求并放入Request队列
        独立线程扫描队列并将调用RequestHandler进行处理
        RequestHandler处理完毕后返回Response.
client与server之间的通信:
       通信协议和技术有很多,如web service,EJB,jms,hessian等,单这里采用基于java NIO的socket,因为其异步性和高并发量.
       采用socket的两个基本标准是:
       1.服务器上的线程数可控,切忌与请求数线性增长
       2.将处理请求和接收请求分开,否则会降低吞吐率和并发量
 
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:冷夜
链接:http://www.zhihu.com/question/20004877/answer/61025046
来源:知乎

java分布式通信系统(J2EE分布式服务器架构)的更多相关文章

  1. Java Hour 62 J2EE App 服务器

    目前略微瓶颈了,准备换工作. tomcat.weblogic.jboss的区别,容器的作用 Apache 是一个http 服务器. Tomcat 是一web 应用程序服务器,支持部分的j2ee. Jb ...

  2. J2EE分布式架构及MySQL交流群

    J2EE分布式架构及MySQL交流群:577913057

  3. Hadoop HDFS分布式文件系统设计要点与架构

      Hadoop HDFS分布式文件系统设计要点与架构     Hadoop简介:一个分布式系统基础架构,由Apache基金会开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群 ...

  4. Java使用Redis实现分布式锁来防止重复提交问题

    如何用消息系统避免分布式事务? - 少年阿宾 - BlogJavahttp://www.blogjava.net/stevenjohn/archive/2018/01/04/433004.html [ ...

  5. j2ee分布式缓存同步实现方案dlcache

    现成的分布式K/V缓存已经有很多的实现,最主要的比如redis,memcached,couchbase.那为什么我们还要自己去实现呢,在我们解决了分布式系统下大量rpc调用导致的高延时后,我们发现很多 ...

  6. java面试题:分布式

    分布式分为分布式缓存(Redis).分布式锁(Redis或Zookeeper).分布式服务(Dubbo或SpringCloud).分布式服务协调(Zookeeper).分布式消息队列(Kafka.Ra ...

  7. 使用ZooKeeper实现Java跨JVM的分布式锁(优化构思)

    一.使用ZooKeeper实现Java跨JVM的分布式锁 二.使用ZooKeeper实现Java跨JVM的分布式锁(优化构思) 三.使用ZooKeeper实现Java跨JVM的分布式锁(读写锁) 说明 ...

  8. [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器

    [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 目录 [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 0x0 ...

  9. 分布式缓存系统 Memcached 整体架构

    分布式缓存系统 Memcached整体架构 Memcached经验分享[架构方向] Memcached 及 Redis 架构分析和比较

  10. j2ee分布式缓存同步实现方案dlcache v1.0.1

    j2ee分布式缓存同步实现方案dlcache v1.0.1 发布 修复问题: 1.支持两个层次的缓存,典型的用于产品大类.产品小类,数据字典以及子项: 更新后见: pan http://pan.bai ...

随机推荐

  1. Linq To Entities 及其相关

    说到Linq,很多人都非常熟悉,我们可以很方便的用它来操纵对象的集合.今天要说的是Linq To Entities及其相关的操作.下面一步一步的来进行.这里我着重强调的是语法上面的一些注意点.所以怎么 ...

  2. java系列: 对不起,JavaFX——Java 8目前还不能救你(zz)

    JavaFX 是SUN公司在2007年JavaOne大会上首次对外公布的以Java为基础构建的富客户端平台,更让开发者印象比较深刻的则是其背后的JavaFX开发团队,仅仅在两年的时间就从1.0版本完善 ...

  3. java系列: 在eclipse中调试时,输入的jsp或者servlet页面的地址要区分大小写

    比如在当前web工程中有一个jsp页面的名字是: Welcome.jsp 在eclipse中调试时,如果在浏览器中输入: http://localhost:8080/MavenWeb/welcome. ...

  4. 树莓派之web服务器搭建

    树莓派之web服务器搭建 (一)使用ufw创建防火墙 设置目的:可以完全阻止对树莓派的访问也可以用来配置通过防火墙对特点程序的访问.使用防火墙更好的保护树莓派. 准备工作 1.带有5V电源的树莓派 2 ...

  5. PowerCMD——cmd的命令行工具

    之前就想整理一下程序员经常使用的一些工具,最近有时间正好整理一下. 有句话叫做:“工欲善其事必先利其器”,而我就算是搜集工具组装成一个系列——善事利器,来记录一下工作学习中常用的一些工具. 总结起来, ...

  6. ROM存储1/4周期正弦信号构造DDS

    上周的时候,老师让编写一个简单的dds程序,本文说明了整个过程中我遇到问题以及一些个人的思考.初次接触FPGA,如有问题请多多指教~ 1.几个疑问,解决和没有解决的. 为何采用ROM而不是直接采用DD ...

  7. 【原创】基于Memcached 实现用户登录的Demo(附源码)

    一个简单的Memcached在Net中运用的一个demo.主要技术 Dapper+MVC+Memcached+sqlserver, 开发工具为vs2015+Sql 效果图如下: 登录后 解决方案 主要 ...

  8. 【逆向怎么玩】 动态调试一款牛逼C++ IDE实录

    声明 本篇只从逆向兴趣出发,研究其程序运行原理. CLion程序版权为jetBrains所有. 注册码授权为jetBrains及其付费用户所有. 不会释出任何完整的源代码. 涉及能直接推算出注册码的地 ...

  9. 『设计』Slithice 分布式架构设计-支持一体式开发,分布式发布

    项目原因: 参与过各种 分布式项目,有 Socket,Remoting,WCF,当然还有最常用的可以跨平台的 WebService. 分布式编码的时间浪费: 但是,无一例外的,开发分布式程序的开发遵循 ...

  10. 同步git修改文件到远端服务器脚本

    #!/usr/bin/perl -w @files=`git status -s` ; @sync_files = (); foreach (@files) { ); # 固定前2个字符为状态 + 1 ...