Dubbo 对象序列化、超时、重试、多版本控制
2022/6/11 23:52:12
本文主要是介绍Dubbo 对象序列化、超时、重试、多版本控制,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
之前已经快速搭建了 Dubbo 入门 Demo,本篇博客将继续在此 Demo 的基础上,介绍一下 Dubbo 在实际项目开发中必然会用到的一些简单实用的技术点,只需要编写很少的代码或者进行一些注解配置即可实现,大大提高了开发效率。在本篇博客的最后,会提供源代码的下载,需要注意的是:在运行本 Demo 代码时,必须先启动 Zookeeper 作为注册中心。
一、对象序列化
我们在编写服务接口时,如果接口参数或者接口返回值,需要使用实体类对象的话,那么实体类必须要实现 Serializable 接口,否则在运行过程中会报错。既然实体类是在接口定义中使用,因此 Dubbo 服务端和客户端都必须使用,所以本 Demo 就将实体类也放到了 dubbo_interface 这个公共模块中,如下图所示:
在 dubbo_interface 公共模块中,增加了 com.jobs.domain 包,增加实体类 User
package com.jobs.domain; import java.io.Serializable; //实体类承载数据,要想在 Dubbo 客户端和服务端之间传输, //必须实现 Serializable 接口 public class User implements Serializable { private String name; private Integer age; public User() { } public User(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
在 TestService 接口中定义一个方法使用 User 实体类:
package com.jobs.service; import com.jobs.domain.User; public interface TestService { User GetUserDetail(int id); }
在 Dubbo 服务端实现该接口:
package com.jobs.service.impl; import com.jobs.domain.User; import com.jobs.service.TestService; import org.apache.dubbo.config.annotation.Service; //需要注意:这里的 @Service 注解是 Dubbo 提供的 //不要使用 Spring 提供的 @Service 注解 @Service public class TestServiceImpl implements TestService { @Override public User GetUserDetail(int id) { User user; if (id == 1) { user = new User("任肥肥", 38); } else { user = new User("候胖胖", 40); } return user; } }
在 Dubbo 客户端进行调用和测试:
package com.jobs.controller; import com.jobs.domain.User; import com.jobs.service.TestService; import org.apache.dubbo.config.annotation.Reference; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/test") public class TestController { //这里生成远程接口代理,从而可以调用远程服务接口 @Reference private TestService testService; //测试实现了 Serializable 接口的实体类承载数据进行传输 //采用 restful 风格,把传递的参数写在路径上 @GetMapping("/getuser/{id}") public User GetCal(@PathVariable("id") int uid) { User user = testService.GetUserDetail(uid); return user; } }
二、地址缓存
当 Dubbo 客户端调用过一次 Dubbo 服务端的接口之后,服务端接口的地址就被缓存到 Dubbo 客户端了,所以 Dubbo 客户端并不是每次调用服务端接口,都得向 Zookeeper 注册中心获取接口服务地址。
当接口服务地址发生变化时,Zookeeper 注册中心会通知 Dubbo 客户端,此时 Dubbo 客户端会重新到注册中心获取最新的接口地址,然后缓存到 Dubbo 客户端中。因此如果 Zookeeper 注册中心宕机挂掉了,不会影响 Dubbo 客户端调用之前已经调用过的接口服务,但是新的接口服务就无法调用了。
三、超时和重试
我们既可以在 Dubbo 客户端的 @Reference 注解上配置超时和重试,也可以在 Dubbo 服务端的 @Service 注解上配置超时和重试。但是比较推荐的做法是在 Dubbo 服务端进行配置超时和重试,因为服务的开发者知道具体接口的执行耗费时间。需要注意的是:如果同时在客户端和服务端都配置了超时和重试的话,客户端上的配置会覆盖服务端的配置。
如果不进行配置的话,超时的时间默认为 1000 毫秒,重试的次数默认为 2 次,下面列出服务端的配置:
package com.jobs.service.impl; import com.jobs.domain.User; import com.jobs.service.TestService; import org.apache.dubbo.config.annotation.Service; //需要注意:这里的 @Service 注解是 Dubbo 提供的 //不要使用 Spring 提供的 @Service 注解 //一般情况下,超时和重试,配置在 Dubbo 服务端, //如果在 Dubbo 客户端配置超时和重试的话,会覆盖服务端的配置 //以下表明超时时间为 2 秒,先尝试请求 1 次,如果超时则再重试 1 次,一共最多请求 2 次 //如果不配置的话,默认超时是 1 秒钟,默认重试次数是 2 次 @Service(timeout = 2000, retries = 1) public class TestServiceImpl implements TestService { @Override public User GetUserDetail(int id) { User user; if (id == 1) { user = new User("任肥肥", 38); } else { user = new User("候胖胖", 40); } return user; } }
需要注意的是:根据业务重要性的实际情况,建议在服务端中,把读服务和写服务,进行分离。因为对于读取数据的服务,在超时后进行重试,一般情况下对业务不会有影响。但是对于写数据的接口服务来说,如果超时后进行重试,可能会影响业务,因此一般对于写服务,配置重试的次数为 0。当然要解决重复写数据对业务影响的问题,也是解决方案的,以上建议仅供参考。
四、多版本控制
对于 Java 来说,同一个接口的实现类,可以有多个。因此对于 Dubbo 服务端来说,同一个服务的实现类可以有多个,可以给不同的实现类通过 @Service 注解配置版本号,版本号是字符串,可以随意配置。在 Dubbo 客户端只需要在 @Reference 注解上配置要调用接口服务的版本,即可调用具体版本的服务接口。如下图所示,我们新建了一个 TestServiceImpl2 类实现 TestService 接口,作为一个新版本的服务。
下面列出两个版本服务的代码:
package com.jobs.service.impl; import com.jobs.domain.User; import com.jobs.service.TestService; import org.apache.dubbo.config.annotation.Service; //需要注意:这里的 @Service 注解是 Dubbo 提供的 //不要使用 Spring 提供的 @Service 注解 @Service(timeout = 2000, retries = 1, version = "1.0") public class TestServiceImpl implements TestService { @Override public User GetUserDetail(int id) { User user; if (id == 1) { user = new User("任肥肥", 38); } else { user = new User("候胖胖", 40); } return user; } }
package com.jobs.service.impl; import com.jobs.domain.User; import com.jobs.service.TestService; import org.apache.dubbo.config.annotation.Service; //这里编写了另外一个版本的服务,多个版本的服务可以同时存在 @Service(timeout = 2000, retries = 1, version = "2.0") public class TestServiceImpl2 implements TestService { @Override public User GetUserDetail(int id) { User user; if (id == 1) { user = new User("李墩墩", 38); } else { user = new User("乔豆豆", 40); } return user; } }
在 Dubbo 客户端通过 @Reference 注解上配置要调用接口服务的版本:
package com.jobs.controller; import com.jobs.domain.User; import com.jobs.service.TestService; import org.apache.dubbo.config.annotation.Reference; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/test") public class TestController { //这里生成远程接口代理,从而可以调用远程服务接口 //通过 version 配置,可以指定调用哪个版本的接口服务 @Reference(version = "2.0") private TestService testService; //测试实现了 Serializable 接口的实体类承载数据进行传输 //采用 restful 风格,把传递的参数写在路径上 @GetMapping("/getuser/{id}") public User GetCal(@PathVariable("id") int uid) { User user = testService.GetUserDetail(uid); return user; } }
多版本控制的情况,比较适合灰度发布。接口在大规模更新之前,大部分用户仍然使用原来的接口服务,先让一部分用户使用新接口服务,如果用了一段时间没有问题的话,就可以让所有的用户都使用新接口服务,从而完成灰度发布。
本篇博客源代码下载地址:https://files.cnblogs.com/files/blogs/699532/DubboDemo2.zip
这篇关于Dubbo 对象序列化、超时、重试、多版本控制的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南