个人前端故事----来聊聊react-native应用的健康监控

监控什么

今天咱们来聊聊如何监控你的应用程序,这里的监控说的不是让咱们去监控用户,而是监控应用的健康状态,什么是健康状态呢?对于后端的同窗来讲,在微服务的架构下,每一个子服务是否正常工做、返回的结果是否知足预期,这些就算是健康状态,再举个例子,你的台式机,对于操做系统来讲,每一个硬件是否能正常的工做、工做的稳定性,这些都是须要关注的健康状态。前端

既然咱们关心健康状态,那么咱们该如何衡量一个“设备”的健康状态呢?对于上面的例子,CPU运行的温度、硬盘读取的速度、子服务执行的效率,这些均可以做为健康状态的参考标准。而对于咱们前端来讲,一个服务的响应速度、某个页面渲染的时间、外接设备是否正常运行、以及正常运行的时间比,这些均可以做为咱们衡量一个“设备”是否健康的标准。node

上面说的了要监控什么指标,那这些指标具体的实例又是什么呢?因为我主要作react-native应用的开发,我今天就基于react-native来讨论一下这件事,而对于传统的web,相对来讲就简单一些了,但具体的思路不会差太多。react

在我遇到的实际场景中,个人应用程序经常须要连接多个外接设备,例如:键盘、扫码枪、各类个感应器,因此我须要时刻关注这些设备的健康状态,一旦发现某个设备不能正常工做或者在将来的某个时刻不能正常工做,就须要立刻反馈出来,而这只是一部分,这些物理设备有着很明确的“指标”。web

另外一方面,诸如网络状态、电池电量,这些应用内的“指标”也须要我时刻的关注,何时处于弱网环境、何时出现低电量等各类各样的异常状况都会让咱们的应用程序变得不健康。因此,咱们的目标就是围绕着这两块展开监控,那么接下来我 们说说该从什么地方下手。redis

生命周期

将全部想要监控的服务收集到一块儿,做为一个总控制,而后在总控中对各个服务器的各个生命周期埋点。数据库

一、主动式:手动的从各个生命周期中hook想要的数据,而后经过计算,收集上报。编程

二、被动式: 在各个生命周期中埋点,等待某一类事件的触发。windows

但是这么多设备,若是咱们一个个的去监控、去适配,那就和给windows系统的硬件写驱动同样繁杂了,这对于咱们前端开发来讲工做量实在是太大了,因此为了方便咱们进行统一的管理,和复用统一的代码,咱们须要一个“模式”去规范和统一咱们的设备。后端

如今咱们用一个统一的class去集中监控咱们的设备,另一个问题就是众多的设备,不管是“物理”的设备仍是“虚拟”的设备,若是咱们专门为每一种去写监控代码,工做量实在是太大了,因此咱们可让这些设备在上层表现的“一致”,为此,咱们引入“生命周期”这个概念,在一个设备启动、运行、暂停、卸载的各个阶段,咱们均可以进行监控,不管是扫码器,仍是网络请求的发起,各类各样的形态都逃不过这个步骤,因此,只要能在这个上面作好文章,那么监控各类数据就易如反掌了。react-native

如下我会从两个方面来介绍一下我总结的“基础”的监控项,我的认为,不管你的项目为了应对什么样的场景,下面的这些例子基本都会是“必备”的选项了,即使你的项目比个人项目更加精简,可是下面介绍的思路也会是不错的参考。

主动式监控

上面说了这么多,那么咱们来具体的看看须要监控些什么呢?

在一个项目刚上线的时候,存在着不少隐藏的问题,因此咱们须要更多的日志去监控应用程序是否正常的运行,以及是否按照咱们自身设定的路线去执行,一旦项目稳定,一些模块或逻辑被证明是没有问题的了,那么相应的咱们也要去移除一些埋点日志,另一方面,在开始上线的时候因为用户量少,一旦出现线上bug,因为缺乏案例,致使定位和分析的难度都会增大,因此,这个时候咱们就须要主动的埋一些监控点,来应对这种状况的发生,在出现紧急bug的时候咱们能够经过日志点去推测和演算用户的行为,以及当时的状况。

可是,说到底这些监控都是临时的,不一个长期的监控,因此个人原则也是尽量的不去侵入到业务代码中,不管是经过切面编程仍是高阶组件封装,都要保证这些监控代码能够经过一个或一组规则快速的关闭统计,解放算力。

所以,凡是主动监控都要具有自动判断和动态策略这两个特色,能够动态的感知到当前的状态,从而作出对主业务影响最小的行为,即使监控再重要,也不能由于监控的行为而影响业务进程的工做,这只能是一个锦上添花行为。

被动式监控

为何要有被动式的监控呢?首先,有些监控的相对“独立”的,每一次的监控点并不会100%的触发,每次的触发并不存在上下文或者先后的必然联系。也就是说,这些点的触发都是单独存在的,因此咱们不须要对其进行诸如计算、格式化等分析操做,也不须要保存它的上下文,好比开始、结束时间。

相对于上面介绍的主动式监控,被动式监控的代码和逻辑都会长期的运行,由于在项目的中后期,在移除了大多数异常、性能监控后,这些仅存的代码就成了咱们排查问题的关键所在了。所以,这些监控要保证自身的稳定,以及所积累的信息准确、及时,谁都不但愿看到奔溃或者逻辑错误的警报在发生以后好久才上报出来。

那么有哪些须要咱们作被动式的监控呢?在个人项目中,一个外接设备是否在线,用户点击键盘上某个按钮等行为就是一个典型的被动式监控,我不知道用户何时去点键盘,我也不知道个人外接设备何时断开,我只是须要捕获到这个行为的发生就能够了。

并且对于这些监控点,咱们其实是不须要开发本身去写代码的,它应该存在于依赖的包中,这就避免了我屡次写重复代码的问题,举个例子,我在A项目中有个对扫码器扫描到内容的监控,而在B、C项目中我仍旧须要这个功能,那么我就能够再也不反复的去写这块的日志代码了,由于它应该存在于这个扫码器的包中,我要作的,只是提供一个logger方法而已,返回的格式、内容都不须要我去关心。

而这些经过埋点、用户输入、事件回调等方式收集上来的日志,咱们都要如实的上报到远程服务器(这里和主动式监控有所区别,主动监控的内容能够容许咱们本身计算、统计),由于这些都是真正的异常,之后会影响咱们debug的日志要最大程度的保留现场。

客户端流程图

服务端

上面说了那么多,都是基于客户端去作的,如今咱们在客户端已经准备好了想要的数据,那么咱们该如何去使用他们呢?

对于发送上来的日志,我能够作以下三件事:

  • 监控24小时在线状态
  • 异常指标的快速报警
  • 可视化的展现监控信息

下面咱们就围绕这三点来设计咱们的服务端系统。

对于第一点,咱们能够经过与客户端的心跳包来检查客户端是否存活,由于在业务场景中,咱们的应用为react-native的,因此在检测心跳的时候就要区分是native模块仍是js的业务模块了,同时不少场景下存在无人使用时js业务不会上传日志以及在移动网络下业务精简日志的状况,所以咱们的24小时监控服务就要足够灵活、多变。因此在报警的时候能够经过读取配置的方式在服务器不重启的状况下动态的变换监控规则。

例如什么项目须要监控native存活,什么项目须要监控js环境存活,何时将报警通知给何人,而且能够通知到是什么地方的什么设备出了什么故障,这些都是基础功能。

而第二点,须要咱们作的除了包含第一点以外的功能外,还有一个异常记录的功能,由于第二点的异常具备偶发性,而且相对于心跳包来讲,日志内容更加丰富,所以咱们能够针对这些日志作更多的事情,但首先就是将这些日志分类的保存起来。同时,在第二点中存在不一样的应用对不一样的异常有不一样的定义的状况,好比说A应用认为数据初始化的接口超时就属于异常,而B应用则认为即使超时也不影响,那么就须要为每一个应用单独配置异常指标,从而作到分项目、分阈值的功能。

还有一些额外的拓展,因为上面作的分项目、分阈值处理,就势必存在一些通用异常,那么每一个项目就应该具备继承公共异常的功能,以及一些模板异常的设定。这些都是这个服务所须要的功能。

最后一点,在搜集到异常以及通知到相关负责人以后,此次异常报警就算结束了嘛?固然没有这么简单了,咱们能够基于web服务来查看一些日志的基本状况,例如什么项目报警最多,什么地方报警最多,什么时间报警最多等等图表提供咱们查看和分析。更有甚者咱们能够根据不一样的报警级别给不一样的人发送不一样的报警内容。

最后是这个服务端自身的健壮性,因为咱们的服务是基于nodejs来作的,所以经过pm2,我能够很方便的在进程挂掉以后立刻恢复服务,同时为了服务相互解耦和最大化cpu效率,经过pm2启动脚原本将24小时离线服务、异常指标报警、日志分析展现服务相互独立开,并为能够启动多线程的服务提供cluster模式的支持。而且将共享的数据经过redis缓存,配置经过数据库持久化等方式来备份和保证服务的健壮与高效。

服务端流程图

总结

至此,一个由客户端+服务端的健康监控系统初步完成。它们这些服务看似相互依赖,但又相互解耦,不会形成一个环节失效致使整个系统奔溃,同时又能够作到对正常业务最小化的侵入。

固然,这些都只是一个雏形,一个所有由js去完成的项目,相对于大公司那些完整而又系统的监控来讲,仅仅只能做为开发业务的咱们自查的一个工具。虽然有这些系统来保证咱们的项目正常、健康的运行,可是更重要的是咱们开发者本身代码的健壮和稳定。工具作的再好,也不能替代咱们本身写的优异的代码。

相关文章
相关标签/搜索