1、Dubbo集成
上面文章已经部署了Dubbo并且已经集成了Mysql,本文以用户中心服务向其他服务提供用户查询接口为例,整理在集成Dubbo过程中的一些配置和问题。
1.1、ac-client模块
该模块以sdk的方式为其他服务提供查询能力,我们之前已经有maven搭建的经验了,此处不再赘述配置过程,直接以pom文件的方式展示该module,其中的common包可忽略(为了方便其他服务统一结果集、工具、异常,自己打包的sdk)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cj</groupId>
<artifactId>ac</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>com.cj.ac</groupId>
<artifactId>ac-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.cj</groupId>
<artifactId>common</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<!--这里的id与settings.xml中的servers节点配置的用户ID一直,这样才能使用配置的用户去上传到maven私有仓库 -->
<!--此仓库对应的为RELEASE版本的jar-->
<id>maven-releases</id>
<url>http://127.0.0.1:8081/nexus/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<!--这里的id与settings.xml中的servers节点配置的用户ID一直,这样才能使用配置的用户去上传到maven私有仓库 -->
<!--此仓库对应的为SNAPSHOT版本的jar-->
<id>maven-snapshots</id>
<url>http://127.0.0.1:8081/nexus/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
1.2、新建用户查询接口
在ac-client模块下新建用户查询接口,及相关入参、返回值等实体类。先不用考虑具体实现,先把sdk发布了再说实现的事。
/**
* 用户信息接口
*
* @Author: changjiang
* UserInfoService
* @date: 2024/7/18 15:24 in beijing
*/
public interface RemoteUserInfoService {
/**
* 分页查询用户列表
*
* @param request 请求参数
* @return 用户分页列表数据
*/
Result<PageResult<UserInfo>> paged(UserInfoRequest request);
/**
* 根据id查询用户详情
*
* @param userId 用户id
* @return 用户数据
*/
Result<UserInfo> findById(Long userId);
}
1.3、sdk发布
通过maven-deploy组件将ac-client发布到maven仓库,可以使用idea的maven插件,注意该插件使用的maven环境问题,如果是第一次发布,则需要父工程全量发布以此,后续才可单独发布ac-client。执行成功后,可以从maven仓库中查看到该jar包,如下图
1.4、服务实现
我们发布完ac-client之后,其他的服务就可以通过maven引入该client了,但此时client并没有被注册到dubbo中,且没有相应的生产者提供服务实现,对此我们开始增加实现。
1.4.1、ac-service引入ac-client
因为为同工程内,所以无需maven私服即可引入,因为本文中ac-service同时负责持久层及其他中间件能力,所以同时增加data-jpa及data-redis等引用,pom文件示例:
<dependencies>
<dependency>
<groupId>com.cj.ac</groupId>
<artifactId>ac-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<type>pom</type>
<exclusions>
<exclusion>
<artifactId>slf4j-reload4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
1.4.2、ac-service实现接口
在ac-service中新增接口实现类,实现RemoteUserInfoService接口,代码如下:
注意几个问题:
@Component:此处增加bean注解是为了可以在本工程内其他service或controller中调用,非dubbo标准接口实现所必须。
@DubboService:dubbo服务提供者的声明,低版本为@Service(Apache或Alibaba的,非Spring的,该点尤其注意),此处使用的是Apache的。其中version建议必填。
jpa懒加载问题:若此时没有关闭jpa懒加载(hibernate懒加载),在查询完用户后,session会被回收,此时再查询tenant时,会报出session异常。解决方式有两种,后面会列一个单章来总结jpa懒加载问题:
关闭懒加载;
修改物理模型增加外键关系,然后使用@OneToMany或者其他注解进行标识,然后进行user实体查询,此时会关联查询出tenant;
/**
* 用户信息服务接口实现
*
* @Author: changjiang
* @date: 2024/7/18 15:27 in beijing
*/
@Slf4j
@Component
@DubboService(version = "1.0.0")
public class RemoteRemoteUserInfoServiceImpl implements RemoteUserInfoService {
@Resource
private UserService userService;
@Resource
private UserLoginService userLoginService;
@Resource
private TenantService tenantService;
@Override
public Result<UserInfo> findById(Long userId) {
// 获取用户信息
UserDTO userDTO = userService.findById(userId);
UserInfo userInfo = new UserInfo();
BeanUtil.copyProperties(userDTO, userInfo);
// 租户信息
TenantDTO tenantDTO = tenantService.findById(userDTO.getTenantId());
if (tenantDTO != null){
TenantInfo tenantInfo = BeanUtil.copyProperties(tenantDTO, TenantInfo.class);
userInfo.setTenant(tenantInfo);
}
return Result.success(userInfo);
}
}
1.4.3、启动入口及配置文件
1)springboot启动入口增加dubbo注解@EnableDubbo
/**
* 启动入口
*
* @Author: changjiang
* AcApplication
* @date: 2024/7/18 17:25 in beijing
*/
@EnableDubbo
@EnableJpaAuditing
@SpringBootApplication
public class AcApplication {
public static void main(String[] args) {
SpringApplication.run(AcApplication.class, args);
}
}
2)在springboot的application.yml文件中增加dubbo配置
其中dubbo.application.name配置的名称在dubbo中唯一,标识提供服务;
protocol为连接协议,dubbo推荐dubbo协议,传输层协议,理论上比feign要快;
port为本地服务提供端口-1为dubbo提供的机制,dubbo工程在启动时会占用一个端口, 端口设置为 -1 的主要原因是自动扫描并使用可用端口,Dubbo 会在启动时自动扫描可用的端口,并从默认端口(如 20880)开始递增,直到找到一个未被占用的端口为止。
除了解决端口冲突的问题,将 Dubbo 协议的端口设置为 -1 还具有其他一些作用。在某些测试或开发环境中,频繁地更换端口可能并不是很方便。通过将端口设置为 -1,开发者可以专注于其他配置和功能测试,而不需要担心端口冲突的问题。
dubbo:
application:
name: AcStarter
protocol:
name: dubbo
port: -1
registry:
address: zookeeper://127.0.0.1:2181
1.4.4、启动springboot
此时可以启动springboot了,启动时一定要将之前在docker中部署的各项服务启动起来。运行日志示例如下:
此时打开之前安装的zookeeper监控工具,可以看到我们的dubbo服务已经注册到zookeeper了 ,如下图:
2、总结
本文简单描述了完整的一个dubbo的发布过程,包括了sdk的发布,相应服务(生产者)的配置及发布,此时我们可以准备另外一个工程,准备调用该接口了,下文我们继续来总结服务调用者(消费者)如果调用该接口