Dubbo是阿里巴巴SOA服務化治理方案的核心框架,天天爲2,000+個服務提供3,000,000,000+次訪問量支持,並被普遍應用於阿里巴巴集團的各成員站點。Dubbo是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。php
Dubbo是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。簡單的說,dubbo就是個服務框架,若是沒有分佈式的需求,實際上是不須要用的,只有在分佈式的時候,纔有dubbo這樣的分佈式服務框架的需求,而且本質上是個服務調用的東東,說白了就是個遠程服務調用的分佈式框架java
其核心部分包含:git
1.遠程通信: 提供對多種基於長鏈接的NIO框架抽象封裝,包括多種線程模型,序列化,以及「請求-響應」模式的信息交換方式。
2.集羣容錯: 提供基於接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集羣支持。
3.自動發現: 基於註冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方能夠平滑增長或減小機器。github
1.透明化的遠程方法調用,就像調用本地方法同樣調用遠程方法,只需簡單配置,沒有任何API侵入。
2.軟負載均衡及容錯機制,可在內網替代F5等硬件負載均衡器,下降成本,減小單點。
3.服務自動註冊與發現,再也不須要寫死服務提供方地址,註冊中心基於接口名查詢服務提供者的IP地址,而且可以平滑添加或刪除服務提供者。算法
節點角色說明spring
節點 | 角色說明 |
---|---|
Provider | 暴露服務的服務提供方 |
Consumer | 調用遠程服務的服務消費方 |
Registry | 服務註冊與發現的註冊中心 |
Monitor | 統計服務的調用次調和調用時間的監控中心 |
Container | 服務運行容器 |
Dubbo提供三個關鍵功能,包括基於接口的遠程呼叫,容錯和負載平衡以及自動服務註冊和發現數據庫
調用關係說明segmentfault
1.服務容器負責啓動,加載,運行服務提供者。
2.服務提供者在啓動時,向註冊中心註冊本身提供的服務。
3.服務消費者在啓動時,向註冊中心訂閱本身所需的服務。
4.註冊中心返回服務提供者地址列表給消費者,若是有變動,註冊中心將基於長鏈接推送變動數據給消費者。
5.服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,若是調用失敗,再選另外一臺調用。
6.服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。api
Dubbo 架構具備如下幾個特色,分別是連通性、健壯性、伸縮性、以及向將來架構的升級性緩存
連通性
健狀性
伸縮性
升級性
當服務集羣規模進一步擴大,帶動IT治理結構進一步升級,須要實現動態部署,進行流動計算,現有分佈式服務架構不會帶來阻力。下圖是將來可能的一種架構:
節點角色說明
節點 | 角色說明 |
---|---|
Deployer | 自動部署服務的本地代理 |
Repository | 倉庫用於存儲服務應用發佈包 |
Scheduler | 調度中心基於訪問壓力自動增減服務提供者 |
Admin | 統一管理控制檯 |
Registry | 服務註冊與發現的註冊中心 |
Monitor | 統計服務的調用次調和調用時間的監控中心 |
Dubbo 採用全 Spring 配置方式,透明化接入應用,對應用沒有任何 API 侵入,只需用 Spring 加載 Dubbo 的配置便可,Dubbo 基於 Spring 的 Schema 擴展進行加載。
任選其一
CentOs7.3 搭建 ZooKeeper-3.4.9 單機服務
CentOs7.3 搭建 ZooKeeper-3.4.9 Cluster 集羣服務
代碼我已放到 Github ,導入spring-boot-dubbo
項目
github github.com/souyunku/sp…
在項目中添加 dubbo
依賴
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.6</version>
</dependency>
複製代碼
項目:dubbo-api
public interface DemoService {
String sayHello(String name);
}
複製代碼
項目:dubbo-provider
,在服務提供方實現接口
@Service("demoService")
public class DemoServiceImpl implements DemoService {
@Override
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();
}
}
複製代碼
加載 dubbo 配置
@Configuration
@PropertySource("classpath:dubbo.properties")
@ImportResource({"classpath:dubbo/*.xml"})
public class PropertiesConfig {
}
複製代碼
在提供方增長暴露服務配置 : <dubbo:service>
dubbo-provider.xml
<!-- 聲明須要暴露的服務接口 -->
<dubbo:service interface="io.ymq.dubbo.api.DemoService" ref="demoService"/>
複製代碼
項目:dubbo-consumer
,消費消費遠程方法
@Service("consumerDemoService")
public class ConsumerDemoService {
@Autowired
private DemoService demoService;
public void sayHello(String name) {
String hello = demoService.sayHello(name); // 執行消費遠程方法
System.out.println(hello); // 顯示調用結果
}
}
複製代碼
加載 dubbo 配置
@Configuration
@PropertySource("classpath:dubbo.properties")
@ImportResource({"classpath:dubbo/*.xml"})
public class PropertiesConfig {
}
複製代碼
在消費方增長引用服務配置: <dubbo:reference>
dubbo-consumer.xml
<!-- 增長引用遠程服務配置 能夠和本地bean同樣使用demoService -->
<dubbo:reference id="demoService" check="false" interface="io.ymq.dubbo.api.DemoService"/>
複製代碼
項目:dubbo-provider
,dubbo-consumer
同樣配置
dubbo.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 提供方應用信息,用於計算依賴關係 -->
<dubbo:application name="${spring.application.name}" />
<!-- 使用multicast廣播註冊中心暴露服務地址 -->
<dubbo:registry protocol="zookeeper" address="${zookeeper.connect}" file="${dubbo.cache}"/>
<!-- 用dubbo協議在20880端口暴露服務 -->
<dubbo:protocol name="dubbo" port="${dubbo.protocol.port}" threadpool="${dubbo.protocol.threadpool}" threads="${dubbo.protocol.threads}"/>
<!-- 提供方的缺省值,當ProtocolConfig和ServiceConfig某屬性沒有配置時,採用此缺省值,可選。-->
<dubbo:provider connections="${dubbo.provider.connections}" timeout="${dubbo.provider.timeout}" retries="${dubbo.provider.retries}" version="${dubbo.provider.version}" />
<!-- 消費方缺省配置,當ReferenceConfig某屬性沒有配置時,採用此缺省值,可選。-->
<dubbo:consumer version="${dubbo.provider.version}" />
<!-- 監控中心配置,用於配置鏈接監控中心相關信息,可選。-->
<dubbo:monitor protocol="registry"/>
</beans>
複製代碼
dubbo.properties
#########################################################
# dubbo config
#暴露服務端口
dubbo.protocol.port=20880
#提供方超時時間
dubbo.provider.timeout=10000
#提供方版本
dubbo.provider.version=1.0
#表示該服務使用獨的五條條長連
dubbo.provider.connections=5
# 固定大小線程池,啓動時創建線程,不關閉,一直持有。(缺省)
dubbo.protocol.threadpool=fixed
# 線程數量
dubbo.protocol.threads=500
#配置重試次數,最好只用於讀的重試,寫操做可能會引發屢次寫入 默認retries="0"
dubbo.provider.retries=0
# dubbo緩存文件
dubbo.cache=/data/dubbo/cache/dubbo-provider
#########################################################
# zookeeper config
zookeeper.connect=127.0.0.1:2181
複製代碼
啓動服務
/opt/zookeeper-3.4.9/bin/zkServer.sh start
複製代碼
package io.ymq.dubbo.provider.run;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
/**
* 描述:啓動提供方服務
*
* @author yanpenglei
* @create 2017-10-27 11:49
**/
@SpringBootApplication
@ComponentScan(value = {"io.ymq.dubbo"})
public class Startup {
public static void main(String[] args) {
SpringApplication.run(Startup.class, args);
}
}
複製代碼
package io.ymq.dubbo.test;
import io.ymq.dubbo.consumer.run.Startup;
import io.ymq.dubbo.consumer.service.ConsumerDemoService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/** * 描述: 測試消費遠程服務 * * @author yanpenglei * @create 2017-10-27 14:15 **/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Startup.class)
public class ConsumerTest {
@Autowired
private ConsumerDemoService consumerDemoService;
@Test
public void sayHello(){
consumerDemoService.sayHello("Peng Lei");
}
}
複製代碼
響應:
[15:54:00] Hello Peng Lei, request from consumer: /10.4.82.6:63993
複製代碼
代碼我已放到 Github ,導入spring-boot-dubbo
項目
github github.com/souyunku/sp…