本文以实际项目和代码为示例,一步一步演示如何以最低成本实现 Apache Dubbo 体系与 Spring Cloud 体系的互通,进而实现不同微服务体系的混合部署、迁移等,帮助您解决实际架构及业务问题。
如果你在微服务开发过程中正面临以下一些业务场景需要解决,那么这篇文章可以帮到您:
对于以上几个场景,我们都可以借助 Dubbo3 内置的 REST 编程范式支持实现,这让 Dubbo 既可以作为消费方调用 HTTP 接口的服务,又可以作为提供方对外发布 REST 风格的 HTTP 服务,同时整个编码过程支持业界常用的 REST 编程范式(如 JAX-RS、Spring MVC 等),因此可以做到基本不改动任何代码的情况下实现 Dubbo 与 Spring Cloud 体系的互相调用。
在已经有一套 Spring Cloud 微服务体系的情况下,演示如何使用 Dubbo 调用 Spring Cloud 服务(包含自动的地址发现与协议传输)。在注册中心方面,本示例使用 Nacos 作为注册中心,对于 Zookeeper、Consul 等两种体系都支持的注册中心同样适用。
设想你已经有一套 Spring Cloud 的微服务体系,现在我们将引入 Dubbo 框架,让 Dubbo 应用能够正常的调用到 Spring Cloud 发布的服务。本示例完整源码请参见 samples/dubbo-call-sc[3]。
示例中 Spring Cloud 应用的结构如下:
应用配置文件如下:
server:
port: 8099
spring:
application:
name: spring-cloud-provider-for-dubbo
cloud:
nacos:
serverAddr: 127.0.0.1:8848 #注册中心
以下是一个非常简单的 Controller 定义,发布了一个 /users/list/的 http 端点。
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/list")
public List<User> getUser() {
return Collections.singletonList(new User(1L, "spring cloud server"));
}
}
启动 SpringCloudApplication,通过 cURL 或浏览器访问 http://localhost:8099/users/list 可以测试应用启动成功。
Dubbo client 也是一个标准的 Dubbo 应用,项目基本结构如下:
其中,一个比较关键的是如下接口定义(正常情况下,以下接口可以直接从原有的 Spring Cloud client 应用中原样拷贝过来即可,无需做任何修改)。
如果之前没有基于 OpenFeign 的 Spring Cloud 消费端应用,那么就需要自行定义一个接口,此时不一定要使用 OpenFeign 注解,使用 Spring MVC 标准注解即可。
通过 DubboReference 注解将 UserServiceFeign 接口注册为 Dubbo 服务。
@DubboReference
private UserServiceFeign userService;
接下来,我们就可以用 Dubbo 标准的方式对服务发起调用了。
List<User> users = userService.users();
通过 DubboConsumerApplication 启动 Dubbo 应用,验证可以成功调用到 Spring Cloud 服务。
在接下来的示例中,我们将展示如何将 Dubbo server 发布的服务开放给 Spring Cloud client 调用。
示例的相关源码在 samples/sc-call-dubbo[4]
Dubbo server 应用的代码结构非常简单,是一个典型的 Dubbo 应用。
相比于普通的 Dubbo 服务定义,我们要在接口上加上如下标准 Spring MVC 注解:
@RestController
@RequestMapping("/users")
public interface UserService {
@GetMapping(value = "/list")
List<User> getUsers();
}
除了以上注解之外,其他服务发布等流程都一致,使用 DubboService 注解发布服务即可:
@DubboService
public class UserServiceImpl implements UserService {
@Override
public List<User> getUsers() {
return Collections.singletonList(new User(1L, "Dubbo provider!"));
}
}
在服务配置上,特别注意我们需要将服务的协议配置为 rest protocol: rest,地址发现模式使用 register-mode: instance:
dubbo:
registry:
address: nacos://127.0.0.1:8848
register-mode: instance
protocol:
name: rest
port: 8090
启动 Dubbo 应用,此时访问以下地址可以验证服务运行正常:http://localhost:8090/users/list
使用 OpenFeign 开发一个标准的 Spring Cloud 应用,即可调用以上发布的 Dubbo 服务,项目代码结构如下:
其中,我们定义了一个 OpenFeign 接口,用于调用上面发布的 Dubbo rest 服务。
@FeignClient(name = "dubbo-provider-for-spring-cloud")
public interface UserServiceFeign {
@RequestMapping(value = "/users/list", method = RequestMethod.GET)
List<User> getUsers();
}
定义以下 controller 作为 OpenFeign 和 RestTemplate 测试入口:
public class UserController {
private final RestTemplate restTemplate;
private final UserServiceFeign userServiceFeign;
public UserController(RestTemplate restTemplate,
UserServiceFeign userServiceFeign) {
this.restTemplate = restTemplate;
this.userServiceFeign = userServiceFeign;
}
@RequestMapping("/rest/test1")
public String doRestAliveUsingEurekaAndRibbon() {
String url = "http://dubbo-provider-for-spring-cloud/users/list";
System.out.println("url: " + url);
return restTemplate.getForObject(url, String.class);
}
@RequestMapping("/rest/test2")
public List<User> doRestAliveUsingFeign() {
return userServiceFeign.getUsers();
}
}
根据以上 Controller 定义,我们可以分别访问以下地址进行验证:
本文系作者在时代Java发表,未经许可,不得转载。
如有侵权,请联系nowjava@qq.com删除。