Spring Boot 2+Dubbo 学习系列2:搭建Spring Boot 2+Dubbo+Zookeeper集群
本项目使用当前(2018年7月)最新的官方正式版本实践,SpringBoot 2.0.3+dubbo-spring-boot-starter 0.2.0(即dubbo2.6.2)文章主要参考了Dubbo在Apache的项目主页的文档,还有Dubbo Spring Boot 工程在github的说明和例子一 项目结构项目结构项目名为dubbo,其下分3个模块base-interfac...
本项目使用当前(2018年7月)最新的官方正式版本实践,SpringBoot 2.0.3+dubbo-spring-boot-starter 0.2.0(即dubbo2.6.2)+zookeeper集群
文章主要参考了Dubbo在Apache的项目主页的文档,还有Dubbo Spring Boot 工程在github的说明和例子
文章写得较繁琐,重点在后半部分
项目GitHub地址:https://github.com/linshenkx/dubbo-springboot
一 项目结构
1 项目结构
项目名为dubbo,其下分3个模块base-interface,provider和consumer
- base-interface:基础接口模块,对应的即Dubbo服务
- provider:提供者
- consumer:消费者
2 模块功能
- 相互关系
主项目dubbo负责版本管理,provider和consumer都依赖base-interface接口,其中,provider提供了接口的具体实现,而consumer则调用了provider的实现,他们通过base-interface来确定使用规范(接口即契约) - 对应MVC关系
- base-interface就是service(接口,为提供实现)
- provider就相当于serviceImpl(service的实现类)
- 而concumer就是controller的角色.
- 框架依赖
- base-interface是单纯的服务接口集,不需要额外的依赖
- provider只提供服务实现,并不对外开放,只需对内提供服务调用就好,不需要spring-web支持
- 真正对外开放接口的就只有consumer
二 项目搭建
新建dubbo项目,在dubbo项目下添加base-interface,provider和consumer 3个模块
修改各个模块pom文件,组成项目结构,具体如下
0 编写根项目pom文件
注意,这里的packing是pom,子模块为jar
而且,子模块不定义groupId和version,即跟随主项目的groupId和version
另外,这里的插件是maven-deploy-plugin,并没有spring-boot-maven-plugin,因为一些子模块不需要(如base-interface)
<?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.linshen.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>dubbo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<!--引入的子模块-->
<modules>
<module>base-interface</module>
<module>provider</module>
<module>consumer</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<dubbo-springboot.version>0.2.0</dubbo-springboot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo-springboot.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-actuator</artifactId>
<version>${dubbo-springboot.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
1 创建base-interface模块
注意,这里没有引入spring-boot-maven-plugin插件,因为base-interface并不是一个真正的SpringBoot项目,也没有启动类
<?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>
<artifactId>base-interface</artifactId>
<name>base-interface</name>
<parent>
<groupId>com.linshen.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
</project>
2 创建provider模块
注意这里引入了actuator,非必须,也可以去掉的
<?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>
<artifactId>provider</artifactId>
<packaging>jar</packaging>
<name>provider</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.linshen.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<!-- 基础接口模块-->
<dependency>
<groupId>com.linshen.dubbo</groupId>
<artifactId>base-interface</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
3 创建consumer模块
consumer比provider多了web依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
4 将base-interface的Application引导类删除,其他无用的文件夹也删去(如resource)
5 修改provider的Application引导类,使其按非web应用运行
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(ProviderApplication.class)
.web(WebApplicationType.NONE)
.run(args);
}
}
至此,项目搭建完毕
三 功能实现
按照前文讲的,我们来实现最基础的问候功能(hello和goodbye)
1 在base-interface模块定义接口
如下,是一个很单纯的接口
public interface HelloService {
String sayHello(String name);
String sayGoodbye(String name);
}
文件结构如下:
2 在provider模块实现接口
如下,重点在于@Service
注解
@Service(
version = "${hello.service.version}",
application = "${dubbo.application.id}",
protocol = "${dubbo.protocol.id}",
registry = "${dubbo.registry.id}"
)
public class DefaultHelloService implements HelloService {
@Override
public String sayHello(String name) {
return "Hello "+name+" !";
}
@Override
public String sayGoodbye(String name) {
return "Goodbye "+name+" !";
}
application.yml文件如下:
注意,dubbo.registry.address请设置为真实zookeeper地址,我这里用的是zookeeper集群,具体可参考上一篇文章:SpringBoot2+Dubbo 学习系列1:使用Docker部署zookeeper
如果要简单的话可以像官方教程一样直接用广播,这样就不需要使用注册中心了(相应的,就不能指定dubbo.registry.protocol)
dubbo.registry.id = my-registry
dubbo.registry.address = N/A
另外注意这里给了dubbo.protocol的参数,因为provider是要通过dubbo协议来提供服务的(当然也可以用其他协议,这里不展开)
spring:
application:
name: linshen-dubbo-provider1
server:
port: 9090
dubbo:
registry:
protocol: zookeeper
address: ip:2181,ip:2182,ip:2183
id: lin-registry-1
protocol:
port: 12345
name: dubbo
id: dubbo
status: server
application:
name: linshen-dubbo-provider-name1
id: linshen-dubbo-provider-id1
qos-enable: true
qos-port: 22222
scan:
basePackages: com.linshen.dubbo.provider.service
hello:
service:
version: 1.0.0
3 在consumer模块编写controller
如下,重点在于@Reference
注意,下面的注解中在官方给的例子中是把registry换成url,如**url = “dubbo://localhost:12345”**来指定dubbo服务地址,这样下面yml文件就可以不用写dubbo.registry板块了(毕竟官方给的例子没有真正的注册中心),但我还是觉得使用一开始就使用zookeeper会更加自然,更容易理解
@RestController
public class HelloController {
@Reference(
version = "${hello.service.version}",
application = "${dubbo.application.id}",
registry = "${dubbo.registry.id}"
)
private HelloService helloService;
@GetMapping("hello/{name}")
public String sayHello(@PathVariable String name){
return helloService.sayHello(name);
}
@GetMapping("goodbye/{name}")
public String sayGoodbye(@PathVariable String name){
return helloService.sayGoodbye(name);
}
}
application.yml文件如下:
注意,这里我开启了actuator
spring:
application:
name: linshen-dubbo-consumer1
server:
port: 9091
hello:
service:
version: 1.0.0
dubbo:
application:
id: linshen-dubbo-consumer-id1
name: linshen-dubbo-consumer-name1
registry:
protocol: zookeeper
address: ip:2181,ip:2182,ip:2183
id: lin-registry-1
management:
endpoint:
dubbo-configs:
enabled: true
dubbo:
enabled: true
dubbo-services:
enabled: true
dubbo-properties:
enabled: true
dubbo-shutdown:
enabled: true
dubbo-references:
enabled: true
health:
dubbo:
status:
defaults: memory
extras: load,threadpool
endpoints:
web:
exposure:
include: '*'
需要注意的是,如果想要执行插件的jar打包,run启动等命令,需要先在根项目下运行mvn install
,注意不是mvn install-install
,否则会出现Failed to collect dependencies
问题
四 项目启动并测试
1 启动项目
启动provider,观察日志
如图是只是日志的一部分,其中红线为本机ip,蓝线为zookeeper所在主机ip,绿框为连接建立状态,从日志中也可以看出来,大概流程是先初始化客户端连接到zookeeper集群,在开通一个socket连接到一台zookeeper主机,接着就注册当前客户端信息(包含dubbo协议地址,服务信息等等,如截图),然后与注册中心建立连接完成,会话建立,状态更改为CONNECTED,然后注册中心会订阅此provider信息并通知所有订阅此provider信息的url.(这个流程只是从日志上粗略地看的,并不一定准确)
启动consumer,观察日志
前面和provider差不多,也是要把自身注册到zookeeper上的,注册完后还会多一些步骤,如下图
可以很直观地看到,注册完之后红线比蓝线要多得多,因为注册完之后就和zookeeper没什么事了,consumer从注册中心获得provider的信息后,便直接和provider建立连接,如图中所示,是通过NettyClient建立的连接,然后从注册中心查阅特定的dubbo service服务,然后建立引用关系
2 测试
使用PostMan测试如下(其实直接用链接打开就可以测试了…)
使用actuator查看如下
以简单地查看dubbo信息为例:
dubbo还开放了很多其他的endpoint来监控
如dubbo/configs查看配置信息,dubbo/references查看引用实体等.
需要注意的是,由于使用的是SpringBoot2,所以Actuator的基础路径是ip:port/actuator,以前只是ip:port而已,这一点在dubbo的官方说明里还没有更改,详情请看Spring Boot 2.0官方文档之 Actuator
其他
到目前来看监控还是很不方便的,特别是当服务较多的时候,我们都值得Spring Cloud的服务治理中心是有终端网页的,图形化界面,关系看起来非常直观,舒服,当然Dubbo也有,而且还原生支持中文,那就是Dubbo Admin,只不过它得另外部署,界面如下,部署放在下一篇文章说:Spring Boot 2+Dubbo 学习系列3:dubbo-ops 之 Dubbo Admin
五 文章参考
官方资料
dubbo官网:http://dubbo.apache.org
dubbo指南:http://start.dubbo.io/
dubboGitHub中文指南:https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/README_CN.md
相关博客
Spring Boot 2+gRPC 学习系列1:搭建Spring Boot 2+gRPC本地项目:https://blog.csdn.net/alinyua/article/details/83030149
Spring Boot 2+gRPC 学习系列2:搭建Spring Cloud +gRPC集群项目:https://blog.csdn.net/alinyua/article/details/83043823
Spring Boot 2+Dubbo 学习系列1:使用Docker部署zookeeper:https://blog.csdn.net/alinyua/article/details/81016734
Spring Boot 2+Dubbo 学习系列2:搭建Spring Boot 2+Dubbo+Zookeeper集群:https://blog.csdn.net/alinyua/article/details/81019925
Spring Boot 2+Dubbo 学习系列3:dubbo-ops 之 Dubbo Admin:https://blog.csdn.net/alinyua/article/details/81034023
GitHub项目
linshenkx/grpc-springboot-cloud(Spring Cloud +gRPC集群项目):https://github.com/linshenkx/grpc-springboot-cloud
linshenkx/grpc-springboot-lin(Spring Boot 2+gRPC本地项目):https://github.com/linshenkx/grpc-springboot-lin
linshenkx/spring-cloud-lin(Spring Boot 2整合Spring Cloud):https://github.com/linshenkx/spring-cloud-lin
更多推荐
所有评论(0)