49

微服务日志的七种最佳实践

 5 years ago
source link: http://developer.51cto.com/art/201811/587412.htm?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【51CTO.com快译】 微服务架构 是一种全新的应用结构,它能够帮助您通过松耦合的系统,开发、测试、部署和发布彼此相互独立的各种服务。因此微服务背后的理念是:将大型系统分解成多个独立的小部分。

通常情况下,每个服务都能通过HTTP的端点与其他服务交互。它们在隐藏技术栈细节的同时,会暴露自己的契约(contract)给其对应的消费者(consumer)角色。例如:服务A可以在调用服务B的同时,也去调用服务C,而只要整个请求链是完整的,那么服务A就能够对发起请求的客户端做出响应。

微服务架构能够给我们的系统带来很多方面的好处,其主要能力包括:使用不同的技术栈、独立地进行部署、一次只解决一个小问题等。但是,由于它在通信和管理上的复杂性,一般使用微服务的成本会比较高。而且在一个或多个服务出现问题时,微服务会变得更加复杂。如果没有掌握良好的、且有意义的日志的话,你都无法回答诸如:哪个服务、为什么、和在什么情况下失败了等问题。

老实说,我本人最憎恨那些由于糟糕的日志策略,所导致的一些“未知”的系统错误。下面我们和您分享一些,自己在与微服务打交道时总结出的七种最佳实践。

1.用唯一性ID来关联各个请求

请回想一下我们上面提到的服务A、B、C之间的请求调用链。在实践中,我们应当给每一个调用分配一个唯一性的ID,以便标识出每一个请求。

设想您正在记录每个服务的访问与错误日​​志。如果您发现在服务B上有错误,那么您就能知道该错误是来自于服务A、还是服务C。

如果错误信息足够详细的话,您也许不必去重现错误。但是多数情况并非如此,您必须通过正确的方式,将各个服务(如服务B)中的所有请求进行错误重现。因此,如果您发现了某个与之相关联的请求,那么您只需要在日志中寻找出它所对应的ID便可。

随后,您可以顺藤摸瓜地从系统中将那些主要请求的某个部分,从服务的全量日志中截取出来。接着,您就可以知道是哪项服务的主请求花费了最多的时间。其可能性包括:可能是某项服务使用到了缓存、或是某项服务不止一次调用了其他服务、以及其他有趣的细节。

2.在响应中包含唯一性ID

微服务的用户可能会不止一次地碰到同一个错误。面对这样的情况,您应该乘机对客户端可能接收到的响应进行编码,以便它能够将一个唯一性的ID,连同与该错误相关的任何其他有用的信息都传递出来。当然,这个唯一性的ID完全可以和我们在上面所提到的相关请求保持一致。

YvUbYfR.png!web

因此,在响应的有效载荷中包含与请求相关的唯一性ID,将有助于您和您的客户更迅速地发现各类问题。同时,您也可以获悉请求日期、时间和其他细节上的参数,以便您能够更好地理解自己所碰到的问题。另外,您还可以将请求的ID,添加到诸如“请联系服务管理员,并报告该问题。”之类的常见补充性错误信息之中,以便深入了解到底是什么原因引起该错误,进而防止它在未来再次发生。

3.发送日志到集中的位置

在此,让我们假设您已经对各种有用的日志信息进行了分类。下一步,我们就需要将各类日志发送到一个集中化的位置。

试想一下:如果您每次都需要登录到各个相互单独的服务器上,以来读取不同的日志信息,那么您将不得不花费更多的时间去试图关联这些问题。这远不如您登录到某一个位置,并一站式地访问到所有的日志,以定位问题。

此外,您的系统通常会随着时间的推移,而变得日趋复杂,而各项微服务的数量也会节节攀升。同时,您的各种服务可能会分处不同的服务器或提供商,这都会让形势变得更为复杂。

因此,集中式存放日志正在成为业界的常规方法,特别是当您的服务工作在云端、容器、或其他混合环境之中,而某些服务器可能会在无任何通知的情况下下线的时候。例如,在出现异常错误,或是内存的消耗水平已经达到100%时,某些容器就会被终止运行。

您可以在服务器中断之前,通过设置代理,每五分钟推/拉一次日志,来解决此类问题。您也可以在服务器上配置一个cronjob(定时任务)、sidecar container、或是一个与其他进程共享的文件位置,来集中化各种日志。为了避免日志被篡改,您还可以自行构建一套解决方案,具体请参见链接: https://blog.scalyr.com/2017/11/log-management-need/

可见,将所有服务的日志都集中到一处,会有助于您更容易、且有效地定位各种关联问题。

4.结构化您的日志数据

在具体实践中,我们很难为所有的日志数据预先定义好格式。有些日志可能需要比其他日志更多的字段,相反这些字段可能会对那些不需要的日志来说不但多余、而且浪费字节数。

微服务架构是通过使用不同的技术堆栈,来解决此类问题的。不过,这会影响每个服务的日志格式。例如:某一个服务可能是用逗号来分隔不同的字段,而其他日志则使用的是管道或命名空间。

上述方法显然比较复杂。因此,我们可以通过将自己的日志数据构建成一套标准的格式,如:J avaScript Object Notation (JSON),来简化解析日志的过程。JSON允许您拥有多层次的数据。在必要的时候,您可以在单个日志的事件中获取更多的语义信息。

同时,此法也使得对于特定日志格式的解析更加直接。通过对数据采取结构化,就算您的日志里有各种不同的字段,其格式也会变得更加标准。籍此,您也可以在集中化的位置上创建各种搜索,例如:检索包含有500条及以上,“HTTP_CODE”字段的日志信息。可以说,使用结构化的日志方式既能让您的微服务日志实现标准化,又不失灵活性。

5.为每个请求添加上下文

vAbu63E.png!web

通常情况下,如果系统能够提供足够的信息,那么我们就能够更好地了解针对某个问题的上下文请求,更快地发现该问题的根本原因。不过,给各种日志添加上下文,也会在代码层面上产生一些重复性的工作,因为在您所需要的许多日志事件中,已经包含了诸如日期和时间等通用数据信息。因此在我们的代码中,应当只记录那些重要的消息、并涉及到一些特定的领域,以使得日志看起来简单明了。

您可能会想到各种五花八门的数据需要被记录,但是让我们通过如下的列表,来告诉您哪些才是真正需要记录的具体特定领域吧。

  • 日期和时间。当然,如果能够保证读取日志的人都在同一时区的话,您大可不必一律采用UTC(世界标准时间)的格式。
  • 堆栈错误。您可以将异常对象作为参数传递给自己的日志库。
  • 服务的名称或代码,这样您就可以根据微服务来区分不同的日志。
  • 发生错误的函数、类或文件名,这样您就省去了跟踪问题出处的时间。
  • 与外部服务交互的各种名称,例如:您可以获悉是哪个进程在调用数据库时出现了问题。
  • 服务器和客户端请求的IP地址。这些信息将有助于发现那些不健康的服务器、或识别出 DDoS类攻击
  • 应用程序的用户代理,以便您能判断是哪些浏览器或用户碰到了问题。
  • 通过HTTP代码来获取错误的更多语义。这些代码将有助于创建各类警报。

可见,为每个请求添加上下文,能够节省您对系统进行排障的时间。

6.将日志存储到本地

将日志存储到本地,似乎听起来和我们前面说的“发送日志到集中的位置”有些矛盾,其实则不然。最初我是将各种日志,直接通过HTTP请求的方式发送到别处的。但是我屡次发现这些流量传输占用掉了我大量的出站带宽,以至于影响到了其他更为重要的微服务调用。

因此,我们需要对日志的外发和本地存储有所取舍。最终,我之所以选择了本地存储,是因为这样有助于从应用程序中分离日志、并减少上下文的切换。针对数据库,您可以采取将应用程序与其日志区分不同存储卷的方式。

例如: 亚马逊的AWS 就一个选项,用户可以使用一种称为 Elastic File System (EFS)的服务,去挂载某个卷。其功能类似于网络附属存储(network-attached storage,NAS)。那么,您可以按需辗转到另一台服务器上,挂载相同容量的卷,然后将各种日志转发到那个集中的位置上。

简单说来,我们可以使用Docker容器,来实现将所有应用程序的日志都发送到相同的位置。然后汇总、过滤和转发这些日志的存储库,到其他进程或服务那里。

7.记录重要且有意义的数据,有备无患

如果您是刚开始接触微服务的日志问题,那么上述最佳实践可能会对你比较“无感”。但是,只要您足够细心,在持续使用了微服务一段时间之后,您就可以通过对现有日志信息和方式的评估,逐渐摸索出哪些才是您可以用来发现和解决奇怪问题的有用信息。

同时,在记录和积累了足够多的日志数据之后,您还可以伺机采用自动化的警报方式,以节约您通过读取大量日志来定位问题的时间。当然,自动化警报也能够帮助您以一种积极主动方式,限制各种错误向所有用户处蔓延。

总之,集中化日志信息,是微服务错误分析的必备手段。而为日志添加足够多的上下文信息,则能够更好地分辨出那些是有用的日志,那些是无用的信息。

原文标题:Microservices Logging Best Practices,作者:Christian Melendez & David McAllister

【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】

【责任编辑:庞桂玉 TEL:(010)68476606】


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK