app服务治理(一):异常快速发现

字数 2703阅读 893

导语:SOA(Service-Oriented Architecture,面向服务的体系结构)服务治理已经提出多年,但仅限于serve端,始终没有深度辐射到app端。借鉴SOA服务治理思想,我们设计和实现轻量级的app服务治理系统,旨在解决app中最紧要的治理问题。其中,异常快速发现是我们最先解决的问题,本文将重点介绍。

1、背景

SOA的出现,标志着软件开发模式从汇编语言->面向过程->面向对象,进入到面向服务。SOA使大规模系统间的连接变得更加容易,软件开发领域大分工革命变成可能。然而,连接规模越大,SOA系统越不稳定,为此,国内外以IBM、oracle、阿里等为首的诸多企业,都对如何有效治理SOA系统进行了长期深入的研究和实践。每个企业理解大同小异,基本都涵盖了服务定义、服务注册、服务监视等几十项细分内容,考虑了服务会遇到的几乎所有关键的治理问题。

SOA服务治理趋于成熟,但仅限于serve端,始终没有深度辐射到app端。虽然有人提到app端的资源治理、安全治理,但并未汲取SOA服务治理的精华,而整套借用SOA服务治理,难免太重,对于很多团队或产品并不适用。基于此,笔者从实际项目出发,借鉴SOA服务治理思想,实现轻量级的app服务治理系统,立足解决app中最紧要的治理问题。

server端服务治理 vs app端服务治理

2、弱水三千只取一瓢:抓住关键问题

借鉴SOA服务治理庞杂的解决方案,我们提炼出最紧要的,加上自己的理解,列出最需要治理的app问题list:

  • 服务定义:一个app模块即是一个治理单元。得益于前端团队的模块化能力,app被切分为多个模块,各个模块有明确的边界,模块彼此间解藕,将治理对象缩小到模块级别,使服务治理变得更简单和安全。
  • 服务发现与注册:要实现对app模块的治理,前提是本系统知道有多少模块、模块名是什么等基本信息,这就要求模块能被发现与注册。
  • 异常快速发现:相当于服务监控,当模块发生异常时,本系统要及时发现。
  • 异常定位:发现异常后,要能够精确定位哪里发生了异常。
  • 异常解决:本系统还应该能够提供异常的解决方案。
  • 系统保护:主要指对server端的保护,比如app流量过大把server端压垮,我们可能需要流控或柔性服务等手段来保护server端。
  • 服务依赖关系:构建服务间的依赖关系,实时更新和可视化反馈。

上述问题list是结合笔者当前项目的实际情况产出的,可能会随时间变化,而不同产品关注的问题也会有所不同

3、目标锁定

本文主要目标是解决上节中标注的问题,即服务定义、服务发现与注册、异常快速发现,其中,异常快速发现是本文重点。其余的问题我们会在后续文章中再讲解。

对于服务定义,是系统设计原则,相当于本系统的能力界限,是其他所有问题定义的前提。

对于服务发现与注册,这个比较容易实现。所有模块元信息(名称、版本、父模块等)存放在配置文件中,通过解析配置文件,得到所有模块信息并存入存储引擎中,完成注册。这里有个问题,如果在app使用时,某个新模块还未注册,那么本系统将失去对该模块的治理能力。如何及时发现新模块?通过jenkins,每一次持续集成都会触发解析,在投入测试和使用前就完成了服务发现与注册。

对于异常快速发现,我们将在下文重点讲。

4、异常快速发现的技术分析

异常快速发现就是当模块发生异常时,本系统要能够快速发现。技术难点在于如何把这个问题转化成可编程的系统模型,而且让这个系统完成尽可能多的任务,减少使用者的工作。

这里涉及到两个问题:什么情况算是异常、发现异常后如何处理。

app异常通常可以由几种数据来衡量:crash、错误请求、性能、耗电量等。当这些数据偶尔出现或增加时,我们认为是正常的,因为没有任何系统保证100%不出问题。但当这些数据在单位时间内超过一定量时,我们认为是异常。这个一定量是多少,因情况而异,比如模块A在10s内出现1次crash算异常,而模块B在20s内出现100次crash才算异常。

发现异常后,我们可以做很多事,比如发邮件通知负责人、关闭模块等等。

综上所述,我们可以做一个策略平台来实现异常快速发现。使用者通过平台配置一些异常监控策略,配好后平台就启动对app数据的监控分析,一旦发现数据满足异常条件,就触发处理程序,如下图:

策略平台整体流程图

此外,我们对策略平台还有一个要求:完成尽可能多的任务,减少使用者的工作。从上图3个步骤来分析:

  • 配置监控策略步骤很容易简化,提供简洁的web页面给使用者即可。
  • app数据分析最大的不便在于数据的采集,我们无法为每个使用者编写数据采集程序(数据源太多),因此需要使用者自己采集好数据,然后传给策略平台。实际上,我们还是为使用者写了一些通用的数据采集程序,比如crash采集。
  • 策略平台根据配好的策略,可以判断是否触发处理程序,但同样,我们无法为每个使用者编写处理程序(处理方案太多),因此需要使用者自己写好处理程序,策略平台只负责处理程序的触发。实际上,我们还是为使用者写了一些通用的处理程序,比如发送邮件。

5、异常快速发现的实现

从处理流的角度来看,策略平台分为数据分析和触发处理,很适合通过MapReduce类计算框架来实现,另外我们对实时性有所要求,最终选择了jstorm。由于jstorm是分布式的,而数据分析的中间结果需要共享,为此我们选择redis进行缓存。策略平台支持丰富的策略配置选项,为了方便扩展,选择mongodb存储。

结合下面的策略系统架构图,我们看一下如何实现异常快速发现。

策略系统架构图

首先,使用者在web平台上配置相关的监控策略。用户需要配置知识策略和应用策略。

  • 知识策略:负责分析数据,扫描所有条件,判断是否满足触发处理程序。部署在架构图两个bolt中。知识策略配置demo见下图。数据过期时间是中间结果存入redis的过期时间。
  • 应用策略:当满足条件时,知识策略将调用对应的应用策略,应用策略再去执行处理程序。部署在架构图的第2个bolt中。可配置项见下图。
知识策略配置demo
应用策略配置demo

结合两个demo图来讲解一下,使用者在知识策略中配了当PAFFRoot模块在10s内crash数>=25时,就触发应用策略heliuxing-app-3,heliuxing-app-3会去执行处理程序(即执行策略执行命令https://sendMail.xxx.com )。

当用户完成知识策略和应用策略配置后,系统将配置存入mongodb。接着,用户写程序来采集用于监控异常的数据,比如crash。采集到数据后,调用一个接口将数据传给策略引擎,策略引擎中的知识策略会分析数据,并将中间结果存入redis。接口参数见下面代码demo。

// inc表示将redis中对应key和field的数据加上value
// set表示用value替换redis中对应key和field的数据
String method = "inc";
String key = "heliuxing-1";    // redis中的key,就是知识策略名
String field = "PAFFRoot";  // redis中的field,就是添加触发应用中的触发应用key
float value = 12;  // redis中的value,对应field的value达到条件时触发应用策略

以上面代码demo为例,数据采集程序传给知识策略heliuxing-1的数据是PAFFRoot模块发生了12个crash,知识策略将<PAFFRoot,12>存入redis,有效期是10s。然后,知识策略将逐个扫描条件,我们配了两个条件:第1个条件配的是PAFFRoot1模块,不满足此条件;第2个条件配的是PAFFRoot模块crash数>=25,但此时crash个数为12,不满足此条件。

在10s内,数据采集程序再次发送了一模一样的请求,由于method选择的是inc,所以会对redis数据累加,此时redis中的数据变为<PAFFRoot,24>。继续扫描2个条件,仍然不满足,退出。

在10s内,数据采集程序第三次发送了一模一样的请求,此时redis数据变为<PAFFRoot,36>。扫描条件时发现第2个条件满足,表示发现了异常,即可触发应用策略heliuxing-app-3。然后heliuxing-app-3取出其下的策略执行命令,即https://sendMail.xxx.com ,执行此url后退出。

到此,一次异常快速发现就完成了。

推荐阅读更多精彩内容