10.凤凰架构:构建可靠的大型分布式系统 --- 可观测性

本文深入探讨了在大型分布式系统中实现可观测性的重要性,通过分享10.凤凰架构的相关理念,展示了如何利用Java和Golang等技术来监控、诊断和优化系统的可靠性。内容涵盖关键指标收集、日志分析、分布式跟踪等方面,旨在帮助开发者提升系统稳定性。
摘要由CSDN通过智能技术生成
第10章 可观测性
	客观测性,原本的含义是 "可以由其外部输出判断其内部状态的程度"。学术界一般会将可观测性分解为3个更具体的方向进行研究,分别是:
		1.事件日志(Logging)
			日志的职责是记录离散的事件,通过这些记录分析程序的行为,譬如曾经调用过哪些方法,操作过哪些数据库等。输出日志很容易,但收集和分析日志
		可能会很复杂。

		2.链路追踪(Tracing)
			单体时代追踪的范畴基本只限于 栈追踪。微服务时代,追踪就不只局限于调用栈了,一个外部请求需要内部若干个服务的联动响应,这时候完整的调用轨迹
		将跨越多个服务,同时包含服务间的网络传输信息与各个服务内部的调用堆栈信息,因此分布式追踪又称为"全链路追踪"。追踪的主要目的是排查故障。

		3.聚合度量(Metrics)
			度量是指对系统中某一类信息的统计聚合。度量的主要目的是监控(Monitoring)和预警(Alert)。

	在工业界,日志、度量两个领域的胜利者算是基本已经尘埃落定了。日志收集和分析基本是ELK,还有什么变化的话,基本是Logstash可能被Fluented取代的趋势。
度量方面,跟随k8s统一容易编排的步伐,Promethues有而击败了度量领域的Zabbix为代表众多前辈。
	
	追踪方面的情况与日志、度量不同,追踪是与具体网络协议、程序语言密切相关,收集日志不必关心这段日志是由Java还是Golang输出的,对程序来说它们就是一段非
结构化文本而已,同理,度量对程序来说也只是一个个聚合的数据指标而已。但追踪不一样,各个服务之间使用HTTP还是gRPC来进行通信会直接影响追踪的实现,各个服务
是使用Java还是Golang来编写,也会直接影响进程内调用栈的追踪方式。这种特性决定了追踪工具本身不会一家独大,也决定了追踪工具本身具有较强的入侵性,通常是以
插件式的探针来实现。如有 Datadog,AWS X-Ray 和 Google Stackdriver Trace,SkyWalking,Zipkin,Jaeger等。
	
	K8s => Borg
	Promethues => BorgMon

10.1 事件日志
		日志用于记录系统运行期间发生过的离散事件。从打印日志到分析查询之间,还隔着 收集、缓冲、聚合、加工、索引、存储等若干个步骤。

	10.1.1 输出
		好的日志应该像"流水账"一样,无有遗漏的记录信息,格式统一,内容恰当。通常不以数量来衡量日志是否得当,而是以内容来衡量。不该出现的内容不要有,
	该有的不要少。

		不该有的:
			1.避免打印敏感信息
				如密码、银行账户、身份证等敏感信息。可以包含如用户ID等。

			2.避免引用慢操作
				日志打印的信息应该是在上下文中可以直接取得的,如果当前上下文没有,需要专门的远程调用或者从数据库取得,需要考虑是否值得。

			3.避免打印追踪诊断信息
				日志中不要打印方法的输入参数、输出结果、方法执行时长之类的调试信息。日志的职责是记录事件,追踪诊断应该由追踪系统去处理。之所以将其归为
			反模式,是因为上面说的敏感信息、慢操作等主要的源头就是这些原本想用于调试的日志。

			4.避免误导他人	
				日志中给日后调试除错的人挖坑是十分恶劣却又常见的行为。

		不该少的:
			1.处理请求时的TraceID
				服务收到请求时,如果该请求没有附带TraceID,就应该自动生成唯一的TraceID对请求进行标识,并使用MDC自动输出到日志。TraceID会贯穿整条
			调用链路,目的是通过它把请求在分布式系统各个服务中执行的过程串联起来。TraceID通常也会随着请求的响应返回给客户端。TraceID是链路追踪里的概念,
			类似的还有标识进程内调用情况的SpanID。

			2.系统运行过程中的关键信息
				日志的职责就是记录事件,譬如进行了哪些操作、发生了与预期不符的情况、运行期间未能处理的异常和告警、定期自动执行的任务,等等,都应该完整的
			记录下来。原则上程序中发生的事情只要有价值就应该记录。

			3.启动时输出配置信息
				与避免输出诊断信息不同,对于系统启动时或者检测到配置中心发生变化更新时,应将非敏感信息输出到日志中。因为初始化配置的逻辑一般只会执行一次,
			不便于诊断时复现,所以应该输出到日志中。

	10.1.2 收集与缓冲
		写日志是在服务节点中进行的,但我们不可能在每个节点都单独建设日志查询功能。这不是资源或者工作量的问题,而是分布式系统处理一个请求要跨越多个节点,
	为了能看到跨节点的日志,就要有能覆盖整个链路的全局日志系统。这个需求决定了节点输出日志文件后,必须将日志文件统一收集起来集中存储、索引,由此催生了
	专门的日志收集器。

		最初,elk的日志收集与聚合的职责都是由logstash 来承担的,logstash 除了部署在各个节点中作为收集的客户端(Shipper)外,还同时设有独立部署的节点,
	扮演归集转换日志的服务端(Master)的角色。logstash有良好的插件化设计,支持收集、转换、输出的插件化定制,应对多重角色本身没有什么问题。但logstash与
	它的插件是基于JRuby编写的,要跑在单独的Java虚拟机上,而且logstash默认的堆大小是1GB。对于归集部分(Master)这种消耗不是什么问题,但作为节点要部署的
	日志收集器就显得太重了。后来,Elastic.co 公司将所有需要在服务节点中处理的工作整理成 Libbeat 为核心的 beats 框架,并使用golang重写了一个功能
	较少,却更轻量的日志收集器,就是 Filebeat。

		现在 Beats 已经是一个很大的家族了,除了Filebeat之外,Elastic.co 还提供了用于收集 Linux 审计数据的 Auditbeat,用于无服务计算架构的
	Functionbeat,用于心跳检测的Heartbeat,用于聚合度量的 Metricbeat,用于收集Linux Systemd Journald 日志的 Journalbeat,用于收集Windows
	事件日志的Winlogbeat,用于网络嗅探包的Packetbeat,等等。

		日志收集器不仅要保证能覆盖全部数据来源,还要尽力保证日志数据的连续性。如淘宝这类系统,每天的日志量超过了10PB,日志收集器的部署实例达到百万级,
	此时归集到系统中的日志要与实际产生的日志保持绝对一致是非常困难的,也不应该为此付出过高的成本。换言之,日志不追求绝对完整的精准,只追求可控范围内尽可能
	的保持较高的数据质量。一种常用的缓解压力的做法是将日志接收者从logstash和es 转移至抗压能力更强的队列缓存,譬如在logstash之前架设一个 kafka或者redis
	作为缓冲层,面对突发流量,logstash和es处理能力出现瓶颈时自动削峰填谷ÿ
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值