Quarkus 云原生java开发框架2: 远程调用

2020-05-24 16:51:53 浏览数 (1)

本篇主要介绍了 Quarkus 中的远程调用,项目的结构采用了传统的微服务模式。演示了如何编写符合 istio 的 Quarkus java 程序。

项目准备

创建一个项目 xyzshop,包括三个模块(按照 dubbo,spring cloud 示例的方式来组织):

  • xyzshop-api: facade 模块,包含接口,方法的声明
  • xyzshop-provider: 服务的具体实现
  • xyzshop-consumer: 服务调用方

本示例源码参见:https://github.com/cloudbeer/quarkus-demo-xyzdemo

facade 模块

facade 模块会被不同的模块引用,服务提供者来实现它,服务消费者通过引用它提供简化调用,这个包应该减小体积,去除非必要外部依赖。

本示例的facade 模块是 xyzshop-api, 里包含了实体类以及 OrderService 接口。

接口中可以约定接口的 restful 地址和配置。

代码语言:txt复制
package com.tencent.xyzshop;

import com.tencent.xyzshop.model.Goods;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/order")
@RegisterRestClient(configKey = "xyzshop-provider")
public interface OrderService {

    @POST
    @Produces("application/json")
    Goods save(Goods goods);

    @GET
    @Path("/id/{goodsId}")
    @Produces("application/json")
    Goods get(@PathParam long goodsId);


    @GET
    @Path("/hello")
    @Produces("text/plain")
    String sayHello();
}

为了能让 facade 模块能被注入,需要在编译的时候加入 CDI 索引。

在 pom.xml 中加入如下配置:

代码语言:txt复制
<build>
  <plugins>
    <plugin>
      <groupId>org.jboss.jandex</groupId>
      <artifactId>jandex-maven-plugin</artifactId>
      <version>1.0.7</version>
      <executions>
        <execution>
          <id>make-index</id>
          <goals>
            <goal>jandex</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

provider 模块

xyzshop-provider 比较简单,直接引用xyzshop-api,实现接口就可以了。

但为了让 Quarkus 能找到资源,需要在实现类中加入 @Path 标记。

代码语言:txt复制
@Path("/order")
public class OrderServiceImpl implements OrderService {
    @Override
    public Goods save(Goods goods) {
        goods.setId(100L);
        return goods;
    }

    @Override
    public Goods get(long goodsId) {
        Goods goods = new Goods();

        goods.setId(goodsId);
        goods.setPrice(12111);
        goods.setStock(20);
        goods.setTitle("腾讯黑鲨手机 M100");
        return goods;
    }
    
    @Override
    public String sayHello() {
        return "世界,你好。 Hello world";
    }
}

使用 mvn compile quarkus:dev 启动项目即可。

consumer 模块

需要在配置里指定服务的远程调用地址:

代码语言:txt复制
# 远程调用配置 
xyzshop-provider/mp-rest/url=http://localhost:8080
#xyzshop-provider/mp-rest/url=http://xyzshop-provider:8080
#xyzshop-provider/mp-rest/scope=javax.inject.Singleton

# 如果没有指定configKey 可以写下面的配置
# com.tencent.xyzshop.OrderService/mp-rest/url=http://xyzshop-provider:8080
# com.tencent.xyzshop.OrderService/mp-rest/scope=javax.inject.Singleton

部署的时候,我会把 k8s 的服务提供者部署成 xyzshop-provider,端口 8080。

但在本地开发的时候,用 http://localhost:8080 就好。

消费端的代码示例如下:

代码语言:txt复制
@Path("/open/order")
public class OrderController {

    @Inject
    @RestClient
    OrderService orderService;
    
    @GET
    @Path("/id/{goodsId}")
    @Produces(MediaType.APPLICATION_JSON)
    public Goods getGoods(@PathParam long goodsId){
        Goods goods =  orderService.get(goodsId);
        goods.setTitle("consumer 给你打8折:"   goods.getTitle()   ": "   goods.getPrice() * 0.8);
        return goods;
    }
}

同时启动,需要重新配置一下启动端口,在 application.properties 文件中:

代码语言:txt复制
quarkus.http.port=9080

启动的时候有个警告 debug 端口被占用,可以重新指定一下,请使用下面的命令启动:

代码语言:txt复制
mvn compile quarkus:dev -Ddebug=5006

rest-client 扩展已经在 rpc 中内置了 opentracing 的 header。istio 的调用链追踪可以完美支持。

0 人点赞