它们都统称为RPC框架。
RPC(Remote Procedure Call)即远程过程调用,它是一个计算机通信协议,这个协议允许两个跨网络节点的进程进行通信,让我们能够像调用本地服务一样调用远程服务。
RPC协议定义了一种通信的标准规范,为了满足不同场景需求,于是很多RPC框架在这个协议基础上应运而生。而Dubbo就是主流RPC框架之一。
Dubbo是Alibaba内部使用的一个分布式服务治理框架,很多公司在应用dubbo时,会根据自身业务特性进行优化改进,从而衍生出了很多版本,比如京东的JSF,新浪的Motan,当当的dubbox。
主要分2.x和3.x两个版本。3.x定义为面向云原生的下一代RPC服务框架,目前还是以2.7.x版本为主。
Dubbo之所以能够被很多公司应用,是因为随着服务化快速发展,远程通信带来了很多弊端,比如:
传统RPC无法很好的解决这些问题,而Dubbo都能支持这些。
所以Dubbo不仅仅是一个RPC框架,更是一个成熟的微服务框架。它包含一下功能:

节点角色说明:
调用关系说明:
新版本Dubbo,多了配置中心和元数据中心


coupon-service-api
- public interface ICouponService {
- // 查询有效的优惠券列表
- String selectValidCoupons();
- }
user-service-api
- public interface IUserService {
- // 查询当前用户能够领取的优惠券列表
- String selectValidTemplates();
- }
coupon-service-provider
pom.xml
- <dependency>
- <artifactId>coupon-service-apiartifactId>
- <groupId>org.normal.examplegroupId>
- <version>1.0-SNAPSHOTversion>
- dependency>
- <dependency>
- <groupId>org.apache.dubbogroupId>
- <artifactId>dubbo-dependencies-zookeeperartifactId>
- <type>pomtype>
- <version>2.7.15version>
- dependency>
- <dependency>
- <groupId>org.apache.dubbogroupId>
- <artifactId>dubbo-spring-boot-starterartifactId>
- <version>2.7.15version>
- dependency>
启动类上通过@EnableDubbo让spring扫描dubbo注解
- @EnableDubbo
- @SpringBootApplication
- public class CouponServiceProviderApplication {
- public static void main(String[] args) {
- SpringApplication.run(CouponServiceProviderApplication.class, args);
- }
- }
通过@DubboService注册dubbo服务
- @DubboService
- public class CouponService implements ICouponService {
- @Override
- public String selectValidCoupons() {
- // TODO 实现数据查询,并且返回
- return "返回有效优惠券列表";
- }
- }
src/main/resources/application.properties
- # 应用名称
- spring.application.name=coupon-service-provider
-
- dubbo.application.name=coupon-service
- # 配置-1代表随机分配端口
- dubbo.protocol.port=-1
- dubbo.protocol.name=dubbo
-
- dubbo.registry.id=zk-registry
- dubbo.registry.address=zookeeper://192.168.1.101:2181?timeout=20000
- dubbo.config-center.address=zookeeper://192.168.1.101:2181?timeout=20000
- dubbo.metadata-report.address=zookeeper://192.168.1.101:2181?timeout=20000
user-service-provider
pom.xml
- <dependency>
- <groupId>org.normal.usergroupId>
- <artifactId>user-service-apiartifactId>
- <version>1.0-SNAPSHOTversion>
- dependency>
- <dependency>
- <artifactId>coupon-service-apiartifactId>
- <groupId>org.normal.examplegroupId>
- <version>1.0-SNAPSHOTversion>
- dependency>
- <dependency>
- <groupId>org.apache.dubbogroupId>
- <artifactId>dubbo-dependencies-zookeeperartifactId>
- <type>pomtype>
- <version>2.7.15version>
- dependency>
- <dependency>
- <groupId>org.apache.dubbogroupId>
- <artifactId>dubbo-spring-boot-starterartifactId>
- <version>2.7.15version>
- dependency>
启动类上通过@EnableDubbo让spring扫描dubbo注解
- @EnableDubbo
- @SpringBootApplication
- public class UserServiceProviderApplication {
- public static void main(String[] args) {
- SpringApplication.run(UserServiceProviderApplication.class, args);
- }
- }
通过@DubboService注册dubbo服务,通过@DubboReference注解发现dubbo服务
- @DubboService
- public class UserService implements IUserService {
- @DubboReference //
- ICouponService couponService;
-
- @Override
- public String selectValidTemplates() {
- // 1. 查询当前用户已经领取过的优惠券
- // 2. 查询优惠券服务,获取当前可以领取的有效优惠券列表
- String list=couponService.selectValidCoupons();
- return "用户服务返回:可以领取的优惠券列表,加载到的可领取优惠券:"+list;
- }
- }
src/main/resources/application.properties
- # 应用名称
- spring.application.name=user-service-provider
-
- dubbo.application.name=user-service
- # 配置-1代表随机分配端口
- dubbo.protocol.port=-1
- dubbo.protocol.name=dubbo
-
- dubbo.registry.id=zk-registry
- dubbo.registry.address=zookeeper://192.168.1.101:2181?timeout=20000
- dubbo.config-center.address=zookeeper://192.168.1.101:2181?timeout=20000
- dubbo.metadata-report.address=zookeeper://192.168.1.101:2181?timeout=20000
pom.xml
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-webartifactId>
- <version>2.3.7.RELEASEversion>
- dependency>
- <dependency>
- <groupId>org.normal.usergroupId>
- <artifactId>user-service-apiartifactId>
- <version>1.0-SNAPSHOTversion>
- dependency>
- <dependency>
- <groupId>org.apache.dubbogroupId>
- <artifactId>dubbo-spring-boot-starterartifactId>
- <version>2.7.15version>
- dependency>
- <dependency>
- <groupId>org.apache.dubbogroupId>
- <artifactId>dubbo-dependencies-zookeeperartifactId>
- <type>pomtype>
- <version>2.7.15version>
- dependency>
启动类
- @EnableDubbo
- @SpringBootApplication
- public class CouponPortalApplication {
- public static void main(String[] args) {
- SpringApplication.run(CouponPortalApplication.class, args);
- }
- }
controller层通过@DubboReference发现dubbo service服务
- @RestController
- public class UserController {
- @DubboReference
- IUserService userService;
-
- @GetMapping("/coupon")
- public String validCoupons(){
- return userService.selectValidTemplates();
- }
- }
resources/application.properties
- # 应用名称
- spring.application.name=coupon-portal
- # 应用服务 WEB 访问端口
- server.port=8080
-
- dubbo.application.name=coupon-portal
-
- dubbo.registry.id=zk-registry
- dubbo.registry.address=zookeeper://192.168.1.101:2181?timeout=20000
- dubbo.config-center.address=zookeeper://192.168.1.101:2181?timeout=20000
- dubbo.metadata-report.address=zookeeper://192.168.1.101:2181?timeout=20000
服务启动后,相应的dubbo服务信息会保存在zookeeper上

原始基于spring集成dubbo,不基于dubbo注解
service api和service api provider和上面类似,只是注册和发现dubbo服务的方式不同,spring基于配置,而springboot基于注解
applicationContext.xml
- "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.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
-
- <dubbo:application name="coupon-service-provider"/>
-
- <dubbo:registry address="zookeeper://192.168.1.101:2181?timeout=60000"/>
-
- <dubbo:protocol name="dubbo"/>
-
- <dubbo:service interface="org.normal.example.ICouponService" ref="couponService"/>
-
- <bean id="couponService" class="com.normal.coupon.couponserviceprovider.service.CouponService"/>
- beans>
application.properties
- # 应用名称
- spring.application.name=coupon-service-provider
Apache Dubbo天然就支持服务注册发现,最早开源的时候,官方建议使用 Apache Zookeeper作为注册中心。因此到现在仍然还有很多公司是Dubbo+Zookeeper这样一个架构。
从Apache Dubbo2.7.x版本开始,支持的注册中心增加了很多,包括: Consul、Etcd、Nacos、Sofa、Zookeeper、Eureka、Redis。
但是在Dubbo3.x版本里面,默认又只支持Nacos和Zookeeper两种,其他的注册中心被分离出来作为独立的组件,如果需要用到,则需要单独增加这些组件的依赖。可以参考dubbo官网文档扩展点分离:https://dubbo.apache.org/zh/docs/new-in-dubbo3/#%E6%89%A9%E5%B1%95%E7%82%B9%E5%88%86%E7%A6%BB
- <properties>
- <dubbo.version>3.0.0dubbo.version>
- properties>
- <dependencies>
- <dependency>
- <groupId>org.apache.dubbogroupId>
- <artifactId>dubboartifactId>
- <version>${dubbo.version}version>
- dependency>
-
- <dependency>
- <groupId>org.apache.dubbogroupId>
- <artifactId>dubbo-dependencies-zookeeperartifactId>
- <version>${dubbo.version}version>
- <type>pomtype>
- dependency>
-
- <dependency>
- <groupId>org.apache.dubbogroupId>
- <artifactId>dubbo-registry-redisartifactId>
- <version>${dubbo.version}version>
- dependency>
- dependencies>
一致性hash,随机,轮询,最小活跃度,最小响应时间,
- @DubboReference(async = true)
- IUserService userService;
可以在api服务中赋值
RpcContext.getContext().setAttachment("parameter-key", "parameter-value");
在provider实现中取值
RpcContext.getContext().getAttachment("parameter-key");
dubbo协议,dubbo 3.x提供了Triple协议
考虑两方面因素:计算效率,序列化之后数据的压缩大小
对外:JSON
对内:Dubbo(Hessian2)
针对Java语言:Kryo, FST
跨语言:Protobuf, Avro, Jute(zookeeper),
不同序列化方式对比
| 序列化方式 | 请求字节数 | 响应字节数 |
|---|---|---|
| Kryo | 272 | 90 |
| FST | 288 | 96 |
| Dubbo Serialization | 430 | 186 |
| Hessian | 546 | 329 |
| FastJson | 461 | 218 |
| Json | 657 | 409 |
| Java Serialization | 963 | 630 |