iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何解决SpringBoot Actuator潜在的OOM问题
  • 288
分享到

如何解决SpringBoot Actuator潜在的OOM问题

2023-06-21 22:06:39 288人浏览 八月长安
摘要

这篇文章主要介绍如何解决SpringBoot Actuator潜在的OOM问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!此问题背景产生于近期需要上线的一个功能的埋点;主要表现就是在应用启动之后的一段时间

这篇文章主要介绍如何解决SpringBoot Actuator潜在的OOM问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

    此问题背景产生于近期需要上线的一个功能的埋点;主要表现就是在应用启动之后的一段时间内,内存使用一直呈现递增趋势。

    下图为场景复线后,本地通过 jconsole 查看到的内部使用走势图。

    如何解决SpringBoot Actuator潜在的OOM问题

    实际环境受限于配置,内存不会膨胀

    背景&问题

    应用 a 使用 rest template 通过 Http 方式调用 应用 b,应用项目中开启了 actuator,api 使用的是 micrometer;在 client 调用时,actuator 会产生一个 name 为 http.client.requests 的 metrics,此 metric 的 tag 中包含点目标的 uri。

    应用 b 提供的接口大致如下:

    @RequestMapping("test_query_params")public String test_query_params(@RequestParam String value) {    return value;}@RequestMapping("test_path_params/{value}")public String test_path_params(@PathVariable String value) {    return value;}

    http://localhost:8080/api/test/test_query_params?value=

    http://localhost:8080/api/test/test_path_params/{value}_

    期望在 metric 的收集结果中应该包括两个 metrics,主要区别是 tag 中的 uri 不同,一个是 api/test/test_query_params, 另一个是 api/test/test_path_params/{value};实际上从拿到的 metrics 数据来看,差异很大,这里以 pathvariable 的 metric 为例,数据如下:

    tag: "uri",values: ["/api/test/test_path_params/glmapper58","/api/test/test_path_params/glmapper59","/api/test/test_path_params/glmapper54","/api/test/test_path_params/glmapper55","/api/test/test_path_params/glmapper56","/api/test/test_path_params/glmapper57","/api/test/test_path_params/glmapper50","/api/test/test_path_params/glmapper51","/api/test/test_path_params/glmapper52","/api/test/test_path_params/glmapper53","/api/test/test_path_params/glmapper47","/api/test/test_path_params/glmapper48","/api/test/test_path_params/glmapper49","/api/test/test_path_params/glmapper43","/api/test/test_path_params/glmapper44","/api/test/test_path_params/glmapper45","/api/test/test_path_params/glmapper46","/api/test/test_path_params/glmapper40","/api/test/test_path_params/glmapper41","/api/test/test_path_params/glmapper42","/api/test/test_path_params/glmapper36","/api/test/test_path_params/glmapper37","/api/test/test_path_params/glmapper38","/api/test/test_path_params/glmapper39","/api/test/test_path_params/glmapper32","/api/test/test_path_params/glmapper33","/api/test/test_path_params/glmapper34","/api/test/test_path_params/glmapper35","/api/test/test_path_params/glmapper30","/api/test/test_path_params/glmapper31","/api/test/test_path_params/glmapper25","/api/test/test_path_params/glmapper26",....]

    可以非常明显的看到,这里将{value} 参数作为了 uri 组件部分,并且体现在 tag 中,并不是期望的 api/test/test_path_params/{value}。

    问题原因及解决

    两个问题,1、这个埋点是怎么生效的,先搞清楚这个问题,才能顺藤摸瓜。2、怎么解决。

    默认埋点是如何生效的

    因为是通过 resttemplate 进行调用访问,那么埋点肯定也是基于对 resttemplate 的代理;按照这个思路,笔者找到了 org.springframework.boot.actuate.metrics.WEB.client.MetricsRestTemplateCustomizer 这个类。RestTemplateCustomizer 就是对 resttemplate 进行定制的,MetricsRestTemplateCustomizer 通过名字也能得知期作用是为了给 resttemplate 增加 metric 能力。

    再来讨论 RestTemplateCustomizer,当使用RestTemplateBuilder构建RestTemplate时,可以通过RestTemplateCustomizer进行更高级的定制,所有RestTemplateCustomizer beans 将自动添加到自动配置的RestTemplateBuilder。也就是说如果 想 MetricsRestTemplateCustomizer 生效,那么构建 resttemplate 必须通过 RestTemplateBuilder 方式构建,而不是直接 new。

    http.client.requests 中的 uri

    塞 tag 的代码在org.springframework.boot.actuate.metrics.web.client.RestTemplateExchangeTags 类中,作用时机是在 MetricsClientHttpRequestInterceptor 拦截器中。当调用执行完成后,会将当次请求 metric 记录下来,在这里就会使用到 RestTemplateExchangeTags 来填充 tags。 下面仅给出 uri 的部分代码

    public static Tag uri(HttpRequest request) {return Tag.of("uri", ensureLeadingSlash(stripUri(request.getURI().toString())));}public static Tag uri(String uriTemplate) {String uri = (StringUtils.hasText(uriTemplate) ? uriTemplate : "none");return Tag.of("uri", ensureLeadingSlash(stripUri(uri)));

    其余的还有 status 和 clientName 等 tag name。

    通过断点,可以看到,这里 request.getURI() 拿到的是带有参数的完整请求链接。

    如何解决SpringBoot Actuator潜在的OOM问题

    这些 tag 的组装最终在 DefaultRestTemplateExchangeTagsProvider 中完成,并返回一个 列表。

    private Timer.Builder getTimeBuilder(HttpRequest request, ClientHttpResponse response) {    return this.autoTimer.builder(this.metricName)                // tagProvider 为 DefaultRestTemplateExchangeTagsProvider.tags(this.tagProvider.getTags(urlTemplate.get().poll(), request, response)).description("Timer of RestTemplate operation");}

    解决

    这里先来看下官方对于 request.getURI  的解释

    URI getURI();

    返回请求的 URI,这里包括了任何的查询参数。那么是不是拿到不用参数的 path 就行呢?

    如何解决SpringBoot Actuator潜在的OOM问题

    这里尝试通过 request.getURI().getPath() 拿到了预期的 path(@pathvariable 拿到的是模板)。

    再回到 DefaultRestTemplateExchangeTagsProvider,所有的 tag 都是在这里完成组装,这个类明显是一个默认的实现(Spring 体系下基本只要是Defaultxxx 的,一般都能扩展 ),查看它的接口类 RestTemplateExchangeTagsProvider 如下:

    @FunctionalInterfacepublic interface RestTemplateExchangeTagsProvider {Iterable<Tag> getTags(String urlTemplate, HttpRequest request, ClientHttpResponse response);}

    RestTemplateExchangeTagsProvider 的作用就是为 resttemplate 提供 tag 的,所以这里通过自定义一个 RestTemplateExchangeTagsProvider,来替换DefaultRestTemplateExchangeTagsProvider,以达到我们的目标,大致代码如下:

    @Override public Iterable<Tag> getTags(String urlTemplate, HttpRequest request, ClientHttpResponse response) {    Tag uriTag;    // 取 request.getURI().getPath() 作为 uri 的 value    if (StringUtils.hasText(request.getURI().getPath())) {      uriTag = Tag.of("uri", ensureLeadingSlash(stripUri(request.getURI().getPath())));    } else {      uriTag = (StringUtils.hasText(urlTemplate) ? RestTemplateExchangeTags.uri(urlTemplate)                    : RestTemplateExchangeTags.uri(request));    }    return Arrays.asList(RestTemplateExchangeTags.method(request), uriTag,                RestTemplateExchangeTags.status(response), RestTemplateExchangeTags.clientName(request));    }

    会不会 OOM

    理论上,应该参数不同,在使用默认 DefaultRestTemplateExchangeTagsProvider 的情况下,meter 会随着 tags 的不同迅速膨胀,在 micrometer 中,这些数据是存在 map 中的

    // Even though writes are guarded by meterMapLock, iterators across value space are supported// Hence, we use CHM to support that iteration without ConcurrentModificationException riskprivate final Map<Id, Meter> meterMap = new ConcurrentHashMap<>();

    一般情况下不会,这里是因为 Spring Boot actuator 自己提供了保护机制,对于默认情况,tags 在同一个 metric 下,最多只有 100 个

    private int maxUriTags = 100;

    如果你想使得这个数更大一些,可以通过如下配置配置

    management.metrics.web.client.max-uri-tags=10000

    如果配置值过大,会存在潜在的 oom 风险。

    以上是“如何解决SpringBoot Actuator潜在的OOM问题”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网精选频道!

    --结束END--

    本文标题: 如何解决SpringBoot Actuator潜在的OOM问题

    本文链接: https://www.lsjlt.com/news/300900.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • 如何解决SpringBoot Actuator潜在的OOM问题
      这篇文章主要介绍如何解决SpringBoot Actuator潜在的OOM问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!此问题背景产生于近期需要上线的一个功能的埋点;主要表现就是在应用启动之后的一段时间...
      99+
      2023-06-21
    • SpringBootActuator潜在的OOM问题的解决
      目录背景&问题问题原因及解决默认埋点是如何生效的http.client.requests 中的 uri解决会不会 OOM此问题背景产生于近期需要上线的一个功能的埋点;主要表现...
      99+
      2024-04-02
    • springboot访问404问题如何解决
      本篇内容介绍了“springboot访问404问题如何解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!第一次自主开发springboot项...
      99+
      2023-07-05
    • 如何解决Android中图片处理避免出现oom的问题
      这篇文章主要介绍如何解决Android中图片处理避免出现oom的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. 通过设置采样率压缩res资源图片压缩 decodeResource  pub...
      99+
      2023-05-30
      android oom
    • 如何解决SpringBoot测试时卡在Resolving Maven dependencies的问题
      这篇文章主要为大家展示了“如何解决SpringBoot测试时卡在Resolving Maven dependencies的问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如...
      99+
      2023-06-29
    • 如何解决springboot启动失败的问题
      这篇文章主要介绍如何解决springboot启动失败的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!springboot启动失败的问题springboot版本是1.3.0.M1,连接的mysql版本为8,用spr...
      99+
      2023-06-22
    • Vue项目中使用setTimeout存在的潜在问题及解决
      目录使用setTimeout存在的潜在问题上代码总结使用setTimeout存在的潜在问题 在开发项目中遇到这样的序曲,点击按钮弹框,每次进入的时候都需要默认选中Android, 这...
      99+
      2023-01-28
      Vue使用setTimeout 使用setTimeout的潜在问题 Vue setTimeout
    • SpringBoot全局异常问题如何解决
      这篇文章主要介绍“SpringBoot全局异常问题如何解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringBoot全局异常问题如何解决”文章能帮助大家解决问题。SpringBoot 是为了...
      99+
      2023-07-06
    • 如何解决SpringBoot扫描不到Controller的问题
      本篇内容主要讲解“如何解决SpringBoot扫描不到Controller的问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决SpringBoot扫描不到Controller的问题”吧!...
      99+
      2023-06-20
    • springboot 如何解决cross跨域请求的问题
      目录springboot 解决cross跨域请求1.使用ajax发送跨域请求接口时2.在被跨域请求的一方配置3.再次测试4.对于只有个别需要开放跨域请求的接口可以这样玩5.其它解决跨...
      99+
      2024-04-02
    • 如何解决SpringBoot整合thymeleaf报错的问题
      这篇文章主要讲解了“如何解决SpringBoot整合thymeleaf报错的问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何解决SpringBoot整合thymeleaf报错的问题”吧...
      99+
      2023-06-20
    • 如何解决SpringBoot整合RocketMQ遇到的问题
      本篇内容主要讲解“如何解决SpringBoot整合RocketMQ遇到的问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决SpringBoot整合RocketMQ遇到的问题”吧!应用场景...
      99+
      2023-06-20
    • 利用springboot-actuator进行监控时出现401无权限访问如何解决
      这篇文章给大家介绍利用springboot-actuator进行监控时出现401无权限访问如何解决,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。访问/beans 等敏感的信息时候报错Tue Mar 07 21:18:5...
      99+
      2023-05-31
      spring actuator 无权限
    • 如何解决Springboot-application.properties中文乱码问题
      本篇内容主要讲解“如何解决Springboot-application.properties中文乱码问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决Springboot-applica...
      99+
      2023-06-21
    • 如何解决springboot-启动bean冲突问题
      小编给大家分享一下如何解决springboot-启动bean冲突问题,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!启动bean冲突在一次启动中遇到了bean冲突的问题,提示存在两个名称重复的beanorg.springfr...
      99+
      2023-06-29
    • 如何解决CollectionUtils.isNotEmpty()不存在的问题
      这篇文章主要介绍“如何解决CollectionUtils.isNotEmpty()不存在的问题”,在日常操作中,相信很多人在如何解决CollectionUtils.isNotEmpty()不存在的问题问题上存在疑惑,小编查阅了各式资料,整理...
      99+
      2023-06-29
    • 如何解决hover在IE6下的问题
      这篇文章给大家分享的是有关如何解决hover在IE6下的问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。hover在IE6下的问题在处理CSS的机制上,IE总是有很多让人吐血的...
      99+
      2024-04-02
    • SpringBoot如何解决配置SwaggerUI访问404错误的问题
      这篇文章将为大家详细讲解有关SpringBoot如何解决配置SwaggerUI访问404错误的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。SpringBoot 配置SwaggerUI 访问404的小...
      99+
      2023-05-30
      springboot swaggerui 404
    • 如何解决javax.servlet不存在的问题
      这篇文章主要讲解了“如何解决javax.servlet不存在的问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何解决javax.servlet不存在的问题”吧!目录javax.servl...
      99+
      2023-06-20
    • 如何解决springboot日志彩色消失的问题
      本篇内容介绍了“如何解决springboot日志彩色消失的问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!springboot 日志彩色消...
      99+
      2023-06-20
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作