Dubbo-入门指南+实例
Dubbo-用戶指南
2017-03-11 La Paz
官方指導文檔:
http://dubbo.io/User+Guide-zh.htm
Github地址:
https://github.com/alibaba/dubbo
概述
Dubbo是阿里巴巴SOA服務化治理方案的核心框架,每天為2,000+個服務提供3,000,000,000+次訪問量支持,并被廣泛應用于阿里巴巴集團的各成員站點.
背景
隨著互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分布式服務架構以及流動計算架構勢在必行,亟需一個治理系統確保架構有條不紊的演進。
單一應用架構
當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。
此時,用于簡化增刪改查工作量的 數據訪問框架(ORM) 是關鍵。
垂直應用架構
當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成互不相干的幾個應用,以提升效率。
此時,用于加速前端頁面開發的 Web框架(MVC) 是關鍵。
分布式服務架構
當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。
此時,用于提高業務復用及整合的 分布式服務框架(RPC) 是關鍵。
流動計算架構
當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基于訪問壓力實時管理集群容量,提高集群利用率。
此時,用于提高機器利用率的 資源調度和治理中心(SOA) 是關鍵。
需求
在大規模服務化之前,應用可能只是通過RMI或Hessian等工具,簡單的暴露和引用遠程服務,通過配置服務的URL地址進行調用,通過F5等硬件進行負載均衡。
(1) 當服務越來越多時,服務URL配置管理變得非常困難,F5硬件負載均衡器的單點壓力也越來越大。
此時需要一個服務注冊中心,動態的注冊和發現服務,使服務的位置透明。
并通過在消費方獲取服務提供方地址列表,實現軟負載均衡和Failover,降低對F5硬件負載均衡器的依賴,也能減少部分成本。
(2) 當進一步發展,服務間依賴關系變得錯蹤復雜,甚至分不清哪個應用要在哪個應用之前啟動,架構師都不能完整的描述應用的架構關系。
這時,需要自動畫出應用間的依賴關系圖,以幫助架構師理清理關系。
(3) 接著,服務的調用量越來越大,服務的容量問題就暴露出來,這個服務需要多少機器支撐?什么時候該加機器?
為了解決這些問題,第一步,要將服務現在每天的調用量,響應時間,都統計出來,作為容量規劃的參考指標。
其次,要可以動態調整權重,在線上,將某臺機器的權重一直加大,并在加大的過程中記錄響應時間的變化,直到響應時間到達閥值,記錄此時的訪問量,再以此訪問量乘以機器數反推總容量。
Dubbo是什么
Dubbo[]是一個分布式服務框架,致力于提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。
其核心部分包含:
1. 遠程通訊: 提供對多種基于長連接的NIO框架抽象封裝,包括多種線程模型,序列化,以及“請求-響應”模式的信息交換方式。
2. 集群容錯: 提供基于接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集群支持。
3. 自動發現: 基于注冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。
Dubbo能做什么
1. 透明化的遠程方法調用,就像調用本地方法一樣調用遠程方法,只需簡單配置,沒有任何API侵入。
2.軟負載均衡及容錯機制,可在內網替代F5等硬件負載均衡器,降低成本,減少單點。
3. 服務自動注冊與發現,不再需要寫死服務提供方地址,注冊中心基于接口名查詢服務提供者的IP地址,并且能夠平滑添加或刪除服務提供者。
架構
節點角色說明:
Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務注冊與發現的注冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
Container: 服務運行容器。
調用關系說明:
0. 服務容器負責啟動,加載,運行服務提供者。
1. 服務提供者在啟動時,向注冊中心注冊自己提供的服務。
2. 服務消費者在啟動時,向注冊中心訂閱自己所需的服務。
3. 注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基于長連接推送變更數據給消費者。
4. 服務消費者,從提供者地址列表中,基于軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
5. 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
(1) 連通性:
注冊中心通過長連接感知服務提供者的存在,服務提供者宕機,注冊中心將立即推送事件通知消費者
(2) 健狀性:
(3) 伸縮性:
(4) 升級性:
當服務集群規模進一步擴大,帶動IT治理結構進一步升級,需要實現動態部署,進行流動計算,現有分布式服務架構不會帶來阻力:
Deployer: 自動部署服務的本地代理。
Repository: 倉庫用于存儲服務應用發布包。
Scheduler: 調度中心基于訪問壓力自動增減服務提供者。
Admin: 統一管理控制臺。
用法
本地服務:(Spring配置)
local.xml
<bean id=“xxxService” class=“com.xxx.XxxServiceImpl” /><bean id=“xxxAction” class=“com.xxx.XxxAction”><property name=“xxxService” ref=“xxxService” /> </bean>遠程服務:(Spring配置)
在本地服務的基礎上,只需做簡單配置,即可完成遠程化:
如下:
remote-provider.xml
remote-consumer.xml
<dubbo:reference id=“xxxService” interface=“com.xxx.XxxService” /> <!-- 增加引用遠程服務配置 --><bean id=“xxxAction” class=“com.xxx.XxxAction”> <!-- 和本地服務一樣使用遠程服務 --><property name=“xxxService” ref=“xxxService” /> </bean>快速啟動
服務提供者
工程目錄:
定義服務接口
(該接口需單獨打包,在服務提供方和消費方共享)
DemoService.java
package com.xgj.dubbo.provider;import java.util.List;public interface DemoService {String sayHello(String name);public List getUsers();}在服務提供方實現接口:
(對服務消費方隱藏實現)
package com.xgj.dubbo.provider.impl;import java.util.ArrayList; import java.util.List;import com.xgj.dubbo.provider.DemoService;public class DemoServiceImpl implements DemoService {public String sayHello(String name) {System.out.println("Provider sayHello");return "Hello " + name;}public List getUsers() {System.out.println("Provider getUser");List list = new ArrayList();User u1 = new User();u1.setName("xiao");u1.setAge(20);u1.setSex("Male");User u2 = new User();u2.setName("gong");u2.setAge(21);u2.setSex("Male");User u3 = new User();u3.setName("jiang");u3.setAge(19);u3.setSex("Female");list.add(u1);list.add(u2);list.add(u3);return list;} }實現類中用到的User類
package com.xgj.dubbo.provider.impl;import java.io.Serializable;public class User implements Serializable {private static final long serialVersionUID = 1L;private int age;private String name;private String sex;public User() {super();}public User(int age, String name, String sex) {super();this.age = age;this.name = name;this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}}用Spring配置聲明暴露服務:
provider.xml
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"><!-- 具體的實現bean --><bean id="demoService" class="com.xgj.dubbo.provider.impl.DemoServiceImpl" /><!-- 提供方應用信息,用于計算依賴關系 --><dubbo:application name="xgj_provider" /><!-- 使用multicast廣播注冊中心暴露服務地址 <dubbo:registry address="multicast://224.5.6.7:1234" /> --><!-- 使用zookeeper注冊中心暴露服務地址 --><dubbo:registry address="zookeeper://127.0.0.1:2181" /><!-- 用dubbo協議在20880端口暴露服務 --><dubbo:protocol name="dubbo" port="20880" /><!-- 聲明需要暴露的服務接口 --><dubbo:service interface="com.xgj.dubbo.provider.DemoService"ref="demoService" /></beans>加載Spring配置:
package com.xgj.dubbo.provider.impl;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(); // 為保證服務一直開著,利用輸入流的阻塞來模擬 } }服務消費者
工程目錄:
通過Spring配置引用遠程服務:
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"><!-- 消費方應用名,用于計算依賴關系,不是匹配條件,不要與提供方一樣 --><dubbo:application name="xgj_consumer" /><!-- 使用zookeeper注冊中心暴露服務地址 --><!-- <dubbo:registry address="multicast://224.5.6.7:1234" /> --><dubbo:registry address="zookeeper://127.0.0.1:2181" /><!-- 生成遠程服務代理,可以像使用本地bean一樣使用demoService --><dubbo:reference id="demoService"interface="com.xgj.dubbo.provider.DemoService" /></beans>加載Spring配置,并調用遠程服務:
(也可以使用IoC注入)
package com.alibaba.dubbo.demo.pp;import java.util.List;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.xgj.dubbo.provider.DemoService;public class Consumer {public static void main(String[] args) throws Exception {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "consumer.xml" });context.start();DemoService demoService = (DemoService) context.getBean("demoService");String hello = demoService.sayHello("xgj");System.out.println(hello);List list = demoService.getUsers();if (list != null && list.size() > 0) {for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}}System.in.read();}}依賴
必需依賴
JDK1.5+
缺省依賴
通過mvn dependency:tree > dep.log命令分析,Dubbo缺省依賴以下三方庫:
[INFO] +- com.alibaba:dubbo:jar:2.1.2:compile [INFO] | +- log4j:log4j:jar:1.2.16:compile [INFO] | +- org.javassist:javassist:jar:3.15.0-GA:compile [INFO] | +- org.springframework:spring:jar:2.5.6.SEC03:compile [INFO] | +- commons-logging:commons-logging:jar:1.1.1:compile [INFO] | \- org.jboss.netty:netty:jar:3.2.5.Final:compile這里所有依賴都是換照Dubbo缺省配置選的,這些缺省值是基于穩定性和性能考慮的。
可選依賴
以下依賴,在主動配置使用相應實現策略時用到,需自行加入依賴。
mina: 1.1.7 grizzly: 2.1.4 httpclient: 4.1.2 hessian_lite: 3.2.1-fixed xstream: 1.4.1 fastjson: 1.1.8 zookeeper: 3.3.3 jedis: 2.0.0 xmemcached: 1.3.6 jfreechart: 1.0.13 hessian: 4.0.7 jetty: 6.1.26 hibernate-validator: 4.2.0.Final zkclient: 0.1 curator: 1.1.10 cxf: 2.6.1 thrift: 0.8.0JEE:
servlet: 2.5 bsf: 3.1 validation-api: 1.0.0.GA jcache: 0.4集群容錯
在集群調用失敗時,Dubbo提供了多種容錯方案,缺省為failover重試。
各節點關系:
Failover Cluster
失敗自動切換,當出現失敗,重試其它服務器。(缺省)
通常用于讀操作,但重試會帶來更長延遲。
可通過retries=”2”來設置重試次數(不含第一次)。
Failfast Cluster
快速失敗,只發起一次調用,失敗立即報錯。
通常用于非冪等性的寫操作,比如新增記錄。
Failsafe Cluster
失敗安全,出現異常時,直接忽略。
通常用于寫入審計日志等操作。
Failback Cluster
失敗自動恢復,后臺記錄失敗請求,定時重發。
通常用于消息通知操作。
Forking Cluster
并行調用多個服務器,只要一個成功即返回。
通常用于實時性要求較高的讀操作,但需要浪費更多服務資源。
可通過forks=”2”來設置最大并行數。
Broadcast Cluster
廣播調用所有提供者,逐個調用,任意一臺報錯則報錯。(2.1.0開始支持)
通常用于通知所有提供者更新緩存或日志等本地資源信息。
重試次數配置如:(failover集群模式生效)
<dubbo:service retries="2" />或:
<dubbo:reference retries="2" />或:
<dubbo:reference><dubbo:method name="findFoo" retries="2" /> </dubbo:reference>集群模式配置如:
<dubbo:service cluster="failsafe" />或:
<dubbo:reference cluster="failsafe" />負載均衡
在集群負載均衡時,Dubbo提供了多種均衡策略,缺省為random隨機調用。
可以自行擴展負載均衡策略,參見:負載均衡擴展
Random LoadBalance
RoundRobin LoadBalance
LeastActive LoadBalance
ConsistentHash LoadBalance
配置如:
<dubbo:service interface="..." loadbalance="roundrobin" />或:
<dubbo:reference interface="..." loadbalance="roundrobin" />或:
<dubbo:service interface="..."><dubbo:method name="..." loadbalance="roundrobin"/> </dubbo:service>或:
<dubbo:reference interface="..."><dubbo:method name="..." loadbalance="roundrobin"/> </dubbo:reference>總結
以上是生活随笔為你收集整理的Dubbo-入门指南+实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Notice 博客暂时停更
- 下一篇: Oracle查询优化-04插入、更新与删