简介:
1、Dubbo:一款高性能,轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。架构如下图所示(摘自官网)
节点 | 说明 |
Consumer | 调用远程服务的服务消费方 |
Provider | 暴露服务的服务提供方 |
Container | 服务运行容器 |
Registry | 服务注册与发现的注册中心 |
Monitor | 统计服务的调用次数和调用时间的监控中心 |
0 | 服务容器负责启动,加载,运行服务提供者。 |
1 | 服务提供者在启动时,向注册中心注册自己提供的服务。 |
2 | 服务消费者在启动时,向注册中心订阅自己所需的服务。 |
3 | 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。 |
4 | 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。 |
5 | 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。 |
2.Zookeeper:Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,Dubbo官方推荐使用。执行流程如下图所示(摘自网站)
|
|
|
Dubbo与Zookeeper就简单介绍到这,详细请参考官方文档,下面开始进入实战练习。
1.安装Zookeeper
- 下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/,我下载是的3.5.5版本,选择3.5.5,之后下载
apache-zookeeper-3.5.5-bin.tar.gz
- 下载完后解压,目录结构如下:
- 修改配置文件,进入conf文件夹下,将zoo_sample.cfg重命名为zoo.cfg,zookeeper启动会默认加载这个配置文件,之后修改配置文件内容,设置数据及日志存储路径,并修改启动端口,避免与其他冲突,完整配置文件如下,主要配置的是dataDir数据存储路径、dataLogDir日志存储路径以及admin.serverPort服务启动端口(避免与其他端口冲突)。
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=D:\\Zookeeper-3.5.5\\data
dataLogDir=D:\\Zookeeper-3.5.5\\logs
# the port at which the clients will connect
clientPort=2181
admin.serverPort=8082
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
- 启动zookeeper,修改完配置文件后,进入到bin文件夹下,由于我是在window下,所以双击zkServer.cmd启动,启动成功如下图所示
启动后不要关闭窗口,最小化就行。
2.项目准备
新建一个SpringBoot项目dubbo-demo,包含三个子模块,分别为dubbo-demo-api、demo-demo-consumer及dubbo-demo-provider,目录结构如下:
其中dubbo-demo-consumer和dubbo-demo-provider都引入dubbo-demo-api,依赖关如下:
dubbo-demo-api | 公共api接口 |
dubbo-demo-consumer | 服务消费者 |
dubbo-demo-provier | 服务提供者 |
(1)dubbo-demo-api
-
pom文件内容如下:就是新建一个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 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/>
</parent>
<groupId>dubbo.demo.api</groupId>
<artifactId>dubbo-demo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo-demo-api</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.bulid.sourceEncoding>UTF-8</project.bulid.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
-
IDeviceService内容如下:简单定义了一个借口,包含一个sayHello()的方法
package dubbo.demo.api;
import java.io.Serializable;
public interface IDemoService {
Serializable sayHello();
}
(2)dubbo-demo-consumer
-
pom文件内容如下:引入dubbo-demo-api,dubbo,zookeeper依赖,顺便复习了下整合swagger,参考我的上一篇博客。
<?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>dubbo.demo.consumer</groupId>
<artifactId>dubbo-demo-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo-demo-consumer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.bulid.sourceEncoding>UTF-8</project.bulid.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入dubbo-demo-api依赖 -->
<dependency>
<groupId>dubbo.demo.api</groupId>
<artifactId>dubbo-demo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 引入swagger2依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- 引入dubbo zookeeper依赖-->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.5</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>
-
Swagger2Config内容如下:
package dubbo.demo.consumer.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableSwagger2
@Configuration
public class Swagger2Config {
@Bean
public Docket swaggerPluginConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo()) //Api文档描述
.select() //选择哪些路径和Api会生成文档
.apis(RequestHandlerSelectors.basePackage("dubbo.demo.consumer.controller")) //对指定路径下Api进行监控
.paths(PathSelectors.any()) //对所有路径进行监控
.build();
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("Dubbo Demo接口文档")
.description("API 接口文档")
.termsOfServiceUrl("http://localhost")
.version("1.0.0")
.contact(new Contact("takano","","xxxxxx@qq.com"))
.build();
}
}
-
DemoController内容如下:简单定义了一个请求方法sayHello(),通过@Reference来标记IDemoSerice接口的成员变量 demoService 是一个 dubbo 服务的引用,在sayHello()方法内的通过该接口向远端的服务提供者发起调用,客户端并没有实现IDemoService接口。其中参数version指定了服务的版本号,要与提供者提供的服务版本号一致。除此之外,@Reference还有许多其他的参数,请参考文档。
package dubbo.demo.consumer.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import dubbo.demo.api.IDemoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.Serializable;
@Api(value = "DemoController",tags = "dubbo-demo控制器")
@RestController
public class DemoController {
@Reference(version = "1.0.0")
private IDemoService demoService;
@ApiOperation(value = "测试方法",tags = "dubbo-demo控制器")
@GetMapping("/sayHello")
public Serializable sayHello(){
return demoService.sayHello();
}
}
-
启动文件内容如下:使用@EnableDubbo注解启用dubbo,它是@EnableDubboConfig和@DubboComponentScan的组合形式,用来扫描服务消费者,即用@Reference注解标注,对其进行组装初始化操作,最终完成服务引用工作。
package dubbo.demo.consumer;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDubbo
@SpringBootApplication
public class DubboDemoConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(DubboDemoConsumerApplication.class, args);
}
}
-
配置文件内容如下:
#服务启动端口
server.port=9001
#dubbo
#当前服务名
dubbo.application.name=dubbo-demo-consumer
#注册中心的协议和地址
dubbo.registry.protocol=zookeeper
dubbo.registry.address=localhost:2181
#连接监控中心
dubbo.monitor.protocol=registry
(3)dubbo-demo-provider
-
pom文件内容如下:引入dubbo-demo-api,dubbo,zookeeper依赖。
<?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>dubbo.demo.provider</groupId>
<artifactId>dubbo-demo-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo-demo-provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.bulid.sourceEncoding>UTF-8</project.bulid.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入dubbo-demo-api依赖 -->
<dependency>
<groupId>dubbo.demo.api</groupId>
<artifactId>dubbo-demo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 引入dubbo zookeeper依赖 -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.5</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>
-
DemoService内容如下:实现了demo-service-api的IDemoService接口,并实现了具体方法,使用“dubbo的@Service”注解配置服务提供者,暴露该服务。version指定了服务的版本号,interfaceClass指定了服务提供者实现的接口类,其他相关参数请查看文档。@Component声明该类是一个组件。
package dubbo.demo.provider.service;
import com.alibaba.dubbo.config.annotation.Service;
import dubbo.demo.api.IDemoService;
import org.springframework.stereotype.Component;
import java.io.Serializable;
@Service(version = "1.0.0",interfaceClass = IDemoService.class)
@Component
public class DemoService implements IDemoService {
@Override
public Serializable sayHello() {
return "Hello World";
}
}
-
启动文件内容如下:同样使用@EnableDubbo注解启动dubbo。
package dubbo.demo.provider;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDubbo
@SpringBootApplication
public class DubboDemoProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DubboDemoProviderApplication.class, args);
}
}
-
配置文件内容如下:
#服务启动端口
server.port=9002
#dubbo
#当前服务名
dubbo.application.name=dubbo-demo-provider
#注册中心的协议和地址
dubbo.registry.protocol=zookeeper
dubbo.registry.address=localhost:2181
#通信规则
dubbo.protocol.name=dubbo
dubbo.protocol.port=8365
#连接监控中心
dubbo.monitor.protocol=registry
3.测试
-
先启动服务提者dubbo-demo-provider,启动成功后,可以在zookeeper窗口下看到如下信息,说明在zookeeper中注册成功。
-
启动服务消费者dubbo-demo-consumer:同样,可以再zookeeper窗口下看到一条输出信息,说明在zookeeper中订阅成功。
-
由于我再服务消费者中整合了swagger,所以在浏览器中输入localhost:9001/swagger-ui.html,即可进入到api文档界面,测试暴露的api,也可以直接在浏览器输入localhost:9001/sayHello测试,结果如下图所示:
可以看到我们成功的远程调用了服务提供者,并返回结果。至此一个简单的dubbo+zookeeper入门案例就完成了。
如有错误请批评指正,我会及时修改,欢迎大佬指点,让我更快进步。