栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

记录一次reactive模型接口问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

记录一次reactive模型接口问题

表现

生产环境一百多台机器,某接口全面返回http错误码590。

接口相关的业务功能不可用,且不能自己恢复,后紧急下线相关功能配置,重启后恢复。

Bug引入

微服务使用netty的reactive模式进行开发,请求返回体为completableFuture

接口处理函数中,新建一个completableFucture,作为返回值。

completableFuture中有代码实现判空不到位,导致抛空指针异常,导致无法走到complete(XXResponse)执行。

从外部看,比如使用postman调用的时候,表现为接口一直阻塞,不响应。

定位过程

尝试在本地环境复现:

1)使用postman runner模拟高频请求。

postman runner本身是不支持并发请求的。

有个小技巧,可以通过修改postman setting里的超时时间,不用上一个等返回就发起下一个。

2)jvisualVM查看内存使用,对内存和线程进行dump。

发现内存并没有明显泄漏。看各个线程池也没发现有特别异常的。

相关知识点:

1)Netty的reactive请求处理模型

https://servicecomb.apache.org/references/java-chassis/zh_CN/general-development/reactive.htmlJava CompletableFuture 详解https://servicecomb.apache.org/references/java-chassis/zh_CN/general-development/reactive.html

请求网络数据到达后,请求会写到channel中,这个过程很快。

vertex线程池对eventloop select到的已经就绪的请求进行处理。这个过程包括:走比如熔断、限流等过滤器,再走到业务代码。

业务代码创建comletableFuture,在另一个线程池中异步执行,在异步线程中通过complete带回结果,主线程直接返回future。

此时注册到另一个eventloop中,当响应完成时会在这里就绪,另一个线程会select到就绪的返回结果,再写回连接数据。

所以,vert.x线程不能阻塞;

业务异步线程要保证complete效率,否则会导致被调堆积。因此如果在业务线程中涉及IO,最好也使用响应式io,返回一个future之后就释放当前线程到下一个任务。

nio的核心思想就是去除因为io阻塞的线程,转换为多路复用,这个有点像操作系统的io中断、中断响应,搞过嵌入式开发的同学应该很熟悉。

实际上当接口中会调用其他接口的时候,使用响应式编程可以将这些一断一断串起来,最大化效率

2)接口熔断

底层还是hystrix,hystrix隔离模式目前有两种方式:信号量模式和线程池模式。

reactive模型下,hystrix通常使用信号量模型。信号量并不支持超时, 早先的一批请求可能长时间无法得到响应。

hystrix两种隔离模式分析 - 指针怒草内存栈 - 博客园

原因分析

1)线程中抛异常后,未在线程内catch,而是在线程外catch,导致没有给future返回值。

2)Netty的reactive请求处理模型下,无返回值的future会维持在NioEventLoop中。

3)hystrix的信号量不是否,触发了hystrix的隔离机制,导致快速失败返回590。

待确认:

是否future不返回会导致内存泄漏。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/704282.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号