配置地址:https://dubbo.apache.org/zh/docsv2.7/user/examples/

1、启动时检查

在启动时检查依赖的服务是否可用,如果不可用的话就报错,比如服务提供者暂未注册到注册中心,但是消费者注册进来了,所有会直接报错启动失败,但是也可以设置为当服务调用的时候去检查服务提供者是否注册进来。

示例:
当前服务注册状态:
image.png
启动服务消费者:报错

  1. Failed to check the status of the service com.lzy.gmail.service.UserService. No provider available for the service com.lzy.gmail.service.UserService from the url zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=order-service-consumer&dubbo=2.6.2&interface=com.lzy.gmail.service.UserService&methods=getUserAddressList&pid=2520&register.ip=192.168.56.1&side=consumer&timestamp=1651646050840 to the consumer 192.168.56.1 use dubbo version 2.6.2

image.png
解决:启动不报错

  1. <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
  2. <dubbo:reference id="userService" interface="com.lzy.gmail.service.UserService" check="false" />
  3. <!-- 配置当前消费者的统一规则-->
  4. <dubbo:consumer check="false"></dubbo:consumer>
  5. <!-- 注册中心没有,也正常启动-->
  6. <dubbo:registry check="false"></dubbo:registry>

2、超时设置

  1. <!-- 生成远程服务代理,可以和本地bean一样使用demoService ,timeout单位毫秒-->
  2. <dubbo:reference id="userService" interface="com.lzy.gmail.service.UserService" check="false" timeout="3000" />

超时覆盖的原则:

  • 1)精确优先(方法级优先,接口级次之,全局配置再次之)
  • 2)消费者设置优先(如果级别一样,则消费方优先,提供方次之)

image.png

3、重试次数

重试次数通常和超时时间配合使用。
当某个服务调用超时后,可以使用重试次数进行多试几次,但是并不包含第一次调用。

  1. <!-- 生成远程服务代理,可以和本地bean一样使用demoService ,timeout单位毫秒, 重试次数:retries,重试三次。如果这个服务不可用,一共会发送四次请求(1+3)-->
  2. <dubbo:reference id="userService" interface="com.lzy.gmail.service.UserService"
  3. check="false"
  4. timeout="3000"
  5. retries="3"/>
  1. @Documented
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
  4. public @interface Reference {
  5. // ......
  6. int retries() default 0;
  7. // ......
  8. }

测试重试次数如下:

  1. @RestController
  2. public class OrderController {
  3. @Autowired
  4. private OrderService orderService;
  5. @RequestMapping("/initOrder")
  6. public List<UserAdress> initOrder(@RequestParam("uid")String userId) {
  7. try {
  8. Thread.sleep(4000);
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. return orderService.initOrder(userId);
  13. }
  14. }
  1. @Service
  2. public class OrderServiceImpl implements OrderService {
  3. @Reference(timeout = 3000, retries = 3) // dubbo提供的,去远程发现从而自动注入
  4. private UserService userService;
  5. @Override
  6. public List<UserAdress> initOrder(String userId) {
  7. // 1. 查询用户的地址
  8. System.out.println("用户id:" + userId);
  9. List<UserAdress> userAddressList = userService.getUserAddressList(userId);
  10. return userAddressList;
  11. }
  12. }
  1. @Service // 暴露服务
  2. @Component
  3. public class UserServiceImpl implements UserService {
  4. @Override
  5. public List<UserAdress> getUserAddressList(String userId) {
  6. try {
  7. System.out.println("我睡五秒钟~~");
  8. Thread.sleep(5000);
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. // ......
  13. return Arrays.asList(userAdress1, userAdress2);
  14. }
  15. }

测试结果如下:
image.png

重试次数在多机的情况下,一个服务不可以用,如果有多个服务那么也是可以请求成功的!

启动三个提供者:
勾选允许多个实例运行,修改参数跑三个提供者
image.png
image.png
访问订单初始化接口:得到相同的结果,四次访问请求。
image.png

3.1)幂等和不幂等

一般可以将方法设置为幂等和非幂等的。
幂等设置重试次数,而对于非幂等下呢不可以设置重试次数。
对于多次操作结果都是一个的话,就可以设置为幂等即有重试次数,比如【查询、删除、修改】
而对于非幂等的话对应有【新增】,也就是说用户对于一个新增操作后感觉等太久了又重新发送请求那么就会发生多个新增对象,不宜设置为幂等。

4、多版本

https://dubbo.apache.org/zh/docsv2.7/user/examples/multi-versions/
在 Dubbo 中为同一个服务配置多个版本
当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用
可以按照以下的步骤进行版本迁移:

  1. 在低压力时间段,先升级一半提供者为新版本
  2. 再将所有消费者升级为新版本
  3. 然后将剩下的一半提供者升级为新版本

使用version关键字。服务提供者和消费者需要使用相同的版本。

  1. // 服务提供者暴露的接口使用version
  2. <dubbo:service interface="com.lzy.gmail.service.UserService" ref="userServiceImpl01" version="1.0.0"/>
  3. <dubbo:service interface="com.lzy.gmail.service.UserService" ref="userServiceImpl02" version="2.0.0"/>
  4. // 服务消费者使用version。
  5. <!-- 生成远程服务代理,可以和本地bean一样使用demoService ,timeout单位毫秒, 重试次数:retries-->
  6. <dubbo:reference id="userService" interface="com.lzy.gmail.service.UserService"
  7. check="false"
  8. timeout="3000"
  9. retries="3"
  10. version="1.0.0"/>
  1. @Service // 消费使用者
  2. public class OrderServiceImpl implements OrderService {
  3. @Reference(timeout = 3000, retries = 3, version = "1.0.0") // dubbo提供的,去远程发现从而自动注入
  4. private UserService userService;
  5. @Override
  6. public List<UserAdress> initOrder(String userId) {
  7. // 1. 查询用户的地址
  8. System.out.println("用户id:" + userId);
  9. List<UserAdress> userAddressList = userService.getUserAddressList(userId);
  10. return userAddressList;
  11. }
  12. }
  13. // 消费提供者。
  14. @Service(version = "1.0.0") // 暴露服务
  15. @Component
  16. public class UserServiceImpl implements UserService {
  17. @Override
  18. public List<UserAdress> getUserAddressList(String userId) {
  19. // ......
  20. }
  21. }

5、本地存根 stub

在调用远程接口的时候想要对参数进行验证,可以使用本地存根。
在 Dubbo 中利用本地存根在客户端执行部分逻辑
远程服务后,客户端通常只剩下接口,而实现全在服务器端,但提供方有些时候想在客户端也执行部分逻辑,比如:做 ThreadLocal 缓存,提前验证参数,调用失败后伪造容错数据等等,此时就需要在 API 中带上 Stub,客户端生成 Proxy 实例,会把 Proxy 通过构造函数传给 Stub 1,然后把 Stub 暴露给用户,Stub 可以决定要不要去调 Proxy。
image.png
编写测试代码:
image.png

  1. <!-- 生成远程服务代理,可以和本地bean一样使用demoService ,timeout单位毫秒, 重试次数:retries
  2. stub:指向的是本地存根,即校验数据类所在的位置,全限定类名
  3. -->
  4. <dubbo:reference id="userService" interface="com.lzy.gmail.service.UserService"
  5. check="false"
  6. timeout="3000"
  7. retries="3"
  8. version="*"
  9. stub="com.lzy.service.impl.UserServiceImpl"/>
  1. @Service
  2. public class OrderServiceImpl implements OrderService {
  3. @Reference(timeout = 3000, retries = 3, version = "1.0.0", stub = "com.lzy.service.impl.UserServiceImpl") // dubbo提供的,去远程发现从而自动注入
  4. private UserService userService;
  5. @Override
  6. public List<UserAdress> initOrder(String userId) {
  7. // ......
  8. }
  9. }

结果如下:
image.png

6、SpringBoot与dubbo整合的三种方式

对于使用注解而言,使用注解的方式对于某些详细设置是无法使用的,比如如下代码:方法级别的设置
image.png
三种方式如下:
image.png