轉載至:https://blog.csdn.net/liuhaiabc/article/details/52781351
第一:介紹Dubbo背景
大規模服務化之前,應用可能只是通過RMI或Hessian等工具,簡單的暴露和引用遠程服務,通過配置服務的URL地址進行調用,通過F5等硬件進行負載均衡。
(1) 當服務越來越多時,服務URL配置管理變得非常困難,F5硬件負載均衡器的單點壓力也越來越大。
此時需要一個服務注冊中心,動態的注冊和發現服務,使服務的位置透明。
並通過在消費方獲取服務提供方地址列表,實現軟負載均衡和Failover,降低對F5硬件負載均衡器的依賴,也能減少部分成本。
(2) 當進一步發展,服務間依賴關系變得錯蹤復雜,甚至分不清哪個應用要在哪個應用之前啟動,架構師都不能完整的描述應用的架構關系。
這時,需要自動畫出應用間的依賴關系圖,以幫助架構師理清理關系。
(3) 接着,服務的調用量越來越大,服務的容量問題就暴露出來,這個服務需要多少機器支撐?什么時候該加機器?
為了解決這些問題,第一步,要將服務現在每天的調用量,響應時間,都統計出來,作為容量規划的參考指標。
其次,要可以動態調整權重,在線上,將某台機器的權重一直加大,並在加大的過程中記錄響應時間的變化,直到響應時間到達閥值,記錄此時的訪問量,再以此訪問量乘以機器數反推總容量。
第二、Dubbo是什么/做什么
1. Dubbo是什么?
Dubbo(注:HSF提供的是分布式服務開發框架,taobao內部使用較多)是一個分布式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。簡單的說,dubbo就是個服務框架,如果沒有分布式的需求,其實是不需要用的,只有在分布式的時候,才有dubbo這樣的分布式服務框架的需求,並且本質上是個服務調用的東東,說白了就是個遠程服務調用的分布式框架
其核心部分包含:
1. 遠程通訊: 提供對多種基於長連接的NIO框架抽象封裝,包括多種線程模型,序列化,以及“請求-響應”模式的信息交換方式。
2. 集群容錯: 提供基於接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集群支持。
3. 自動發現: 基於注冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。
2. Dubbo能做什么?
1.透明化的遠程方法調用,就像調用本地方法一樣調用遠程方法,只需簡單配置,沒有任何API侵入。
2.軟負載均衡及容錯機制,可在內網替代F5等硬件負載均衡器,降低成本,減少單點。
3. 服務自動注冊與發現,不再需要寫死服務提供方地址,注冊中心基於接口名查詢服務提供者的IP地址,並且能夠平滑添加或刪除服務提供者。
Dubbo采用全Spring配置方式,透明化接入應用,對應用沒有任何API侵入,只需用Spring加載Dubbo的配置即可,Dubbo基於Spring的Schema擴展進行加載。
第三、Dubbox 實現原理
節點角色說明:
Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務注冊與發現的注冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
Container: 服務運行容器。
調用關系說明:
0 .(start)服務容器負責啟動,加載,運行服務提供者。
1. (register)服務提供者在啟動時,向注冊中心注冊自己提供的服務。
2. (subscribe)服務消費者在啟動時,向注冊中心訂閱自己所需的服務。
3. (notify)注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基於長連接推送變更數據給消費者。
4. (invoke) 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
5. (count)服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鍾發送一次統計數據到監控中心。
Doubbox 特性:
(1) 連通性:
注冊中心負責服務地址的注冊與查找,相當於目錄服務,服務提供者和消費者只在啟動時與注冊中心交互,注冊中心不轉發請求,壓力較小
監控中心負責統計各服務調用次數,調用時間等,統計先在內存匯總后每分鍾一次發送到監控中心服務器,並以報表展示
服務提供者向注冊中心注冊其提供的服務,並匯報調用時間到監控中心,此時間不包含網絡開銷
服務消費者向注冊中心獲取服務提供者地址列表,並根據負載算法直接調用提供者,同時匯報調用時間到監控中心,此時間包含網絡開銷
注冊中心,服務提供者,服務消費者三者之間均為長連接,監控中心除外
注冊中心通過長連接感知服務提供者的存在,服務提供者宕機,注冊中心將立即推送事件通知消費者
注冊中心和監控中心全部宕機,不影響已運行的提供者和消費者,消費者在本地緩存了提供者列表
注冊中心和監控中心都是可選的,服務消費者可以直連服務提供者
(2) 健狀性:
監控中心宕掉不影響使用,只是丟失部分采樣數據
數據庫宕掉后,注冊中心仍能通過緩存提供服務列表查詢,但不能注冊新服務
注冊中心對等集群,任意一台宕掉后,將自動切換到另一台
注冊中心全部宕掉后,服務提供者和服務消費者仍能通過本地緩存通訊
服務提供者無狀態,任意一台宕掉后,不影響使用
服務提供者全部宕掉后,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復
(3) 伸縮性:
注冊中心為對等集群,可動態增加機器部署實例,所有客戶端將自動發現新的注冊中心
服務提供者無狀態,可動態增加機器部署實例,注冊中心將推送新的服務提供者信息給消費者
(4) 升級性:
當服務集群規模進一步擴大,帶動IT治理結構進一步升級,需要實現動態部署,進行流動計算,現有分布式服務架構不會帶來阻力
第四、dubbo環境搭建(Demo)
以下是基於maven的,預先使用,先裝maven。
dubbo是一個分布式服務框架,提供一個SOA的解決方案。簡單的說,dubbo就像在生產者和消費者中間架起了一座橋梁,使之能透明交互。
本文旨在搭建一個可供使用和測試的dubbo環境,使用了spring框架;使用了zookeeper和dubbo服務。
准備:
zookeeper:直接去官方網站下載即可(以下是:zookeeper-3.4.6),下載后解壓,不需要改任何配置即可使用,或者改配置(..\zookeeper-3.4.6\conf\zoo.cfg)如下:
dubbo:直接去阿里巴巴下載即可(dubbo-admin即dubbo管理頁面),下載后解壓並放到tomcat的webapps目錄下,修改WEB-INF/dubbo.properties中屬性如下:
#zookeeper的地址和端口
dubbo.registry.address=zookeeper://127.0.0.1:2181
#登錄dubbo管理頁面時的root用戶和guest用戶的密碼
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest
代碼:
如果你清楚生產者-消費者模型,那么將會很容易理解dubbo的使用步驟。
一個生產者-消費者模型的代碼實現需要3部分:生產者代碼,消費者代碼,中間接口。
中間接口:創建一個mavan項目,然后添加一個接口如下:
-
publicinterface ITest {
-
public voidsayHello(String message);
-
}
生產者代碼:創建一個 mavan項目,並引入spring依賴、中間接口依賴、zookeeper依賴及dubbo依賴如下:
-
<!--jetty啟動插件-->
-
<build>
-
<plugins>
-
<plugin>
-
<groupId>org.mortbay.jetty</groupId>
-
<artifactId>maven-jetty-plugin</artifactId>
-
<version> 6.1.7</version>
-
<configuration>
-
<connectors>
-
<connector implementation= "org.mortbay.jetty.nio.SelectChannelConnector">
-
<port> 8888</port>
-
<maxIdleTime> 30000</maxIdleTime>
-
</connector>
-
</connectors>
-
<webAppSourceDirectory>${project.build.directory}/${pom.artifactId}-${pom.version}</webAppSourceDirectory>
-
<contextPath>/</contextPath>
-
</configuration>
-
</plugin>
-
<plugin>
-
<groupId>org.apache.maven.plugins</groupId>
-
<artifactId>maven-compiler-plugin</artifactId>
-
<version> 2.3.2</version>
-
<configuration>
-
<source> 1.6</source>
-
<target> 1.6</target>
-
<encoding>UTF- 8</encoding>
-
</configuration>
-
</plugin>
-
</plugins>
-
</build>
-
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework</groupId>
-
<artifactId>spring-context</artifactId>
-
<version> 4.0.2.RELEASE</version>
-
</dependency>
-
<dependency>
-
<groupId>org.apache.zookeeper</groupId>
-
<artifactId>zookeeper</artifactId>
-
<version> 3.4.6</version>
-
</dependency>
-
<dependency>
-
<groupId>com.alibaba</groupId>
-
<artifactId>dubbo</artifactId>
-
<version> 2.5.3</version>
-
</dependency>
-
<!-- 連接zookeeper的客戶端 -->
-
<dependency>
-
<groupId>com.github.sgroschupf</groupId>
-
<artifactId>zkclient</artifactId>
-
<version> 0.1</version>
-
</dependency>
-
</dependencies>
-
package com;
-
public class Test implements ITest {
-
public void sayHello(String message) {
-
System.out.println( "service say:" +message);
-
}
-
}
-
<?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:jee= "http://www.springframework.org/schema/jee"
-
xmlns:dubbo= "http://code.alibabatech.com/schema/dubbo"
-
xmlns:context= "http://www.springframework.org/schema/context"
-
xmlns:util= "http://www.springframework.org/schema/util"
-
xmlns:configurator= "http://cocoon.apache.org/schema/configurator"
-
xmlns:avalon= "http://cocoon.apache.org/schema/avalon"
-
xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
-
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
-
http://cocoon.apache.org/schema/configurator http://cocoon.apache.org/schema/configurator/cocoon-configurator-1.0.1.xsd
-
http://code.alibabatech.com/schema/dubbo
-
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
-
http://cocoon.apache.org/schema/avalon http://cocoon.apache.org/schema/avalon/cocoon-avalon-1.0.xsd"
-
default-lazy-init="false">
-
-
<!--提供方應用名稱信息,這個相當於起一個名字,我們dubbo管理頁面比較清晰是哪個應用暴露出來的 -->
-
<dubbo:application name= "dubbo_provider"></dubbo:application>
-
<!--使用zookeeper注冊中心暴露服務地址 -->
-
<dubbo:registry address= "zookeeper://127.0.0.1:2181" check="false" subscribe="false" register=""></dubbo:registry>
-
<!--要暴露的服務接口 -->
-
<dubbo:service interface="com.ITest" ref="springservice"/>
-
<bean id= "springservice" class="com.Test">
-
</bean>
-
</beans>
-
package com;
-
import org.springframework.context.ApplicationContext;
-
import org.springframework.context.support.ClassPathXmlApplicationContext;
-
public class Demo {
-
public static void main(String[] arg){
-
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] {"classpath*:config/applicationContext.xml" });
-
while(true);
-
}
-
}
消費者代碼:
-
<?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:jee= "http://www.springframework.org/schema/jee"
-
xmlns:dubbo= "http://code.alibabatech.com/schema/dubbo"
-
xmlns:context= "http://www.springframework.org/schema/context"
-
xmlns:util= "http://www.springframework.org/schema/util"
-
xmlns:configurator= "http://cocoon.apache.org/schema/configurator"
-
xmlns:avalon= "http://cocoon.apache.org/schema/avalon"
-
xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
-
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
-
http://cocoon.apache.org/schema/configurator http://cocoon.apache.org/schema/configurator/cocoon-configurator-1.0.1.xsd
-
http://code.alibabatech.com/schema/dubbo
-
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
-
http://cocoon.apache.org/schema/avalon http://cocoon.apache.org/schema/avalon/cocoon-avalon-1.0.xsd"
-
default-lazy-init="false">
-
-
<dubbo:application name= "dubbo_consumer"></dubbo:application>
-
<!--使用zookeeper注冊中心暴露服務地址 -->
-
<dubbo:registry address= "zookeeper://127.0.0.1:2181"></dubbo:registry>
-
-
<dubbo:protocol name= "dubbo" port="20880" />
-
<!--要引用的服務 -->
-
<dubbo:reference interface="com.ITest" id="springservice" ></dubbo:reference>
-
</beans>
-
package com;
-
import java.io.IOException;
-
import org.springframework.context.ApplicationContext;
-
import org.springframework.context.support.ClassPathXmlApplicationContext;
-
public class ClientDemo {
-
public static void main(String[] args) {
-
// 這里注意spring配置文件的名字和路徑
-
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
-
new String[] { "classpath*:applicationContext.xml" });
-
ITest test = (ITest) applicationContext.getBean( "springservice");
-
test.sayHello( "我在這里消費!!!");
-
try {
-
System.in.read();
-
} catch (IOException e) {
-
e.printStackTrace();
-
}
-
}
-
}
開始測試:
1.啟動zookeeper。執行zookeeper目錄下:bin/zkServer.cmd啟動服務
2.啟動dubbo服務。啟動dubbo所在tomcat(詳見本文開頭),dubbo啟動后,可通過http://127.0.0.1:8080/dubbo-admin來查看dubbo服務狀態
3.啟動生產者服務(clean package jetty:run)。運行生產者測試類Client.java
4.啟動消費者服務(clean package jetty:run)。運行消費者服務代碼ClientDemo.java,此時可以在生產者的控制台看到服務被調用了。
此時整個dubbo測試已經完成。同時我們可以在dubbo的web端看到生產者、消費者的狀態以及各個服務的調用情況。
為了方便大家,本測試用例以及需要的工具都可以在這里下載:
zookeeper下載:http://download.csdn.net/detail/sxyandapp/9425428
dubbo下載(配置文件已修改,可直接解壓后放到tomcat中使用):http://download.csdn.net/detail/sxyandapp/9425438