一、Dubbo是什麼?
Dubbo是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。簡單的說,dubbo就是個服務框架,如果沒有分佈式的需求,其實是不需要用的,只有在分佈式的時候,纔有dubbo這樣的分佈式服務框架的需求;這容易和負載均衡弄混,負載均衡是對外提供一個公共地址,請求過來時通過輪詢、隨機等,路由到不同server。目的分攤壓力。dubbo在淘寶也是解決他們實際問題的,不一定適合其他。
原理就是:A系統調用B系統接口服務, 後面就是怎麼把這個流程,動態化(zookeeper通知)、權限化、配置化、低耦合化、自動化。
其核心部分包含:
- 遠程通訊: 提供對多種基於長連接的NIO框架抽象封裝,包括多種線程模型,序列化,以及“請求-響應”模式的信息交換方式。
- 集羣容錯: 提供基於接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集羣支持。
- 自動發現: 基於註冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。
二. Dubbo能做什麼?
1.透明化的遠程方法調用,就像調用本地方法一樣調用遠程方法,只需簡單配置,沒有任何API侵入。
2.軟負載均衡及容錯機制,可在內網替代F5等硬件負載均衡器,降低成本,減少單點。
3. 服務自動註冊與發現,不再需要寫死服務提供方地址,註冊中心基於接口名查詢服務提供者的IP地址,並且能夠平滑添加或刪除服務提供者。
三.dubbo出現的背景
隨着互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分佈式服務架構以及流動計算架構勢在必行,需一個治理系統確保架構有條不紊的演進。
目前市場一些基本的架構:
單一應用架構
當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。
此時,用於簡化增刪改查工作量的 數據訪問框架(ORM) 是關鍵。
垂直應用架構
當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成互不相干的幾個應用,以提升效率。
此時,用於加速前端頁面開發的 Web框架(MVC) 是關鍵。
分佈式服務架構
當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作爲獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。
此時,用於提高業務複用及整合的 分佈式服務框架(RPC) 是關鍵。
流動計算架構
當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實時管理集羣容量,提高集羣利用率。
此時,用於提高機器利用率的 資源調度和治理中心(SOA) 是關鍵。
在大規模服務化之前,一般只是簡單的暴露和引用遠程服務,通過配置url進行調用,用f5或者nginx等進行負載均衡;
四、Dubbo架構
官網架構圖:
節點角色說明:
Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務註冊與發現的註冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
Container: 服務運行容器。
調用關係說明:
0.服務容器負責啓動,加載,運行服務提供者。
1 服務提供者在啓動時,向註冊中心註冊自己提供的服務。
2. 服務消費者在啓動時,向註冊中心訂閱自己所需的服務。
3. 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
4. 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
5. 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
連通性:
註冊中心負責服務地址的註冊與查找,相當於目錄服務,服務提供者和消費者只在啓動時與註冊中心交互,註冊中心不轉發請求,壓力較小
監控中心負責統計各服務調用次數,調用時間等,統計先在內存彙總後每分鐘一次發送到監控中心服務器,並以報表展示
服務提供者向註冊中心註冊其提供的服務,並彙報調用時間到監控中心,此時間不包含網絡開銷
服務消費者向註冊中心獲取服務提供者地址列表,並根據負載算法直接調用提供者,同時彙報調用時間到監控中心,此時間包含網絡開銷
註冊中心,服務提供者,服務消費者三者之間均爲長連接,監控中心除外
註冊中心通過長連接感知服務提供者的存在,服務提供者宕機,註冊中心將立即推送事件通知消費者
註冊中心和監控中心全部宕機,不影響已運行的提供者和消費者,消費者在本地緩存了提供者列表
註冊中心和監控中心都是可選的,服務消費者可以直連服務提供者
健狀性:
監控中心宕掉不影響使用,只是丟失部分採樣數據
數據庫宕掉後,註冊中心仍能通過緩存提供服務列表查詢,但不能註冊新服務
註冊中心對等集羣,任意一臺宕掉後,將自動切換到另一臺
註冊中心全部宕掉後,服務提供者和服務消費者仍能通過本地緩存通訊
服務提供者無狀態,任意一臺宕掉後,不影響使用
服務提供者全部宕掉後,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復
伸縮性:
註冊中心爲對等集羣,可動態增加機器部署實例,所有客戶端將自動發現新的註冊中心
服務提供者無狀態,可動態增加機器部署實例,註冊中心將推送新的服務提供者信息給消費者
升級性:
當服務集羣規模進一步擴大,帶動IT治理結構進一步升級,需要實現動態部署,進行流動計算,現有分佈式服務架構不會帶來阻力:
dubbo支持的註冊中心
Dubbo提供的註冊中心有如下幾種類型可供選擇:
Multicast註冊中心
Zookeeper註冊中心
Redis註冊中心
Simple註冊中心
ZooKeeper是一個開源的分佈式服務框架,它是Apache Hadoop項目的一個子項目,主要用來解決分佈式應用場景中存在的一些問題,如:統一命名服務、狀態同步服務、集羣管理、分佈式應用配置管理等,它支持Standalone模式和分佈式模式,在分佈式模式下,能夠爲分佈式應用提供高性能和可靠地協調服務,而且使用ZooKeeper可以大大簡化分佈式協調服務的實現,爲開發分佈式應用極大地降低了成本。
四、Dubbo使用
Dubbo採用全Spring配置方式,透明化接入應用,對應用沒有任何API侵入,只需用Spring加載Dubbo的配置即可,Dubbo基於Spring的Schema擴展進行加載。
1、啓動zookeeper
參考上一篇博客:https://mp.csdn.net/mdeditor/97176024#
2. 建立項目
2.1首先創建一個maven父項目
創建過程參考:https://blog.csdn.net/u014429653/article/details/97181403
創建完成後可刪除src文件夾,父項目用不到這個文件夾;
2.2接着創建DubboDemoApi、DubboDemoProvider、DubboDemoConsumer
一共分三個模塊,每個模塊都有獨立的pom文件。
稍微說明一下三個模塊的作用。DubboDemoApi內爲公用接口,DubboDemoProvider提供遠程服務,DubboDemoConsumer調用遠程服務。
2.3 在DubboDemoApi內添加接口
寫一個sayHello的方法
public interface DemoService {
String sayHello(String name);
}
然後打成一個jar包
然後找到jar包對應的信息,利於下一步進行
2.4在DubboDemoProvider的pom.xml中添加依賴
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.9</version>
</dependency>
<dependency>
<groupId>com.ali.dubbo</groupId>
<artifactId>DubboDemoApi</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.0.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.37.Final</version>
</dependency>
</dependencies>
在DubboDemoConsumer的pom.xml中添加依賴
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.9</version>
</dependency>
<dependency>
<groupId>com.ali.dubbo</groupId>
<artifactId>DubboDemoApi</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.0.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
2.5 在DubboDemoProvider中實現接口
public class DemoServiceImpl implements DemoService {
public String sayHello(String name) {
System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
return "Hello " + name + ", response form provider: " + RpcContext.getContext().getLocalAddress();
}
}
注意:@Service註解可加額不加,不影響;
引入import org.springframework.stereotype.Service;或者import com.alibaba.dubbo.config.annotation.Service;不影響;
@Override可加可不加,不影響;
2.6 在DubboDemoProvider中resources文件夾下添加配置文件provider.xml
然後在provider.xml中添加以下內容
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- provider's application name, used for tracing dependency relationship -->
<dubbo:application name="demo-provider"/>
<!-- use multicast registry center to export service
<dubbo:registry address="multicast://224.5.6.7:1234"/>-->
<dubbo:registry address="zookeeper://localhost:2181"/>
<!-- use dubbo protocol to export service on port 20880 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- service implementation, as same as regular local bean -->
<bean id="demoService" class="com.alibaba.dubbo.demo.DemoServiceImpl"/>
<!-- declare the service interface to be exported -->
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService"/>
</beans>
2.7創建Provider.java,然後啓動,啓動前先啓動zookeeper
public class Provider {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"provider"});
context.start();
System.out.println("----------------服務已啓動,按任意鍵結束···········--------------------");
System.in.read(); // press any key to exit
}
}
DubboDemoProvider結構如下:
2.8 在DubboDemoConsumer中resources文件夾下添加配置文件consumer.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- consumer's application name, used for tracing dependency relationship (not a matching criterion),
don't set it same as provider -->
<dubbo:application name="demo-consumer"/>
<!-- use multicast registry center to discover service
<dubbo:registry address="multicast://224.5.6.7:1234"/>-->
<dubbo:registry address="zookeeper://localhost:2181"/>
<!-- generate proxy for the remote service, then demoService can be used in the same way as the
local regular interface -->
<dubbo:reference id="demoService" check="false" interface="com.alibaba.dubbo.demo.DemoService"/>
</beans>
2.9 在DubboDemoConsumer中創建Consumer.java,然後啓動,啓動之前必須先啓動Provider
public class Consumer {
public static void main(String[] args){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-consumer.xml"});
context.start();
DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxy
String hello = demoService.sayHello("world"); // call remote method
System.out.println(hello);
}
}
3.運行項目
先啓動zookeeper,啓動成功後啓動provider,最後啓動consumer
再運行Provider.java
再運行Consumer.java,成功調用
五、Dubbo-admin監控搭建
dubbo-admin有兩種方法運行
1、使用war包運行
下載dubbo-admin
dubbo-admi再github上下載地址https://github.com/apache/dubbo/tree/2.5.x
注意:在github上的branch上選擇2.5.x上有的,master分支上沒有dubbuo-admin
打包war包
進入dubbo-admin這個文件目錄 運行命令:
mvn package -Dmaven.skip.test=true
看到如下結果,說明打包成功了:
打包成功之後,就會發現dubbo-admin下多了個target文件夾,打開target文件夾,發現裏面有個war包:
部署war包
我們得到dubbo-admin-2.5.10.war,下面我們將這個war包部署到tomcat上。
把dubbo-admin-2.5.10.war放到tomcat的webapps目錄下;
啓動tomcat,讓tomcat把war解壓了
劃重點:如果一直提示unable to open the service ‘tomcat’,那麼重新安裝一個tomcat(注意一定要使用tomcat安裝包,重新安裝,不是解壓可用那種)*
tomcat的webapps裏面就會多了這個文件夾:
運行war包
運行tomcat之前必須先運行zookeeper,zookeeper啓動默認端口是8080,但是tomcat服務是8080在用,會衝突,啓動前需要修改zookeeper端口爲9091
去zoo.cfg文件中修改端口號,輸入admin.serverPort=9091
在瀏覽器輸入:http://localhost:8088/dubbo-admin-2.5.10/
查找dubbo-admin的用戶名和密碼,去dubbo-admin下面查找dubbo.properties
用戶名:root 密碼:root
用戶名:guest 密碼:guest
2、使用jar包運行
在dubbo加入apache後,github地址也變了。dubbo-admin需要從https://github.com/apache/incubator-dubbo-ops下載。,必須切換到master分支
將項目克隆到本地後,可以看到dubbo-admin模塊。
值得注意的是,最新的dubbo-admin集成了springboot,可以打包爲jar運行。
進入dubboadmin項目 修改application.properties文件
dubbo-admin\src\main\resources\application.properties;zookeeper改爲自己電腦安裝的
cmd到在dubbo-admin下,執行mvn package -DskipTests=true
,將dubbo-admin打成jar包。
打包完成後,我們會在dubbo-admin/target下看到dubbo-admin的jar包 。
注意:dubbo-admin的端口默認是7001,dubbo註冊中心的地址是本機的2181端口
PS:注意必須先運行本機的zookeeper
運行jar包
啓動後,瀏覽器輸入http://localhost:7001即可訪問,默認的用戶名密碼輸入root,即進入首頁。
3 查看服務提供者和消費者
主頁
中英文切換
點擊服務治理——服務
查看服務提供者
查看服務消費者