doubbo是什么?
Apache Dubbo 最初在 2008 年由 Alibaba 捐献开源,很快成为了国内开源服务框架选型的事实标准框架 ,得到了各行各业的广泛应用。在 2017 年,Dubbo 正式捐献到 Apache 软件基金会并成为 Apache 顶级项目,目前 Dubbo3 已经是一站式的微服务解决方案提供:
- 基于 HTTP/2 的 Triple 协议以及面向代理 API 的编程体验。
- 强大的流量治理能力,如地址发现、负载均衡、路由选址、动态配置等。
- 多语言 SDK 实现,涵盖 Java、Golang、Javascript 等,更多语言实现将会陆续发布。
- 灵活的适配与扩展能力,可轻松与微服务体系其他组件如 Tracing、Transaction 等适配。
- Dubbo Mesh 解决方案,同时支持 Sidecar、Proxyless 等灵活的 Mesh 部署方案。
Apache Dubbo 总体架构能很好的满足企业的大规模微服务实践,因为它从设计之初就是为了解决超大规模微服务集群实践问题,不论是阿里巴巴还是工商银行、中国平安、携程等社区用户,它们都通过多年的大规模生产环境流量对 Dubbo 的稳定性与性能进行了充分验证,因此,Dubbo 在解决业务落地与规模化实践方面有着无可比拟的优势:
- 开箱即用
- 易用性高,如 Java 版本的面向接口代理特性能实现本地透明调用
- 功能丰富,基于原生库或轻量扩展即可实现绝大多数的微服务治理能力
- 面向超大规模微服务集群设计
- 极致性能,高性能的 RPC 通信协议设计与实现
- 横向可扩展,轻松支持百万规模集群实例的地址发现与流量治理
- 高度可扩展
- 调用过程中对流量及协议的拦截扩展,如 Filter、Router、LB 等
- 微服务治理组件扩展,如 Registry、Config Center、Metadata Center 等
Dubbo 基本工作流程
在分布式系统中,尤其是随着微服务架构的发展,应用的部署、发布、扩缩容变得极为频繁,作为 RPC 消费方,如何动态的发现服务提供方地址成为 RPC 通信的前置条件。Dubbo 提供了自动的地址发现机制,用于应对分布式场景下机器实例动态迁移的问题。如下图所示,通过引入注册中心来协调提供方与消费方的地址,提供者启动之后向注册中心注册自身地址,消费方通过拉取或订阅注册中心特定节点,动态的感知提供方地址列表的变化。
Dubbo 核心特性
高性能 RPC 通信协议
跨进程或主机的服务通信是 Dubbo 的一项基本能力,Dubbo RPC 以预先定义好的协议编码方式将请求数据(Request)发送给后端服务,并接收服务端返回的计算结果(Response)。RPC 通信对用户来说是完全透明的,使用者无需关心请求是如何发出去的、发到了哪里,每次调用只需要拿到正确的调用结果就行。除了同步模式的 Request-Response 通信模型外,Dubbo3 还提供更丰富的通信模型选择:
- 消费端异步请求(Client Side Asynchronous Request-Response)
- 提供端异步执行(Server Side Asynchronous Request-Response)
- 消费端请求流(Request Streaming)
- 提供端响应流(Response Streaming)
- 双向流式通信(Bidirectional Streaming)
具体可参见各语言 SDK 实现的可选协议列表 或 Triple协议
自动服务(地址)发现
Dubbo 的服务发现机制,让微服务组件之间可以独立演进并任意部署,消费端可以在无需感知对端部署位置与 IP 地址的情况下完成通信。Dubbo 提供的是 Client-Based 的服务发现机制,使用者可以有多种方式启用服务发现:
- 使用独立的注册中心组件,如 Nacos、Zookeeper、Consul等。
- 将服务的组织与注册交给底层容器平台,如 Kubernetes,这被理解是一种更云原生的使用方式
运行态流量管控
透明地址发现让 Dubbo 请求可以被发送到任意 IP 实例上,这个过程中流量被随机分配。当需要对流量进行更丰富、更细粒度的管控时,就可以用到 Dubbo 的流量管控策略,Dubbo 提供了包括负载均衡、流量路由、请求超时、流量降级、重试等策略,基于这些基础能力可以轻松的实现更多场景化的路由方案,包括金丝雀发布、A/B测试、权重路由、同区域优先等,更酷的是,Dubbo 支持流控策略在运行态动态生效,无需重新部署。
入门程序
1、父项目版本锁定:
<dependencyManagement>
<dependencies>
<!-- springboot 版本锁定 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.8.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- springcloud的 阿里巴巴 版本锁定 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 添加SpringCloud版本锁定 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2、 dobbo-client定义服务接口
public interface UserDubboClient {
String hello(String id);
}
3、 dobbo-product提供方实现接口并暴露服务
@DubboService
public class UserServiceImpl implements UserDubboClient {
@Override
public String hello(String id) {
return "dubbo com.hk.client ... " + id;
}
}
4、dobbo-product配置 application.yml 文件
server:
port: 8000
spring:
application:
name: dubboproduct
cloud:
nacos:
discovery:
server-addr: localhost:8848
dubbo:
scan:
base-packages: com.hk.product.service # dubbo 扫描包路径
protocol:
name: dubbo # dubbo 协议
port: -1
registry:
address: nacos://localhost:8848 # 注册地址
5、dobbo-consumer引用远程服务
@RestController
@RequestMapping("/user")
public class UserController {
@DubboReference(check = false)
private UserDubboClient userDubboClient;
@RequestMapping("{id}")
public String hello(@PathVariable("id")String id){
String hello = userDubboClient.hello(id);
return hello;
}
}
6、dobbo-consumer定义 application.yml
server:
port: 9000
spring:
application:
name: dubboconsumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
dubbo:
scan:
base-packages: com.hk.product.service
protocol:
name: dubbo
port: -1
registry:
address: nacos://localhost:8848
7、dobbo-consumer加载 Spring 配置,并调用远程服务
@EnableDubbo
@SpringBootApplication
public class DubboConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(DubboConsumerApplication.class,args);
}
}
注解说明:
1、@DubboService 注解,定义好 Dubbo 服务接口后,提供服务接口的实现逻辑,并用 @DubboService
注解标记,就可以实现 Dubbo 的服务暴露
@DubboService
public class UserServiceImpl implements UserDubboClient {
}
2、@DubboReference 注解,@DubboReference
注解将自动注入为 Dubbo 服务代理实例,使用 userDubboClient即可发起远程服务调用
@RestController
@RequestMapping("/user")
public class UserController {
@DubboReference(check = false)
private UserDubboClient userDubboClient;
@RequestMapping("{id}")
public String hello(@PathVariable("id")String id){
String hello = userDubboClient.hello(id);
return hello;
}
}
3、@EnableDubbo 注解
@EnableDubbo
注解必须配置,否则将无法加载 Dubbo 注解定义的服务,@EnableDubbo
可以定义在主类上
@EnableDubbo
@SpringBootApplication
public class DubboConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(DubboConsumerApplication.class,args);
}
}
Spring Boot 注解默认只会扫描 main 类所在的 package,如果服务定义在其它 package 中,需要增加配置
@EnableDubbo(scanBasePackages = {"org.apache.dubbo.springboot.demo.provider"})
dobbo-Product的依赖pom文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>com.hk</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-product</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 注册中心 把 服务注册到nacos中-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- dubbo 的依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<!--dubbo nacos-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>com.hk</groupId>
<artifactId>dubbo-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
dobbo-Consumer的依赖pom文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>com.hk</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-consumer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 注册中心 把 服务注册到nacos中-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- dubbo 的依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<!--dubbo nacos-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>com.hk</groupId>
<artifactId>dubbo-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>