执行命令:mvn clean package -Dmaven.test.skip=true
,可能会遇到标签报错问题,调整下即可
然后在控制中心执行如下命令:
cd dubbo-admin-distribution/target //因为我们生成的版本为0.3.0,所以命令如下 java -jar dubbo-admin-0.3.0.jar
命令执行后dubbo服务启动,我们再将zookeeper服务启动后注册中心才可用:
我们访问地址http://localhost:7001/
,结果如下:
输入配置文件中的账号密码即可登录:
3 创建服务提供者模块
首先我们创建一个服务提供者,也就是服务生产者模块。
选择如下依赖即可:
1 pom.xml依赖
在pom.xml文件中配置坐标如下:
<dependencies> <!--导入Dubbo依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.3</version> </dependency> <!--导入zookeeper依赖--> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <!--引入zookeeper--> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> <!--解决 java.lang.NoClassDefFoundError: org/apache/curator/framework/recipes/cache/TreeCacheListener--> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.12.0</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.14</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-common</artifactId> <version>2.7.12</version> </dependency> </dependencies>
2 生产者Dubbo配置
在配置文件中进行Dubbo的配置
application.yml
server: port: 8081 # 服务端口 dubbo: application: name: provider-server # 注册服务应用名字 scan: base-packages: com.example.providerserver.service # dubbo服务发布者所在的包 registry: address: 127.0.0.1:2181 # zookeeper注册中心的地址 protocol: zookeeper protocol: name: dubbo port: 20880
3 接口服务代码配置
BookService
package com.example.providerserver.service; public interface BookService { String getBookByUserId(Integer id); }
BookServiceImpl
package com.example.providerserver.service; import org.springframework.stereotype.Component; import org.apache.dubbo.config.annotation.Service; @Service // dubbo的注解,可以被扫描到,在项目一启动就自动注册到注册中心 @Component public class BookServiceImpl implements BookService { @Override public String getBookByUserId(Integer id) { if(id==1){ return "tml很帅,他喜欢《围城》"; } return "查无此人"; } }
创建完成后整体布局如下:
4 创建服务消费者模块
首先我们创建一个服务消费者模块:
选择如下依赖即可:
1 pom.xml
在pom.xml中配置坐标如下,和生产者的依赖一样:
<dependencies> <!--导入依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.3</version> </dependency> <!--zkclient--> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <!--解决日志冲突--> <!--引入zookeeper--> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> <!--解决 java.lang.NoClassDefFoundError: org/apache/curator/framework/recipes/cache/TreeCacheListener--> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.12.0</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.14</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>provider-server</artifactId> <version>0.0.1-SNAPSHOT</version> <scope>compile</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies>
2 消费者Dubbo配置
在配置文件中进行Dubbo的配置
server: port: 8082 dubbo: application: name: consumer-server registry: address: 127.0.0.1:2181 # zookeeper注册中心的地址 protocol: zookeeper protocol: name: dubbo port: 20880
3 消费者接口代码配置
本来正常步骤是需要将服务提供者的接口打包,然后用pom文件导入,我们这里使用简单的方式,直接将服务的接口拿过来,路径必须保证正确,即和服务提供者相同
UserInfoService
package com.example.consumerserver.service; public interface UserInfoService { String getBook(); }
UserInfoServiceImpl
package com.example.consumerserver.service; import com.example.providerserver.service.BookService; import org.apache.dubbo.config.annotation.Reference; import org.springframework.stereotype.Service; @Service public class UserInfoServiceImpl implements UserInfoService { @Reference BookService bookService; //远程引用指定的服务,按照全类名进行匹配,看谁给注册中心注册了这个全类名 @Override public String getBook() { String bookName = bookService.getBookByUserId(1); System.out.println("在注册中心买到"+bookName); return bookName; } }
UserController
package com.example.consumerserver.controller; import com.example.consumerserver.service.UserInfoService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class UserController { @Resource UserInfoService userInfoService; @GetMapping("/userinfo") public String userinfo(){ String book= userInfoService.getBook(); return book; } }
创建完成后整体布局如下:
5 测试Dubbo远程RPC调用
按照如下步骤进行测试,首先我们整体看下模块划分如下:整体模块划分如下
1 开启zookeeper
直接双击zkServer.cmd
即可
2 打开dubbo-admin实现监控
我们先启动监控服务:
然后访问网址:http://localhost:7001/
3 启动服务者
然后我们启动服务者:
4 启动消费者
启动完服务者后,我们再启动下消费者:
5 页面请求测试
我们访问消费者的Controller,间接的调用远程服务:
同时观察dubbo-admin也体现出了注册信息:
服务关系:
总结一下
花了很长的篇幅和时间来学习关于分布式架构、集群、分布式理论,再到RPC调用方式,具体到Dubbo如何实现分布式的RPC调用。然后又以SpringBoot为核心,zookeeper为注册中心,Dubbo为RPC框架实践了一把Dubbo的调用方式,总算搞清楚了Dubbo的作用机制和使用方式,说白了RPC就是大家把服务都注册到一个注册中心,然后通过注册中心远程调用自己想要调用的资源,Dubbo让这看起来就像你在本地调用一样。其实Dubbo这种RPC调用和HTTP调用实现目的是类似的,但是Dubbo因为使用的是 TCP/IP是传输层协议,所以要比 HTTP协议包装一层一般而言要快些。有个比较形象的例子:
- HTTP,讲普通话,好处就是谁都听得懂,谁都会讲。
- RPC,讲黑话,好处是可以更精简、更加保密、更加可定制,坏处就是要求“说”黑话的那一方(client端)也要懂,而且一旦大家都说一种黑话了,换黑话就困难了
目前对于分布式的架构来说,用RPC方式的Dubbo比HTTP的会多一些,HTTP通常用作对外提供服务。