官方文档:https://cn.dubbo.apache.org/zh-cn/overview/home/
都是服务调用、远程通信框架。
OpenFeign:
Netflix 开发的声明式、基于注解的轻量级 HTTP 客户端框架。提供简洁的方式来定义和使用 RESTful API 接口,
在客户端代码中使用注解来描述服务接口,自动处理请求和响应,自动负载均衡、服务发现和容错处理等功能。
Dubbo:
阿里巴巴 开发的高性能、面向 RPC(远程过程调用)的服务框架,网络通信框架:Netty(默认)、Mina、Grizzly。支持:高性能远程方法调用,智能容错和负载均衡,服务自动注册和发现。具备低延迟和高吞吐量。
Dubbo不绑定任何一款特定通信协议,支持 HTTP/2、REST、gRPC、JsonRPC、Thrift、Hessian2 等主流通信协议,不要代理实现协议转换,可通过 Dubbo 实现不同协议间的迁移。
Dubbo 内置支持 Dubbo2、Triple 两款高性能通信协议
Dubbo2:基于 TCP 传输协议之上构建的二进制私有 RPC 通信协议,非常简单、紧凑、高效的通信协议。
Triple:基于 HTTP/2 的新一代 RPC 通信协议,在网关穿透性、通用性以及 Streaming 通信上具备优势,Triple 完全兼容 gRPC 协议。
1.地址发现
默认提供 Nacos、Zookeeper、Consul 等多种注册中心适配,与 Spring Cloud、Kubernetes Service 模型打通,支持自定义扩展。
2.负载均衡
提供加权随机、加权轮询、最少活跃请求数优先、最短响应时间优先、一致性哈希和自适应负载等策略
3.流量路由
支持通过一系列流量规则控制服务调用的流量分布与行为,可实现基于权重的比例流量分发、灰度验证、金丝雀发布、按请求参数的路由、同区域优先、超时配置、重试、限流降级等。
4.链路追踪
通过适配 OpenTelemetry 提供对 Tracing 全链路追踪支持,可接入支持 OpenTelemetry 标准的产品如 Skywalking、Zipkin 等。
很多社区如 Skywalking、Zipkin 等在官方也提供了对 Dubbo 的适配。
5.可观测性
实例通过 Prometheus 等上报 QPS、RT、请求次数、成功率、异常次数等多维度的可观测指标帮助了解服务运行状态,通过接入 Grafana、Admin 控制台帮助实现数据指标可视化展示。
服务治理生态还提供对 API 网关、限流降级、数据一致性、认证鉴权等场景的适配支持。
Dubbo使用3.0
及以上时,要用Nacos 2.0
及以上
公共接口:nacos-dubbo-api
发布者:nacos-dubbo-provider
消费者:nacos-dubbo-consummer
public interface HelloService {
String syHello(String name);
}
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
com.alibaba.cloud
spring-cloud-starter-dubbo
com.example
nacos-dubbo-api
1.0.0
server.port=8020
spring.application.name=nacos-dubbo-provider
##################nacos 配置###################################
## 名称空间
spring.cloud.nacos.discovery.namespace=evone
## nacos 链接账号 没有设置不可以不选
spring.cloud.nacos.username=evone
# nacos 链接 密码 没有设置不可以不选
spring.cloud.nacos.password=evone123456
#用的nacos改了端口号, 默认端口 8848
spring.cloud.nacos.server-addr=192.168.104.110:16848
##################dubbo 配置##################################
#指定 Dubbo 服务实现类的扫描基准包
#dubbo.scan.base-packages=com.example.dubbo
#Dubbo服务暴露的协议配置,其中子属性name为协议名称,port为协议端口(-1 表示自增端口,从 20880 开始)
dubbo.protocol.port=-1
dubbo.protocol.name=dubbo
#Dubbo 服务注册中心配置,其中子属性address 的值 "spring-cloud://192.168.44.129",说明挂载到 Spring Cloud 注册中心
dubbo.registry.address=spring-cloud: nacos://192.168.104.110:16848
#在 Spring Boot 2.1 以及更高的版本增加该设定,因为 Spring Boot 默认调整了 Bean 定义覆盖行为。
spring.main.allow-bean-definition-overriding=true
import com.example.dubbo.api.HelloService;
import org.apache.dubbo.config.annotation.DubboService;
@DubboService
public class HelloServiceImpl implements HelloService {
public String syHello(String name) {
return "hello "+name;
}
}
import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient // 开启nacos 服务发现
@DubboComponentScan
public class NacosDubboProviderApplication {
public static void main(String[] args) {
SpringApplication.run(NacosDubboProviderApplication.class, args);
}
}
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
com.alibaba.cloud
spring-cloud-starter-dubbo
com.example
nacos-dubbo-api
1.0.0
server.port=8021
spring.application.name=nacos-dubbo-consumer
##################nacos 配置###################################
## 名称空间
spring.cloud.nacos.discovery.namespace=evone
## nacos 链接账号 没有设置不可以不选
spring.cloud.nacos.username=evone
# nacos 链接 密码 没有设置不可以不选
spring.cloud.nacos.password=evone123456
# 使用的nacos改了端口号, 默认端口 8848
spring.cloud.nacos.server-addr=192.168.104.110:16848
##################dubbo 配置##################################
#指定 Dubbo 服务实现类的扫描基准包
#dubbo.scan.base-packages=com.example.dubbo
#Dubbo服务暴露的协议配置,其中子属性name为协议名称,port为协议端口(-1 表示自增端口,从 20880 开始)
dubbo.protocol.port=-1
dubbo.protocol.name=dubbo
#Dubbo 服务注册中心配置,其中子属性address 的值 "spring-cloud://192.168.44.129",说明挂载到 Spring Cloud 注册中心
dubbo.registry.address=spring-cloud: nacos://192.168.104.110:16848
# dubbo.cloud.subscribed-services 默认 *
dubbo.cloud.subscribed-services=nacos-dubbo-provider
#在 Spring Boot 2.1 以及更高的版本增加该设定,因为 Spring Boot 默认调整了 Bean 定义覆盖行为。
spring.main.allow-bean-definition-overriding=true
import com.example.dubbo.api.HelloService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@DubboReference
private HelloService helloService;
@GetMapping("/syHello")
public String syHello(String name){
return helloService.syHello(name);
}
}
import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient // 开启nacos 服务发现
@DubboComponentScan
public class NacosDubboConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(NacosDubboConsumerApplication.class, args);
}
}
# 服务端口号
server.port=8080
# Dubbo应用名
dubbo.application.name=demo-provider
# 注册中心地址
dubbo.registry.address=nacos://127.0.0.1:2181
# 服务提供者协议
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
# 服务提供者接口类全限定名
dubbo.scan.base-packages=com.example.demo.service
# 服务提供者负载均衡策略
# 随机(Random)、最少活跃数(LeastActive)、一致性哈希(ConsistentHash)、轮询(RoundRobin)、加权轮询(WeightedRoundRobin)、加权随机(WeightedRandom)
dubbo.loadbalance=leastactive
多个路由器组成一条路由链共同协作,经过层层路由规则筛选后,最终生成有效的地址集合。
Dubbo 的流量管控规则可基于应用、服务、方法、参数等粒度精准的控制流量走向。
1.条件路由
对发起流量的请求参数进行匹配,符合匹配条件的请求将被转发到包含特定实例地址列表的子集。
应用粒度
# app1的消费者只能消费所有端口为20880的服务实例
# app2的消费者只能消费所有端口为20881的服务实例
scope: application
key: governance-conditionrouter-consumer
enabled: true
force: true
runtine: true
conditions:
- application=app1 => address=*:20880
- application=app2 => address=*:20881
服务粒度
# DemoService的sayHello方法只能消费所有端口为20880的服务实例
# DemoService的sayHi方法只能消费所有端口为20881的服务实例
scope: service
key: org.apache.dubbo.samples.goverance.api.DemoService
enabled: true
force: true
runtime: true
conditions:
- method=sayHello => address=*:20880
- method=sayHi => address=*:20881
2.标签路由
用于提供者应用,通过将某个服务的实例划分到不同的分组,不同分组为不同的流量场景服务,可作为蓝绿发布、灰度发布等。
如在:shop-detail 应用中圈出了一个隔离环境 gray,gray 环境包含所有带有 env=gray 标识的机器实例。
configVersion: v3.0
force: true
enabled: true
key: shop-detail
tags:
- name: gray
match:
- key: env
value:
exact: gray
3.脚本路由
脚本语法支持 Javascript、Groovy、Kotlin 等
configVersion: v3.0
key: demo-provider
type: javascript
enabled: true
script: |
(function route(invokers,invocation,context) {
var result = new java.util.ArrayList(invokers.size());
for (i = 0; i < invokers.size(); i ++) {
if ("10.20.3.3".equals(invokers.get(i).getUrl().getHost())) {
result.add(invokers.get(i));
}
}
return result;
} (invokers, invocation, context)); // 表示立即执行方法
控制台可视化展示了集群中的应用、服务、实例及依赖关系,支持流量治理规则下发,同时还提供如服务测试、mock、文档管理等提升研发测试效率的工具。
1.下载地址
前端vue:https://nodejs.org/en/
后端springboot:https://github.com/apache/dubbo-admin
2.配置文件
admin.registry.address=nacos://192.168.149.135:2181
admin.config-center=nacos://192.168.149.135:2181
admin.metadata-report.address=nacos://192.168.149.135:2181
1.注册中心(registry)
生产者在此注册并发布内容,消费者在此订阅并接收发布的内容。
2.消费者(consumer)
客户端,从注册中心获取到方法,可以调用生产者中的方法。
3.生产者(provider)
服务端,生产内容,生产前需要依赖容器(先启动容器)。
4.容器(container)
生产者在启动执行的时候,必须依赖容器才能正常启动(默认依赖的是spring容器)。
5.监控(Monitor)
统计服务的调用次数与时间等。
1.服务接口层(Service)
该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
2.配置层(Config)
对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。
3.服务代理层(Proxy)
服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。
4.服务注册层(Registry)
封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService。可能没有服务注册中心,此时服务提供方直接暴露服务。
5.集群层(Cluster)
封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
6.监控层(Monitor)
RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService。
7.远程调用层(Protocol)
封将RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
8.信息交换层(Exchange)
封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
9.网络传输层(Transport)
抽象mina和netty为统一接口,以 Message 为中心,扩展接口为 Channel、Transporter、Client、Server和Codec。
10.数据序列化层(Serialize)
可复用的一些工具,扩展接口为 Serialization、 ObjectInput、ObjectOutput和ThreadPool。
1、服务提供者启动,开启Netty服务,创建Zookeeper客户端,向注册中心注册服务;
2、服务消费者启动,通过Zookeeper向注册中心获取服务提供者列表,与服务提供者通过Netty建立长连接;
3、服务消费者通过接口开始远程调用服务,ProxyFactory通过初始化Proxy对象,Proxy通过创建动态代理对象;
4、动态代理对象通过invoke方法,层层包装生成一个Invoker对象,该对象包含了代理对象;
5、Invoker通过路由,负载均衡选择了一个最合适的服务提供者,在通过加入各种过滤器,协议层包装生成一个新的DubboInvoker对象;
6、再通过交换成将DubboInvoker对象包装成一个Reuqest对象,该对象通过序列化通过NettyClient传输到服务提供者的NettyServer端;
7、到了服务提供者这边,再通过反序列化、协议解密等操作生成一个DubboExporter对象,再层层传递处理,会生成一个服务提供端的Invoker对象;
8、这个Invoker对象会调用本地服务,获得结果再通过层层回调返回到服务消费者,服务消费者拿到结果后,再解析获得最终结果。