<?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>io.vertx.howtos</groupId>
<artifactId>service-proxy-howto</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<vertx.version>5.0.0.CR2</vertx.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-stack-depchain</artifactId>
<version>${vertx.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-codegen</artifactId>
<classifier>processor</classifier>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-service-proxy</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<mainClass>io.vertx.howtos.ebservice.BeersApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
使用 Vert.x Service Proxy 构建事件总线 RPC 服务
本文档将向你展示如何使用 Vert.x Service Proxy 模块快速搭建基于 Event Bus 的 RPC 微服务。 你将深刻体会到:通过简单的 Java 接口声明,即可在事件总线上轻松定义与消费强类型异步服务。
你将构建什么
你将构建一个 Vert.x 应用程序,发布并调用 BarmanService —— 这是一个在 Event Bus 上运行、负责调制啤酒并管理顾客账单的远程服务。
我们将部署两个 Verticle:
* BarmanVerticle:负责提供并暴露该服务的服务端;
* DrunkVerticle:负责消费调用该服务的客户端。
前置要求
-
文本编辑器或 IDE
-
Java 11 或更高版本
-
Maven
创建工程项目
这是你应该使用的 pom.xml 文件内容:
pom.xml必须引入带有 processor 分类器的 vertx-codegen 以及 vertx-service-proxy。
声明 BarmanService 接口契约
首先,我们定义服务契约接口。底层代码生成器会自动分析该接口,生成 Event Bus 消息分发处理器以及客户端代理代理类(Proxy):
package io.vertx.howtos.ebservice.beers;
import io.vertx.codegen.annotations.ProxyGen;
import io.vertx.codegen.annotations.VertxGen;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
@VertxGen
@ProxyGen (1)
public interface BarmanService {
Future<Beer> giveMeARandomBeer(String customerName); (2)
Future<Integer> getMyBill(String customerName); (3)
void payMyBill(String customerName); (4)
static BarmanService createProxy(Vertx vertx, String address) { (5)
return new BarmanServiceVertxEBProxy(vertx, address);
}
}
服务接口的必须遵循以下规则:
. 添加 @ProxyGen 注解告知代码生成器;
. 方法异步回调必须以 Handler<AsyncResult<T>> 或返回 Future<T> 作为结尾。
服务端与客户端 Verticle 实现
服务端实现
BarmanVerticle 创建服务实现类实例,并使用自动生成的 BarmanServiceVertxEBProxy 将其绑定到 Event Bus 地址上:
package io.vertx.howtos.ebservice;
import io.vertx.core.Future;
import io.vertx.core.VerticleBase;
import io.vertx.core.eventbus.MessageConsumer;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.WebClient;
import io.vertx.howtos.ebservice.beers.BarmanService;
import io.vertx.howtos.ebservice.beers.impl.BarmanServiceImpl;
import io.vertx.serviceproxy.ServiceBinder;
public class BarmanVerticle extends VerticleBase {
@Override
public Future<?> start() {
BarmanService service = new BarmanServiceImpl(WebClient.create(vertx)); (1)
MessageConsumer<JsonObject> consumer = new ServiceBinder(vertx) (2)
.setAddress("beers.services.myapplication") (3)
.register(BarmanService.class, service);(4)
return consumer.completion();
}
}
客户端消费实现
DrunkVerticle 直接使用自动生成的工厂方法获取代理对象,像调用本地普通 Java 方法一样发起跨组件异步通信:
package io.vertx.howtos.ebservice;
import io.vertx.core.Future;
import io.vertx.core.VerticleBase;
import io.vertx.howtos.ebservice.beers.BarmanService;
public class DrunkVerticle extends VerticleBase {
@Override
public Future<?> start() {
BarmanService barmanService = BarmanService.createProxy(vertx, "beers.services.myapplication"); (1)
return barmanService.giveMeARandomBeer("homer") (2)
.onSuccess(beer1 -> System.out.println("My first beer is a " + beer1.getName() + " and it costs " + beer1.getPrice() + "€")) (3)
.compose(v -> vertx.timer(1500))
.compose(v -> barmanService.giveMeARandomBeer("homer")) (4)
.onSuccess(beer2 -> System.out.println("My second beer is a " + beer2.getName() + " and it costs " + beer2.getPrice() + "€")) (5)
.compose(v -> barmanService.getMyBill("homer")) (6)
.onSuccess(bill -> {
System.out.println("My bill with the bar is " + bill + "€");
barmanService.payMyBill("homer"); (7)
});
}
}
运行应用程序
通过 Maven 编译运行:
mvn compile exec:java
控制台将输出酒保服务收到订单、调制啤酒以及酒客结账的完整 Event Bus 交互日志。
总结
本文档展示了:
-
使用
@ProxyGen声明强类型异步服务契约; -
利用代码生成技术透明屏蔽 Event Bus 消息序列化与地址路由细节;
-
构建松耦合且类型安全的微服务通信架构。