当前位置: 首页 > 科技观察

创业小公司如何做好日常监控运维_0

时间:2023-03-16 14:00:11 科技观察

从大公司到创业小公司,我感触最深的就是“奢入俭难”五个字。过去,公司有完整的框架体系,涵盖分布式日志、监控、实时告警、大数据存储等,有成熟的团队运作。很多时候,用户只需要做好集成即可;刚转到小公司的时候,很长一段时间,技术团队只有3个人,初期很穷很空,而且要生产两个系统的产品,日常业务压力很大,而我们只能用一些粗略的方法来做事。业务的压力和对品质的追求永远是矛盾的。但是该有的必有,所以我们还是尽量抽出一些时间来做一些必要的框架工作。我们认为,监控和警报框架是最高优先级:  1。创业型公司测试不够,出现问题的概率比较高,需要做好监控。  2。一个复杂系统的掌握必然是大量的自动化监控和测量,需要时刻了解系统中各个组成部分的各种运行指标。事实上,有经验的工程师会意识到,做好监控和运维远比你写的功能代码困难和重要。  3。更少的人意味着更高的自动化程度。只有做好监控和自动报警,才能腾出更多的精力去做生意,晚上睡觉。  所以,想要做出可靠稳定的产品,首先要有可靠的监控告警框架来支撑。对于像我们这样的创业公司,需要注意以下几点:  1。有没有成熟的开源产品?大公司可以花一个团队专心做一件事;而在小公司,每个人都是非常宝贵的资源,半个人的成本太高,所以他们会更多的使用开源产品。  2。没有太多的陷阱。开源产品的质量和支持是商业产品无法比拟的,所以我们要选择能hold住、坑少、稳定的产品。  3。是否支持跨语言。我们的产品基本上是C、Java、Python、JSON的混合体,尤其是后端主要是Java和Python。  4。可扩展性是否足够好。我们的业务和数据都在飞速发展,所以我们使用的产品必须能够支撑后期涌入的海量数据。  5.是否有一定的可扩展性。在使用过程中难免会有一些特殊的需求,如何快速的进行一些定制化也是需要考虑的一点。  6。能否同时支持单机和分布式部署?我们的情况比较特殊。我们既有传统的私有化部署软件解决方案,也有公共的SaaS和配套的大规模计算集群。所以我们的很多产品都要实现高低配置,同时通过配置实现无缝切换。监控系统也不例外。  非常重要,需求多,资源少,所以我们还是花心思在监控告警上。下面,我将详细分享我们所做的实践探索。  先看监控  首先说说监控。监控的目的是通过定义各种指标来帮助我们了解产品。从硬件到软件,从LB到后端数据库的实时运行状态,帮助我们发现问题、识别故障、确认恢复。这是最重要的事情。  举个例子  废话少说,我们先看上一张图:  这张图是我们业务系统指标的一个例子,展示了我们pre-nginx的一些指标,通过real-time通过分析nginx日志,我们可以一目了然的了解所有机房nginx的吞吐量、延迟、负载分布、流量等实时信息;我们还可以根据不同的维度进行分析比较,帮助我们有效的发现各种异常情况(图中有小缝隙)。我们目前有数百个类似的指标,通过不同的面板组织起来,并且还在增加。目前公司的原则是,在每个项目开发之前,需要尽可能多地定义相应的指标,并进行详细的监控。  技术选型  眼尖的同学会发现,我们使用的是开源组件grafana。实际上,我们使用influxdb/redis+grafana的组合来进行metrics存储:  1。在我们的SaaS后台,我们采用influxdb+grafana2.0(2.0有单独的后台服务)的组合来存储大量的metrics,同时满足大量数据的写入和监控报警系统的频繁读取,同时保留横向扩展的可能性。  2。在我们的测试环境/私有部署环境中,使用的是redis+grafana1.9的组合。这种组合易于部署且开销相对较低,可以满足少量指标。在实现上,我们按照influxdb的存储结构在redis上拷贝了一份,通过proxy模拟了influxdb的接口。  3。在实现上,我们提供了Python/Java两个库,通过配置文件在redis/influxdb之间无缝切换。各个应用根据自己的需求决定配置,调用api将metrics信息记录到合适的地方;同时框架本身也做了一些组件来收集系统级的metrics(比如上面的例子就是通过syslog服务接收nginx的日志,做实时的metrics统计)。  想出了这样的架构选择,一开始我们也很辛苦:  1。之前公司用的是类似opentsdb的系统,易用性和性能没得说,但是后端强烈依赖于hbase,不适合我们。  2。当时也看过其他针对这种Time-series数据的开源方案,但是目前其实并没有特别好的方案。  3。最后我们选择了influxdb作为主力。这是一个比较轻量级的开源时序数据库,非常适合作为指标使用:它有类似SQL的查询语句,更容易使用;自带简单的管理界面;你可以使用grafana作为前端看板;以及各种语言的客户支持;***,最近还是比较流行的。  4。选择redis的原因是在私有环境中需要一个简单的解决方案;我熟悉它。当influxdb遇到问题时,redis版本可以作为备胎。  5.最初,我们也考虑过使用elasticsearch作为指标的大杀器。然而:  (1)es是重读轻写。由于其作为搜索引擎的起源,它强调索引。当你写一条记录的时候,伴随着大量的索引工作。有人做过实验,es和influxdb的存储关系是10x。所以es注定写入性能不是强项(单机而言),索引的建立必然带来延迟和复杂性。当然有了索引,在做一些过滤和聚合的时候,就会发挥搜索引擎的优势,可以生成更多的报表,也可以支持长期的查询。  (2)Influxdb是一个面向时间序列的数据库。这类数据的特点是数据量大,写入压力大。因此,influxdb不以索引为核心,保证海量数据的快速存储;缺点是没有Index,每次查询都需要过滤全量数据,但基本上可以保证读到最新的数据(没有延迟索引的影响)。因此,influxdb是lightreadrewrite。  (3)我们的指标主要是监控当前情况,偶尔会回溯一下历史。同时,这些数据会被实时报警系统使用,需要更快的响应。从使用场景和成本考虑,我们最终选择了influxdb作为metrics的存储,elasticsearch只作为BI工具。  metrics监控架构  此图概述了我们的监控架构。  1.Python和Java程序通过metrics库将相应的数据发送到指定的地方。  (1)程序中使用的框架组件(如rpc、分布式日志等)将由组件自行管理,便于在框架层面进行统一监控和故障排除。  (2)程序中的业务指标需要工程师手动管理,记录每个业务和程序模块的特殊运行状态。  (3)为了保证后台metrics数据写入的稳定性,我们在client部分进行了一些聚合操作,减少打点数据的数量。  ‘*redis和influxdb做成驱动,通过配置指定,开发者无需关心具体实现。  2。通过jmx,我们可以获取系统数据,并将其输入到metrics系统中,查看每台机器的物理状态(感谢前同事wxc的jmx库)。  3。设置syslog服务,对nginx日志进行统计分析,获取网站访问的各种统计信息。  4。对于外网延迟等其他数据,也可以使用相应的agent进入metrics系统。  5.由于我们的架构是跨数据中心的统一架构,所以我们还需要接收各个分机房的数据。我们在每个机房建立代理接收数据,使用自研的跨数据中心rpc服务来进行数据传输。这样就可以在机房的报表中看到全国的系统运行情况。  6。对于大型在线系统,我们使用grafana2.0直连进行数据展示,历史数据通过proxy完成。  7。对于私有部署环境和测试环境,我们将数据记录在redis版本的tsdb中,通过代理提供influxdb接口无缝连接到grafana1.9(相对轻量级,可以嵌入web应用)中。  其他监控工具  上面介绍的metrics系统解决了我们大部分的问题,是我们监控系统的主要组成部分。同时,我们还使用了其他一些分散的手段:  1.uptime。Uptime是一个开源项目,通过获取网页的心跳数据来检测网页的可用性。如图:  2。系统资源(CPU、内存、硬盘)监控。有许多系统监控工具。一开始我们用的是collectd这个传统工具;后来因为定制化、统一化、训练的需要,改成自己写Java程序,通过jmx获取相关数据,输入到metricsTie中。collectd已停产。  3。脚本和外部工具。当遇到通用系统无法满足的特殊需求时,我们也会通过编写shell脚本来做一些工作。这种方式在开发效率和功能上都比较好,但是不能很好的和其他数据集成;同时,目前网上有很多监控服务,我们也用一些作为自己监控系统的补充和备胎。  二次开发  由于主要依赖开源系统,所以有时需要进行一些二次开发来满足公司的定制化需求。这里有一些有用的例子:  1。Grafana默认的分组展示(groupby)只支持一个标签,这种使用场景比较有限。为了让它支持多版本,我们在两个版本上都修改了它的前端JS代码,如下图,修改后的版本可以显示多个标签组合的数据(这里是我们的rpc统计,延迟所有服务的范围统计)。  2。Grafana不支持聚合嵌套,所以无法实现distinctcount等功能。这个也可以通过修改前端代码来解决。  3。Grafana可以创建多个指标进行对比查看,但是会一直显示最新的数据,不方便进行同比对比。我们前段时间使用代理返回数据来达到这个目的。  4。Uptime检测到https网页会出现证书错误,需要在代码中手动禁用相应的环境变量。  接下来说说报警  光靠监控是不够的,因为这么多的数据和报告是人肉无法追踪到的,所以收集了这么多的数据之后,还需要一个自动化的报警系统来做进一步的监控。分析和处理。为此,我们基于收集到的海量数据开发了一个轻量级的报警系统,包括报警系统的完整架构如下图所示:  本系统主要由DataSource、Drivers、Rules、Actions等组成零件组成:  1。DataSource和对应的Driver对应不同的监控数据源。  2.rules代表我们的一些告警规则。  3.actions是规则末尾的触发动作。  DataSource和Driver  数据源代表不同的数据源,每个数据源由对应的driver获取,抽象成统一的数据格式(我们使用的是time-series-like的格式),从而进行数据抽取系统与规则引擎完全解耦,降低开发复杂度。目前,我们的数据源包括:  1.tsdb中的metrics数据。  2。这是最重要的数据来源。通过获取存储在redis/influxdb中的metrics数据,我们可以对海量的监控指标进行详细的分析。  3。grafana面板可以生成influxdbdsl。我们的报警系统直接支持使用这个DSL进行报警。在grafana面板配置监控项后,用户可以方便的进行相应的告警。  4。通过上面介绍的metricsproxy,可以获得metrics的历史数据,方便进行同比检测。  5.正常运行时间数据。uptime可以监控每一个url,通过获取其数据,可以对网站的生存能力进行报警。  6。其他数据。还有其他类型的数据,比如collectd等,也可以方便的集成到报警系统中。  规则  定期从各个数据源获取统一格式的监控数据后,接下来就是通过告警规则对数据进行校验,验证数据是否超过了预设的阈值。告警规则一直是一个复杂的问题,需要满足各种需求。为此,我们在开发规则引擎的时候,更加注重降低开发的复杂度。目前,我们的规则分为以下两类:  1。具有单一数据源的简单规则。简单规则通过比较每次攻击的监控数据的阈值来获得告警。例如:  (1)上下阈值的比较。这是最简单的一个。一旦定义了上限和下限,就可以找到异常值。  (2)数据可行性比较。当发现某个监控项的数据存在(或消失)时,即告警,用于检查错误指标(或生存指标)。  2。单一数据源组合规则。简单规则产生的告警可能会很多,我们可以通过对简单规则产生的结果进一步处理来减少告警的数量。例如:  (1)多次报警。当简单规则触发的内部告警在一段时间内超过一定次数后,才会发出真正的告警。  (2)警报冷却时间。当相同的告警不断出现时,该规则将相应地抑制它。  (3)悬崖警报。当监控数据出现断崖式特征时,会发出告警。  3。多数据源组合规则。有时候,单一的数据源是不够的,需要计算和获取多个数据源。例如:  (1)同期报警。可以针对同一个监控项拉取不同时间段的两条数据,并发出相应的告警。  (2)组合操作报警。比如监控nginx2xx状态的比例,可以通过计算2xx次数和总访问次数来得到。  这里只是举例说明一些规则类型,实际系统中还会有更多的类型。  动作  获取报警数据后,需要触发一些动作来完成整个自动化。  1。最常用的报警动作是发送邮件。通过为每一类告警设置不同的监控器,可以第一时间将系统异常情况通知相关人员。  2。微信报警,邮件补充。  3。规则引擎产生的数据可以进一步回写到指标系统,用于第二轮监控告警。比如上面说的2xx比例(还有各种比例等等)。这样的话,报警系统就相当于一个时序自动化引擎,做一些有规律的数据处理,这样我们就可以做更好的监控和上报。事实上,这个规则引擎将成为我们后期自动化任务引擎的基础。  有了这个系统,我们的运营监控基本实现了自动化。当系统出现故障时,会有相应的报警邮件进行通知,让开发者可以集中精力进行新功能的研发。  数字化运营  事实上,整套报警监控系统不仅可以帮助我们维护网站/系统的稳定性,提高自动化程度,还可以提高我们的数字化运营能力,最大限度地提高效率整个公司。  1。简单的报告。可视化工具Grafana可以解决大部分初期的报表需求,省去了初期BI人员的投入。  2。定期报告。我们使用报警系统并进行简单的修改。有些监控项可以强制每天早上报警(数据采集选择1天,报警显示详细数据),这样每天早上都能收到过去一天的统计报表。由于复用了现有系统,省略了相关报表功能的开发。  总结  这篇文章是我们近半年来在监控告警方面所做的一些实践探索。事实上,在接下来的日子里,需要做的工作越来越复杂:  1。从其他来源接收数据,同时大力完善公司内部监控系统。  2。完善分布式日志机制,便于故障排除和更细粒度的监控。  3。连接告警监控系统和生产业务发布系统,实现弹性扩容和自动容灾的可能。  作者简介  吕梦奇,上海奇安信息技术有限公司bigsec框架研发负责人,领导底层框架体系和Java服务器的研发。擅长Java研发、分布式系统、监控系统,以及各类开源项目的引入与改造。