引言
用户在使用EDAS进行应用变更的时候,一定会接触到发布单功能。发布单以图形化的方式展现了应用部署、启动、停止和扩缩容等操作的具体过程,并能查看发布脚本的执行日志,以及出错信息。对于分批进行的变更,用户可以看到每一批变更的具体信息,对于手动分批的变更,还可以在发布单界面里进行“继续”操作。如果需要中途停止变更,可以使用“终止变更”功能强行中断正在进行的操作,从而减少因误操作而造成的损失。
图1:EDAS发布单界面展示
但发布单到底是如何工作的呢?为什么EDAS控制台上的操作可以影响ECS上的应用进程?这些发布单脚本到底是什么?如果发布单里出现了异常,有哪些排查的方法呢?本文将为您一一进行揭晓。
发布单的工作原理
图2:发布单工作原理图
(1)当用户提交应用变更请求以后,会先经过Gateway进行鉴权,然后传递给EAM服务。
(2)EAM服务会将此变更请求生成为一条发布单记录,并存储在Redis缓存中。
(3)AgentServer服务中运行有一个定时任务,会定时从Redis缓存中拉取发布单。
(4)EAM服务将下发发布单任务到运行在ECS上的StarAgent服务。
(5)发布单在ECS上执行并回传日志数据。
这里用户可能会有疑问,为什么EAM服务将发布单放入Redis缓存之后,AgentServer拉取到的发布单任务又返还给EAM来进行下发,难道不是多此一举吗?这里其实Redis不仅仅是缓存,而是充当了一个消息队列。消息队列的能力包括异步处理和削峰填谷,当有大量发布单请求进入系统的时候,EAM会先将数据存储在Redis中,此时发布单提交操作就结束了。但是发布单的真正运行是由下游的AgentServer定时拉取后返还给EAM,从而实现了异步执行的效果。另外因为每个发布单的时间长短不一,但通常都是分钟级,这对于请求响应式的在线服务而言太过漫长,会导致线程池被占满,从而影响系统为后续请求提供服务。引入消息队列以后当有大量请求进入系统的时候会先缓存到队列中,再由系统慢慢消化处理,不至于让系统在高峰期失去服务能力。因此看上去多此一举的设计,在大规模分布式系统中起到了非常重要的作用。
各组件之间的交互时序图如下:
图3:各组件交互时序图
发布单的结构
如图1所示,发布单模型具有一定的结构,从图中大致可以看出发布单有三个层级,如下图所示:
图4:发布单层级图
一个发布单由若干条流水线组成,每条流水线又分为几个阶段,最后一个阶段下面包含一些任务,由此构成了发布单的结构模型。其中Event和Listener是发布单的通知机制,当一个任务结束以后,其通过事件报告自己的完成状态,再由其他组件通过Listener监听该事件进行一些业务逻辑上的后续处理。一个发布单的样例描述文件如下:
图5:发布单样例描述文件
可以看出该发布单有一条流水线(edas-app-deploy)和四个阶段(startPipeline、slbOffline、vipserverOfflineStage和deployApp),而每个阶段下又包含数量不等的任务,比如deployApp阶段包含hsfOffline、preStoreInstance和stopInstance等三个任务。阶段和任务都包含一些描述属性,例如任务之间是串行还是并行执行,每个任务的失败重试次数,以及是否忽略错误等等。
发布单问题排查
图6:发布单问题排查流程
①service类型的任务,主要是涉及外部服务的调用,service类型的任务有(括号中是任务对应的名称,在日志中展示的是括号中的名称):
- Teinge上线/下线(tengineOnline/tengineOffline)
- Tegine配置更新(updateTengineConfig)
- SLB上线/下线、SLB设置权重(slbOnline/slbOffline、reopenSLBInstance/muteSLBInstance)
②agent类型任务,需要通过staragent把命令下发到用户ECS上执行,主要有(括号中是任务对应的名称,在日志中展示的是括号中的名称):
- 下载/安装Tomcat(pullTomcatPack/)
- 下载应用程序包(pullWar)
- 应用实例启动/停止(startInstance/stopInstance)
- Teigine启动/停止(startTengineInstance/stopTengineInstance)
- 下载镜像(pullImage)
- URL/端口健康检查(healthCheckWithURL/healthCheckWithPort)
- 删除应用实例/Tegine实例数据(deleteInstanceData/deleteTengineInstanceData)
- HSF服务优雅下线(hsfOffline)
- 更新Tomcat配置(updateTomcatConfig)
- 更新命令执行所需的python脚本(updateTaskScript)
基本排查步骤
(1)当应用实例生命周期变更操作出现问题,首先通过变更列表,进入发布单详情,查看具体执行失败的任务日志,根据错误具体信息,来定位问题。
(2)Agent类型任务,可以在用户ECS机器上查看/home/admin/edas/logs/tasks/{taskId},用taskId标示(这些日志可以在控制台发布单详情页,具体任务“查看日志”功能中可以看到),也可以查看ECS上的日志/home/admin/edas/script/logs/edas.action.trace;也可以通过查询数据库,查询SQL: select cmd from cmd_record where cid = ‘任务Id’,任务id可以在发布单详情页面具体任务执行日志的最上方查看。
tip:命令执行手动执行时不要最后的-q、–async等,通常以bash开头。
(3)如果命令在机器上执行没有失败,则综合分析agent-server、edas-admin、edas-console的日志,定位错误原因。
(4)service类型的任务,例如Tegine上下线、Tegine状态更新、SLB上下线、SLB权重设置等任务,需要在EDAS服务组件上查看相关日志。
- Tegine任务命令下发在EDAS-AGENT-SERVER/home/admin/edas/logs/changeorder.log,或者/home/admin/edas/logs/agent-server.log中查询,回调日志在edas-admin中/home/admin/edas/logs/admin.log或者/home/admin/edas/logs/tengine.log中查询,参考tegine流程管控流程来定位问题。
- SLB日志在EDAS-AGENT-SERVER/home/admin/edas/logs/slb.log,或者/home/admin/edas/logs/agent-server.log中查询。
- 其他服务类型的日志可以在/home/admin/edas/logs/agent-server.log,或者/home/admin/edas/logs/changeorder.log中查询。
常见问题解决思路
- 命令通道不通
这个直接可以通过发布单详情页中任务执行的日志来定位问题:一般任务执行日志有“please check if service is available”字样,可以在机器上执行pkill -9 staragent && /home/staragent/bin/agent.sh start,然后让用户重置应用实例。
- 普通应用用户ECS目录或文件权限为root,无法操作相关文件
一般在任务执行日志,或者edas.action.trace中会有显示权限不够的信息,可以在机器上执行chown admin:admin {要修改的目录或文件},然后重试。
- Tegine启动、停止失败
大多是一些前置操作失败或者目录权限不正确造成的,通常可以通过重置解决。
- exit XXX 常见错误原因
exit 3: 磁盘满(du -h)
exit 5: 域名解析失败(ping -c 1 $domain 测试)
exit 8: 下载脚本或WAR包失败,通常为4XX/5XX(curl测试)
- Tegine上下线、状态更新失败
查看与tegine管控交互的日志,定位问题,多起是因为Tegine上线的操作失败,造成后续对Tegine的操作失败;可以通过重置解决。
- SLB上下线失败、权重设置失败
通过查询EDAS-AGENT-SERVER/home/admin/edas/logs/slb.log,或者/home/admin/edas/logs/agent-server.log日志定位。
作者:唐睿阿里云智能基础产品团队产品专家
阿里云智能中间件和容器团队产品专家,15年企业级分布式架构及业务研发和产品经验,目前主要负责阿里云中间件PaaS领域的产品设计、用户洞察及技术布道等工作。打造更好、更易用、更满足用户需要的阿里云产品。
我们是阿里云智能全球技术服务-SRE团队,我们致力成为一个以技术为基础、面向服务、保障业务系统高可用的工程师团队;提供专业、体系化的SRE服务,帮助广大客户更好地使用云、基于云构建更加稳定可靠的业务系统,提升业务稳定性。我们期望能够分享更多帮助企业客户上云、用好云,让客户云上业务运行更加稳定可靠的技术,您可用钉钉扫描下方二维码,加入阿里云SRE技术学院钉钉圈子,和更多云上人交流关于云平台的那些事。