预发部署时机器总是重启两次的“简单”排查

作者:曲池

一、问题

前天同学反馈, 搜索业务的核心应用 magellan 在预发环境部署时总是重启两次,刚部署好,开始联调,突然又重启了,也导致老是被人抱怨搜索环境不稳定。

第一反应是,大概率是应用第一次启动失败了吧?总不可能是 Aone(阿里内部 CI/CD 系统)调度两次吧。结果:

这的确没有遇到过,只能表示:

这么神奇的现象是偶尔还是必现呢?竟然是必现。

既然必现,那还是从能排查的、好排查的试试吧!

二、查看日志,确认到底部署了几次

开发同学发来了部署日志截图,如上面几张图所示:

  • 01:41 时停止应用,然后销毁容器,创新新容器

  • 01:43 时开始启动应用,启动成功

  • 01:50 时又开始停止应用、重启应用了,但此时并没有新的部署记录。

当然上面的图里看的不太清晰,我们还是做下简单匹配:匹配下停止和启动时的日志(grep -E),同时向上向下各显示一行日志(-C 1),主要是为了把时间打印出来。

cat magellan_deploy.log  |grep -E "INFO: magellan try to stop...|INFO: magellan try to start..." -C 1

机器 1 的启动日志

机器 2 的启动日志

当然上面这命令,也只是此刻我梳理整体过程时才想起来(所以跟开发同学提供的截图不太一致),排查问题时也就大概看看日志。不过通过上面的图,我倒是又发现了一个之前遗漏的点:两个机器的第一次启动时间不一样(分 2 批启动,机器 1 是第一批启动,机器 2 是第二批启动),但是他们第二次的重启时间是一样的,都是 21:00:02 ,说明是同一时刻被调度的,这也印证了后面的结论,不过,目前我们暂且忽略该信息。

无论是从上面事前开发同学截的图,还是从我事后截的图,都可以看出:应用的确是重启了两次,第一次应该是 Aone 调度的,但第二次不知道是谁调度的。

三、手动重启应用会不会也有这个问题呢?

手动重启了下,启动成功后,应用就上线了,等了 2、3 分钟,应用没有再次重启。

难道只有在 Aone 部署的时候才会?

看了最近一周的部署日志,的确基本都是重启两次。

四、有没有定时任务

没有定时任务!

五、没啥思路,看看有没有有用的报错信息吧

仔细翻了翻,应用启动日志中并没有什么特别的、新的报错,部署日志倒是有一个警告信息:

Pandoraboot 可以类比于 Springboot

记得之前看过一些文章,说这个错误有可能会影响 JDK 版本的判断(主要是由于部分 JDK 版本判断的脚本不太健壮)。

另外,我刚才手动部署时,好像也有一行报错,估计是由这个错误引起的,赶紧重新执行下 sh stop.sh(阿里内部手动下线某台机器的命令):

提示 update_setenv.sh(阿里内部应用启动脚本之一) 的 21 行有问题,看下代码:

梳理了逻辑,大概是执行 java -version ,获取版本号,如果大于等于 JDK8,则替换一些 JVM 参数。估计是当年升级 JDK8 时的遗留产物。

为啥会报错呢?登录机器执行了下命令:

执行该命令时 OpenJDK 报了 Warning 信息,而且报错信息在 version 那行之前,这样第一行就匹配不到真正的版本号 8 了,按照上面代码的执行逻辑,JAVA_VERSION_MAJOR 会取到 "Server" 中的第一个"e",取到了一个字符串,导致下面和数字 8 比较时报错。

那这里执行报错会带来什么影响呢?

下面的替换逻辑就不会执行了,最终 JVM 的启动参数设置不合理,可能导致 JVM 被杀掉了?

那看看应用现在的启动参数设置吧:

启动参数已经改成 JDK8 之后的了,所以上面的替换逻辑不执行也不会影响最终的启动参数。

虽然不影响启动参数,但部署日志里,有这么多的这行错误日志,而且 JDK 版本获取错误估计也会引起一些不可知的问题。先修复掉试试!

六、修复 JDK 版本判断错误的逻辑

看了下这个 update_setenv.sh 的代码,发现已经没用了,而且判断 JDK 版本的代码逻辑也写的很有问题,可以直接删除。

拉变更,删除,部署预发。

部署成功,应用开始启动后,登录机器观察部署日志:应用部署正常,无 JDK warning 信息,等了几分钟也没有重新部署,好像是解决了。

但为什么解决了呢?不科学呀。

照理说,这个版本判断和两次重启关系不是很大呀。

算了,先不纠结,赶紧反馈给开发同学。

为了能将这份喜悦第一时间传递给开发,我还特意使用了快速通道—DING,结果很快就打脸了。

七、是运行时问题?

赶紧上机器看了下日志,发现:这个机器在 20:54 分的时候已经启动成功了,运行了 5 分钟后才被重启(我只等了 3 到 4 分钟)。

这就说明:不是应用启动时的问题,而是运行时问题,怪不着我之前老是观察不到,原来是启动后不确定的时间内会被重启。

嘴上跟开发同学说,我再努力找找,但其实内心没有一点思路。

找 Aone 同学问问吧,万一是 Aone 重复调度了呢?

八、咨询 Aone 同学是否存在重复调度的可能性

Aone(阿里内部 CI/CD 系统) 右下角咨询了研发小蜜,很快就有了答复。

不过,同学回复的答案跟我的问题并不相关,应该是理解错我的意思了。他估计以为我要暂停容器、排查问题,可以理解,问题是比较诡异。

提问前,我还仔细阅读了下 Aone 的历史提问记录,发现里面并没有类似的问题,大概率不是 Aone 的问题。还是先再试试其他方法,实在不行的话,再找 Aone 同学确认是否有重复调度。

还能从什么角度进行排查呢?有点排查不下去了。

想起来了,据开发同学说,只有预发机器有,线上机器没有这个问题,那就对比下线上和预发的机器吧。

九、全方位对比线上和预发机器

对比应用部署日志:无异常

对比应用启动日志:无异常

对比 JVM 参数:有点不一样,如下,第一张是线上机器的参数,第二张是预发机器的参数。

区别有几个地方:

  • 使用的 java 路径不一样:线上是/opt/taobao/install/ajdk-8_2_4-b52/bin/java,预发是 /opt/taobao/java/bin/java

  • 预发环境的机器开启了 Debug 端口: -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000

  • 预发环境的机器挂载了一个 Java Agent: -javaagent:/home/admin/remote-debug/libs/remote-debug-agent.jar

Java 路径的:

登录机器看了下,两个路径做了软链接,本质是一样的(预发和线上有区别是由于我在预发环境删除了 update_setenv.sh 导致的)。

预发机器的 Debug 端口开启:估计是有同学在预发 Debug,这也不会有啥问题。

预发环境的机器挂载 Java Agent:

这个一般也是常规操作了,比如用来做启动耗时分析的 start-ops,用来做代码染色的 rbc 等,都是只挂载预发,防止 Agent 影响线上真实用户,就是不知道这个 remote-debug 是用来干啥的。

对比了半天,也没有任何头绪。

总不能是这个 Agent 引起的吧?Agent 一般也不会,并且也不能重启应用的呀。

算了,先看看这个 Agent 是干啥的。

十、看看 remote-debug Agent 是干啥的

既然是 Java Agent,而应用代码里又没有 Agent 部署的相关代码,那么这个 Agent 应该是通过运维插件下发的,这样应用才是无感的。

先在 staragent 插件市场(阿里内部运维容器插件市场)里搜索看看是干啥的:

试了 remote debug、remote debug agent 等一系列关键词,发现都搜索不到,奇怪,难道插件不叫这个名字?

那就网上搜索下,信息都没啥用,全是远程 debug 的,没办法,谁让这个插件叫这个名字呢。

语雀搜索,内网公开,排在前面的也没啥用(其实这里,我忘记在外网搜索了,其实 github 是可以搜索到一些相关信息的)。

代码搜索(阿里内部代码仓库搜索平台)下吧,不过这次我为了更精确的匹配使用了关键词“remote-debug-agent”,有戏!

路径完全一致,QA 出品,放在 euler-service 的仓库里,难道插件名字叫 euler?这脚本里好像执行了 appctl.sh restart 重启!

赶紧再次在插件市场搜索了下,果然有!

登录预发机器看看 staragent 的插件目录,没错,就是你,原来叫 euler !

进去目录看看实际的脚本,果然与代码搜索到的基本一致:

看看逻辑:

  • 在预发、测试、日常、项目环境下,如果 remote-debug-agent.jar 不存在,就从 oss 下载到 /home/admin 目录下

  • 如果 remote-debug-agent 已经被挂载了,就啥也不干

  • 如果 remote-debug-agent 没有被挂载,就修改 setenv.sh 脚本里的 JVM 参数,追加 Agent 参数,然后重启应用

难道第二次的重启是为了挂载 remote-debug-agent 这个 Agent?

十一、观察应用的两次重启

第一次重启后,赶紧观察:

等待第二次重启后,观察:

果然,第二次多了 -javaagent:/home/admin/remote-debug/libs/remote-debug-agent.jar!

八九不离十了,应该就是这个 euler 运维插件引起的了。

十二、找插件负责人确认

找 euler 插件的维护同学确认了下是否存在这个逻辑:

哈哈,终于找到了,测试同学表示:你是怎么查出来的,这个很难查到是这个插件引起的。我说,是难,我都打算放弃了。

赶紧约测试同学当面沟通了下,确认了他们的诉求。

他们期望,在不需要开发同学修改代码的前提下,应用预发部署的时候就可以挂载这个 Java Agent,辅助他们采集一些数据。但他们研究了之后,发现无法做到在应用启动前就修改启动脚本里的 JVM 参数,所以只好采取了重启的方式。每 10 分钟左右调度一次,所以才会出现启动 5 分钟后突然重启的现象。他们以为应用启动一般比较快,对开发的影响较小。

其实,正常情况下影响的确很小,但现在的应用一般都需要 3 分钟才能完成重启,同时 magellan 又是高频发布应用(1 个月预发部署 150 次左右),开发人员多,需求多,所以很容易被开发同学发现:

知道了问题,怎么解决呢?简单,近期我正好在和架构组同学在一起开发、推广另一款插件,我们的插件在第一次重启的时候就挂载上了,不用二次重启,赶紧拉上测试同学和架构组同学一起沟通下修改方案(本文重点不在于怎么修复,所以就不放出修复方案相关的内容了)。

确定方案后,测试同学就赶紧回去改代码了,说是太不好意思了,今天肯定优化好。

其实,这有啥不好意思的,大家不都是互相伤害来伤害去的嘛,如果实在不好意思,一杯咖啡的事。

十三、最后

  • 先给 magellan 预发环境摘除了插件,保证开发体验,等插件逻辑修复好了再重新挂载

  • 在设计上,运维容器和主容器在同一个 Pod 内,共享磁盘,运维容器的确有权限操作主容器里的进程,那么在架构上要如何防范呢?我还没有答案,不知各位是否有,有的话,请留言告知。

  • 如果非要说本次排查过程有什么深刻体会的话,那就是“不要放过任何一个可疑的地方”!

十四、补:如果代码搜索没找到,是否还有其他方法

昨晚在回家的路上,在想一个问题,如果在使用代码搜索并没有搜到“remote-debug-agent”相关的任何信息,我是否还有其他方法?

想了一会,发现还有一个笨方法—关键字匹配,即全文搜索“ restart”关键词。虽然笨,但很有效。

先在 /home/admin 目录下搜索,没有结果就在 /home 目录下,还没有结果就在根目录下搜索。

为什么这个方法可以呢?因为看部署日志,一定是执行了应用启动脚本 appctrl.sh 里的 restart 命令,所以一定含有“appctrl.sh restart” 或“ restart”关键字。

搜索的文件太多了,执行有点慢,被我终止了,那能不能快点?

既然要执行这个命令,一般情况下应该是个脚本文件,可以优先在 *.sh 脚本文件中查找。

/home/admin 目录下,结果较少。既然扩大搜索范围,在 /home 目录下有 57 条记录,里面就有 euler-service 插件的脚本:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

下载huggingface预训练模型到本地并调用

写在前面 在大模型横行的时代,无法在服务器上连接外网的研究僧真的是太苦逼了,每次想尝试类似于CLIP,BLIP之类的大模型都会得到“requests.exceptions.ConnectionError: (MaxRetryError("HTTPSConnectionPool(host‘huggingface.co’, …

【Spring】加载properties文件

文章目录 在Spring Context中加载properties文件测试总结 在Spring Context中加载properties文件 分为三步&#xff0c;如下图所示&#xff1a; 完整代码&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.…

2019年12月 Scratch(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 以下程序执行后,角色面向的方向是? A:右上 B:右下 C:左上 D:左下 答案:B 面向-135度,是面向左下角,向右旋转-90度等于向左旋转90度。所以会旋转到右下角。 第2题 以下程…

opencv dnn模块 示例(23) 目标检测 object_detection 之 yolov8

文章目录 1、YOLOv8介绍1.1、概述1.2、骨干网络和 Neck1.3、Loss 计算1.4、数据增强1.5、训练策略1.6、推理过程 2、测试2.1、官方Python测试2.2、Opencv dnn测试2.3、测试统计 3、训练4、Yolov8-pose 简单使用 1、YOLOv8介绍 YOLOv3之前的所有YOLO对象检测模型都是用C语言编写…

从算法到应用:直播美颜滤镜SDK的全面解读与评测

直播美颜滤镜SDK技术逐渐成为直播平台不可或缺的一环。本文将对直播美颜滤镜SDK进行全面解读&#xff0c;深入探讨其算法原理和应用效果&#xff0c;并通过评测分析展现其在直播领域的实际价值。 一、算法原理解读 直播美颜滤镜的背后是复杂而精密的算法&#xff0c;旨在提升…

OpenCV快速入门:绘制图形、图像金字塔和感兴趣区域

文章目录 前言一、绘制图形1. 绘制直线2. 绘制圆3. 绘制矩形4. 绘制椭圆5. 绘制多边形6. 绘制文字7. 可选参数8. 手工绘制OpenCV的logo 二、图像金字塔1. 高斯金字塔2. 拉普拉斯金字塔 三、感兴趣区域&#xff08;ROI&#xff09;数组切片方式OpenCV截取方式 总结 前言 OpenCV…

修改服务器端Apache默认根目录

目标&#xff1a;修改默认Apache网站根目录 /var/www/html 一、找到 DocumentRoot “/var/www/html” 这一段 apache的根目录&#xff0c;把/var/www/html 这个目录改 #DocumentRoot "/var/www/html" DocumentRoot "/home/cloud/tuya_mini_h5/build" 二、…

echarts 横向柱状图示例

该示例有如下几个特点&#xff1a; ①实现tooltip自定义样式&#xff08;echarts 实现tooltip提示框样式自定义-CSDN博客&#xff09; ②实现数据过多时滚动展示&#xff08;echarts 数据过多时展示滚动条-CSDN博客&#xff09; ③柱状图首尾展示文字&#xff0c;文字内容嵌入图…

【C++】内存管理

目录 C/C内存分布 C语言中动态内存管理方式 C内存管理方式 operator new与 operator delete函数 匹配使用的相关问题-内存泄漏: delete与delete [ ] malloc/free和 new/delete的区别 内存泄漏 C/C内存分布 栈又叫堆栈--非静态局部变量/函数参数/返回值等等&#xff0c;栈…

人工智能引领环境保护的新浪潮:技术应用及其影响

在全球范围内&#xff0c;环境保护已经成为一个迫切的话题。随着人工智能技术的发展&#xff0c;它开始在环境保护领域扮演越来越重要的角色。AI不仅能够帮助更有效地监测环境变化&#xff0c;还能提出解决方案来应对环境问题。 污染监测与控制&#xff1a; AI系统可以分析来自…

redis运维(十)列表

一 列表 强调&#xff1a; 知道原生redis具备的能力,以便后续API调用 ① 基础概念 备注&#xff1a; 单个list最多2^32-1个元素 列表操作常用命令,涉及&#xff1a;CURD ② lpush 左插入 说明&#xff1a; 如果key不存在就会初始化,否则就是插入元素备注&#xff1a; l…

指针——C语言初阶

一.指针基本概念&#xff1a; 指针是内存中一个最小单元的编号&#xff0c;也就是地址平时口语中说的指针&#xff0c;通常指的是指针变量&#xff0c;是用来存放地址的变量 #include<stdio.h> int main() {int a 0;//a是整型变量&#xff0c;占用四个字节的内存空间&a…

Linux系统(CentOS7)上安装MYSQL8.x

Linux系统是CentOS7版本&#xff0c;今天在新电脑上安装MYSQL&#xff0c;跟着网上的文章&#xff0c;尝试了好几次&#xff0c;都是启动失败&#xff0c;删了安&#xff0c;安了删&#xff0c;搞了一下午&#xff0c;头昏脑胀&#xff0c;网上的一些文章太乱了&#xff0c;每种…

SSM框架

SSM SSM框架说明SpringBootMyBatis整合MyBatis数据库中表的设计Pojo对象设计Dao接口设计Dao单元方法进行测试 XML管理整合MyBatis框架映射配置文件的位置XML配置SQL标签常用的SQL标签 动态SQL语句动态删除数据动态修改数据 SSM框架说明 Spring 指 Spring Framework&#xff0c…

前段-用面向对象的方式开发一个水管小鸟的游戏

首先准备好各类空文件 index.js css html 和图片 图片是下面这些&#xff0c;如果没有的可在这里下载 2 开发开始 好了&#xff0c;基础准备工作完毕&#xff0c;开发开始&#xff0c; 首先&#xff0c;先把天空&#xff0c;大地&#xff0c;小鸟的盒子准备好&#xff0c;并…

Redis数据库双写一致性解决方案

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

好用的企业防泄密软件盘点

企业防泄密软件是专门设计用于保护企业敏感信息不被泄露的软件产品。这类软件通常采用多种安全技术和策略&#xff0c;以增强企业数据的安全性和保密性&#xff0c;防止核心知识产权和商业机密的泄露。 企业防泄密软件的主要功能包括数据加密、访问控制、审计和监控、文件和数据…

CSS样式穿透

当我们在vue项目中使用第三方组件时&#xff0c;有时候需要去修改某些元素的样式&#xff0c;但有时写的css样式不会覆盖组件的样式&#xff0c;所以要用到样式穿透。 常用的方法有这几种&#xff1a;&#xff08;1&#xff09;>>> &#xff08;2&#xff09;/deep/ …

flink中配置Rockdb的重要配置项

背景 由于我们在flink中使用了状态比较大&#xff0c;无法完全把状态数据存放到tm的堆内存中&#xff0c;所以我们选择了把状态存放到rockdb上&#xff0c;也就是使用rockdb作为状态后端存储,本文就是简单记录下使用rockdb状态后端存储的几个重要的配置项 使用rockdb状态后端…

电子器件系列44:环形线圈电感

干货&#xff01;电感最重要、最常见的几个作用_线圈 环形线圈电感的原理&#xff1a; 电感中包含了哪三个物理学定律&#xff0c;为什么它能以磁场形式储能_哔哩哔哩_bilibili 电感的基本原理_哔哩哔哩_bilibili 环形线圈电感的作用: 1.储能器&#xff1a; 环形线圈电感能够…