程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 分布式架構剖析 Maven Springmvc mybatis shiro Druid Restful,Dubbo ZooKeeper,Redis,FastDFS ,ActiveMQ,mavenspringmvc

分布式架構剖析 Maven Springmvc mybatis shiro Druid Restful,Dubbo ZooKeeper,Redis,FastDFS ,ActiveMQ,mavenspringmvc

編輯:JAVA綜合教程

分布式架構剖析 Maven Springmvc mybatis shiro Druid Restful,Dubbo ZooKeeper,Redis,FastDFS ,ActiveMQ,mavenspringmvc


聲明:該框架面向企業,是大型互聯網分布式企業架構,後期會介紹linux上部署高可用集群項目。

有願意了解框架技術或者源碼的朋友直接加Q(2137028325)一起學習

了解更多分布式架構文檔及相關源碼可以查看我的博客列表

http://2137028325.iteye.com/

一、序言

近幾個月一直從事一個分布式異步通信系統,今天就整理並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,單這裡采用基於java NIO的socket,因為其異步性和高並發量.        采用socket的兩個基本標准是:        1.服務器上的線程數可控,切忌與請求數線性增長        2.將處理請求和接收請求分開,否則會降低吞吐率和並法量 了解更多分布式架構文檔及相關源碼可以查看我的博客列表 http://2137028325.iteye.com/

聲明:該框架面向企業,是大型互聯網分布式企業架構,後期會介紹linux上部署高可用集群項目。

有願意了解框架技術或者源碼的朋友直接加Q(2137028325)一起學習

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved