1.为什么用异步化处理
异步化的目的无非就是为了减少response响应时间, 提高用户体验, 提高资源(CPU, IO)利用率.
同步请求示意图
异步请求示意图
这里假设function1和service1都是比较耗时的操作, 调用时间如下:
- function1 = 2s
- service1 = 3s
那么最后的结果如下:
- 同步请求的request等待时间 = 2s + 3s = 5s
- 异步请求, 由于是请求立马得到相应的, 时间消耗应该在100ms之内.
- 后续的获得结果()这个步骤不一定是每个场景都需要(就是需要的话, 这个步骤应该也是一个很快的操作, 控制在1s之内)
结论: 用异步化处理可以减少RT(响应时间), 优化用户体验.
2.哪些场景比较适合用异步化来处理呢 ?
异步化处理有它的好处, 但不是所有的请求都适合用异步化.
异步化的缺点:
- 用户的交互次数可能会增加
- 编码变得复杂(要考虑多线程问题)
下面列举一些比较适合用异步化来处理的场景.
2.1 弱依赖的事务
比如一条数据的修改, 需要发送通知.
这里的发送通知就是弱依赖的事务(一般来说是这样的), 那么这个发送通知就可以异步化.
2.2 长事务
比如导入, 导出.
这是一个非常耗时的事务, 有时候可能要几分钟甚至十几分钟的, 这样的事务没必要让用户一直等着.
直接提示一个"正在导入/正在导出", 然后后台慢慢执行就好了.
做的好一点的, 还可以监控一下整个进度, 在页面上显示出来.
2.3 非业务功能
比如说日志记录, 性能测试等.
特别是这些操作还需要操作数据库, 或者有一些网络请求的时候, 特别要注意异步化处理.
3.请求异步化处理要注意的问题
先看一下tomcat内部的Request请求流程:
注意上图的1.3.1和1.3.2, tomcat会在一个请求结束之后, 清理session和cookie中的信息.
结论:
由于异步化必然会产生一个新的线程, 然后这个新的线程对于request, response相关的操作(主要是针对cookie和session)是不能进行的, 因为cookie和session可能会被清除, request中的attribute估计也会被清理掉(待研究)
但是如果实在要依赖于request中的信息的话, 比如要获取登录用户的一些信息(一般放在session或cookie中), 也可以提前把request中需要的信息copy一份出来, 供异步线程使用.
水平有限, 如有错误, 欢迎拍砖.
网友评论