Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >线上服务发布抖动,该怎么解决呢

线上服务发布抖动,该怎么解决呢

作者头像
卷福同学
发布于 2023-04-28 03:59:51
发布于 2023-04-28 03:59:51
4480
举报
文章被收录于专栏:奶奶看了都会奶奶看了都会

之前的文章分别讲了优雅上线 和 优雅下线,实际工作中做了优雅上下线后,服务发布后还是会有短暂的“抖动”,接口的响应时间急剧升高后又恢复正常,就和下面的监控图一样,图片来源于 得物 的InfoQ技术文档服务发布时网络“抖动”

背景

小卷现在负责的系统已经达到20万QPS了,每天即使是在半夜,QPS依然过万。每次系统升级发布时,抖动比较频繁,上游应用方都跑过来质问,怎么服务又超时了啊,还能不能用了。。。(巴拉巴拉),小卷只能陪着笑脸的一番解释。后来小卷加上了优雅上下线,想着这下发布应该没问题了吧。哪知再次发布,超时问题依然存在。。。小卷决定好好分析一下发布抖动问题的根因是啥

1.抖动问题分析

服务抖动问题需要根据具体场景分析,这里列一下可能的原因:

  • • redis、DB连接初始化耗时长,引起启动后的接口RT升高
  • • JIT即时编译耗时长,造成CPU利用率高,引起接口RT升高

对于高并发的应用来说,这里JIT即时编译是通用的原因。

JIT是什么?

JIT(just-in-time)即时编译,是一种执行计算机代码的方法,这种方法涉及在程序执行过程中(在执行期)而不是在执行之前进行。关于JIT的历史,摘抄一段维基百科上的内容

最早发布的JIT编译器是 约翰·麦卡锡在1960年对LISP的研究。在他的重要论文《符号表达式的递归函数及其在机器上的计算》(Recursive functions of symbolic expressions and their computation by machine, Part I)提到了在运行时被转换的函数,因此不需要保存编译器输出来打孔卡。在Self被Sun公司抛弃后,研究转向了Java语言。“即时编译”这个术语是从制造术语“及时”中借来的,并由Java普及,Java之父James Gosling从1993年开始使用这个术语。目前,大多数Java虚拟机的实现都使用JIT技术,而且使用广泛。

了解JVM的都知道,Java的编译分为两部分:

  • javac.java文件编译为.class文件,即转换为字节码
  • 解释器.class字节码文件解释为机器码(0、1)执行

但是解释执行的缺点很明显,执行速度慢。

Java早期使用解释执行,将字节码逐条解释执行,这种方式运行很慢。如果是快速反复调用某段代码,执行效率大大降低。后来为了解决这种问题,JVM引入了JIT即时编译,当Java虚拟机发现某段代码块或是方法执行比较频繁,超过设定的阈值时,就会把这些代码视为热点代码(Hot Spot code)

为了提高热点代码的执行效率,虚拟机会将其编译为机器码,并存到CodeCache里,等到下次再执行这段代码时,直接从CodeCache里取,直接执行,大大提升了运行效率,整个执行过程如下:

看上图很容易理解JIT是什么,然后思考下面的问题:

  • • 怎么判断属于热点代码?
  • • 阈值是怎么设定的?
  • • codeCache又是什么?

怎么判断热点代码

我们知道JIT是将热点代码编译成机器码缓存起来的,那么什么样的代码才属于热点代码呢

HotSpot虚拟机使用的是基于计数器的热点代码探测,JVM统计每个方法调用栈的弹出频率作为指标,提供了2种次数级别热点探测方法:

  1. 1. 精确计数,超过阈值触发编译 (统计的是总调用量)
  2. 2. 记录一段时间内被调用的次数,超过阈值触发编译(类似QPS的含义)

JVM默认使用的第二种方法统计方法调用次数,因为第一种方法计算开销大,第二种方法与调用时间有关,适用于大多数场景

阈值如何设定

上面说到超过阈值才触发编译,阈值是设置为多少了呢?

先说说JVM的分层编译器,Hotspot虚拟机中,JIT有2种编译器C1编译器(客户端模式)、C2编译器(服务端模式)。

C1编译器:简单快速,搜集信息较少,主要关注点在局部化的优化,编译速度快,适用于对启动性能有要求的应用。缺点是编译后的代码执行效率低;

C2编译器:需要搜集大量的统计信息在编译时进行优化,为长期运行的应用程序做性能优化的编译器,优化手段复杂,编译时间长,编译出来的机器码执行效率高。代价是启动时间变长,程序需要执行较长时间后,才能达到最佳性能;

JAVA8之后默认开启了分层编译,即:应用启动初期使用C1编译器缓存热点代码,在系统稳定后使用C2编译器继续优化性能。

可通过一些参数进行设置

在 Java8 中默认开启分层编译(-XX:+TieredCompilation默认为true)

  • • 如果只想用 C1,可以在打开分层编译的同时使用参数“-XX:TieredStopAtLevel=1”
  • • 如果只想用 C2,使用参数“-XX:-TieredCompilation=false”关闭分层编译即可

通过java -version可看到当前JVM使用的编译模式

方法被调用的次数,在 C1 模式下默认阈值是 1500 次,在 C2 模式是 10000 次,可通过参数-XX: CompileThreshold 手动设定,在分层编译的情况下,-XX: CompileThreshold 指定的阈值将失效,此时将会根据当前待编译的方法数以及编译线程数来动态调整。超过阈值触发编译,编译完成后系统会把方法调用入口改为最新地址,下次直接使用机器码。

需要注意的是,计数器统计的是一段时间内的调用次数,当超过时间限度调用次数仍然未达到阈值,那么该方法的调用次数就会减半,并不是一直累加的,这段时间称为该方法的统计半衰周期,可以使用虚拟机参数-XX:-UseCounterDecay 关闭热度衰减,参数-XX:CounterHalfLifeTime 设置半衰周期的时间,需要注意进行热度衰减的动作是在虚拟机进行垃圾收集时顺便进行的。

CodeCache是什么

CodeCache主要用于存储JIT编译后的机器码,随着程序的运行,大部分热点代码都会编译为机器码来运行。所以Java的运行速度比较快,除了JIT编译的代码外,本地方法代码(JNI)也会存储在Codecache内。可配置一些参数设置Codecache的属性

  • • -XX:ReservedCodeCacheSize:codeCache最大大小
  • • -XX:InitialCodeCacheSize:codeCache初始大小

Linux环境下,Codecache默认大小是2.4375M,可通过jinfo -flag InitialCodeCacheSize [java进程ID]查看,如图

2.为什么应用刚启动时会抖动?

上面已经讲了JIT即时编译,这样也好理解为什么刚启动完的应用,RT突然升高,CPU利用率也很高。在高并发场景下,一个方法的调用次数激增,会瞬间达到JIT编译的阈值,JVM会执行即时编译,讲热点代码转为机器码。热点代码过多时,JIT编译的压力会增大,造成系统的load升高,CPU利用率跟着升高,导致服务的整体性能下降

3.解决方案

这里小卷列了一些解决方案,需要根据具体场景具体使用,如图

JWarmup

AJDK内嵌的功能模块,相关wiki在阿里的Github上阿里巴巴Dragonwell8用户指南

其原理是先发布beta服务器,等到beta服务器的JIT编译完成后,将热点方法dump下来,然后production环境发布时直接加载dump文件,不需要再进行JIT编译了。从JVM层面解决了该问题,但是接入门槛较高,可能会踩一些坑。

平台预热

借助流量调度平台的能力,小流量预热后再放开,把JIT编译的影响降低。是综合考虑接入成本以及推广维护最合适的方案。这里阿里云微服务引擎MSE已提供功能小流量预热服务,但是是收费的哦~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-10-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 卷福同学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
使用 EFKLK 搭建 Kubernetes 日志收集工具栈
前面大家介绍了 Kubernetes 集群中的几种日志收集方案,Kubernetes 中比较流行的日志收集解决方案是 Elasticsearch、Fluentd 和 Kibana(EFK)技术栈,也是官方现在比较推荐的一种方案。
CNCF
2021/05/07
2.1K0
使用 EFKLK 搭建 Kubernetes 日志收集工具栈
Filebeat+Kafka+Logstash+Elasticsearch+Kibana 构建日志分析系统
随着时间的积累,日志数据会越来越多,当你需要查看并分析庞杂的日志数据时,可通过 Filebeat+Kafka+Logstash+Elasticsearch 采集日志数据到Elasticsearch(简称ES)中,并通过 Kibana 进行可视化展示与分析。
高楼Zee
2021/09/23
2.3K0
Filebeat+Kafka+Logstash+Elasticsearch+Kibana 构建日志分析系统
Helm部署Filebeat + ELK
官方chart地址:https://github.com/elastic/helm-charts/tree/master/elasticsearch
院长技术
2021/02/19
2.8K0
Helm部署Filebeat + ELK
Kubernetes部署ELK并使用Filebeat收集容器日志
Elasticsearch运行时要求vm.max_map_count内核参数必须大于262144,因此开始之前需要确保这个参数正常调整过。
大江小浪
2018/09/19
5.8K0
Kubernetes部署ELK并使用Filebeat收集容器日志
Kubernetes中部署ELK Stack日志收集平台
ELK是Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称。市面上也被称为Elastic Stack。其中Elasticsearch是一个基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。像类似百度、谷歌这种大数据全文搜索引擎的场景都可以使用Elasticsearch作为底层支持框架,可见Elasticsearch提供的搜索能力确实强大,市面上很多时候我们简称Elasticsearch为es。Logstash是ELK的中央数据流引擎,用于从不同目标(文件/数据存储/MQ)收集的不同格式数据,经过过滤后支持输出到不同目的地(文件/MQ/redis/elasticsearch/kafka等)。Kibana可以将elasticsearch的数据通过友好的页面展示出来,提供实时分析的功能。
没有故事的陈师傅
2021/07/21
1.9K6
ELK+FileBeat日志分析系统(正式环境nginx日志)
ElasticSearch、Logstash和Kibana 这里还用到一个插件那就是filebeat进行进行采集日志 添加filebeat插件现在已经是非常提倡的做法
全栈程序员站长
2021/06/08
5890
ELK+FileBeat日志分析系统(正式环境nginx日志)
kubernetes日志采集ELK(一)
在Kubernetes中,日志采集是一个非常重要的任务,因为它可以帮助我们监控应用程序的运行状态,并诊断潜在的问题。ELK(Elasticsearch、Logstash、Kibana)是一个流行的日志采集和分析工具集。
玖叁叁
2023/05/04
4930
Kubernetes 1.19.0——部署EFK
所以Logstash一般可以用fluentd或者filebeat替代,这就有了EFK
gz_naldo
2020/11/16
1.5K1
Kubernetes 1.19.0——部署EFK
ELK7.x日志系统搭建 4. 结合kafka集群完成日志系统
以上是我的节点及机器上安装的相关软件,东西会比较多,但是运行都离不开我们上面的架构图。
憧憬博客
2020/07/21
9720
ELK7.x日志系统搭建 4. 结合kafka集群完成日志系统
想过为你的应用加上skywalking(链路监控)吗?
skywalking是什么?为什么要给你的应用加上skywalking 在介绍skywalking之前,我们先来了解一个东西,那就是APM(Application Performance Management)系统。 一、什么是APM系统 APM (Application Performance Management) 即应用性能管理系统,是对企业系统即时监控以实现 对应用程序性能管理和故障管理的系统化的解决方案。应用性能管理,主要指对企业的关键业务应用进 行监测、优化,提高企业应用的可靠性和质量,保证用
极客运维圈
2020/10/09
1.5K2
想过为你的应用加上skywalking(链路监控)吗?
kubernetes Filebeat+ELK日志收集监控方案
接收来自filebeat的数据,根据其中的tags进行分类,再添加index进行分类,例如nginx-access-%{+YYYY.MM.dd},在kibana中会根据这个index获取日志。
kubernetes中文社区
2019/06/24
3.2K0
kubernetes  Filebeat+ELK日志收集监控方案
Spring Cloud + ELK 统一日志系统搭建
ELK 是 Elasticsearch、Logstash、Kibana 的简称,这三者是核心套件,但并非全部。
大数据真好玩
2021/01/26
3.5K0
Kubernetes K8S之Helm部署ELK日志分析系统 chart下载与配置修改Elasticsearch部署Elasticsearch访问elasticsea
ELK是Elasticsearch、Logstash、Kibana的简称,这三者是核心套件,但并非全部。
踏歌行
2021/01/29
1.8K0
使用 Elastic Stack 构建 Kubernetes 全栈监控(3/4)
在本节中我们将要安装配置 Filebeat 来收集 Kubernetes 集群中的日志数据,然后发送到 ElasticSearch 去中,Filebeat 是一个轻量级的日志采集代理,还可以配置特定的模块来解析和可视化应用(比如数据库、Nginx 等)的日志格式。
我是阳明
2020/07/10
1.6K0
Elastic stack日志分析集群部署
Elastic stack 俗称 ELK stack,是一组包括 Elasticsearch、Logstash 和 Kibana 在内的开源产品。Elastic Stack 由 Elastic 公司开发和维护。使用 Elastic stack,可以将系统日志发送到 Logstash,它是一个数据收集引擎,接受来自可能任何来源的日志或数据,并对日志进行归一化,然后将日志转发到 Elasticsearch,用于分析、索引、搜索和存储,最后使用 Kibana 表示为可视化数据,使用 Kibana,我们还可以基于用户的查询创建交互式图表。
Power
2025/03/03
1760
Kubernetes实战之部署ELK Stack收集平台日志
ELK是Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称。市面上也被成为Elastic Stack。其中Elasticsearch是一个基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。像类似百度、谷歌这种大数据全文搜索引擎的场景都可以使用Elasticsearch作为底层支持框架,可见Elasticsearch提供的搜索能力确实强大,市面上很多时候我们简称Elasticsearch为es。Logstash是ELK的中央数据流引擎,用于从不同目标(文件/数据存储/MQ)收集的不同格式数据,经过过滤后支持输出到不同目的地(文件/MQ/redis/elasticsearch/kafka等)。Kibana可以将elasticsearch的数据通过友好的页面展示出来,提供实时分析的功能。
没有故事的陈师傅
2019/12/11
5.7K0
Linux安装ELK日志平台(7.5.1)
一般我们需要进行日志分析场景:直接在日志文件中 grep、awk 就可以获得自己想要的信息。但在规模较大也就是日志量多而复杂的场景中,此方法效率低下,面临问题包括日志量太大如何归档、文本搜索太慢怎么办、如何多维度查询。需要集中化的日志管理,所有服务器上的日志收集汇总。常见解决思路是建立集中式日志收集系统,将所有节点上的日志统一收集,管理,访问。
子润先生
2021/07/07
1.9K1
日志分析平台ELK 7.0时代来了
集群架构图 1. Elasticsearch集群部署 1.1 初始化java组件 # 安装jdk root@es-logs-20-114:/usr/local# ls -l | grep jdk lrwxrwxrwx 1 root root 22 Apr 1 2017 jdk -> /usr/local/jdk1.8.0_65 drwxr-xr-x 8 root root 4096 Nov 25 2015 jdk1.8.0_65 # 配置java环境变量 export JAVA_HOME
公众号: 云原生生态圈
2021/11/15
3690
日志分析平台ELK 7.0时代来了
Elasticsearch+Filebeat+Kibana+Metricbeat)搭建K8s集群统一日志管理平台Demo
我所渴求的,無非是將心中脫穎語出的本性付諸生活,為何竟如此艱難呢 ------赫尔曼·黑塞《德米安》
山河已无恙
2023/01/30
1.3K0
kubernetes集群交付一套ELK Stack日志分析
日志,对于任何系统来说都是及其重要的组成部分,在计算机系统中比较复杂,日志有不同的来源,如操作系统,应用服务,业务逻辑等,它们都在不停产生各种各样的日志。 K8S系统里的业务应用是高度 “动态化”的,随着容器编排的进行,业务容器在不断的被创建、被销毁、被迁移、被扩缩容…
王先森sec
2023/04/24
8330
kubernetes集群交付一套ELK Stack日志分析
推荐阅读
相关推荐
使用 EFKLK 搭建 Kubernetes 日志收集工具栈
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档