一、REST or RPC ? 1.1 REST & RPC
微服务之间的接口调用通常包含两个部分,序列化和通信协议。常见的序列化协议包括json、xml、hession、protobuf、thrift、text、bytes等;通信比较流行的是http、soap、websockect,RPC通常基于TCP实现,常用框架例如dubbo,netty、mina、thrift。
REST:严格意义上说接口很规范,操作对象即为资源,对资源的四种操作(post、get、put、delete),并且参数都放在URL上,但是不严格的说Http+json、Http+xml,常见的http api都可以称为Rest接口。
RPC:即我们常说的远程过程调用,就是像调用本地方法一样调用远程方法,通信协议大多采用二进制方式。
1.2 HTTP vs 高性能二进制协议HTTP相对更规范,更标准,更通用,无论哪种语言都支持HTTP协议。如果你是对外开放API,例如开放平台,外部的编程语言多种多样,你无法拒绝对每种语言的支持,相应的,如果采用HTTP,无疑在你实现SDK之前,支持了所有语言,所以,现在开源中间件,基本最先支持的几个协议都包含RESTful。
RPC协议性能要高的多,例如Protobuf、Thrift、Kyro等,(如果算上序列化)吞吐量大概能达到http的二倍。响应时间也更为出色。千万不要小看这点性能损耗,公认的,微服务做的比较好的,例如,netflix、阿里,曾经都传出过为了提升性能而合并服务。如果是交付型的项目,性能更为重要,因为你卖给客户往往靠的就是性能上微弱的优势。
所以,最佳实践一般是对外REST,对内RPC,但是追求极致的性能会消耗很多额外的成本,所以一般情况下对内一般也REST,但对于个别性能要求较高的接口使用RPC。
二、案例结构这里假设有两个服务,一个ClinetService和一个PaymentService,其中PaymentService有两部分,一部分是基于REST风格的WebApi部分,它主要是负责一些对性能没有要求的查询服务,另一部分是基于TCP的RPC Server,它主要是负责一些对性能要求高的服务,比如支付和支出等涉及到钱的接口。假设User在消费ClientService时需要调用PaymentService根据客户账户获取Payment History(走REST)以及进行交易事务操作(走RPC)。
三、REST调用 3.1 一个好用的REST Client : WebApiClient使用过Java Feign Client的人都知道,一个好的声明式REST客户端可以帮我们省不少力。在.NET下,园子里的大大老九就写了一款类似于Feign Client的REST Client:WebApiClient。WebApiClient是开源在github上的一个httpClient客户端库,内部基于HttpClient开发,是一个只需要定义C#接口(interface),并打上相关特性,即可异步调用http-api的框架 ,支持.net framework4.5+、netcoreapp2.0和netstandard2.0。它的GitHub地址是:https://github.com/dotnetcore/WebApiClient
如何安装?
NuGet>Install-Package WebApiClient-JIT
3.2 使用实例:走API GatewayStep1.定义HTTP接口
[HttpHost(":5000")] public interface IPaymentWebApi: IHttpApi { // GET api/paymentservice/history/edisonzhou // Return 原始string内容 [HttpGet("/api/paymentservice/history/{account}")] ITask<IList<string>> GetPaymentHistoryByAccountAsync(string account); }