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

如何快速实现一个基于Nginx网站的监控场景

时间:2023-03-16 23:16:38 科技观察

一切从应用服务监控开始小明所在的一家小型互联网创业公司,一直在阿里云上运行应用。应用采用通用的分布式Nginx+App架构,为用户提供电子商务数据统计的webservice服务。应用运行至今,除了偶尔出现各种bug和性能问题,情况还是不错的。undefined最近,小明的老板给小明布置了一个任务,希望对应用服务进行监控,提高应用运行质量。老板需要三点:1、首先从应用服务监控入手,能够实时统计各种服务的调用次数。基于a,实时统计各种服务返回值的个数,比如200、404、500等。基于b,如果某类返回值调用超过限制,会实时报警。2、提供历史查询功能,可以随时返回任何服务的任何返回值的调用次数统计。3、未来公司的各种定制化业务监控可以快速扩展到系统中,比如各个接口的响应统计时间、用户特征统计等。“监控平台最好在阿里云上搭建,数据不要放在第三方云上,主要是为了公网流量和以后大数据分析的成本做准备。”老板最后说。到达。技术选择接到任务后,小明开始进行技术选择。摆在他面前的是三个看似可行的选择,传统的OLAP式处理、搜索引擎、实时计算。undefined调研了现状和很多技术后发现,因为公司业务规模不小,白天高峰期的平均QPS达到了几百,而且业务还在快速增长,所以每秒几百条调用信息直接被存储在数据库中实时查询肯定是不合适的,成本太高也不适合扩展。阿里云提供搜索引擎服务,错误统计功能基本可以满足老板的需求。但有两个不确定因素。一方面,搜索引擎价格存储成本高(搜索引擎需要引入索引存储),接口响应时间统计等各种聚合查询的查询响应时间不易保证。另一方面,考虑到实时告警,API需要不断的写Poll各种类型调用的错误次数,性能和成本都不太确定。基于实时计算架构,所有在线日志可以通过服务、返回值错误类型、时间等维度在内存中实时聚合计算,持久化存储。一方面,实时计算效率高,聚合后的结果规模会比原始数据大为减小,持久化成本低,实时性得到保证;另一方面可以在内存中实时验证告警策略,使得告警的性能开销足够小。基于以上考虑,基于实时计算的架构似乎最符合当前公司的需求。做出决定后,小明开始思考进一步的架构设计。在架构设计确定了基于实时计算的技术后,小明开始着手进行架构设计。通过查阅各种技术网站,他发现要构建可靠的网站监控解决方案,以下组件不可或缺。数据通道:负责从Nginx中拉取数据,传输给搜索引擎。数据通道同时承担着数据积累和数据重新计算的任务。计算引擎:基于Nginx服务,需要根据选择的引擎编写错误码和时间维度的聚合实时计算逻辑。计算引擎最好同时负责一些告警逻辑。Storage:存放最终Nginx监控结果的地方。考虑到监控结果虽然表结构简单,但是各个维度的查询较多,最好使用类似于OLAP的存储类型。展示入口:多维度快速分析展示所有Nginx监控结果。undefined幸运的是,对于前三个组件,阿里云提供了一些现成的产品组件,小明不需要手动一一搭建,入门门槛并不高。数据通道,小明在阿里云上选择了类似Kafka的数据通道,不仅支持性能和消息积累,而且在数据访问上也提供了一定的简单性。在计算引擎上,为了简单起见,小明选择了基于spark-stream的计算引擎组件,直接在上面写SQL语句进行实时计算和编排,不用自己写流式计算程序。在存储方面,小明选择了类似Hbase的云存储产品,因为他对东西没有太多的需求,对容量的要求很高。在展示入口方面,没有直接对应的产品。小明挠了挠头,决定只能自己偷袭前端编程技术,基于开源展示框架写一个简单的查询入口。跟老板申请了预算后,小明开始打开各种产品进行开发测试。任务预计1个月完成,漫长的开发之旅开启过程非常简单。不到半天就搞定了kafka、storm、hbase的租户集群。不幸的是,俗话说,开发项目80%的时间都花在了最后20%的陷阱上。该项目已有一个多月的历史,但该功能尚未完成70%。小明在自己的技术博客上默默记录了以下坑。集成故障处理的成本是由于需要在代码中集成数据通道、实时计算层、后台存储等组件,并在代码中集成推送数据逻辑和告警查询逻辑。每一个环节稍有失误都会导致整个环节的阻塞,调试成本非常高。在日志清洗开发期间,为了获取相关应用和调整日志推送逻辑,需要在各个Nginx的日志内容发生变化后,在各个服务器上更改API推送逻辑。变更过程漫长且容易出错。持久化表的设计除了要针对监控项做出合适的表库设计,避免索引热点,还需要考虑在实时计算层不稳定导致数据结果重复计算时,如何保证数据库写入的幂等性。表结构设计是一个不小的挑战。延迟数据合并如果Nginx日志数据由于应用原因延迟,如何保证延迟1小时的数据能够被实时计算引擎准确计算出来并与之前的结果合并。告警需要给所有结果设置一个定时任务,每分钟遍历查询一次数据。例如,对于任何一个返回500次调用错误中5%以上的服务,所有服务都需要进行多次调用结果进行遍历查询。如何保证查询高效,不遗漏所有服务错误检查,也是一个很大的挑战。告警的准确性有时是因为日志的延迟,一些服务器的正常日志最后一分钟还没有采集到,导致一些500调用错误服务暂时超过5%。类似错误需要报警吗?如果报警,可能会误报,没有报警如果是,可能漏报,怎么处理?如何统计UV,TopN以UV为例。如果要跨任何时间尺度查询UV,传统的方法还需要在数据库中存储单位时间(如分钟级别)的全量IP访问信息。这对于存储利用率来说显然是不可接受的。有没有更优化的解决方案?错误场景的诊断方法针对各种返回值为500的调用错误,业务方建议在出现500错误时,可以根据时间和调用业务维度查询详细的调用入参等详情。场景类似于日志搜索。对于类似的新需求,似乎不能直接实现实时聚合计算和存储。需要另寻他法来处理日志。上述问题不包括上一段中显示的各种问题。算起来,两个月过去了。工程还没完成一半,小明有些着急。又一个新思路小明晚上约了师兄老旦一起蹭。喝了点酒,小明将自己最近的烦恼从头到尾告诉了老丹。老丹一听,拍了拍大腿:“小明,你太特别了,其实阿里云上有一个云产品,叫业务实时监控,简称ARMS,基本上你遇到的问题都已经解决了。”ARMS上提供。一站式解决方案,您只需快速接入。”。“哦,是这样吗?我们很多业务监控逻辑都是基于Nginx日志定制的,ARMS有访问Nginx日志的能力,是否允许我定制业务监控能力?”小明问道。”当然。ARMS不仅提供了监控Nginx的任务模板,还有自己的告警和监控报表,还开放了全程定制化能力。如果你想添加自己的业务监控逻辑,或者删除修改一般的监控逻辑你不要,可以直接在它的平台上定制即可。”老丹回答。undefined“听起来不错。除了报表和报警,公司的下游业务平台也可以用吗?”“可以,ARMS提供API,下游系统可以直接对接数据API,可以直接读取云端的数据库。没有本质区别。”“听起来不错,看来我的项目可以省了,我去看看。”实现一个基于Nginx的网站监控场景1.ARMSNginx监控方案概述及准备目前流行的Nginx监控方案在监控领域,数据处理的方式有很多,比如搜索引擎、时序数据库、实时计算,甚至大数据离线计算等,ARMS采用实时计算+列式存储,这种方案的优势是实时数据高,对于固定数据查询接口查询效率非常快,在Nginx的监控方案中,其架构大纲如下,蓝色部分为开箱即用ARMS集成的Nginx监控黑框,由于ARMS的分析是针对Nginx的access.log日志,因此对Nginx日志有一定的要求,用户需要在nginx.config中配置打印的内容,包括:“$upstream_response_time""$request_time"等代表请求信息花费时间的日志。例如:log_formatmain'$remote_addr-$remote_user[$time_local]$status''"$request"$body_bytes_sent"$http_referer"''"$http_user_agent""$http_x_forwarded_for"''"$upstream_response_time""$request_time""$user_cookie_id"';这种情况下,打印出来的日志大致如下表所示。58.211.119.29144288-[16/Mar/2017:21:47:07+0800]"POSThttp://arms.console.aliyun.com/api/query.json?action=DataQueryAction&eventSubmitDoQueryData=1"200594"https://arms.console.aliyun.com/""127.0.0.1:8080""Mozilla/5.0(WindowsNT5.1)AppleWebKit/537.4(KHTML,likeGecko)Chrome/22.0.1229.79Safari/537.4""0.144""0.144""EX866MB1-Y70JO57WM37ST3HWDVFK3-JWPNH30J-Z"58.211.119.29148219-[16/Mar/2017:21:47:08+0800]"POSThttp://arms.console.aliyun.com/api/query.json?action=DataQueryAction&eventSubmitDoQueryData=1"200583"https://arms.console.aliyun.com/""127.0.0.1:8080""Mozilla/5.0(WindowsNT5.1)AppleWebKit/537.4(KHTML,likeGecko)Chrome/22.0.1229.79Safari/537.4""0.148""0.148""EX866MB1-Y70JO57WM37ST3HWDVFK3-JWPNH30J-Z"完成以上日志配置自定义后,就可以开始在ARMS上进行配置了。下面分三部分介绍配置:ARMS数据集、告警、交互面板。ARMS中如何添加数据源请参考文档,这里不再赘述。2、基于ARMS的Nginx监控数据集在Nginx监控模板中实现。用户数据分为两类,一类是指标,相当于数据仓库中的Measure;另一个是维度,相当于数据仓库中的Dimension。对于Nginx监控,最常见的指标有以下几类指标:页面的PV,UVPV:页面的PV是通过统计access.log中的每条日志来统计的,UV:日志中对应的用户ID$cookie_id做countdistinct来计数。对应的cookie_id需要开发者手动统计。PageResponseTime页面平均响应时间:在ARMS中,total_request_time是通过对$request_time进行求和运算得到的,然后通过国际total_request_time/pv得到某个维度的瓶子的平均响应时间。MaximumResponseTime:对单个日志request_time进行最大统计。页面流量平均页面流量和最大页面流量:供$body_bytes_sent统计。统计方式与页面响应时间类似,不再赘述。对于Nginx监控,最常见的维度如下:页面URL:$request。用户可以对特定网址进行访问统计,甚至可以对不同网址进行访问排名。该页面返回状态:$status。用户可以对不同的返回值维度进行统计,比如只统计返回值为200的正常页面访问,或者返回值为非200的错误页面访问。浏览器类型:根据$http_user_agent统计的用户浏览器客户端,比如Chrome、Safari、IE、Firefox,甚至Curl命令等,用户可以根据这些维度统计客户端的分布情况。UserID:根据$cook_id的统计,用户的使用习惯,比如哪些用户经常访问哪些类型的页面等。ARMS的数据集设计其实就是对Nginx监控的各个维度进行排列组合用户感兴趣的结果。比如在页面URL维度统计UV、PV、页面响应时间,可以统计不同页面各自的UV、PV、页面响应时间,甚至可以根据TopN进行排名以PV为例。下图是数据集配置的示例。数据集配置了URL和Status两个维度(支持URL下钻到Status的查询方式),分别统计两个指标:PV和UV。这样用户就可以依次向下钻取页面路径和返回值,查询PV和UV情况。下图是另一个数据集配置的例子。该数据集配置了两个与上例相同但顺序相反的维度:Status和URL(支持Status下钻到URL的查询方式),分别统计两个指标:PV、平均响应时间、最大响应时间。其中,平均通话时长是一个复合指标,由整体通话时长/PV间接得出。3、基于ARMS实现Nginx监控告警常见的Nginx告警如下:某类页面响应时间过长。某类页面的错误率页面过高。使用ARMS的原生告警的一些特性天然支持Nginx监控告警的各种场景。下面的例子。支持某些类型指标的维度下钻遍历。比如检查(遍历)所有页面维度的响应时间是否超过100ms。支持不同指标之间的复合计算。典型的例子是错误代码是5xx。并得到。支持其他各种告警高级告警配置包括最后N分钟同比、环、最大值、最小值比较等。例如最近5分钟PV同比下降50%的典型场景。下面的例子结合了以上三个特点,介绍了如何在ARMS中定义一个“一分钟内任意URL调用500次,返回10%以上”的告警定义的例子,如下图。4、基于ARMS的Nginx监控面板配置监控面板一般有以下用途:挂在作战室,全面掌控运行状态。用于实时查看和深入分析每个特定用户或网页的实际网站使用情况。对于Nginx监控,ARMS可以根据相似的用户维度、页面维度、IP维度,甚至地域维度展示不同的数据。以展示用户整体UV、PV为例,假设对应的数据集为“全站UVPV”,配置如下:最终的交互dashboard效果图整合了各种UV、PV、响应时间和其他统计如下:5.立即快速上手以上各种Nginx监控场景。目前ARMS上已经有成熟的商业模板支持。用户只需在ARMS首页点击“新建标准模板监控”,选择Nginx高级模板即可。想要了解更多分布式监控,欢迎参与首届阿里巴巴中间件技术峰会线上举办,揭秘阿里巴巴10年分布式技术积累!阿里巴巴高可用系统核心缔造者、全链路压测创始人、DRDS和TDDL负责人等大咖登场,干货分享,不容错过!