SpringCloudGateway内存泄漏问题
项目完善差不多,在进入压力测试阶段期间,发现了gateway有内存泄漏问题,问题发现的起因是,当时启动一台gateway,一台对应的下游应用服务,在压力测试期间,发现特别不稳定,并发量时高时低,而且会有施压机卡住的现象,然后找到容器对应的宿主机,并使用container stats命令观察内存,经过观察发现,压力测试时内存会暴涨,并由于超过限制最大内存导致容器挂掉( 这里由于用的swarm所以会自动选择节点重启 )最终发现由于之前测试服务器配置低,所以限制了堆大小为1g,容器cpu 1,容器内存限制为了1g,经过调整后将内存改为4g且不限制容器资源的情况下,并发稳定,单机qps也不错,但是多次压力测试后依然会有卡住的问题,观察了日志之后确定为内存泄漏
io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 4110417927, max: 4116185088) - LEAK: ByteBuf.release() was not called before it's garbage-collected.
发现问题之后,我进入容器内dump了内存快照,并下载到本机由jvisualvm分析,分析过程中并没有发现异常情况,由于gateway底层是netty,所以怀疑是堆外内存出了问题,这时候我从快照中查询bytebuff,依然很小,后来直接使用arthas去线上分析,分析发现堆内存正常,gc也没有问题
最后为了快速测试出异常,我调小了堆外内存大小,并配合nmt调查
-XX:NativeMemoryTracking=detail -XX:MaxDirectMemorySize=100M
在线上使用pmap去查看内存,发现了很多的anon,并且每次并发都会增长
转移到本地进行测试,发现内存远超出分配的堆大小,最终确定为堆外内存出了问题
既然是堆外内存出的问题,我们就只关心是否申请了buff没有释放,通过对代码的检查发现,只有两个地方使用到了相关的内容
DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes); return serverHttpResponse.writeWith(Flux.just(buffer));
对上面的代码进行大量压测后发现并无问题,内存没有异常增长不回收
ServerHttpRequest httpRequest = exchange.getRequest().mutate().headers(httpHeaders -> { httpHeaders.add(GatewayConstants.LOGIN_USER_KEY, JSON.toJSONString(s)); }).build(); return chain.filter(exchange.mutate().request(httpRequest).build());
还有一处就是修改请求头这部分代码,当注释掉这部分时,内存稳定没有异常增长,当放开时,3000并发几乎增加800M内存,几次就怼到了5g+,由于gateway内置了一个请求头工厂(AddRequestHeaderGatewayFilterFactory),我去查看对应的源代码,是怎么实现的
如图,除了多了解析配置之外和我写的基本也一样,那为何会内存异常呢?只能去github上找找问题看看有人遇到相同的事没。
这个老哥遇到的问题也类似,他是修改请求体的内容时出现的
这个问题我也遇到了
看起来这个问题还是挺严重的,最后我也反手提了一个问题
没有啥回答,最后还是参考了一些别人的写法最后内存不会飙升了,但是不知其为何,还得继续调查
到此这篇关于详解SpringCloudGateway内存泄漏问题的文章就介绍到这了,更多相关SpringCloudGateway内存泄漏内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
时间:2020-07-16
Spring在因Netflix开源流产事件后,在不断的更换Netflix相关的组件,比如:Eureka.Zuul.Feign.Ribbon等,Zuul的替代产品就是SpringCloud Gateway,这是Spring团队研发的网关组件,可以实现限流.安全认证.支持长连接等新特性. Spring Cloud Gateway Spring Cloud Gateway是SpringCloud的全新子项目,该项目基于Spring5.x.SpringBoot2.x技术版本进行编写,意在提供简单方便.可
引入依赖 <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <ty
创建网关项目 加入网关后微服务的架构图 创建项目 POM文件 <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springfram
这篇文章主要介绍了spring cloud gateway整合sentinel实现网关限流,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 说明: sentinel可以作为各微服务的限流,也可以作为gateway网关的限流组件. spring cloud gateway有限流功能,但此处用sentinel来作为替待. 说明:sentinel流控可以放在gateway网关端,也可以放在各微服务端. 1,以父工程为基础,创建子工程 2,添加pom依赖
前言 Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式.Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代Netflix ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等
在高并发的系统中,往往需要在系统中做限流,一方面是为了防止大量的请求使服务器过载,导致服务不可用,另一方面是为了防止网络攻击. 常见的限流方式,比如Hystrix适用线程池隔离,超过线程池的负载,走熔断的逻辑.在一般应用服务器中,比如tomcat容器也是通过限制它的线程数来控制并发的:也有通过时间窗口的平均速度来控制流量.常见的限流纬度有比如通过Ip来限流.通过uri来限流.通过用户访问频次来限流. 一般限流都是在网关这一层做,比如Nginx.Openresty.kong.zuul.Spring
开发高并发系统时有三把利器用来保护系统:缓存.降级和限流. API网关作为所有请求的入口,请求量大,我们可以通过对并发访问的请求进行限速来保护系统的可用性. 常用的限流算法比如有令牌桶算法,漏桶算法,计数器算法等. 在Zuul中我们可以自己去实现限流的功能 (Zuul中如何限流在我的书 <Spring Cloud微服务-全栈技术与案例解析> 中有详细讲解) ,Spring Cloud Gateway的出现本身就是用来替代Zuul的. 要想替代那肯定得有强大的功能,除了性能上的优势之外,Spr
问题描述 在搭建分布式应用时,每个应用通过nacos在网关出装配了路由,我们希望网关也可以将所有的应用的swagger界面聚合起来.这样前端开发的时候只需要访问网关的swagger就可以,而不用访问每个应用的swagger. 框架 springcloud+gateway+nacos+swagger 问题分析 swagger页面是一个单页面应用,所有的显示的数据都是通过和springfox.documentation.swagger.web.ApiResponseController进行数据交互,
Spring Cloud Gateway介绍 前段时间刚刚发布了Spring Boot 2正式版,Spring Cloud Gateway基于Spring Boot 2,是Spring Cloud的全新项目,该项目提供了一个构建在Spring 生态之上的API网关,包括:Spring 5,Spring Boot 2和Project Reactor. Spring Cloud Gateway旨在提供一种简单而有效的途径来发送API,并为他们提供横切关注点,例如:安全性,监控/指标和弹性.当前最新的
前言 本文主要给大家分享了关于spring cloud的入门教程,主要介绍了config配置的相关内容,下面话不多说了,来一起看看看详细的介绍吧. 简介 Spring cloud config 分为两部分 server client config-server 配置服务端,服务管理配置信息 config-client 客户端,客户端调用server端暴露接口获取配置信息 config-server 创建config-server 首先创建config-server工程. 文件结构: ├── co
1. 前言 4月25号,Sentinel 1.6.0 正式发布,带来 Spring Cloud Gateway 支持.控制台登录功能.改进的热点限流和注解 fallback 等多项新特性,该出手时就出手,紧跟时代潮流,昨天刚发布,今天我就要给大家分享下如何使用! 2. 介绍(本段来自Sentinel文档) Sentinel 1.6.0 引入了 Sentinel API Gateway Adapter Common 模块,此模块中包含网关限流的规则和自定义 API 的实体和管理逻辑: Gatewa
1.Spring Gateway概述 1.1 什么是Spring Cloud Gateway Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式.Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代Netflix ZUUL,其不仅提供统一的路由
Spring Cloud Gateway 服务网关 API 主流网关有NGINX.ZUUL.Spring Cloud Gateway.Linkerd等:Spring Cloud Gateway构建于 Spring 5+,基于 Spring Boot 2.x 响应式的.非阻塞式的 API.同时,它支持 websockets,和 Spring 框架紧密集成,用来代替服务网关Zuul,开发体验相对来说十分不错. Spring Cloud Gateway 是 Spring Cloud 微服务平台的一个子
动态路由背景 无论你在使用Zuul还是Spring Cloud Gateway 的时候,官方文档提供的方案总是基于配置文件配置的方式 例如: # zuul 的配置形式 routes: pig-auth: path: /auth/** serviceId: pig-auth stripPrefix: true # gateway 的配置形式 routes: - id: pigx-auth uri: lb://pigx-auth predicates: - Path=/auth/** filte
前言 重试,我相信大家并不陌生.在我们调用Http接口的时候,总会因为某种原因调用失败,这个时候我们可以通过重试的方式,来重新请求接口. 生活中这样的事例很多,比如打电话,对方正在通话中啊,信号不好啊等等原因,你总会打不通,当你第一次没打通之后,你会打第二次,第三次...第四次就通了. 重试也要注意应用场景,读数据的接口比较适合重试的场景,写数据的接口就需要注意接口的幂等性了.还有就是重试次数如果太多的话会导致请求量加倍,给后端造成更大的压力,设置合理的重试机制才是最关键的. 今天我们来简单的了