Dubbo应用开发之基于xml的第一个Dubbo程序
这章主要介绍基于Spring的xml文件来开发第一个Dubbo的程序,为什么不直接使用springboot呢?主要是因为Springboot封装的太好了,导致我们看不到Dubbo内部的具体应用
环境搭建
创建一个父工程我这边就叫dubbo-study,然后对应的下面依赖这里我就不过多讲解了
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>
然后分别创建三个子模块,分别为dubbo-prod,dubbo-api,dubbo-consumer如下图
创建实体类
这里我们在dubbo-api中创建实体类
User
package org.example.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User implements Serializable {
private String name;
private String password;
}
创建Service接口
也是在dubbo-api中创建
UserService
package org.example.service;
public interface UserService {
public String login(String name, String password);
}
创建接口实现
接口实现我们在dubbo-prod中创建,这里也是只做简单实现即可,在这之前需要将dubbo-prod模块中的pom.xml文件导入dubbo-api的依赖
<dependency>
<groupId>org.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
UserServiceImpl
package org.example.service;
public class UserServiceImpl implements UserService {
@Override
public String login(String name, String password) {
System.out.println("name = " + name);
System.out.println("password = " + password);
return "login ok!";
}
}
编写配置文件
这里我们在dubbo-prod的resource目录下创建applicationContext-prod.xml文件,这里使用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-prod"/>
<!--这里配置网络端口-->
<dubbo:protocol name="dubbo" port="28080"/>
<!--这里配置的就是正常Spring对象-->
<bean id="UserService" class="org.example.service.UserServiceImpl"/>
<!--最后这里是配置对外提供的接口服务-->
<dubbo:service interface="org.example.service.UserService" ref="UserService"/>
</beans>
创建一个启动类
这里我们通过工厂的方式启动
package org.example;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.concurrent.CountDownLatch;
public class ProdMain {
public static void main(String[] args) throws InterruptedException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-prod.xml");
context.start();
new CountDownLatch(1).await();
}
}
下面是整个的项目结构,别把位置创建错了
启动日志
可以看到这里暴露出一个dubbo服务就是我们直接写的UserService,现在的话就需要我们的dubbo-consumer去调用这个dubbo服务,下面我们来完善dubbo-consumer
Consumer模块开发
首先我们想调用userService的login方法肯定是需要引入dubbo-api模块的
pom.xml
<dependency>
<groupId>org.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
创建配置文件
还是和之前的dubbo-prod一样,创建spring配置文件
applicationContext-consumer.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-consumer"/>
<!--定义我们需要调用的接口-->
<dubbo:reference interface="org.example.service.UserService" url="dubbo://222.20.83.141:28080/org.example.service.UserService"/>
</beans>
创建consumer启动类
ConsumerMan
package org.example;
import org.example.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class ConsumerMain {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-consumer.xml");
context.start();
UserService userService = context.getBean(UserService.class);
String res = userService.login("xiaohei", "1111");
System.out.println("res = " + res);
System.in.read();
}
}
运行结果
我们先启动dubbo-prod的main,然后再启动dubbo-consumer的main来测试是否调用成功,对应的日志能否输出
可以看到各自的模块都输出了日志,说明这次调用已经成功了,但是可以发现这块报错信息俩边都有是什么原因呢?
报错信息
ERROR org.apache.dubbo.qos.server.Server
Address already in use
问题产⽣的原因:
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-->
这里叮嘱jdk版本和dubbo版本一定要配套使用,不然会出现一系列问题!