大家好,又见面了,我是你们的朋友全栈君。
环境:jdk1.8 springboot-2.2.1 dubbo-2.5.3 zookeeper-3.5.5 maven
构建工具:IDEA
我们知道,dubbo的本质就是一个远程服务调用的分布式框架。为了演示分布式架构的大致流程,我们项目里首先要建立对应的角色节点,即服务提供者、消费者以及公共接口服务,总体结构为:
dubbo_demo:是总项目 duboo-api:主要是实体类和接口服务 dubbo-customer:调用远程服务的服务消费方 duboo-provider:暴露服务的服务提供方
创建各个module的过程就不贴出来了,就是普通的springboot项目。需要注意的一点是在创建的时候每个module的GroupId要完全一致,否则在互相调用资源的时候会出现无法引入资源的问题。
一、dubbo_demo的pom.xml配置:
代码语言:javascript复制<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<zkclient.version>0.10</zkclient.version>
<dubbo.version>2.5.3</dubbo.version>
</properties>
<modules>
<!-- 主要放实体、接口、也可以放一些公用的工具类工程-->
<module>dubbo-api</module>
<!-- 服务消费者工程 -->
<module>dubbo-customer</module>
<!-- 服务提供者工程-->
<module>dubbo-provider</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>${zkclient.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
由于dubbo的jar中也引入了spring依赖,所以在引入dubbo依赖时,需要将spring相关排除掉,否则会和项目本身的spring冲突。
即上面pom中的:
代码语言:javascript复制 <exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
二、接下来是dubbo-api的pom.xml配置,这个就比较简单了,这里不用引入dubbo等依赖 :
代码语言:javascript复制<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.dubbo</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo-api</name>
<description>Demo project for Spring Boot</description>
<packaging>jar</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>dubbo-api</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在dubbo-api中新建service包,添加测试接口
代码语言:javascript复制package com.dubbo.api.service;
public interface TestService {
String sayHello(String name);
}
三、1.dubbo-provider的pom.xml配置:
代码语言:javascript复制<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.dubbo</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo-provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<zkclient.version>0.10</zkclient.version>
<dubbo.version>2.5.3</dubbo.version>
</properties>
<dependencies>
<dependency>
<groupId>com.dubbo</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- zookeeper客户端 -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>${zkclient.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.创建TestService的实现类TestServiceImpl:
代码语言:javascript复制package com.dubbo.provider.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.dubbo.api.service.TestService;
@Service(version = "1.0.0",timeout = 3000)
public class TestServiceImpl implements TestService {
@Override
public String sayHello(String name) {
return "哈哈哈,hello " name;
}
}
需要注意的是这里的@Service注解是dubbo的而不是spring的,不要用错了。
3.接下来在resources下创建spring-dubbo.xml文件,向zookeeper及dubbo注册并暴露服务
代码语言:javascript复制<?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://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--服务名称-->
<dubbo:application name="dubbo-provider"/>
<!-- 注册中心的ip地址 -->
<!-- 将服务提供者的地址暴露出去。这个过程通过zookeeper实现服务注册中心,进行注册暴露 -->
<dubbo:registry address="zookeeper://192.168.4.54:2181"/>
<!-- 扫描注解包路径,多个包用逗号分隔,不填pacakge表示扫描当前ApplicationContext中所有的类 -->
<dubbo:annotation package="com.dubbo.provider.impl"/>
<!-- 将服务提供者的端口号暴露出去 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- service implementation, as same as regular local bean -->
<bean id="testService" class="com.dubbo.provider.impl.TestServiceImpl"/>
<!-- 将服务提供者需要对外提供的功能暴露出去 -->
<dubbo:service interface="com.dubbo.api.service.TestService" ref="testService"/>
</beans>
4.application.yml 中配置服务端口号:
代码语言:javascript复制server:
port: 9010
四、1.dubbo-customer的pom.xml配置文件:
代码语言:javascript复制<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.dubbo</groupId>
<artifactId>customer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>customer</name>
<description>Demo project for Spring Boot</description>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<zkclient.version>0.10</zkclient.version>
<dubbo.version>2.5.3</dubbo.version>
</properties>
<dependencies>
<dependency>
<groupId>com.dubbo</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>${zkclient.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>customer</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.创建消费端服务调用类 TestController
代码语言:javascript复制package com.dubbo.customer.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.dubbo.api.service.TestService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Reference(version = "1.0.0",timeout = 300)
private TestService testService;
@RequestMapping("/sayHello")
public String sayHello(@RequestParam String name) {
System.out.println("name==" name);
System.out.println("testService==" testService);
return testService.sayHello(name);
}
}
3.同样在resources下创建spring-dubbo.xml文件,配置注册中心地址等信息
代码语言:javascript复制<?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://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="dubbo-consumer"/>
<!-- 注册中心的ip地址 -->
<dubbo:registry address="zookeeper://192.168.4.54:2181"/>
<!-- 扫描注解包路径,多个包用逗号分隔,不填pacakge表示扫描当前ApplicationContext中所有的类 -->
<dubbo:annotation package="com.dubbo.customer.controller"/>
<!-- use dubbo protocol to export service on port 20880 -->
<dubbo:protocol name="dubbo" port="20880"/>
<dubbo:reference id="testService" check="false" interface="com.dubbo.api.service.TestService"/>
</beans>
4.application.yml 中配置服务端口号:
代码语言:javascript复制server:
port: 9011
五、接下来就可以测试服务提供者和消费者是否能成功注册到dubbo上了,先启动放置dubbo-admin的tomcat以及zookeeper,再依次启动dubbo-provider和dubbo-customer服务,登录dubbo-admin控制台页面,可以看到provider和customer都已成功注册。
访问消费者服务customer也能成功调用provider
至此,所有流程算是成功了。下面说一下过程中遇到的一些问题。
构建过程中遇到的问题
1.最初在provider中调用com.dubbo.api.service.TestService类时一开始报错ClassNotFound,提示在dubbo-provider中 找不到TestService,虽然我们在pom中已经引入了要调用的项目配置。经过各种调试,因为被调用者是dubbo-api module中的类, 最终我这里的解决方法是重新clean并编译一遍dubbo-api
然后执行Rebuild Project
再次强调,如果要想各个module相互调用,它们的GroupId必须是一致的。
2.通过执行以上操作,虽然在IDEA中没问题了,但是当我将dubbo-customer打成jar放到其它机器上运行时,又报了空指针异常,经调试发现原来是这里通过@Reference引入的testService为null
解决方法:
在被依赖项目dubbo-api的pom.xml文件spring-boot-maven-plugin依赖中加入配置<classifier>exec</classifier>,即:
代码语言:javascript复制 <build>
<finalName>dubbo-api</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
</build>
另外,打包顺序也要注意,要先编译被依赖项dubbo-api,再编译dubbo-customer。
参考文章:
https://blog.csdn.net/qq_19419233/article/details/86678035#dubbo_1
https://www.cnblogs.com/gaopengfirst/p/9555240.html
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/127505.html原文链接:https://javaforall.cn