文章目錄
- 一、Dubbo簡介
- 二、SSM項目整合Dubbo
- 1.生產者方配置
- 2.消費者方配置
- 三、Spring Boot 項目整合Dubbo
- 1.生產者方配置
- 2.消費者方配置
- 四、應用案例
- 五、Dubbo配置的優先級別
- 1. 方法級配置(Highest Priority)
- 2. 接口級配置
- 3. 消費者/提供者級配置
- 4. 全局配置
- 六、Dubbo超時時間和重試
- 七、設置本地存根
- 八、整合Hystrix
- 總結
一、Dubbo簡介
??Dubbo 是一個RPC(遠程過程調用)
服務框架:
- 服務注冊與發現:Dubbo 提供內置的注冊中心(如 Zookeeper 等),服務提供者注冊服務,消費者動態發現服務。
- 高效的遠程調用:通過支持多種通信協議(默認 Dubbo 協議),實現快速、可靠的遠程方法調用。
- 負載均衡:提供多種負載均衡策略,如隨機、輪詢、一致性哈希等,保證服務調用的高效性和穩定性。
- 服務治理:包括限流、降級、熔斷、動態路由等功能,提升系統穩定性和靈活性。
- 擴展性強:采用模塊化設計,用戶可以根據需求定制和擴展功能。
??Dubbo主要由以下五部分組成:
- Provider(服務提供者):提供服務的應用。
- Consumer(服務消費者):調用服務的應用。
- Registry(注冊中心):管理服務的注冊與發現。
- Monitor(監控中心):監控服務的調用性能。
- Protocol(協議層):定義服務調用的規則和數據傳輸方式。
??常見的遠程調用工具,除了Dubbo還有Open Feign,HttpClient等,那么Dubbo和Open Feign有什么區別?
- 框架定位和設計目標
Dubbo | OpenFeign |
---|---|
分布式服務框架,重點在 服務治理。 | 聲明式 HTTP 客戶端,主要關注 HTTP 調用。 |
提供端到端的解決方案,包括服務注冊發現、負載均衡、服務路由、服務降級等。 | 偏重于與 REST API 的集成,通常依賴 Spring Cloud 生態提供更多功能。 |
支持多種通信協議(如 Dubbo 協議、HTTP、gRPC)。 | 僅支持基于 HTTP 的遠程調用。 |
- 通信協議
Dubbo | OpenFeign |
---|---|
支持多種通信協議,默認采用高性能的 Dubbo 協議,基于二進制序列化,通信效率高。 | 僅支持 HTTP,通常基于 JSON 格式的數據交換,性能比二進制協議略低。 |
可以支持 TCP、HTTP、gRPC 等不同的底層傳輸協議。 | 依賴 HTTP 和 RESTful 風格,靈活性較低。 |
- 注冊與發現
Dubbo | OpenFeign |
---|---|
通過注冊中心(如 Zookeeper、Nacos)實現動態的服務注冊與發現。 | 通常依賴 Spring Cloud 服務注冊中心(如 Eureka、Consul)。 |
服務發現、路由完全由 Dubbo 框架管理。 | 需要依賴 Spring Cloud 相關組件完成服務發現。 |
- 負載均衡與服務治理
Dubbo | OpenFeign |
---|---|
內置多種負載均衡算法(如隨機、輪詢、一致性哈希)。 | 負載均衡通常依賴 Ribbon 或 Spring Cloud LoadBalancer。 |
提供豐富的服務治理功能,如熔斷、限流、動態路由等。 | 通常通過 Hystrix、Resilience4j 等第三方庫實現。 |
- 性能與適用場景
Dubbo | OpenFeign |
---|---|
性能高,適合 高并發、低延遲的場景(如 RPC 調用)。 | 易用性高,適合 跨服務的 RESTful 調用 場景。 |
偏向于大規模、高性能分布式系統。 | 偏向于 REST 風格 API 的微服務開發。 |
- 擴展性與生態
Dubbo | OpenFeign |
---|---|
自帶強大的擴展能力,可以通過 SPI 自定義組件,如協議、序列化機制等。 | 集成簡單,主要依賴 Spring Cloud 生態,與其他組件兼容性好。 |
社區活躍度較高,但主要適用于阿里系生態。 | 社區支持廣泛,與 Spring Cloud 微服務結合更緊密。 |
二、SSM項目整合Dubbo
??無論是生產者方,消費者方,首先加入依賴:
<!-- dubbo--><dependency><groupId>com.alibaba</groupId><artifactId>dubbo</artifactId><version>2.6.2</version></dependency>
<!-- zookeeper--><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>2.10.0</version></dependency>
1.生產者方配置
??resource
目錄下編寫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/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"><!-- 1、指定當前服務/應用的名字(同樣的服務名字相同,不要和別的服務同名) --><dubbo:application name="user-service-provider"></dubbo:application><!-- 2、指定注冊中心的位置 在本案例中使用的是zk,也可以使用其他的 --><dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry><!-- 3、指定通信規則(通信協議?通信端口) --><dubbo:protocol name="dubbo" port="20882"></dubbo:protocol><!-- 4、暴露服務 ref:指向服務的真正的實現對象 --><dubbo:service interface="com.atguigu.gmall.service.UserService"ref="userServiceImpl01" timeout="1000" version="1.0.0"><dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method></dubbo:service><!-- 服務的實現 --><bean id="userServiceImpl01" class="com.light.gmall.service.impl.UserServiceImpl"></bean><!--統一設置服務提供方的規則 --><dubbo:provider timeout="1000"></dubbo:provider><!-- 連接監控中心 --><dubbo:monitor protocol="registry"></dubbo:monitor></beans>
2.消費者方配置
<?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://dubbo.apache.org/schema/dubbo"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"><!-- 掃描消費者的業務類,注冊成bean放入容器--><context:component-scan base-package="com.light.gmall.service.impl"></context:component-scan><dubbo:application name="order-service-consumer"></dubbo:application><dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry><!--聲明需要調用的遠程服務的接口;生成遠程服務代理 --><dubbo:reference interface="com.atguigu.gmall.service.UserService" id="userService" timeout="5000" retries="3" version="*"></dubbo:reference><!-- 配置當前消費者的統一規則:所有的服務都不檢查 --><dubbo:consumer check="false" timeout="5000"></dubbo:consumer><dubbo:monitor protocol="registry"></dubbo:monitor></beans>
三、Spring Boot 項目整合Dubbo
??同樣地,無論是生產者方,消費者方,首先加入依賴,并且啟動類上加入@EnableDubbo
注解:
<dependency><groupId>com.alibaba.boot</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>0.2.0</version></dependency>
1.生產者方配置
dubbo.application.name=user-service-provider #指定當前服務/應用的名字
dubbo.registry.address=127.0.0.1:2181 #指定注冊中心的位置
dubbo.registry.protocol=zookeeper #指定注冊中心的類型dubbo.protocol.name=dubbo # 指定通信協議
dubbo.protocol.port=20880 # 指定通信端口dubbo.monitor.protocol=registry #連接監控中心
??暴露服務可以通過@Service
注解實現,該注解是import com.alibaba.dubbo.config.annotation.Service
。并且只能加在類上。
2.消費者方配置
dubbo.application.name=boot-order-service-consumer # 指定當前服務/應用的名字
dubbo.registry.address=zookeeper://127.0.0.1:2181 # 指定注冊中心
dubbo.monitor.protocol=registry #連接監控中心
??調用生產者方暴露的類的方法,可以在注入目標類時加入@Reference
方法,并且可以指定負載均衡和超時時間等策略:
@Reference(loadbalance="random",timeout=1000) //dubbo直連UserService userService;
四、應用案例
??在本篇的應用中,將所有需要被遠程調用的接口,抽取成一個獨立的模塊進行管理,消費者
和生產者
去依賴該模塊:
??生產者方:
@Service//暴露服務
@Component
public class UserServiceImpl implements UserService {@HystrixCommand@Overridepublic List<UserAddress> getUserAddressList(String userId) {// TODO Auto-generated method stubSystem.out.println("UserServiceImpl..3.....");UserAddress address1 = new UserAddress(1, "xxxx", "1", "李老師", "010-56253825", "Y");UserAddress address2 = new UserAddress(2, "yyyy", "1", "王老師", "010-56253825", "N");if(Math.random()>0.5) {throw new RuntimeException();}return Arrays.asList(address1,address2);}}
??消費者方:
@Controller
public class OrderController {@AutowiredOrderService orderService;@ResponseBody@RequestMapping("/initOrder")public List<UserAddress> initOrder(@RequestParam("uid")String userId) {return orderService.initOrder(userId);}}
@Service
public class OrderServiceImpl implements OrderService {//@Autowired@Reference(loadbalance="random",timeout=1000) //dubbo直連UserService userService;@HystrixCommand(fallbackMethod="hello")@Overridepublic List<UserAddress> initOrder(String userId) {// TODO Auto-generated method stubSystem.out.println("用戶id:"+userId);//1、查詢用戶的收貨地址return userService.getUserAddressList(userId);}
}
??啟動Zookeeper和Dubbo-Admin,訪問Controller層的路徑:
??登錄Dubbo Admin也可以看到:
五、Dubbo配置的優先級別
總體原則:
環境變量或啟動參數的優先級更高:
- 如果通過系統屬性(如
-D
參數)或環境變量設置某些配置,它們會覆蓋 XML 或注解中的設置。
動態配置的優先級更高:
- Dubbo Admin 提供的動態配置可以在運行時覆蓋靜態配置,優先級更高。
本地優先于遠程:
- 如果本地和遠程注冊中心(如 Zookeeper)同時有配置,本地配置通常優先生效。
1. 方法級配置(Highest Priority)
- 方法級配置對單個方法生效,優先級最高。
- 主要用于對某些特殊方法的調用行為進行單獨優化。
<dubbo:reference id="demoService" interface="com.example.DemoService"><dubbo:method name="sayHello" timeout="3000" retries="2"/>
</dubbo:reference>
2. 接口級配置
- 通過
<dubbo:reference>
或<dubbo:service>
對整個接口的行為進行配置。 - 優先級低于方法級配置,但高于全局配置。
<dubbo:reference id="demoService" interface="com.example.DemoService" timeout="5000" retries="3"/>
3. 消費者/提供者級配置
- 分別通過
<dubbo:consumer>
或<dubbo:provider>
標簽進行配置,針對消費者或提供者應用全局生效。 - 優先級低于接口級配置。
<dubbo:consumer timeout="6000" retries="1"/>
<dubbo:provider timeout="4000"/>
4. 全局配置
- 通過
<dubbo:application>
或<dubbo:registry>
等標簽進行全局性配置。 - 優先級最低,提供默認值或全局設置。
<dubbo:application name="demoApplication"/>
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
六、Dubbo超時時間和重試
??在Spring Boot項目中,設置超時時間和重試次數,可以通過在服務消費端的 @DubboReference
注解中設置,優先級高于配置文件中的全局配置。
@Reference(loadbalance="random",timeout=1000,retries = 3) //dubbo直連UserService userService;
??可以在配置文件中全局設置:
dubbo:consumer:timeout: 5000 # 超時時間,單位為毫秒retries: 2 # 重試次數
??可以在配置文件中單個設置:
dubbo:consumer:services:com.example.MyService:retries: 1 # 針對某個服務的重試次數timeout: 3000 # 指定服務的超時時間
??上述兩段配置是放在消費者方的,如果消費者沒有設置,可以在生產者方設置:
dubbo:provider:timeout: 5000retries: 2
??如果需要更細粒度控制到接口中的方法級別,則可以:
dubbo:consumer:services:com.example.MyService:methods:- name: method1retries: 0 # method1 不重試- name: method2retries: 2 # method2 重試 2 次
??演示接口超時:
??目前在頁面上是直接打印出了報錯信息,后續可以通過引入
Hystrix
引導到降級邏輯上。
七、設置本地存根
??Dubbo 本地存根用于在消費端(Consumer)對服務進行代理或增強,常用于參數校驗、緩存、限流等場景。
??編寫本地存根方法,和接口放在同一個包下:
public class UserServiceStub implements UserService{private final UserService userService;public UserServiceStub(UserService userService) {this.userService = userService;}/*** 按照用戶id返回所有的收貨地址** @param userId* @return*/@Overridepublic List<UserAddress> getUserAddressList(String userId) {System.out.println("進入本地存根方法....");return userService.getUserAddressList(userId);}
}
??在消費者方的@Reference
注解上加入stub = "存根類的全路徑"
,重新訪問接口:
八、整合Hystrix
??在生產者方和消費者方同時引入依賴,并且在啟動類上加入@EnableHystrix
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>
??生產者方對外暴露的方法上加入@HystrixCommand
注解:
??消費者方同樣加上注解,并且指定觸發降級后的邏輯:@HystrixCommand(fallbackMethod="hello")
,在本案例中,觸發降級之后,會調用hello方法。
??觸發降級策略:
總結
??本篇介紹了Dubbo在SSM項目,以及Spring Boot項目中的集成使用,以及配置文件的優先級,超時時間和重試機制等。此外還有負載均衡策略,如何保證高可用,在官方文檔里都有提及,本篇不再贅述。
Dubbo官方文檔