17 | 异步RPC:压榨单机吞吐量

在我们知道RPC框架基础知识后,我们需要从RPC框架整体性能去考虑问题,例如怎么提升RPC框架的性能、稳定性、安全性、吞吐量,以及如何在分布式的场景下快速定位问题等。

影响RPC调用吞吐量的根本原因是什么?

处理RPC请求比较耗时,并且CPU大部分时间都在等待而非去计算,从而导致CPU利用率不高。RPC请求的耗时大部分是业务耗时,比如业务逻辑中有访问数据库执行慢SQL的操作,所以我们要看怎么能提升业务逻辑处理。

要提升吞吐量,关键就两个字:异步

服务调用端怎么异步?
对于调用端来说,向服务端发送请求消息与接受服务端发送过来的响应消息,这两个处理过程是两个完全独立的过程,这两个过程甚至在大多数情况下都不在一个线程中进行,也就是说,对于RPC框架,无论是同步调用还是异步调用,调用端的内部实现都是异步的。

调用端发送的每条信息都有一个唯一的消息标识,实际上调用端想服务端发送请求消息之前会创建一个Future,并会存储这个消息标识与这个Future的映射,动态代理所获得的返回值最终就是从这个Future中获取的,当收到服务端响应的消息时,调用端会根据响应消息的唯一标识,通过之前存储的映射找到对应的Future,将结果注入给那个Future,再进行一系列的处理逻辑,最后动态代理从Future中得到正确的返回值。

所谓同步调用,是指RPC框架在调用端的处理逻辑中主动执行了Future.get()方法,让动态代理等待返回值,而异步调用则是RPC框架没有主动执行这个方法,用户可以从请求上下文中得到这个Future,自己决定什么时候执行Future.get()方法。

Future模式的示意图如下。

服务提供方如何支持业务逻辑异步?
我们可以让RPC框架支持CompletableFuture,实现RPC调用在调用方和提供方之间完全异步。

CompletableFuture是Java 8原生支持的。如果RPC框架能够支持CompletableFuture,那发布一个RPC服务,服务接口定义的返回值是CompletableFuture对象,整个调用过程会分为以下几步:

  1. 服务调用方发起RPC请求,直接拿到返回值CompletableFuture对象,之后就不需要任何额外的与RPC框架相关的操作了,直接就可以进行异步处理。
  2. 在服务提供方业务逻辑中创建一个返回值CompletableFuture对象,之后服务端真正的业务逻辑完全可以在一个线程池中异步处理,业务逻辑完成之后再调用这个CompletableFuture对象的complete方法,完成异步通知。
  3. 服务调用方在收到服务提供方发送过来的响应之后,RPC框架再自动地调用服务调用方拿到的那个 返回值CompletableFuture对象的complete方法,这样一次异步调用就完成了。

RPC远程方法调用,有以下几种方式:

  1. sync,默认方式,这是在“方法”内部同步,但RPC框架还是异步处理的。
  2. future,RPC消费者得到future,自行决定何时获取返回结果。
  3. callback,RPC调用端不需要同步处理响应结果,可以直接返回,最后返回结果将会在回调线程中异步处理。
  4. oneway,调用端发起请求后不需要接收响应。

18 | 安全体系:如何建立可靠的安全体系?

RPC一般用于解决内部应用之间的通信,这里的“内部”是指应用都部署在同一个大局域网中,这样在RPC中,我们很少考虑像数据包篡改、请求伪造等恶意行为。

我们主要关注两种类型的安全场景:

  1. 调用方之间的安全保证。
  2. 服务发现中的安全保证。

我们可以引入一个授权平台,来对调用方的身份进行验证,调用方可以在授权平台上申请自己应用里面需要调用的接口,而服务方可以在授权平台上进行审批,只有服务提供方审批后,调用方才能够调用。

上面的设计方案,授权平台承担了公司内所有RPC请求的次数总和,当RPC请求量达到一定水平,授权平台会成为一个瓶颈点。

为了解决这个问题,我们可以将授权平台所做的事情转移到服务提供方。我们使用一种不可逆加密算法,例如HMAC算法。服务提供方应用里面放一个用于HMAC签名的私钥,在授权平台上用这个私钥为申请调用的调用方应用进行签名,这个签名生成的串就变成了调用方唯一的身份。服务提供方在收到调用方的授权请求之后,我们只需要验证这个签名更调用方应用信息是否对应的上就可以了。

服务提供方可以提供的安全校验方式:

  1. md5摘要校验
  2. 非对称加密算法
  3. OAuth2授权

为了避免同一个接口有多个应用做发布提供者,我们需要把接口跟应用绑定上,一个接口只允许有一个应用发布提供者,避免其他应用也能发布这个接口。

当注册中心收到服务提供方注册申请时,可以验证下请求过来的应用是否跟接口绑定的应用一样,只有相同才允许注册,否则就返回错误信息给启动的应用,从而避免假冒的服务提供者对外提供错误服务。

    作者:李潘    出处:http://wing011203.cnblogs.com/    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。