springcloud gateway 使用nacos 动态过滤器 记一次线上网关升级cpu升高的问题

大家好,我是烤鸭:

​ 网关升级,想使用 springcloud gateway nacos 动态过滤器配置(原来是硬编码的方式),升级之后出了一些问题(cpu升高,ygc频繁),记录一下。

关于 springcloud gateway 集成 nacos 可以看这篇。

https://blog.csdn.net/Angry_Mills/article/details/108821602

springcloud gateway 源码解析、请求响应流程 可以看这篇。

https://blog.csdn.net/Angry_Mills/article/details/109035426

pom

父pom

  <dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${springcloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

gateway pom

<!--springcloud 组件start -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- nacos组件 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

配置文件

springcloud gateway 支持配置文件 filters,RequestBodyAddCache为自定义过滤器,这里注意filters 的编写顺序和实际过滤的顺序一样。

spring:application:name: gatewaycloud:gateway:routes:- id: tick-routefilters:- RequestBodyAddCache- StripPrefix=1predicates:- name: Pathargs[pattern]: /tick/**uri: lb://demo-tick- id: tick-routefilters:- StripPrefix=1predicates:- name: Pathargs[pattern]: /dick/**uri: lb://demo-dicknacos:discovery:server-addr: localhost:8848password: nacosusername: nacos

默认自带的有哪些过滤器:
在这里插入图片描述

常用的像:StripPrefix、RewritePath

还可以传入参数,会封装到 config对象里,创建过滤器时使用。

在这里插入图片描述

StripPrefix -> StripPrefixGatewayFilterFactory

RewritePath -> RewritePathGatewayFilterFactory

发现一点规律么,只要我们也按照这个方式写一个工厂就可以,像这样

RewritePathGatewayFilterFactory
在这里插入图片描述

过滤器类

这个过滤器的目的是 获取请求路径和请求方式

RequestBodyAddCacheGlobalFilter

package com.maggie.gateway.filter;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.http.HttpMethod;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.reactive.function.server.HandlerStrategies;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.List;public class RequestBodyAddCacheGlobalFilter implements GatewayFilter, Ordered {private Logger logger = LoggerFactory.getLogger(RequestBodyAddCacheGlobalFilter.class);private final List<HttpMessageReader<?>> messageReaders = HandlerStrategies.withDefaults().messageReaders();@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest serverHttpRequest = exchange.getRequest();ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders);String path = serverHttpRequest.getPath().value();HttpMethod method = serverHttpRequest.getMethod();// 打印请求路径和请求方式logger.info("filter path : {},method : {}", path, method);return chain.filter(exchange);}@Overridepublic int getOrder() {return 0;}}

RequestBodyAddCacheGatewayFilterFactory

package com.maggie.gateway.filter;import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;@Component
public class RequestBodyAddCacheGatewayFilterFactory extends AbstractGatewayFilterFactory {@Overridepublic GatewayFilter apply(Object config) {return new RequestBodyAddCacheGlobalFilter();}
}

问题(cpu 升高)

但是这种方式升级之后,线上网关的cpu消耗差不多是之前的两倍。

后来在测试环境压测发现了问题源头,artas 查看线程阻塞。

在这里插入图片描述

就是 RequestBodyAddCacheGlobalFilter 里的成员变量 messageReaders 阻塞了。

查了下源码,HandlerStrategies.withDefaults() 的时候 ServerCodecConfigurer codecConfigurer 会初始化Jackson2JsonEncoder ->ClassUtils.forName(“com.fasterxml.jackson.datatype.jdk8.Jdk8Module”) -> Classloader.loadClass() 有锁

在这里插入图片描述

为啥之前没有问题呢?

原来的 RequestBodyAddCacheGlobalFilter 是@Autowired(单例的),按照上面的改后变成每次触发apply方法都会创建一个RequestBodyAddCacheGlobalFilter 对象。

每次创建对象其实也没有问题,源码里的工厂类都是new GatewayFilter()。(上面 StripPrefixGatewayFilterFactory 和 RewritePathGatewayFilterFactory 源码的图)

还有一个疑问就是 RequestBodyAddCacheGatewayFilterFactory.apply() 方法理论上只会项目启动调用一次,不会创建多个对象。

其实不管是 eurka 或者 nacos 或者 apollo 会触发 AbstractApplicationContext.refresh

而nacos(Watch-task 线程) NacosWatch.nacosServicesWatch( this.publisher.publishEvent )

eurka (DiscoveryClient-CacheRefresh 线程) CloudEurekaClient.onCacheRefreshed( this.publisher.publishEvent )
在这里插入图片描述

下图可以看出频繁访问并不会触发apply方法,apply方法是在固定的周期触发。(触发次数取决于拦截器配置的次数,比如几个route配置了这个filter,就会初始化几次,线上配置这个filter的route比较多,每次都会初始化十几次,所以cpu变化也比较明显)

在这里插入图片描述

解决方式

跟原来一样,RequestBodyAddCacheGlobalFilter 采用单例,注入进来就行。不会创建多余的对象。cpu和ygc恢复了。

@Component
public class RequestBodyAddCacheGatewayFilterFactory extends AbstractGatewayFilterFactory {@AutowiredRequestBodyAddCacheGlobalFilter requestBodyAddCacheGlobalFilter;@Overridepublic GatewayFilter apply(Object config) {return requestBodyAddCacheGlobalFilter;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/412591.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[css] 你是怎样抽离样式模块的?

[css] 你是怎样抽离样式模块的&#xff1f; 说的是 webpack extract-text-webpack-plugin插件吧&#xff1f; 把样式文件单独打包出来。 webpack4 升级了插件为 mini-css-extract-plugin个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c;…

【1】生产者-消费者模型的三种实现方式

(手写生产者消费者模型&#xff0c;写BlockingQueue较简便 ) 1、背景 生产者生产数据到缓冲区中&#xff0c;消费者从缓冲区中取数据。 如果缓冲区已经满了&#xff0c;则生产者线程阻塞&#xff1b; 如果…

springboot mybatis-plus 配置 yml 、druid 配置 yml 、mybatis-plus 代码生成

大家好&#xff0c;我是烤鸭&#xff1a; 今天分享一下 springboot mybatis-plus 和 druid 的yml 配置文件。 pom <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency…

[css] 说说你对媒体查询的理解

[css] 说说你对媒体查询的理解 当年做响应式布局的时候用过媒介查询&#xff0c;media query。包括现在有的时候为了兼容也会用到一些&#xff0c;查找对应范围使用不同的样式个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定…

Spring Boot 2.1 版本变化[翻译]

大家好&#xff0c;我是烤鸭&#xff1a; ​ 最近在把低版本的springboot项目升级&#xff0c;正好翻译了下springboot 2.1-2.3 版本的更新日志。 ​ Github 原文&#xff1a;https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes ​ 2.2 版…

实验吧Web-易-天网管理系统(php弱类型,==号)

打开网页&#xff0c;查看源码&#xff0c;看到 <!-- $test$_GET[username]; $testmd5($test); if($test0) --> 说明用户名需要加密之后为0。 对于PHP的号&#xff0c;在使用 运算符对两个字符串进行松散比较时&#xff0c;PHP会把类数值的字符串转换为数值进行比较&…

[css] 你知道的等高布局有多少种?写出来

[css] 你知道的等高布局有多少种&#xff1f;写出来 flex拉伸display: flex; align-items: stretch;padding margin抵消 然后background-clip默认是border-box所以会在被抵消的位置依然显示背景 造成等高假象.box,.box2{float: left;width: 100px; } .box {background: #cccccc…

Spring Boot 2.2版本变化[翻译]

大家好&#xff0c;我是烤鸭&#xff1a; ​ 最近在把低版本的springboot项目升级&#xff0c;正好翻译了下springboot 2.1-2.3 版本的更新日志。 ​ Github 原文&#xff1a;https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.2-Release-Notes ​ 2.1 版…

[css] 手写一个满屏品字布局的方案

[css] 手写一个满屏品字布局的方案 <!DOCTYPE html> <html><head><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta charset"UTF-8"><link rel"stylesheet" href"st…

个人的博客搭建(持续更新)

最近的CSDN的博客阅读体验非常的糟糕&#xff0c;恰好自己也一直想搭建一个属于自己的网站&#xff0c;放下自己的技术心得情感体会&#xff0c;从零开始慢慢搭建项目磨练技术&#xff0c;以后也把自己新习得的技术放在里面增加自己的学习乐趣。 一&#xff0c;搭建基本的项目模…

Spring Boot 2.3 版本变化[翻译]

大家好&#xff0c;我是烤鸭&#xff1a; ​ 最近在把低版本的springboot项目升级&#xff0c;正好翻译了下springboot 2.1-2.3 版本的更新日志。 ​ Github 原文&#xff1a;https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes ​ 2.1 版…

[css] span与span之间有看不见的空白间隔是什么原因引起的?有什么解决办法?

[css] span与span之间有看不见的空白间隔是什么原因引起的&#xff1f;有什么解决办法&#xff1f; 可能是设置成了inline-block。 第一种解决方案是&#xff0c;去掉span标签内的空白。 第二种解决方案是&#xff0c;设置margin负值&#xff0c;但要根据字体调整&#xff0c;…

[css] 重置(初始化)css的作用是什么?

[css] 重置&#xff08;初始化&#xff09;css的作用是什么&#xff1f; 这是一个&#xff0c;还有就是视觉问题&#xff0c;浏览器默认样式会影响我们的设计还原&#xff0c;而且默认样式一般不够美观&#xff0c;满足不了定制化的视觉需求&#xff0c;达不到视觉产品的信息传…

《代码整洁之道 Clean Architecture》-读书笔记

大家好&#xff0c;我是烤鸭&#xff1a; 关于《代码整洁之道》&#xff0c;记录一下读书笔记。 代码整洁之道第一章 整洁代码整洁代码的艺术第二章 有意义的命名避免误导有意义的区分使用读得出来和可搜索的名字避免使用编码第三章 函数第四章 注释第五章 格式第六章 对象和数…

用Java实现图片验证码功能

一、什么是图片验证码&#xff1f; 可以参考下面这张图&#xff1a; 我们在一些网站注册的时候&#xff0c;经常需要填写以上图片的信息。 1、图片生成实体类&#xff1a; 1 package com.hexianwei.graphic;2 3 import java.awt.Color;4 import java.awt.Font;5 import java.aw…

[css] 怎么让英文单词的首字母大写?

[css] 怎么让英文单词的首字母大写&#xff1f; 楼上用的没问题&#xff0c;学习嘛&#xff0c;那我就来扩展一下。text-transform 属性控制文本的大小写&#xff0c;是CSS2.1的属性&#xff0c;兼容性问题不大。 属性值是关键字&#xff0c;有41种&#xff0c;这个1是实验性属…

Zuul 1.x 升级 springcloud gateway 2.x 遇到的一点问题

大家好&#xff0c;我是烤鸭&#xff1a; 今天分享 Zuul 1.x 升级 springcloud gateway 2.x 遇到的一点问题。 介绍 zuul 和springcloud gateway 都是比较优秀的网关&#xff0c;而 zuul 1.x 采用的是 servlet 模型&#xff0c;gate 采用的是 reactor模型&#xff0c;效率和资…

render_template 网页模板

模板简单介绍&#xff1a; 视图函数&#xff1a;视图函数就是装饰器所装饰的方法&#xff0c;视图函数的主要作用是生成请求的响应&#xff0c;这是最简单的请求。实际上&#xff0c;视图函数有两个作用&#xff1a;处理业务逻辑和返回响应内容。在大型应用中&#xff0c;把业务…

[css] 怎么才能让图文不可复制?

[css] 怎么才能让图文不可复制&#xff1f; -webkit-user-select: none; -ms-user-select: none; -moz-user-select: none; -khtml-user-select: none; user-select: none;个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷…

nacos配置刷新失败导致的cpu上升和频繁重启,nacos配置中心源码解析

大家好&#xff0c;我是烤鸭&#xff1a; nacos 版本 1.3.2&#xff0c;先说下结论&#xff0c;频繁重启的原因确实没有找到&#xff0c;跟nacos有关&#xff0c;日志没有保留多少&#xff0c;只能从源码找下头绪(出问题的版本 server用的是 nacos 1.1&#xff0c;nacos-client…