Dubbo3技术一套通之直连开发初探

结构术语

在深入学习 Dubbo 开发之前,我们首先需要对其结构和相关的专业术语有所了解。Dubbo 主要在微服务领域得到广泛应用,所以了解它的结构尤为关键。请参考下面的描述: 如图所示,commons-api模块作为一个基础模块,其主要负责定义实体类、服务接口等核心元素 。这些定义不仅为服务提供者所使用,也为服务消费者所依赖。而 provider 模块,如其名字所示,是服务的提供者 。它实现了 commons-api模块中的服务接口,并对外发布这些服务。相对地,consumer模块作为服务的消费者,负责对 provider 发起远程服务调用 。 这里还有一个可选组件,即 register。如果没有这个组件,consumer 会直接与 provider 通讯进行服务调用。但如果引入了 register,事情就变得更加有趣:consumer 不再直接与 provider 交互,而是首先查询 register 以获取 provider 的集群地址,然后基于这些地址发起服务调用。 总的来说,这整个结构为微服务的开发和交互提供了一个灵活而高效的框架,使得服务的提供和消费变得既简单又高效

版本选择

此教程的版本搭配主要使用JDK8+Dubbo3.2.0,部分章节使用JDK17与Dubbo2.x

注意事项

  • JDK8+Dubbo3.1.x及之前版本使用Zookeeper做注册中心,消费者会出现节点已存在异常
  • JDK17与Dubbo3.2.0-beta4版本不兼容
    • 原因:Dubbo-3.2.0-beta4及之前版本都是使用的Spring5.2.x,但是Spring5.2.x只支持JDK8-JDK15
    • 解决方案:升级为Dubbo-3.2.0-beta5,beta5版本使用的是Spring5.3.x,Spring5.3.x支持JDK8-JDK21
  • JDK9+出现的深反射问题,项目启动会有异常
    • 解决方案:添加下面的JVM参数即可
shell 复制代码
-Dio.netty.tryReflectionSetAccessible=true
--add-opens
java.base/jdk.internal.misc=ALL-UNNAMED
--add-opens
java.base/java.nio=ALL-UNNAMED
--add-opens
java.base/java.lang=ALL-UNNAMED
--add-opens 
java.base/java.math=ALL-UNNAMED

直连开发

直连开发是一种不通过注册中心,让消费者(consumer)与提供者(provider)直接进行通信的方法。为了便于更深入地理解Dubbo与SpringBoot的整合以及注解的使用,本章节将采用Spring配置文件的方式进行说明和处理

项目结构

如下图所示的项目结构包括api模块、consumer模块和provider模块。所有的依赖管理均交由父级pom统一处理。在这种结构中,api模块负责提供实体类并定义服务接口;provider模块实现了api模块中定义的服务接口,并发布这些服务;consumer模块则负责远程调用这些已发布的服务

父POM依赖管理

xml 复制代码
<?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>

    <groupId>com.aomsir</groupId>
    <artifactId>dubbo-lession</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>dubbo-01-api</module>
        <module>dubbo-02-provider</module>
        <module>dubbo-03-consumer</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.32</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.9</version>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>3.2.0</version>
        </dependency>
    </dependencies>
</project>

模块代码与演示

API模块

实体类

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User implements Serializable {
    private String name;
    private String password;
}

服务接口

java 复制代码
public interface UserService {
    public boolean login(String username, String password);
}

Provider模块

服务实现

java 复制代码
public class UserServiceImpl implements UserService{
    @Override
    public boolean login(String username, String password) {
        System.out.println("UserServiceImpl.login,name:" + username + "password:" + password);
        return false;
    }
}

spring配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!--全局唯一的应用名-->
    <dubbo:application name="dubbo-02-provider">
        <!--关闭qos启动-->
        <dubbo:parameter key="qos.enable" value="false" />
    </dubbo:application>

    <!--网络通信协议与端口-->
    <dubbo:protocol name="dubbo" port="-1" serialization="hessian2"/>

    <!--将UserService服务实现类注册到容器-->
    <bean id="userService" class="com.aomsir.service.UserServiceImpl" />

    <!--Dubbo发布服务-->
    <dubbo:service interface="com.aomsir.service.UserService" ref="userService" />
</beans>

启动类

java 复制代码
public class ProviderMain {
    public static void main(String[] args) throws InterruptedException {

        // 创建工厂并启动
        ClassPathXmlApplicationContext applicationContext
                = new ClassPathXmlApplicationContext("applicationContext-provider.xml");
        applicationContext.start();
        
        // 阻塞
        new CountDownLatch(1).await();
    }
}

启动输出

下图展示了启动日志,从中我们可以看到Provider已经对外发布了我们的UserService服务,发布地址为dubbo://198.18.0.1:20880/com.aomsir.service.UserService?anyhost=true&application=dubbo-02-provider&background=false&bind.ip=198.18.0.1&bind.port=20880&deprecated=false&dubbo=2.0.2&dynamic=true&executor-management-mode=isolation&file-cache=true&generic=false&interface=com.aomsir.service.UserService&methods=login,login&pid=80310&prefer.serialization=hessian2&qos.enable=false&release=3.2.0&serialization=hessian2&side=provider&timestamp=1691391591286。 从这个地址我们可以提取出以下信息:IP地址是198.18.0.1 ,端口号是20880 ,服务的全类名为com.aomsir.service.UserService 。此外,我们还看到了采用的序列化方案为hessian2,这是一种由Dubbo团队优化过的序列化方案,旨在提高序列化的效率和性能。 这个日志的输出对我们理解服务是如何发布,以及如何配置服务发布的参数都非常有帮助。通过这个日志,我们可以了解到服务发布的一些关键信息,包括服务地址、服务名、使用的序列化方案等,这都是我们在进行服务开发和调试时需要关注的重要信息

Consumer模块

spring配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <dubbo:application name="dubbo-03-consumer" />

    <!--远端服务接口,id,地址-->
    <dubbo:reference interface="com.aomsir.service.UserService" id="userService" url="dubbo://198.18.0.1:20880/com.aomsir.service.UserService?serialization=hessian2" />
</beans>

启动类

java 复制代码
public class ClientApplication {

    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext applicationContext
                = new ClassPathXmlApplicationContext("applicationContext-consumer.xml");

        UserService userService = (UserService) applicationContext.getBean("userService");
        boolean ret = userService.login("Aomsir", "123456");
        
        System.out.println("ret = " + ret);

        System.in.read();
    }
}

发起调用

细节分析

Provider模块配置文件

在Provider模块的配置文件中,我们为Dubbo设置了应用名称并选择关闭了QoS功能。此配置还明确了整体通信的协议 、所使用的序列化方法和端口号。默认情况下,端口号被设置为20880。若将其设置为-1,系统将从20880开始逐一增加,直至找到一个可用的端口。此外,配置确保服务被注入到容器中,并从容器中发布该服务,使其对外可用

Consumer模块配置文件

在Consumer模块的配置文件中,我们为Dubbo指定了应用名称。此外,我们详细配置了远程服务的诸如id、接口的全类名和地址等关键信息。这样的配置确保了程序能够从IoC容器中准确而轻松地获取和调用所需的远程服务的地址进而发起调用

注意

在Spring的配置文件中,我们必须引入Dubbo的命名空间以确保正确的配置和功能性。若Consumer的地址或端口发生任何变化,Provider的配置文件必须被立即更新。否则,Provider将无法与Consumer建立正确的通信,从而导致远程调用失败

注意观察两个配置文件的标签嗷,这些标签在整个SpringBoot的时候都会变成注解配置嗷

参考文献

相关推荐
掘金-我是哪吒12 小时前
分布式微服务系统架构第156集:JavaPlus技术文档平台日更-Java线程池使用指南
java·分布式·微服务·云原生·架构
FPGA之旅12 小时前
FPGA从零到一实现FOC(一)之PWM模块设计
fpga开发·dubbo
微风粼粼13 小时前
程序员在线接单
java·jvm·后端·python·eclipse·tomcat·dubbo
DavidSoCool14 小时前
RabbitMQ使用topic Exchange实现微服务分组订阅
分布式·微服务·rabbitmq
掘金-我是哪吒16 小时前
分布式微服务系统架构第158集:JavaPlus技术文档平台日更-JVM基础知识
jvm·分布式·微服务·架构·系统架构
Kookoos17 小时前
ABP VNext + Tye:本地微服务编排与调试
微服务·云原生·架构·tye
guojl21 小时前
Ribbon原理和源码分析
spring cloud·微服务
掘金-我是哪吒1 天前
分布式微服务系统架构第157集:JavaPlus技术文档平台日更-Java多线程编程技巧
java·分布式·微服务·云原生·架构
掘金-我是哪吒1 天前
分布式微服务系统架构第155集:JavaPlus技术文档平台日更-Java线程池实现原理
java·分布式·微服务·云原生·架构
Code季风2 天前
深入理解微服务中的服务注册与发现(Consul)
java·运维·微服务·zookeeper·架构·go·consul