REST Service 开发 - 客户端
【摘要】REST Service 的客户端开发是比较简单的,每种框架都提供了各种访问服务端的实现,如 Apache Httpclient, JAX-RS2 client,Feign Client。本文重点罗列客户端异步服务编排技术,服务端异步技术,这些将使得你的云服务更加健壮、高效。
1、Rest 客户端概述
Restful Sevice 客户端没有什么特别,普通 HTTP 访问协议即可。从 Apache Httpclient 开始,出现了各种方便使用的客户端,如基于 build pattern 设计的 JAX-RS2 client;基于 template 设计的 Feign。这些技术对于软件设计者都是必须掌握的实用的方法。
1.1 Apache Httpclient
Apache Httpclient 是采用 Socket 的 stream 访问 HTTP 应用,高效是它的特点。Apache HttpClient 分为新版和旧版,参见: http://hc.apache.org/httpcomponents-client-ga/
cxf 演示程序使用的是旧版,maven、与程序见 domo 代码:
1.2 JAX-RS2.0 Client
为了简化 REST 客户端开发,RS2.0 提供 javax.ws.rs.client 包,它提供了构建 REST 客户端需要的两个类 ClientBuilder
和 Entity<T>
。这个包不仅定义了同步访问客户端标准,也包括异步访问客户端的标准。javax.ws.rs.client API
让我们看标准提供的一段代码,创建一个 REST 客户端访问 REST 服务:
Client client = ClientBuilder.newClient();
Response res = client.target("http://example.org/hello").request("text/plain").get();
简单直接。ClientBuilder -> Client -> WebTarget -> Invocation.Builder/SyncInvoker -> Response
。这种链式反应过程,很易于理解。
上述代码标准与风格,无论 cxf 或 jersey 都是支持的。详细:
1.3 Feign HttpApi
2、异步访问 REST 服务
2.1 同步与异步 web 服务的区别
要知道什么是异步模式,就先要知道什么是同步模式,先看最典型的同步模式:
上图所示,请求处理线程会在Call了之后等待Return,自身处于阻塞状态。这也是绝大多数Web服务器的做法,一般来说这样做也够了,为啥?一来“长时间处理服务”调用通常不多,二来请求数其实也不多。要不是这样的话,这种模式会出现什么问题呢?——会出现的问题就是请求处理线程的短缺!因为请求处理线程的总数是有限的,如果类似的请求多了,所有的处理线程处于阻塞的状态,那新的请求也就无法处理了,也就所谓影响了服务器的吞吐能力。要更加好地发挥服务器的全部性能,就要使用异步模式。
2.2 Reactive Jersey Client API
原文:Chapter 6. Reactive Jersey Client API
问题陈述
旅游代理编排服务(下图):
如何编排(Orchestration)这些服务呢?
解决方案
- 按顺序编排,同步访问;
- 按服务之间数据依赖编排,使用 JAX-RS2.0 异步访问机制;
- 使用 RxJava 响应式编排。
同步编排如下:
异步编排如下:
请实现不同方式的编排。(官网案例)
2.3 异步服务端
JAX-RS2.0 提供 javax.ws.rs.container 包,规范 REST 服务对容器异步服务的支持。其中,最重要的接口是 AsyncResponse 和 CompletionCallback、ConnectionCallback 接口。
其中:
- AsyncResponse:异步返回响应
- CompletionCallback:任务完成或失败的回调
- ConnectionCallback:客户连接丢失
Jersey 和 CXF 都由不错的支持:
注意:服务端异步支持受服务容器限制,tomcat 和 jetty 都是不错的选择。
3、Feign-Hystrix 云服务访问
4、小结
尽管远端访问不难,但是异步编排是非常重要的技术。从我们罗列的资料来看,完全掌握也不是一件容易的事情。