现在越来越多的组件都是集群化,任务化。我们接下来谈谈任务化的挑战和解决方案。
分布式任务的挑战
以前的进程都是常驻进程。ip都是固定的,如果想知道运行状态,可以说方案就很多很多。最简单的直接用jconsole去连接,jstat去看看。这个都是可行的方案。对于分布式任务,如何找出运行的ip就成了一个问题。一般的开源程序,都会带着管理界面,就是通过自带的任务界面去查看现在是在哪个机器上运行,然后再当做单独的进程进行管理。这个在给诊断调优上带来了很大麻烦,可能大家感觉这个似乎是没怎么麻烦,不就是多了一个步骤获取ip吗。下面我们开始按照生产的标准来操作一下。
- 客户发现程序运行没有满足条件。找运维开发。
- 运维开发根据客户描述,找到了分布式任务,一看任务分布在3个机器上。
- 然后根据任务的执行情况,运行状态等找出了可能有问题的2个。
- 再去申请机器的登录权限吧,毕竟机器的权限是个重要的点,赶紧申请。
- 申请审批下来,进了机器,发现,咦进程已经被管理程序发现异常,杀掉了,任务转移到其他机器了。
- 又开始第一步。运气好的话,这还是个死循环。
生成系统上的权限控制各位严格,不像自己搭建做demo,可以很快的用root等高级权限去登录机器。这个时间周期会发生很多情况了。
我们再看另外一个情况。
- 客户发现程序运行没有满足条件。找运维开发。
- 运维开发一看,这是跑在一个大集群上的分布式任务啊,现在有6000台机器都在运行这个分布式任务。
- 然后一个一个找吧,看看哪个运行很慢,哪个指标不太正常,仔细看看,这个不太正常,但是也不确定是错误的,先记录下来,然后呢,再往后看。
- 等6000看完了,任务都执行完了,刚才的情况已经无法再获取更详细的信息了。
生产集群规模的数量远超我们的想象,数据太多了筛选成了一个大难题。
解决问题
上面描述了分布式任务的难题,我们尝试解决一下问题。
任务失败重试等问题,我们利用主动标识的方式解决。
想在1000个里找你要的,如果没有规律就很麻烦,不如改成,你喊名字,那个人出列。
每个进程可以上报自己的数据,带上自己的pid,暴露的信息,任务信息等。
这样就可以准确的获取到当时进程跑的数据了。我们不知道ip但是可以根据任务名称或者任务的id,找出5个ip的数据,可以看到暴露的指标。
5个确实容易看,这个不解决上千力度的问题。
对于这种筛选,我们应该分两个维度,首先是集群维度,就是要找出问题点。这种数据,往往不需要几千个一起看,都是选择top10,top5来查看,毕竟是找问题,那么问题的表现一般都是伴随着特别高,特别低等。这个其实也是我们常见的一个筛选思路。找出top之后,然后切换视角到单个进程,查看单个进程的详细数据。数量量就从上千到单个了。
如何针对程序迁移呢,例如原来在ip1上跑,出了问题,发现也慢了,也被切换到ip2这里怎么解决。进程某一个时间点上,他肯定是跑在一台机器上的。根据这个问题,我们可以依靠时序数据库他本身的一些功能,例如找出1小时内的一个top,这个必须是有时间线索的,或者说我们持续关注或者增加告警,等下次出现,快速响应。
部署
解决方式其实就是主动上报数据带着足够的信息,这样容易及时发现。因为这个都是动态的,那部署如何去暴露指标是一个难题。我们常见2种方式。
- 自己专属暴露
这里其实就是依靠程序自己编写自己的暴露内容,当自己的程序启动时,就可以把指标吐在一个固定的地方,等待被抓取。 - 公众服务
例如java程序可以利用javaagent,把agent放在一个共享存储上。然后启动的时候加载共享存储的数据,这样不论你跑在哪个机器上,都可以获取到javaagent。通过一些约定的方式,例如启动参数,或者是环境变量等等,获取到任务的id等等。
挑战
上面已经解决了任务飘动以及快速查看错误的方式。但这些还不够,最关键的部分是如何从集群角度分析数据。可能简单的top规则已经不符合需求了,这个就需要业务经验来支撑。如何构建一套规则引擎,这个成了分析的最大挑战。如何找出有问题的数据的方式,我们常见的有最简单的阈值,箱线图,正态分布的标准差。如何更快速的发现问题,这个是在解决基本不可达问题之后,新的挑战。