服务端开发时经常会用到“异步”这个概念。要注意你说的是哪种异步,否则可能会导致沟通的误会,甚至设计的失误。
1.
客户端和服务端之间的异步交互。 客户端发出一个业务请求,服务端在这个业务请求完成之前就发出响应,然后再在后台进行处理。
2.
服务端处理请求时,在内部使用异步模式。 比如收到请求时将它丢给一个线程池来处理。
请求处理中可以同时使用这两种异步,也可以只用一种。
对于http来说,一般是“交互要同步”,但“服务端内部处理要异步”。I/O线程收到请求后,立即丢给worker线程池处理;但在worker线程处理完请求、回送响应之前,客户端要处于阻塞状态,等待响应;服务端内部使用异步处理,对客户端并没有什么好处,但它可以提高服务端自身的吞吐率。
一个常见的失误就是,一味想着“异步”,结果把一些本该同步的c/s交互也变成了异步。 最近我在处理websocket握手逻辑时就遇到这样一个问题。我们基于Netty在握手时进行了用户验证。Netty的握手API采用异步编程模型,于是我们就把验证的逻辑放到了握手API的callback中;结果 验证逻辑还没执行完,客户端就收到“握手成功”的通知,然后发出正常的业务请求。解决办法是先验证,再执行握手;如果验证逻辑采用了异步编程模型,则可以把握手API放到验证逻辑的callback中。