Apache Dubbo与Nacos整合过程
Dubbo服务发现
Dubbo 提供的是一种 Client-Based 的服务发现机制,依赖第三方注册中心组件来协调服务发现过程,支持常用的注册中心如 Nacos、Consul、Zookeeper 等。
以下是 Dubbo 服务发现机制的基本工作原理图:
服务发现包含提供者、消费者和注册中心三个参与角色,其中,Dubbo 提供者实例注册 URL 地址到注册中心,注册中心负责对数据进行聚合,Dubbo 消费者从注册中心读取地址列表并订阅变更,每当地址列表发生变化,注册中心将最新的列表通知到所有订阅的消费者实例。
Dubbo与Nacos整合
前置条件
● 当Dubbo使用3.0.0及以上版本时,需要使用Nacos 2.0.0及以上版本。
● 注意:目前最新版本Dubbo 3.1.8不支持Spring Boot 3,因此开发环境必须基于Spring Boot 2.x + JDK17/8,对应的Spring Cloud与Spring Cloud Alibaba也要调整为2021.x
17 2021.0.3 2021.0.4.0
生产者服务provider-service-dubbo
org.apache.dubbo dubbo-spring-boot-starter 3.1.8
配置文件application.yaml
server: port: 8001 spring: application: name: provider-service cloud: nacos: server-addr: 192.168.31.231:8848 username: nacos password: nacos dubbo: application: name: provider-service-dubbo registry: address: nacos://192.168.31.231:8848 username: nacos password: nacos protocol: name: dubbo port: 20880 logging: level: root: info
应用入口增加两个注解,启用Dubbo
● @EnableDubbo
@EnableDubbo是一个注解,用于启用Dubbo的自动配置,将Dubbo服务注册到注册中心。它可以放置在Spring Boot应用程序的主类上。通过使用@EnableDubbo注解,可以避免手动配置Dubbo服务的繁琐工作,只需添加相应的注解和配置参数即可自动配置Dubbo。
● @DubboComponentScan
@DubboComponentScan是一个注解,用于扫描Dubbo服务的实现类。它可以放置在Spring Boot应用程序的主类上。通过使用@DubboComponentScan注解,可以自动扫描指定包及其子包中的Dubbo服务实现类,将它们注册为Dubbo服务。这样,Dubbo框架就能够自动发现和管理Dubbo服务,方便使用和维护。
package com.itlaoqi.providerservicedubbo; import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableDubbo @DubboComponentScan public class ProviderServiceDubboApplication { public static void main(String[] args) { SpringApplication.run(ProviderServiceDubboApplication.class, args); } }
实现业务接口
接口
package com.itlaoqi.providerservicedubbo.dubbo; import com.itlaoqi.providerservicedubbo.entity.User; import org.springframework.http.ResponseEntity; import java.util.List; import java.util.Map; public interface ProviderService { public Map hello(); public User createUser(String uid, String username, String password, String nickname); public ResponseEntity query(int page, int rows); }
实现
@DubboService是一个注解,用于标注Dubbo服务的实现类。在Dubbo框架中,服务提供者需要将服务注册到注册中心,以便服务消费者能够发现和调用服务。@DubboService注解可以将标注的服务实现类注册为Dubbo服务,使其能够被Dubbo框架自动管理和发布。
package com.itlaoqi.providerservicedubbo.dubbo.impl; import com.itlaoqi.providerservicedubbo.dubbo.ProviderService; import com.itlaoqi.providerservicedubbo.dto.User; import org.apache.dubbo.config.annotation.DubboService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @DubboService public class ProviderServiceImpl implements ProviderService { public Map hello() { Map result = new HashMap(); result.put("code", "0"); result.put("message", "hello world~"); return result; } public User createUser(String uid, String username , String password , String nickname) { return new User(uid,username,password,nickname); } public ResponseEntity query(int page, int rows) { List users = new ArrayList(); for (int i = rows * (page - 1); i注意,需要依赖的DTO对象,必须实现序列化接口Serializable
package com.itlaoqi.providerservicedubbo.dto; import lombok.AllArgsConstructor; import lombok.Data; import java.io.Serializable; @Data @AllArgsConstructor public class User implements Serializable { private String uid; private String username; private String password; private String nickname; }启动时要万分注意,JDK17与Dubbo 3.1.8有兼容问题,需要在启动项增加,官方说3.2版本会修正这个问题
--add-opens java.base/java.lang=ALL-UNNAMED消费者服务consumer-service-dubbo
org.apache.dubbo dubbo-spring-boot-starter 3.1.8配置消费者接口
server: port: 8002 spring: application: name: consumer-service cloud: nacos: server-addr: 192.168.31.231:8848 username: nacos password: nacos dubbo: application: name: consumer-service-dubbo registry: address: nacos://192.168.31.231:8848 username: nacos password: nacos logging: level: root: info启用Dubbo
package com.itlaoqi.consumerservicedubbo; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableDubbo public class ConsumerServiceDubboApplication { public static void main(String[] args) { SpringApplication.run(ConsumerServiceDubboApplication.class, args); } }将服务端接口与依赖的类加载到本地
● 复制源代码
● Maven依赖
注意包名是com.itlaoqi.providerservicedubbo.dubbo
package com.itlaoqi.providerservicedubbo.dubbo; import com.itlaoqi.providerservicedubbo.dto.User; import java.util.List; import java.util.Map; public interface ProviderService { public Map hello(); public User createUser(String uid, String username, String password, String nickname); public List query(int page, int rows); }package com.itlaoqi.providerservicedubbo.dto; import lombok.AllArgsConstructor; import lombok.Data; import java.io.Serializable; @Data @AllArgsConstructor public class User implements Serializable { private String uid; private String username; private String password; private String nickname; }依赖并远程访问
● @DubboReference
通过在 Spring 容器中标记 @DubboReference 注解,可以让 Dubbo 自动为该属性注入一个代理对象,该对象可以调用远程 Dubbo 服务的方法,使得在使用 Dubbo 服务时可以像调用本地服务一样方便。
package com.itlaoqi.consumerservicedubbo.controller; import com.itlaoqi.providerservicedubbo.dubbo.ProviderService; import com.itlaoqi.providerservicedubbo.dto.User; import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class ConsumerController { @DubboReference private ProviderService providerService; @GetMapping("/list") public List list(int page, int rows) { return providerService.query(page, rows); } }执行结果
### GET http://localhost:8002/list?page=2&rows=10 [ { "uid": "uid:10", "username": "username-10", "password": "password-10", "nickname": "nickname-10" }, { "uid": "uid:11", "username": "username-11", "password": "password-11", "nickname": "nickname-11" }, { "uid": "uid:12", "username": "username-12", "password": "password-12", "nickname": "nickname-12" }, { "uid": "uid:13", "username": "username-13", "password": "password-13", "nickname": "nickname-13" }, { "uid": "uid:14", "username": "username-14", "password": "password-14", "nickname": "nickname-14" }, { "uid": "uid:15", "username": "username-15", "password": "password-15", "nickname": "nickname-15" }, { "uid": "uid:16", "username": "username-16", "password": "password-16", "nickname": "nickname-16" }, { "uid": "uid:17", "username": "username-17", "password": "password-17", "nickname": "nickname-17" }, { "uid": "uid:18", "username": "username-18", "password": "password-18", "nickname": "nickname-18" }, { "uid": "uid:19", "username": "username-19", "password": "password-19", "nickname": "nickname-19" } ]启动时要万分注意,JDK17与Dubbo 3.1.8有兼容问题,需要在启动项增加,官方说3.2版本会修正这个问题
--add-opens java.base/java.lang=ALL-UNNAMED