跟孙哥学java
代码结构及其术语解释
provider ---->功能提供者 consumer---->功能调用者(功能消费者) commons-api--->通用内容---->provider和consumer都使用的内容 entity,service接口 registry---->注册中心
其中provider与consumer可以调换的,就是一个模块既可以是功能调用者,也可以是功能提供者
软件版本
IDEA 2023.1.4 JDK 17 Maven 3.6.1 Dubbo 3.2.0
JDK与Dubbo版本对应问题
:::info
- JDK8 与 Dubbo3.1.x以前的版本匹配,在使⽤Zookeeper注册作为注册中⼼时,消费者会出现节点已经存在的异常 github.com/apache/dubb…
- JDK17 与 Dubbo3.1.x之前的版本搭配使⽤会出现如下问题
a. JDK9之后的深反射问题,需要通过JVM参数配置解决
-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
b. Dubbo3.2.0.beat4以前的版本使⽤的是Spring5.2.x 不能⽀持 JDK17会产⽣如下异常
Unsupported class file major version 61 【major 61 对应 17 】
版本需要升级到Dubbo3.2.0.beat5以上版本
:::
Spring与JDK版本对应关系
JDK Major版本 JDK n Major= 44+n JDK6----50 JDK17---61
环境搭建
1.父项目pom.xml
<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>
<!--可选依赖 zookeeper注册中⼼使⽤,⽬前不导⼊也没有问题,后续注册中⼼讲解时在添加即
可-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.8.0</version>
</dependency>
基于XML的Dubbo开发
API模块
主要是entity和service接口
public interface UserService {
boolean login(String name,String password);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private String password;
}
Provider模块
1.导入公共模块API
<dependency>
<groupId>org.huy</groupId>
<artifactId>dubbo-01-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
2.实现具体接口
public class UserServiceImpl implements UserService {
@Override
public boolean login(String name, String password) {
System.out.println("UserServiceImpl.login name :"+name+"password:"+password);
return false;
}
}
3.编写xml配置文件 注意:这里选择的dubbo是apache不是alibba
<?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服务唯一的名字-->
<dubbo:application name="dubbo-02-provider"/>
<!--指定协议:Dubbo的协议和端口 -1表示从20880开始选择可以用的端口-->
<dubbo:protocol name="dubbo" port="-1"/>
<!--注入spring-->
<bean id="userService" class="org.huy.service.UserServiceImpl"/>
<!--注册成dubbo服务-->
<dubbo:service interface="org.huy.service.UserService" ref="userService"/>
</beans>
4.启动服务
public class ProviderMain {
public static void main(String[] args) throws IOException, InterruptedException {
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("/applicationContext-provider.xml");
applicationContext.start();
// System.in.read();
new CountDownLatch(1).await();
}
}
启动服务
dubbo://192.168.1.108:20880/org.huy.service.UserService 这个就是我们服务的地址
Consumer模块的开发
1.导入API模块
<dependency>
<groupId>org.huy</groupId>
<artifactId>dubbo-01-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
2.编写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的唯一名字-->
<dubbo:application name="dubbo-03-consumer"/>
<!--注入实现类选择接口,地址-->
<dubbo:reference interface="org.huy.service.UserService" id="userService" url="dubbo://192.168.1.108:20880/org.huy.service.UserService">
<!--关闭运维监控的服务,因为这个端口和我们服务端的接口冲突了,因为两个在同一个电脑上-->
<dubbo:parameter key="qos.enable" value="true"/>
</dubbo:reference>
</beans>
:::info Qos=Quality of Service,qos是Dubbo的在线运维命令,可以对服务进⾏动态的配置、控制及查询, Dubboo2.5.8新版本重构了telnet(telnet是从Dubbo2.0.5开始⽀持的)模块,提供了新的telnet命令⽀ 持,新版本的telnet端⼝与dubbo协议的端⼝是不同的端⼝, 默认为22222。正是因为这个问题:如果在⼀台服务器⾥⾯,启动provider时22222端⼝,⽽consumer启动 时就会报错了。 解决方案就是--要么关闭在线运维,要么换一个端口 :::
<dubbo:parameter key="qos.enable" value="true"/> <!--是否开启在线运维命令 -->
<dubbo:parameter key="qos.accept.foreign.ip" value="false"/> <!--不允许其他机器的访问 -->
<dubbo:parameter key="qos.port" value="33333"/> <!--修改port-->
3.调用远端接口
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 login = userService.login("xiaohei", "12345");
System.out.println(login);
System.in.read();
}
}
客户端
服务端
JDK17存在的问题
这是 因为JDK9之后的深反射问题,需要通过JVM参数配置解决
-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
基于SpringBoot的方式使用Dubbo
主要区别是,由xml配置改到yml中,并且可以通过注解进行服务开发,服务引用