API异步 & 同步的决策树

定义

Synchronous: A business transaction done in a single HTTP request/response exchange, which means that the HTTP response provides all data and associated resources resulting from the transaction

Asynchronous: A business transaction done over multiple HTTP request/response exchanges, which means that the initial HTTP response does not provide all data and associated resources resulting from the transaction, such data and resources can be obtained in subsequent interactions.

问题域

HTTP是一个同步协议:

  • 客户端和服务器端通过三次握手建立TCP连接。
  • 客户端发出请求,然后就等待响应。
  • 服务器端处理请求,并返回相应的状态码和数据。
  • 客户端完成接收,通过四次挥手,断开连接。

一些情况下,这种同步-blocking的通信方式,并不适合,比如以下的场景:

  • 复杂的服务编排, 比如一个请求需要通过调用多个downstream系统来更新或者创建一个资源(一个long running的http连接,可能会影响web server的性能或者API gateway的性能)。
  • 系统的可用性和稳定性, 比如一个后端系统,响应非常的慢,不稳定,甚至不可用(一个请求响应时间长短,直接影响到用户体验和转化率)。

方法域

异步模式:

  1. Web hook

web hook.png

  • 作为Consumer,需要提供成功或者失败的回调接口
  • 作为Provider,需要在一次接收到请求的时候,返回202;需要在resource成功或者失败创建后,调用callback接口,通知Consumer; 如果consumer提供的callback接口,返回失败的status code,需要设置一定的retry机制。

2.Asynchronous Notification

async-notification.png

什么时候使用异步呢?

  1. 根据HTTP操作来判断
  • HEAD, OPTIONS, CONNECT, TRACE等方法不能使用异步。
  • GET方法通常不使用异步,如果你的GET请求时间太长,可以考虑以下的这些方法改进:e.g: 将你的聚合根拆分为更细粒度的resource、引入分页、引入缓存、将你的GET操作改为POST(比如search)。
  • 其他的HTTP操作,比如PUT, POST, PATCH和DELETE能够异步就尽量异步。
  1. 根据响应时间来判断
  • 如果你的API操作,大于5秒的时间,就选择异步。
  • 如果你的API操作,大于1秒并小于5秒,应选择异步。
  • 如果你的API操作,小于1秒,则可以选择同步。
    P.S: 关于响应时间,根据用户行为调查,发现用户在等待大约5秒左右,就会失去耐心; 关于HTTP Client的timeout设置,浏览器,客户端JS库,服务器端http client库,他们的timeout设置都不一样,从20s到几分钟都有。

辅助决策树

Sync & Async decision tree .png

异步参考资料

[1]I cannot have my users wait on the API on finish
[2]http://jsonapi.org/recommendations/#asynchronous-processing