共计 8218 个字符,预计需要花费 21 分钟才能阅读完成。
本文将基于 Dubbo Samples 示例演示如何疾速搭建并部署一个微服务利用。
背景
Dubbo 作为一款微服务框架,最重要的是向用户提供跨过程的 RPC 近程调用能力。如上图所示,Dubbo 的服务消费者(Consumer)通过一系列的工作将申请发送给服务提供者(Provider)。
为了实现这样一个指标,Dubbo 引入了注册核心(Registry)组件,通过注册核心,服务消费者能够感知到服务提供者的连贯形式,从而将申请发送给正确的服务提供者。
指标
理解微服务调用的形式以及 Dubbo 的能力
难度
低
环境要求
- 零碎:Windows、Linux、MacOS
- JDK 8 及以上(举荐应用 JDK17)
- Git
- Docker(可选)
入手实际
本章将通过几个简略的命令,一步一步教你如何部署并运行一个最简略的 Dubbo 用例。
1. 获取测试工程
在开始整个教程之前,咱们须要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在 apache/dubbo-samples 这个仓库中,以下这个命令能够帮你获取 Samples 仓库的所有代码。
git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git
2. 意识 Dubbo Samples 我的项目构造
在将 apache/dubbo-samples 这个仓库 clone 到本地当前,本大节将就仓库的具体组织形式做阐明。
.
├── codestyle // 开发应用的 style 配置文件
├── 1-basic // 根底的入门用例
├── 2-advanced // 高级用法
├── 3-extensions // 扩大应用示例
├── 4-governance // 服务治理用例
├── 10-task // Dubbo 学习系列示例
├── 99-integration // 集成测试应用
├── test // 集成测试应用
└── tools // 三方组件疾速启动工具
如上表所示,apache/dubbo-samples 次要由三个局部组成:代码格调文件、测试代码、集成测试。
- 代码格调文件是开发 Dubbo 代码的时候能够应用,其中包含了 IntelliJ IDEA 的配置文件。
- 测试代码即本教材所须要的核心内容。目前包含了 5 个局部的内容:面向初学者的 basic 入门用例、面向开发人员的 advanced 高级用法、面向中间件维护者的 extensions Dubbo 周边扩大应用示例、面向生产的 governance 服务治理用例以及 Dubbo 学习系列。本文将基于 basic 入门用例中最简略的 Dubbo API 应用形式进行解说。
- 集成测试是 Dubbo 的品质保证体系中重要的一环,Dubbo 的每个版本都会对所有的 samples 进行回归验证,保障 Dubbo 的所有变更都不会影响 samples 的应用。
3. 启动一个繁难的注册核心
从这一大节开始,将正式通过三个命令部署一个微服务利用。
从 背景 一节中可知,运行起 Dubbo 利用的一个大前提是部署一个注册核心,为了让本教程更易于上手,咱们提供了一个基于 Apache Zookeeper 注册核心的繁难启动器,如果您须要在生产环境部署注册核心,请参考生产环境初始化一文部署高可用的注册核心。
Windows:
./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
Linux / MacOS:
./mvnw clean compile exec:java -pl tools/embedded-zookeeper
注:须要开一个独立的 terminal 运行,命令将会放弃始终执行的状态。Docker:
docker run --name some-zookeeper --restart always -d zookeeper
在执行完上述命令当前,期待一会呈现如下图所示的日志即代表注册核心启动结束,能够继续执行后续工作。
4. 启动服务提供者
在启动了注册核心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,能够通过以下命令疾速拉起。
Windows:
./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.provider.Application"
Linux / MacOS:
./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.provider.Application"
注:须要开一个独立的 terminal 运行,命令将会放弃始终执行的状态。
在执行完上述命令当前,期待一会呈现如下图所示的日志(DubboBootstrap awaiting
)即代表服务提供者启动结束,标记着该服务提供者能够对外提供服务了。
[19/01/23 03:55:49:049 CST] org.apache.dubbo.samples.provider.Application.main() INFO bootstrap.DubboBootstrap: [DUBBO] DubboBootstrap awaiting ..., dubbo version: 3.2.0-beta.3, current host: 169.254.44.42
5. 启动服务消费者
最初一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的外围,为服务消费者提供调用服务提供者的桥梁。
Windows:
./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.client.Application"
Linux / MacOS:
./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.client.Application"
在执行完上述命令当前,期待一会呈现如下图所示的日志(hi, dubbo
),打印出的数据就是服务提供者解决之后返回的,标记着一次服务调用的胜利。
Receive result ======> hi, dubbo
延长浏览
1. 生产端是怎么找到服务端的?
在本用例中的步骤 3 启动了一个 Zookeeper 的注册核心,服务提供者会向注册核心中写入本人的地址,供服务消费者获取。
Dubbo 会在 Zookeeper 的 /dubbo/interfaceName
和 /services/appName
下写入服务提供者的连贯信息。
如下所示是 Zookeeper 上的数据示例:
[zk: localhost:2181(CONNECTED) 5] ls /dubbo/org.apache.dubbo.samples.api.GreetingsService/providers
[dubbo%3A%2F%2F30.221.146.35%3A20880%2Forg.apache.dubbo.samples.api.GreetingsService%3Fanyhost%3Dtrue%26application%3Dfirst-dubbo-provider%26background%3Dfalse%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26environment%3Dproduct%26generic%3Dfalse%26interface%3Dorg.apache.dubbo.samples.api.GreetingsService%26ipv6%3Dfd00%3A1%3A5%3A5200%3A3218%3A774a%3A4f67%3A2341%26methods%3DsayHi%26pid%3D85639%26release%3D3.1.4%26service-name-mapping%3Dtrue%26side%3Dprovider%26timestamp%3D1674960780647]
[zk: localhost:2181(CONNECTED) 2] ls /services/first-dubbo-provider
[30.221.146.35:20880]
[zk: localhost:2181(CONNECTED) 3] get /services/first-dubbo-provider/30.221.146.35:20880
{"name":"first-dubbo-provider","id":"30.221.146.35:20880","address":"30.221.146.35","port":20880,"sslPort":null,"payload":{"@class":"org.apache.dubbo.registry.zookeeper.ZookeeperInstance","id":"30.221.146.35:20880","name":"first-dubbo-provider","metadata":{"dubbo.endpoints":"[{\"port\":20880,\"protocol\":\"dubbo\"}]","dubbo.metadata-service.url-params":"{\"connections\":\"1\",\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"3.1.4\",\"side\":\"provider\",\"ipv6\":\"fd00:1:5:5200:3218:774a:4f67:2341\",\"port\":\"20880\",\"protocol\":\"dubbo\"}","dubbo.metadata.revision":"871fbc9cb2730caea9b0d858852d5ede","dubbo.metadata.storage-type":"local","ipv6":"fd00:1:5:5200:3218:774a:4f67:2341","timestamp":"1674960780647"}},"registrationTimeUTC":1674960781893,"serviceType":"DYNAMIC","uriSpec":null}
更多对于 Dubbo 服务发现模型的细节,能够参考服务发现一文。
2. 生产端是如何发动申请的?
在 Dubbo 的调用模型中,起到连贯服务消费者和服务提供者的桥梁是接口。
服务提供者通过对指定接口进行实现,服务消费者通过 Dubbo 去订阅这个接口。服务消费者调用接口的过程中 Dubbo 会将申请封装成网络申请,而后发送到服务提供者进行理论的调用。
在本用例中,定义了一个 GreetingsService
的接口,这个接口有一个名为 sayHi
的办法。
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java
package org.apache.dubbo.samples.api;
public interface GreetingsService {String sayHi(String name);
}
服务消费者通过 Dubbo 的 API 能够获取这个 GreetingsService
接口的代理,而后就能够依照一般的接口调用形式进行调用。得益于 Dubbo 的动静代理机制,这所有都像本地调用一样。
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java
// 获取订阅到的 Stub
GreetingsService service = reference.get();
// 像一般的 java 接口一样调用
String message = service.sayHi("dubbo");
3. 服务端能够部署多个吗?
能够,本大节将演示如何启动一个服务端 集群。
1)启动一个注册核心,能够参考入手实际中第 3 大节的教程
2)批改服务提供者返回的数据,让第一个启动的服务提供者返回 hi, dubbo. I am provider 1.
批改 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java
文件的第 25 行如下所示。
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java
package org.apache.dubbo.samples.provider;
import org.apache.dubbo.samples.api.GreetingsService;
public class GreetingsServiceImpl implements GreetingsService {
@Override
public String sayHi(String name) {return "hi," + name + ". I am provider 1.";}
}
3)启动第一个服务提供者,能够参考入手实际中第 4 大节的教程
4)批改服务提供者返回的数据,让第二个启动的服务提供者返回 hi, dubbo. I am provider 2.
批改 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java
文件的第 25 行如下所示。
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java
package org.apache.dubbo.samples.provider;
import org.apache.dubbo.samples.api.GreetingsService;
public class GreetingsServiceImpl implements GreetingsService {
@Override
public String sayHi(String name) {return "hi," + name + ". I am provider 2.";}
}
4)启动第二个服务提供者,能够参考入手实际中第 4 大节的教程
5)启动服务消费者,能够参考入手实际中第 5 大节的教程。屡次启动消费者能够看到返回的后果是不一样的。
在 dubbo-samples 中也提供了一个会定时发动调用的生产端利用org.apache.dubbo.samples.client.AlwaysApplication
,能够通过以下命令启动。
Windows:
./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.client.AlwaysApplication"
Linux / MacOS:
./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass="org.apache.dubbo.samples.client.AlwaysApplication"
启动后能够看到相似以下的日志,生产端会随机调用到不同的服务提供者,返回的后果也是远端的服务提供者感觉其后果。
Sun Jan 29 11:23:37 CST 2023 Receive result ======> hi, dubbo. I am provider 1.
Sun Jan 29 11:23:38 CST 2023 Receive result ======> hi, dubbo. I am provider 2.
Sun Jan 29 11:23:39 CST 2023 Receive result ======> hi, dubbo. I am provider 2.
Sun Jan 29 11:23:40 CST 2023 Receive result ======> hi, dubbo. I am provider 1.
Sun Jan 29 11:23:41 CST 2023 Receive result ======> hi, dubbo. I am provider 1.
4. 这个用例简单吗?
不,Dubbo 只须要简略的配置就能够实现稳固、高效的近程调用。
以下是一个服务提供者的简略示例,通过定义若干个配置就能够启动。
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/Application.java
// 定义所有的服务
ServiceConfig<GreetingsService> service = new ServiceConfig<>();
service.setInterface(GreetingsService.class);
service.setRef(new GreetingsServiceImpl());
// 启动 Dubbo
DubboBootstrap.getInstance()
.application("first-dubbo-provider")
.registry(new RegistryConfig(ZOOKEEPER_ADDRESS))
.protocol(new ProtocolConfig("dubbo", -1))
.service(service)
.start();
以下是一个服务消费者的简略示例,通过定义若干个配置启动后就能够获取到对应的代理对象,之后用户齐全不须要感知这个对象背地的简单实现,所有只须要和本地调用一样就行了。
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java
// 定义所有的订阅
ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
reference.setInterface(GreetingsService.class);
// 启动 Dubbo
DubboBootstrap.getInstance()
.application("first-dubbo-consumer")
.registry(new RegistryConfig(ZOOKEEPER_ADDRESS))
.reference(reference)
.start();
// 获取订阅到的 Stub
GreetingsService service = reference.get();
// 像一般的 java 接口一样调用
String message = service.sayHi("dubbo");
更多
本用例介绍了一个 RPC 近程调用的根底流程,通过启动注册核心、服务提供者、服务消费者三个节点来模仿一个微服务的部署架构。
下一个教程中,将就服务提供者和服务消费者别离都做了什么配置进行解说,从零通知你如何搭建一个微服务利用。
欢送在 https://github.com/apache/dubbo 给 Dubbo Star。
搜寻关注官网微信公众号:Apache Dubbo,理解更多业界最新动静,把握大厂面试必备 Dubbo 技能