Dubbo 是一款高性能、轻量级的开源 Java 服务框架
提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维
节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器
一、基于spring 配置文件方式配置:
(一)服务的提供方
1.导入相关需要的jar包;
Dubbo jar
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
注册中心jar
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
2.编写相关配置文件
<!-- 1.指定当前服务/应用名称 -->
<dubbo:application name="user-service-provider"></dubbo:application>
<!-- 2.指定注册中心位置 -->
<!-- <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry> -->
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>
<!--指定通信规则( 用dubbo协议在20880端口暴露服务) -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.atguigu.service.UserService" ref="UserService" />
<bean id="UserService" class="com.atguigu.service.impl.UserServiceImpl" />
<!-- 连接监控中心 -->
<!-- <dubbo:monitor protocol="registry"></dubbo:monitor> -->
<dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor>
(二)服务的消费方
-
导入相关jar
Dubbo jar
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
注册中心jar
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
2. 相关配置
<context:component-scan base-package="com.atguigu.gmall.service.impl"></context:component-scan>
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="order-service-consumer" />
<!-- 使用multicast广播注册中心暴露发现服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 生成远程服务代理,可以和本地bean一样使用UserServcie -->
<dubbo:reference id="UserServcie" interface="com.atguigu.service.UserService" />
<!-- 连接监控中心 -->
<!-- <dubbo:monitor protocol="registry"></dubbo:monitor> -->
<dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor>
二、基于springboot 整合 dubbo 配置文件方式配置
(参考官网 https://github.com/apache/dubbo-spring-boot-project ;https://dubbo.apache.org/zh/docs/v2.7/user/references/xml/):
(一)服务的提供方
1.导入dubbo-starter依赖;
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
2、导入dubbo的其他依赖;
3、在springboot 项目下的application.properties 文件配置dubbo;
//duboo应用的名字
dubbo.application.name=boot-user-service-provider
//指定注册中心的位置
dubbo.registry.address=127.0.0.1:2181
//协议
dubbo.registry.protocol=zookeeper
//duboo通信协议
dubbo.protocol.name=dubbo
//duboo通信端口
dubbo.protocol.port=20880
//连接监控中心 注册中心自动发现
dubbo.monitor.protocol=registry
4.暴露服务只需要在Service 层需要暴露的服务添加@DubboService 注解;
5.开启基于注解的dubbo功能,在springboot启动类添加@EnableDubbo注解;
(二)服务的消费方
1.导入dubbo-starter依赖;
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
2、在springboot 项目下的application.properties 文件配置dubbo;
server.port=8081
dubbo.application.name=boot-order-service-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.monitor.protocol==registry
3.声明需要需要调用远程服务的接口,使用@DubboReference注解(@DubboReference 注解帮我们远程引用某个服务,会从注册中心发现该服务);
4、.开启基于注解的dubbo功能,在springboot启动类添加@EnableDubbo注解;
三、以java config 的方式配置文件
4、.开启基于注解的dubbo功能,在springboot启动类添加@EnableDubbo注解;
其他额外的标签都可以通过这种创建bean的方式进行注入到容器中。
总结:使用springboot 注解方式配置dubbo
如果需要暴露服务使用@DubboService 注解;
如果需要消费服务使用@DubboReference注解;
三、配置_dubbo.properties&属性加载顺序
优先级从高到低:
- JVM -D 参数:当你部署或者启动应用时,它可以轻易地重写配置,比如,改变 dubbo 协议端口;
- XML:XML 中的当前配置会重写 dubbo.properties 中的;
- Properties:默认配置,仅仅作用于以上两者没有配置时。
- 如果在 classpath 下有超过一个 dubbo.properties 文件,比如,两个 jar 包都各自包含了 dubbo.properties,dubbo 将随机选择一个加载,并且打印错误日志。
- 如果 id 没有在 protocol 中配置,将使用 name 作为默认属性。
四、用法示例
(一) 启动时检查(当服务的消费者检测不到有服务提供者,启动服务消费者会报错,错误如下:)
1、通过 spring 配置文件
关闭某个服务的启动时检查 (没有提供者时报错):
<dubbo:reference interface="com.foo.BarService" check="false" />
关闭所有服务的启动时检查 (没有提供者时报错):
<dubbo:consumer check="false" />
关闭注册中心启动时检查 (注册订阅失败时报错):
<dubbo:registry check="false" />
2、通过 dubbo.properties
dubbo.reference.com.foo.BarService.check=false
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false
3、通过 -D 参数
java -Ddubbo.reference.com.foo.BarService.check=false
java -Ddubbo.reference.check=false
java -Ddubbo.consumer.check=false
java -Ddubbo.registry.check=false
(二) 超时时间
timeout(****) 单位毫秒
(三)重试次数配置(不包含第一次调用)
<dubbo:consumer retries="2"></dubbo:consumer>
(四)多版本
当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。
可以按照以下的步骤进行版本迁移:
在低压力时间段,先升级一半提供者为新版本
再将所有消费者升级为新版本
然后将剩下的一半提供者升级为新版本
老版本服务提供者配置: <dubbo:service interface="com.foo.BarService" version="1.0.0" /> 新版本服务提供者配置: <dubbo:service interface="com.foo.BarService" version="2.0.0" /> 老版本服务消费者配置: <dubbo:reference id="barService" interface="com.foo.BarService" version="1.0.0" /> 新版本服务消费者配置: <dubbo:reference id="barService" interface="com.foo.BarService" version="2.0.0" /> 如果不需要区分版本,可以按照以下的方式配置: <dubbo:reference id="barService" interface="com.foo.BarService" version="*" /> |
(五)高可用(.zookeeper宕机与dubbo直连(zookeeper 宕机还可以消费dubbo暴露的服务)
- 监控中心宕掉不影响使用,只是丢失部分采样数据
- 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
- 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
- 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
- 服务提供者无状态,任意一台宕掉后,不影响使用
- 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
(六) 集群下dubbo负载均衡配置(一个服务启动多次,每次设置启动端口号不同)
Dubbo提供了四种负载均衡策略
1.随机 Random LoadBalance 按照权重设置的大小,随机
2.轮询 RoundRobin LoadBalance 例如:a b c a执行完b执行然后c,然后在到a...
3.最少活跃调用数(权重)LeastActive LoadBalance
活跃数指调用前后计数差,优先调用高的,相同活跃数的随机。使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
4.一致性Hash ConsistentHash LoadBalance
相同参数总是发送到同一个提供者,如果这个提供者挂掉了,它会根据它的虚拟节点,平摊到其它服务者,不会引起巨大的变动
注意*:缺省为random 随机 (也就是说,不配置负载均衡策略的时候,默认为random)
配置方式 @DubboReference(loadbalance="random") 消费者serviceImpl添加;
(七) 服务降级
当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。
可以通过服务降级功能临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。
向注册中心写入动态配置覆盖规则:
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181")); registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null")); |
其中:
- mock=force:return+null 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
- 还可以改为 mock=fail:return+null 表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
(八) 服务容错
当一个服务调用另一个远程服务出现错误时的外观
Dubbo提供了多种容错方案,默认值为failover(重试)
1)、Failover Cluster(默认)
失败自动切换,当出现失败,重试其他服务器,通常用于读操作,但重试会带来更长延迟,可以通过属性retries来设置重试次数(不含第一次)
2)、Failfast Cluster
快速失败,只发起一次调用,失败立即报错,通常用于非幂等性的写操作,比如新增记录。
3)、Failsafe Cluster
失败安全,出现异常时,直接忽略,不做任何操作,通常用于写入审计日志等操作。
4)、Failback Cluster
失败自动重发,后台记录失败请求,定时重发,用于一些一定要成功的服务调用,例如消息通知等。
5)、Forking Cluster
并行调用多个服务器,只要有一个成功即返回,用于实时性较高的读操作,但需要浪费更多的服务资源,可通过forks=“2”来设置最大并行数量。
6)、Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则认为这次调用是失败的,适用于类似于同步的效果,例如通知所有提供者更新缓存或日志等本地资源信息。
*配置方式(二选其一即可)
服务消费者
1 @Reference(cluster = "failsafe")
2 private UserService userService;
服务提供者
1 @Component //org.springframework.stereotype.Component
2 @Service(cluster = "failsafe") //com.alibaba.dubbo.config.annotation.Service
3 public class UserServiceImpl implements UserService {
4 ...
5 }
五、dubbo原理
1、RPC原理
一次完整的RPC调用流程(同步调用,异步另说)如下: 1)服务消费方(client)调用以本地调用方式调用服务; 2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体; 3)client stub找到服务地址,并将消息发送到服务端; 4)server stub收到消息后进行解码; 5)server stub根据解码结果调用本地的服务; 6)本地服务执行并将结果返回给server stub; 7)server stub将返回结果打包成消息并发送至消费方; 8)client stub接收到消息,并进行解码; 9)服务消费方得到最终结果。 RPC框架的目标就是要2~8这些步骤都封装起来,这些细节对用户来说是透明的,不可见的。 |
2、netty通信原理
Netty是一个异步事件驱动的网络应用程序框架, 用于快速开发可维护的高性能协议服务器和客户端。它极大地简化并简化了TCP和UDP套接字服务器等网络编程。
BIO:(Blocking IO)
NIO (Non-Blocking IO)
Selector 一般称 为选择器 ,也可以翻译为 多路复用器,
Connect(连接就绪)、Accept(接受就绪)、Read(读就绪)、Write(写就绪)
Netty基本原理: