分佈式框架dubbo原理解析

dubbo原理解析

互聯網架構演化

  • 單一應用架構:網站初期,訪問量小,只需一個應用,將全部功能都部署在一塊兒,以減小部署節點和成本。
  • 分佈式服務架構:當網站訪問量愈來愈多,系統升級愈來愈頻繁,單一應用架構的不可靠和難以維護的特色會逐漸顯露。須要將大的服務系統拆成多個小型服務,利用分佈式服務框架進行相互調用。

dubbo是什麼

Dubbo[]是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。spring

其核心部分包含:安全

  • 遠程通信: 提供對多種基於長鏈接的NIO框架抽象封裝,包括多種線程模型,序列化,以及「請求-響應」模式的信息交換方式。
  • 集羣容錯: 提供基於接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集羣支持。
  • 自動發現: 基於註冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方能夠平滑增長或減小機器。

dubbo能作什麼

  • 透明化的遠程方法調用,就像調用本地方法同樣調用遠程方法,只需簡單配置,沒有任何API侵入。
  • 軟負載均衡及容錯機制,可在內網替代F5等硬件負載均衡器,下降成本,減小單點。
  • 服務自動註冊與發現,再也不須要寫死服務提供方地址,註冊中心基於接口名查詢服務提供者的IP地址,而且可以平滑添加或刪除服務提供者。

dubbo架構圖

深刻剖析Dubbo

  • Provider:服務提供方。服務器

    定義服務端、消費端公共接口:架構

    package com.alibaba.dubbo.demo;
    
    	public interface DemoService {
    
    	    String sayHello(String name);
    
    	}

    實現接口:app

    package com.alibaba.dubbo.demo.provider;
    
    	import com.alibaba.dubbo.demo.DemoService;
    
    	public class DemoServiceImpl implements DemoService {
    
    	    public String sayHello(String name) {
    	        return "Hello " + name;
    	    }
    
    	}

    配置Provider端:負載均衡

    <?xml version="1.0" encoding="UTF-8"?>
    	<beans xmlns="http://www.springframework.org/schema/beans"
    	    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    	    xsi:schemaLocation="
    		http://www.springframework.org/schema/beans        
    		http://www.springframework.org/schema/beans/spring-beans.xsd        
    		http://code.alibabatech.com/schema/dubbo        
    		http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    
    	    <!-- 提供方應用信息,用於計算依賴關係 -->
    	    <dubbo:application name="hello-world-app"  />
    
    	    <!-- 使用zookeeper註冊中心(單機)-->
    	    <dubbo:registry address="zookeeper://10.100.51.146:2181" />
    
    		<!-- 配置監控中心 -->
    		<dubbo:monitor protocol="registry"/>
    
    		<!-- 各類的協議以及暴露的服務端口 -->
    	    <dubbo:protocol name="dubbo"         port="20880" />
    
    	    <!-- 聲明須要暴露的服務接口,並指定引用的協議(若是全局只配置了一種協議,那麼這裏無需配置protocol屬性便可直接引用這個協議) -->
    	    <dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" protocol="dubbo"/>
    
    	    <!-- 和本地bean同樣實現服務 -->
    	    <bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />
    
    	</beans>

    因爲Demo中採用是dubbo協議,dubbo協議默認使用hessian2的序列化方式,並採用Netty做爲遠程通信服務器。框架

    完成Provider端配置,啓動Provider。dom

    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    	public class Provider {
    
    	    public static void main(String[] args) throws Exception {
    	        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"provider.xml"});
    	        context.start();
    
    	        System.in.read(); // 按任意鍵退出
    	    }
    
    	}

    Provider端啓動的整個流程: Provider分佈式

  • Consumer:服務消費方。ide

    配置Consumer端:

    <?xml version="1.0" encoding="UTF-8"?>
    	<beans xmlns="http://www.springframework.org/schema/beans"
    	    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    	    xsi:schemaLocation="
    		http://www.springframework.org/schema/beans        
    		http://www.springframework.org/schema/beans/spring-beans.xsd        
    		http://code.alibabatech.com/schema/dubbo        
    		http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    
    	    <!-- 消費方應用名,用於計算依賴關係,不是匹配條件,不要與提供方同樣 -->
    	    <dubbo:application name="consumer-of-helloworld-app"  />
    
    	    <!-- 使用zookeeper註冊中心(單機)-->
    	    <dubbo:registry address="zookeeper://10.100.51.146:2181" />
    
    		<!-- 配置監控中心 -->
    		<dubbo:monitor protocol="registry"/>
    
    	    <!-- 生成遠程服務代理,能夠和本地bean同樣使用demoService -->
    	    <dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" />
    
    	</beans>

    完成Consumer端配置,啓動Consumer。

    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    	import com.alibaba.dubbo.demo.DemoService;
    
    	public class Consumer {
    	    public static void main(String[] args) throws Exception {
    	        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"consumer.xml"});
    	        context.start();
    	    }
    	}

    Consumer端啓動的整個流程: Consumer

  • Provider&Consumer:服務提供方與消費方的交互過程,完成遠程方法調用的流程細則。

    Provider和Consumer已經前後完成啓動,而且Consumer已經打通了到Provider的Socket鏈接。

    遠程調用的代碼片斷:

    // 獲取遠程服務代理
    DemoService demoService = (DemoService)context.getBean("demoService"); 
    	// 執行遠程方法
    String hello = demoService.sayHello("world"); 
    		// 顯示調用結果
    System.out.println( hello );

    執行程序,完成遠程調用。

    遠程調用流程: Provider&Consumer

  • Registry&Router:註冊中心與路由規則。

    用戶經過管理平臺將路由規則添加到zookeeper中,zookeeper信息一旦發生改變,會通知Consumer接受數據。Consumer將接收到的數據進行處理,分類成遠程主機信息和路由規則信息,並根據路由規則信息過濾不合格的遠程主機,並交給Cluster進行調度。 Registry&Router

  • Cluster:集羣控制中心。

    集羣控制中心封裝了集羣調度訪問遠程主機的細則。從外面看來,Cluster讓用戶覺得只有一個invoker去調用目標主機的程序,其實Cluster採起的方式是從多個invoker中選擇一個,完成遠程調用,返回執行結果。

    • 集羣容錯:在集羣調用失敗時,Dubbo提供了多種容錯方案,缺省爲failover重試。 failover
      • Failover Cluster:失敗自動切換,當出現失敗,重試其它服務器。重試次數能夠配置,默認爲兩次。
      • Failfast Cluster:快速失敗,只發起一次調用,失敗當即報錯。
      • Failsafe Cluster:失敗安全,出現異常時,直接忽略。
      • Failback Cluster:失敗自動恢復,後臺記錄失敗請求,每一個5秒定時重發。
      • Forking Cluster:並行調用多個服務器,只要一個成功即返回。
      • Broadcast Cluster:廣播調用全部提供者,逐個調用,任意一臺報錯則報錯。若是都成功,則返回最後一臺的執行結果。
    • 負載均衡:在集羣負載均衡時,Dubbo提供了多種均衡策略,缺省爲random隨機調用。
      • Random LoadBalance:隨機,按權重比率設置隨機機率。
      • RoundRobin LoadBalance:輪循,按公約後的權重比率設置輪循比率。
      • LeastActive LoadBalance:最少活躍調用數,相同活躍數的隨機,活躍數指調用先後計數差。使慢的提供者收到更少請求,由於越慢的提供者的調用先後計數差會越大。
      • ConsistentHash LoadBalance:一致性Hash,相同參數的請求老是發到同一提供者。當某一臺提供者掛時,本來發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引發劇烈變更。
  • Monitor:監控平臺。 本次不做爲重點,簡要介紹。 Monitor的主要做用是監控Provider和Consumer之間的調用次數和調用時間等信息。 基本思路是當Provider和Consumer兩端都配置了監控中心信息以後,每次調用都會記錄信息,並傳遞給監控中心,監控中心記錄本地,並經過JFreeChart繪圖。

相關文章
相關標籤/搜索