Linkedin-SRE-中文教程-五-

Linkedin SRE 中文教程(五)

原文:School of SRE

协议:CC BY-NC-SA 4.0

总结

原文:https://linkedin.github.io/school-of-sre/level102/system_calls_and_signals/conclusion/

SRE 的主要目标之一是提高大规模系统的可靠性。为了做到这一点,对系统内部运作的基本理解是必要的。

了解信号是如何工作的非常重要,因为它们在流程的生命周期中扮演着重要的角色。我们看到信号在一系列流程操作中的使用:从创建流程到终止流程。信号知识非常重要,尤其是在程序中处理它们的时候。如果您预期某个事件会引起信号,您可以定义一个处理函数,并告诉操作系统在特定类型的信号到达时运行它。

在调试任何 Linux 进程时,理解系统调用对 SRE 特别有用。系统调用提供了操作系统内部功能的精确知识。它为程序员提供了对 C 库函数的深入理解,这些库函数在较低的层次上实现系统调用。使用 strace 命令,可以轻松调试缓慢或挂起的进程。

进一步阅读

www . oreilly . com/library/view/understanding-the-Linux/0596002130/ch01s 06 . html

jvns . ca/blog/2021/04/03/what-problems-do-people-solve-with-strace/

medium . com/@ akhandmishra/important-system-calls-every-programmer-should-know-8884381 ceadb

www . brendang regg . com/blog/2014-05-11/strace-wow-much-syscall . html

建立网络

先决条件

原文:https://linkedin.github.io/school-of-sre/level102/networking/introduction/

建议具备网络安全、TCP 和数据中心设置以及其中使用的常用术语的基本知识。此外,读者应该浏览学校的 Sre 内容-

从本课程中可以期待什么

这一部分将介绍如何针对不同的应用需求划分数据中心基础架构,以及在决定应用放置位置时需要考虑的事项。这些将主要基于安全性、规模、RTT(延迟)、基础架构功能。

这些主题中的每一个都将被详细讨论,

安全性-将涵盖面向外部/内部客户端的服务所面临的威胁媒介。部署时要考虑的潜在缓解选项。这将涉及外围安全、 DDoS 保护、网络划分和服务器集群的隔离。

规模—部署大规模应用需要更好地了解基础架构功能,包括资源可用性、故障域、使用任播、第 4/7 层负载平衡器、基于 DNS 的负载平衡等扩展选项。

RTT(延迟)-延迟在确定分布式服务/应用的整体性能方面起着关键作用,其中主机之间进行调用以服务于用户。

基础设施特性——需要考虑的一些方面包括,底层数据中心基础设施是否支持 ToR 弹性,例如,链路捆绑(绑定)、BGP(边界网关协议)、支持任播服务、负载平衡器、防火墙、服务质量等特性。

本课程不包括哪些内容

尽管这些参数在设计应用时起着一定的作用,但我们不会深入设计的细节。这些主题中的每一个都很庞大,因此目标是介绍其中参数的术语和相关性,而不是提供每个主题的详细信息。

课程内容

  1. 安全
  2. 刻度
  3. RTT
  4. 基础设施特征
  5. 结论

术语

在讨论每个主题之前,熟悉一些常用术语是很重要的

这是指来自不同提供商的托管解决方案,如 Azure、AWS 和 GCP。其中企业可以为公共或私人用途托管它们的应用。

内部部署

该术语指由企业自己构建和管理的物理数据中心(DC)基础设施。这既可用于私人访问,也可用于公共访问(如用户通过互联网连接)。

叶开关

这是指 DC 中服务器连接到的交换机。它们有许多名称,如接入交换机、架顶交换机、叶交换机。

术语叶交换机来自主干叶架构,其中的接入交换机称为叶交换机。主干叶架构通常用于大型/超大规模数据中心,它为 DC 交换层带来了非常高的可扩展性选项,并且在构建和实施这些交换机时也更加高效。有时这些被称为 Clos 体系结构。

脊柱开关

主干交换机是几个叶子交换机的聚合点,它们提供叶子之间的通信,并且还连接到 DC 基础设施的上层。

DC 织物

随着数据中心的增长,需要将多个 clo 网络互连起来以支持扩展,而光纤交换机有助于实现互连。

内阁

这是指安装服务器和 ToR 的机架。一个机柜指的是整个机架。

边界网关协议(Border Gateway Protocol)

它是边界网关协议,用于在路由器和交换机之间交换路由信息。这是互联网和数据中心常用的协议之一。其他协议也用来代替 BGP,如 OSPF。

虚拟专用网络

虚拟专用网是一种隧道解决方案,其中两个专用网络(如办公室、数据中心等)可以通过公共网络(互联网)互连。作为一种安全措施,这些 VPN 隧道在通过互联网发送流量之前对其进行加密。

国民保险分担

网络接口卡是指服务器中的模块,由以太网端口和与系统总线的互连组成。它用于连接交换机(通常是 ToR 交换机)。

流动

流指的是两个节点(可能是服务器、交换机、路由器等)之间的流量交换,它具有共同的参数,如源/目的 IP 地址、源/目的端口号、IP 协议号。这有助于两个节点之间的特定业务交换会话(如文件复制会话或 HTTP 连接等)的业务。

ECMP

等价多路径意味着交换机/路由器可以在多个送出接口之间将流量分配到目的地。流信息用于构建哈希值,并基于该哈希值选择送出接口。一旦数据流被映射到特定的送出接口,该数据流的所有数据包都只能通过同一接口送出。这有助于防止分组的无序传递。

循环时间(RTT)

这是对数据包从源设备到达目的设备并返回源设备所需时间的度量。这最常用于测量网络性能和故障排除。

TCP 吞吐量

这是衡量两个节点之间数据传输速率的指标。这受到许多参数的影响,如 RTT、数据包大小、窗口大小等。

单播

这是指单个源到单个目的地之间的流量,如 ssh 会话,其中存在一对一的通信。

任播

如上所述,这指的是一对一的流量,但是端点可以是多个(即,单个源可以向该组中的任何一个目的主机发送流量)。这是通过在多个服务器中配置相同的 IP 地址来实现的,并且每个新的流量都被映射到其中一个服务器。

多点传送

这指的是一对多流量(即单个源可以向多个目的地发送流量)。为了使其可行,网络路由器将流量复制到不同的主机(这些主机注册为特定多播组的成员)。

安全性

原文:https://linkedin.github.io/school-of-sre/level102/networking/security/

本节将涵盖面向外部/内部客户的服务所面临的威胁媒介。部署时要考虑的潜在缓解选项。这将涉及周边安全、DDoS 保护、网络划分和运营实践。

安全威胁

在任何基础设施中,安全性都是主要考虑因素之一。存在各种安全威胁,可能导致数据窃取、服务丢失、欺诈活动等。攻击者可以使用网络钓鱼、垃圾邮件、恶意软件、Dos/DDoS、利用漏洞、中间人攻击等技术。在本节中,我们将讨论其中一些威胁和可能的缓解措施。由于攻击和保护基础设施的方法很多,我们将只关注一些最常见的方法。

网络钓鱼大多通过电子邮件(和其他大众传播方式)进行,攻击者提供虚假网站/URL 的链接。在访问该网站时,受害者的敏感信息(如登录凭据或个人数据)会被收集并可能被滥用。

垃圾邮件也类似于网络钓鱼,但攻击者不会从用户那里收集数据,而是试图向特定网站发送垃圾邮件,很可能会淹没他们(导致速度变慢),并利用这个机会危及受攻击网站的安全。

恶意软件就像特洛伊木马,攻击者设法在基础设施中的安全系统上安装一段代码。利用这一点,黑客可以收集敏感数据,并感染目标公司的关键服务。

利用漏洞是攻击者获得系统访问权限的另一种方法。这些可能是 web 服务器、面向互联网的路由器/交换机/防火墙等中的错误或错误配置。

DoS/DDoS 是基于互联网的服务/解决方案中常见的攻击之一,尤其是那些基于眼球流量的业务。在这里,攻击者试图通过向面向外部的服务生成虚假流量来淹没受害者的资源。这样,主要是服务变得缓慢或无响应,在此期间,如果某些安全机制由于过载而无法过滤攻击流量,攻击者可能会试图侵入网络。

保护基础设施

任何基础设施管理的首要方面是识别可能影响在该基础设施上运行的业务的各种安全威胁。一旦知道了不同的威胁,就必须设计和实施安全防御机制。保护基础设施的一些常用方法有

周边安全

这是任何基础设施中的第一道防线,过滤/阻止不需要的/意外的流量流入基础设施。这些可以是边缘路由器中的过滤器,允许预期的服务(如在 HTTPS 上运行的 web 服务的端口 443 流量),或者如果服务不依赖于 UDP,则可以设置该过滤器来阻止不想要的流量,如阻止 UDP 端口。

类似于进入网络的应用流量,可能存在其他流量,如针对互联网对等体的 BGP 消息、VPN 隧道流量,以及其他服务,如电子邮件/DNS 等。有一些方法可以保护其中的每一个,例如对 BGP、VPN 的对等体使用身份验证机制(基于密码或密钥),以及将这些特定对等体列入白名单以进行入站连接(在边界过滤器中)。除此之外,可以将消息/流量的数量限制在已知的规模或预期的负载,这样资源就不会不堪重负。

DDoS 缓解

防范 DDoS 攻击是另一个重要方面。攻击流量看起来类似于真正的用户/客户端请求,但目的是淹没外部暴露的应用,可能是 web 服务器、DNS 等。因此,区分攻击流量和真实流量至关重要,为此,在应用级别有不同的方法,例如在 web 服务上使用 Captcha 来捕获源自僵尸程序的流量。

为了使这些方法有用,节点应该能够处理攻击流量和真实流量。在基于云的基础架构中,可以动态添加更多的虚拟机/资源,以应对流量的突然激增,但在内部,添加额外资源的选项可能具有挑战性。

为了处理大量的攻击流量,有一些可用的解决方案,这些解决方案可以检查数据包/流量流,并识别不像真正连接的异常(即)流量模式,如客户端发起 TCP 连接,但无法完成握手,或具有异常巨大流量流的一组源。一旦识别出这种不需要的流量,这些流量就会被丢弃在网络本身的边缘,从而保护应用节点的资源。可以更详细地讨论这个主题,但这超出了本节的范围。

网络划界

当应用根据其安全需求和易受攻击性进行分组时,网络划分是部署在不同网络中的另一种常见策略。一些常见的划分是,面向外部/互联网的节点被分组到一个单独的区域,而那些具有敏感数据的节点被隔离到一个单独的区域。并且在安全工具的帮助下限制这些区域之间的任何通信,以限制暴露给不需要的主机/端口。这些区间通信过滤器有时被称为隔离。要创建的区域数量因不同的部署而异,例如,可能有一台主机应该能够与外部世界以及内部服务器(如代理、电子邮件)进行通信,在这种情况下,这些可以分组到一个区域中,例如非军事化区域(DMZ)。创建区域的主要优势在于,即使有一台主机遭到破坏,也不会成为基础架构其余部分的后门入口。

节点保护

无论是服务器、路由器、交换机、负载平衡器、防火墙等,这些设备都具有某些保护自身安全的功能,例如支持过滤器(如访问列表、Iptables)来控制要处理的流量和要丢弃的流量,可以在服务器中使用防病毒软件来检查安装在服务器中的软件。

操作实践

基础设施面临众多安全威胁,有不同的解决方案来防御这些威胁。防御的关键部分不仅是确定正确的解决方案和工具,还要确保有可靠的操作程序,以便对任何安全事件做出迅速、果断和清晰的响应。

标准操作程序

SOP 需要明确定义,并作为安全事故期间随叫随到参考。本 SoP 应涵盖以下内容:

  • 当安全事故发生时,如何报警,向谁报警。

  • 确定安全事件的规模和严重性。

  • 谁是上报点以及传达上报点的界限/时间,可能有其他相关团队或管理层,甚至负责安全运营的人员。

  • 使用哪些解决方案(以及其中遵循的程序)来缓解安全事故。

  • 此外,有关安全事故的数据必须进行整理,以供进一步分析。

许多组织都有一个专注于安全的专门团队,他们在攻击期间甚至之前推动大多数活动,以提出最佳实践、指导方针和合规性审计。确保基础架构符合这些建议并修复差距是各个技术团队的责任。

定期审查

在定义 SoP 的同时,必须定期审查基础设施的整体安全性。该审查应包括:

  • 识别可能以基础设施为目标的任何新的/改进的安全威胁。

  • 根据新的安全威胁或程序中的变化,必须定期审查 SoP(以实施解决方案)

  • 确保及时完成软件升级/补丁。

  • 审核基础架构是否存在任何不符合安全标准的情况。

  • 审查最近的安全事件,并找到临时建立防御机制的方法。

规模

原文:https://linkedin.github.io/school-of-sre/level102/networking/scale/

部署大规模应用需要更好地了解基础设施的能力,包括资源可用性、故障域、扩展选项,如使用任播、第 4/7 层负载平衡器、基于 DNS 的负载平衡。

构建大规模的应用是一项复杂的活动,应该涵盖设计、开发和运营的许多方面。本节将讨论部署它们时需要考虑的事项。

故障域

在任何基础架构中,由硬件或软件问题导致的故障都很常见。虽然从服务可用性的角度来看,这可能是一个难题,但是这些故障确实会发生,一个实用的目标是尽量将这些故障降到最低。因此,在部署任何服务时,需要考虑一些节点的故障/不可用性。

服务器故障

由于电源、网卡或软件缺陷,服务器可能会出现故障。有时,它可能不是完全的故障,但可能是网卡中的错误,这会导致一些数据包丢失。这是一个非常常见的场景,对有状态服务的影响更大。在设计此类服务时,对这类故障提供一定程度的容忍度非常重要。

ToR 故障

这是一种常见的情况,连接服务器的边缘交换机发生故障,同时整个机柜也随之关闭。在这种情况下,同一服务可能会有多个服务器停机。它需要计划决定在不使其他服务器过载的情况下可以处理多少服务器丢失。基于此,服务可以分布在许多机柜中。根据 ToR 设计中的弹性,这些计算可能会有所不同,这将在 ToR 连通性一节中介绍。

站点故障

在这里,站点故障是一个通用术语,它可能意味着站点中的特定服务停止运行,这可能是由于新版本的推出,或者防火墙、负载平衡器等设备的故障(如果服务依赖它们),或者与远程站点的连接丢失(这可能具有有限的弹性选项),或者 DNS 等关键服务的问题。虽然这些事件可能并不常见,但它们可能会产生重大影响。

总之,在设计应用本身时,必须考虑如何处理这些故障场景。这将在应用中提供从意外故障中恢复所需的容差。这不仅有助于故障,甚至有助于计划的维护工作,因为这将更容易使部分基础设施停止服务。

资源可用性

大规模部署应用时要考虑的另一个方面是所需基础设施和服务所依赖的功能的可用性。例如,对于机柜的弹性,如果决定将服务分配给 5 个机柜,但服务需要负载平衡器(将传入的连接分配给不同的服务器),如果负载平衡器不是在所有机柜中都受支持,这可能会变得具有挑战性。或者可能存在没有足够的机柜可用(满足要设置的服务的最低要求规格)的情况。在这些情况下,最好的方法是确定需求和差距,然后与基础结构团队合作,以最好的方式解决它们。

缩放选项

将应用分发到不同的机柜时,这些服务的传入流量必须分布在这些服务器上。为了实现这一点,可以考虑以下几点

任播

这是在多个机柜间实现流量分配的最快方式之一。在这种情况下,作为集群一部分的每个服务器(在其中设置服务)向 DC 交换结构通告一个环回地址(/32 IPv4 或/128 IPv6 地址)(通常 BGP 用于此目的)。该服务必须设置为侦听此环回地址。当客户端尝试连接到服务时,解析到这个虚拟地址并转发它们的查询。DC 交换结构将每个流分发到不同的可用下一跳(最终分发到该服务群集中的所有服务器)。

注意:DC 交换机根据 IP 数据包报头计算哈希,这可能包括源地址和目的地址、源端口和目的端口、mac 地址和 IP 协议号的任意组合。基于这个散列值,选择特定的下一跳。由于通信流中的所有数据包都带有相同的报头值,因此该流中的所有数据包都将被映射到相同的路径。

Diagram Description automatically generated with mediumconfidence

图 1:选播设置

为了在这些服务器之间实现均衡的流量分配,保持每个机柜和机架的一致性非常重要。但是请记住,分发仅基于流,如果有任何大的流,一些服务器可能会收到更大的流量。

如果有任何服务器或 ToR 故障,将停止向交换机通告环回地址,从而新的数据包将被转发到剩余的可用服务器。

负载平衡

另一种常见的方法是使用负载平衡器。在负载平衡器中设置一个虚拟 IP,客户端在尝试访问服务时连接到该虚拟 IP。负载平衡器进而将这些连接重定向到运行服务的实际服务器之一。为了验证服务器是否处于可服务状态,负载平衡器会定期进行健康检查,如果检查失败,LB 会停止将连接重定向到这些服务器。

负载平衡器可以部署在单臂模式下,在这种模式下,到 VIP 的流量由 LB 重定向,从服务器到客户端的返回流量直接发送。另一个选项是双臂模式,返回流量也通过 LB。

Graphical user interface, application Description automaticallygenerated

图 2:单臂模式

Graphical user interface, application Description automaticallygenerated

图 3:双臂模式

这种方法的缺点之一是,在更高的规模下,负载平衡器可能会成为瓶颈,以支持更高的流量或每秒并发连接数。

基于 DNS 的负载平衡

这与上述方法类似,唯一的区别是负载平衡是在 DNS 上完成的,而不是在设备上。当客户端查询服务的 DNS 记录时,它们获得不同的 IP 来连接。DNS 服务器必须进行健康检查,以了解哪些服务器处于良好状态。

这种方法缓解了负载平衡器解决方案的瓶颈。但是 DNS 记录需要更短的 TTL,因此有问题的服务器可以快速退出轮换,这意味着将会有更多的 DNS 查询。

循环时间(RTT)

原文:https://linkedin.github.io/school-of-sre/level102/networking/rtt/

延迟在决定分布式服务/应用的整体性能中起着关键作用,其中在主机之间进行调用以服务于用户。

RTT 是时间的度量单位,它是数据包从 A 到达 B 并返回 A 所用的时间,以毫秒为单位。这一措施在确定服务的性能方面发挥了作用。它的影响体现在为用户服务的不同服务器/服务之间的调用,以及可以实现的 TCP 吞吐量。

服务多次调用其集群中的服务器或不同的服务(如身份验证、日志记录、数据库等)来响应每个用户/客户端请求是很常见的。这些服务器可以分布在不同的机柜中,有时甚至分布在同一地区的不同数据中心之间。这种情况在云解决方案中很有可能发生,在云解决方案中,部署分布在一个区域内的不同站点。随着 RTT 的增加,每个呼叫的响应时间变长,从而对发送给用户的最终响应产生级联效应。

RTT 与吞吐量的关系

RTT 与 TCP 吞吐量成反比。随着 RTT 的增加,它会降低 TCP 吞吐量,就像丢包一样。下面是一个基于 TCP mss、RTT 和包丢失来估计 TCP 吞吐量的公式。

Diagram, schematic Description automaticallygenerated

在数据中心内,这些计算对于互联网上的通信也很重要,在互联网上,客户可以通过不同的电信网络连接到 DC 托管的服务,并且由于互联网路由政策的不可预测性,RTT 不是很稳定。

基础设施服务

原文:https://linkedin.github.io/school-of-sre/level102/networking/infrastructure-features/

需要考虑的一些方面是,底层数据中心基础设施是否支持 ToR 弹性,即链路捆绑(绑定)、BGP、选播服务支持、负载平衡器、防火墙、服务质量等功能。

如前所述,要大规模部署应用,需要基础设施支持某些功能。本节将介绍不同的可用选项及其适用性。

ToR 连接

这是最常见的故障点之一(考虑到部署的规模),有不同的选项可以将服务器连接到 ToR。我们将在下面详细介绍它们,

一个

这是所有选项中最简单的。其中服务器的网卡连接到一个 ToR。这种方法的优点是,使用的交换机端口数量最少,允许 DC 结构支持服务器基础架构的快速增长(注意:不仅 ToR 端口得到有效利用,DC 结构中的上层交换层也是如此,端口使用效率也很高)。不利的一面是,如果 ToR、链接或 NIC 出现问题,服务器可能无法访问。这将对有状态应用产生更大的影响,因为现有的连接会突然断开。

Graphical user interface, application Description automaticallygenerated with mediumconfidence

图 4:单 ToR 设计

双重 ToR

在此选项中,每台服务器都连接到同一机柜的两个 ToR。这可以设置为主动/被动模式,从而在 ToR/链路/NIC 故障期间提供弹性。弹性可以在第 2 层或第 3 层实现。

第二层

在这种情况下,两个链路在服务器端作为绑定捆绑在一起(其中一个 NIC 扮演主动角色,另一个扮演被动角色)。在交换机端,这两个链路构成了多机箱延迟的一部分(类似于绑定,但分布在交换机上)。这里的先决条件是,两个 ToR 都应该是同一个第 2 层域的一部分。IP 地址配置在服务器的绑定接口和交换机端的 SVI 上。

Diagram Description automaticallygenerated

注意:在这种情况下,ToR 2 的作用只是提供弹性。

图 5:双 ToR 第 2 层设置

第三层

在这种情况下,两条链路都被配置为独立的第 3 层接口。弹性是通过建立路由协议(如 BGP)来实现的。其中一个链接被给予比另一个更高的优先级。在这种情况下,两个 ToR 可以在第 3 层模式下独立设置。服务器需要一个虚拟地址,服务必须绑定到这个虚拟地址。

Diagram Description automaticallygenerated

注意:在这种情况下,ToR 2 的作用只是提供弹性。

图 6:双 ToR 第 3 层设置

虽然双 ToR 的弹性更好,但缺点是使用的端口数量。随着 ToR 中的接入端口加倍,主干层中所需的端口数量也加倍,并不断级联到更高层。

类型 一个 双 ToR(第 2 层) 双 ToR(第 3 层)
弹性 1 2
端口使用 1:1 1:2 1:2
布线 较少的 更大的 更大的
DC 织物的成本 低的 高的 高的
所需的 ToR 功能 低的 高的 中等

1ToR/Link/NIC 方面的弹性

2 作为替代方案,弹性可以在应用层解决。

除了上面提到的那些,一个应用可能需要基础设施之外的更多功能来大规模部署。有些是,

任播

如前一节所述,在大规模部署中,任播是一种将服务分布在不同机柜中,同时仍有流量流向每台服务器的方法。要做到这一点,需要做两件事

  1. ToR 和服务器之间的路由协议(宣布任播地址)

  2. 支持基础架构中的 ECMP(等价多路径)负载平衡,以在机柜间分配流量。

负载平衡

与任播类似,另一种实现跨服务器负载平衡的方法(托管特定的应用)是使用负载平衡器。这些可以用不同的方式实现

  1. 硬件负载平衡器:LB 设备放置在通信流的内联中,并查看传入数据包中的第 3 层和第 4 层信息。然后确定连接将被重定向到的真实主机集。如 Scale 主题所述,这些负载平衡器可以通过两种方式进行设置,

    • 单臂模式:在这种模式下,负载平衡器只处理传入 VIP 的请求。来自服务器的响应直接发送到客户端。有两种方法可以实现这一点,

      • L2·DSR:负载均衡器和真正的服务器在同一个 VLAN。在收到一个传入的请求时,负载均衡器会识别真正的服务器来重定向该请求,然后修改该以太网帧的目的 mac 地址。在处理这个包时,真正的服务器直接响应客户机。

      • L3 DSR :在这种情况下,负载平衡器和真实服务器不需要在同一个 VLAN 中(消除第 2 层的复杂性,如运行 STP、管理更广泛的广播域等)。在收到请求时,负载平衡器通过修改数据包的目的 IP 地址重定向到真实服务器。与此同时,数据包的 DSCP 值被设置为预定义的值(为该 VIP 映射)。收到此数据包后,实际服务器使用 DSCP 值来确定回送地址(VIP 地址)。响应再次直接到达客户端。

    • 双臂模式:在这种情况下,负载均衡器会处理传入和传出的流量。

  2. 基于 DNS 的负载均衡器:在这里,DNS 服务器检查真实服务器的健康状况,并以这样的方式解析域,使得客户端可以连接到集群中的不同服务器。该部分在规模的部署章节中有详细解释。

  3. 基于 IPVS 的负载平衡:这是另一种方法,IPVS 服务器将自己作为服务端点呈现给客户端。收到请求后,IPVS 会将请求定向到真实的服务器。可以设置 IPVS 为真正的服务器运行状况。

精灵

需要连接到互联网上的目的地,但不想暴露其配置的 NIC 地址的主机将需要网络地址转换(NAT)。在这种情况下,防火墙会将(内部服务器的)地址转换为公共地址。代理服务器、邮件服务器等就是很好的例子。

服务质量

服务质量是一种为少数数据包提供区别对待的手段。这些可以在转发队列或带宽预留中提供优先级。在数据中心场景中,根据带宽预订比率,对 QoS 的需求会有所不同,

  1. 1:1 的带宽订阅比率:在这种情况下,服务器到 ToR 的连接(该机柜中的所有服务器)带宽应等于 ToR 到主干交换机的连接。对于上层也是类似的。在这种设计中,链路上不会发生拥塞,因为总会有足够的带宽可用。在这种情况下,QoS 能够带来的唯一区别是,它为转发队列中的某些数据包提供优先处理。注意:当数据包在不同速度(如 100Gbps、10Gbps)的端口之间移动时,会发生数据包缓冲。

  2. 超额预订网络:在这种情况下,并非所有层都保持带宽预订比率,例如,与 ToR 与服务器带宽相比,ToR 上行链路的带宽可能较低(这有时称为超额预订比率)。在这种情况下,有可能出现拥堵。这里可能需要 QoS,以便为某些类型的业务流提供优先级和带宽预留。

总结

原文:https://linkedin.github.io/school-of-sre/level102/networking/conclusion/

本课程将介绍在数据中心部署服务的一些背景知识,以及要考虑的各种参数和可用的解决方案。必须注意的是,这里讨论的每个解决方案都有不同的优点和缺点,因此对于特定的场景/需求,需要确定和使用其中的正确组合。由于我们在本课程中没有深入探讨各种技术/解决方案,这可能会引起读者对某些主题的好奇。下面是一些参考或网上培训的内容,供进一步学习。

链接工程博客:有关于 Linkedin 数据中心如何建立和一些关键问题如何解决的信息。

IPSpace 博客:有很多关于数据中心网络的文章。

edx 中的网络基础知识课程。

快乐学习!!

系统设计

系统设计

原文:https://linkedin.github.io/school-of-sre/level102/system_design/intro/

先决条件

从本课程中可以期待什么

目的是使读者能够理解设计良好的系统的构建模块,评估现有的系统,了解权衡,提出自己的设计,并探索实现这样一个系统的各种工具。在本模块的第一阶段,我们讨论了系统设计的基础,包括可扩展性、可用性和可靠性等概念。在这一阶段,我们将继续在这些基础上继续努力。

Throughout the course, there are callout sections that appear like this, and talk about things that are closely related to the system design process, but don’t form a part of the system itself. They also have information about some common issues that crop up in system design. Watch out for them.

本课程不包括哪些内容

虽然本课程涵盖了系统设计的许多方面,但并未涵盖最基本的概念。对于这类题目,建议先过一遍前提。

总的来说,本模块不会深入实际实施该架构——我们不会讨论选择托管/云提供商或编排设置或 CI/CD 系统。相反,我们试图把重点放在需要进入系统设计的基本考虑上。

课程内容

介绍

在本课程的前一阶段,我们讨论了如何构建基本的照片共享应用。我们对该应用的基本要求是

  1. 它应该适用于相当多的用户
  2. 避免出现任何问题时出现服务故障/集群崩溃

换句话说,我们想要建立一个可用的、可伸缩的和容错的系统。我们将继续设计该应用,并在设计过程中涵盖其他概念。

照片共享应用是一个 web 应用,它将处理从用户注册、登录、上传、feed 生成、用户交互以及与上传内容的交互的所有事情。还有一个数据库来存储这些信息。在最简单的设计中,web 应用和数据库可以在同一台服务器上运行。回想一下第一阶段的初始设计。

First architecture diagram

在此基础上,我们将讨论系统设计中的性能元素——设置正确的性能测量指标并使用它们来驱动我们的设计决策,使用缓存、内容交付网络(cdn)等来提高性能。我们还将通过一些系统设计模式——适度降级、超时和断路器——来讨论如何进行弹性设计。

费用

System design considerations like availability, scalability cannot exist in isolation. When operating outside the lab, we have other considerations / the existing considerations take on a different hue. One such consideration is cost. Real world systems almost always have budget constraints. System design, implementation and continued operation needs to have predictable costs per unit output. The output is usually the business problem you are trying to solve. Striking a balance between the two is very important.

了解您系统的功能

A well designed system requires understanding the building blocks intimately in terms of their capabilities. Not all components are created equal, and understanding what a single component can do is very important - for e.g., in the photo upload application it is important to know what a single database instance is capable of, in terms of read or write transactions per second and what would be a reasonable expectation be. This helps in building systems that are appropriately weighted - and will eliminate obvious sources of bottlenecks.

On a lower level, even understanding the capabilities of the underlying hardware (or a VM instance if you are on cloud) is important. For eg., all disks don’t perform the same, and all disks don’t perform the same per dollar. If we are planning to have an API that is expected to return a response in 100ms under normal circumstances, then it is important to know how much of it will be spent in which parts of the system. The following link will help in getting a sense of each component’s performance, all the way from the CPU cache to the network link to our end user.

Numbers every programmer should know

大型系统设计

原文:https://linkedin.github.io/school-of-sre/level102/system_design/large-system-design/

设计一个系统通常从抽象开始——我们有需要一起工作的大型功能块,并且被抽象成前端、后端和数据库层。然而,到了实施这一制度的时候,特别是作为一个 SRE 人,我们别无选择,只能具体问题具体考虑。服务器具有固定数量的内存、存储容量和处理能力。因此,我们需要考虑我们系统的现实期望,评估需求,将它们转化为系统每个组件(如网络、存储和计算)的具体需求。几乎所有的大型系统都是这样构建的。谷歌的人已经将这种设计系统的方法正式化为“非抽象大系统设计”(NALSD)。根据谷歌网站可靠性工作手册,

实际上,NALSD 结合了容量规划、组件隔离和适度系统降级等元素,这些元素对于高可用性生产系统至关重要

我们将使用类似的方法来构建我们的系统。

应用要求

让我们用更具体的术语来定义我们的应用需求,即特定的功能:

我们的照片分享应用必须让用户

  • 注册成为会员,并登录到应用

  • 上传照片,并可选地添加描述和标签位置和/或人

  • 关注平台上的其他用户

  • 查看由他们关注的其他用户的照片组成的源

  • 查看他们自己的个人资料页面,并管理他们关注的人

让我们定义对应用性能的期望,以获得更好的用户体验。我们还需要定义系统的健康状况。SLIs 和 SLOs 帮助我们做到了这一点。

SLIs 和 SLOs

谷歌 SRE 的书将服务水平指标(SLI)定义为“对所提供的服务水平的某个方面的一个精心定义的量化测量”对于我们的应用,我们可以定义多个 sli。一个指标可以是加载照片共享应用提要的响应时间。选择正确的 sli 集合非常重要,因为它们本质上帮助我们使用具体的数据来定义系统整体的健康状况。应用的 sli 由服务所有者与 SREs 协商后定义。

服务水平目标(SLO)被定义为“由 SLI 测量的服务水平的目标值或值范围”。SLO 是我们通过定义 SLI 边界来锚定最佳用户体验的一种方式。如果我们的应用需要很长时间来加载提要,用户可能不会经常打开它。因此,SLO 的一个例子是,至少 99%的用户应该在 1 秒钟内看到他们的提要被加载。

既然我们已经定义了 SLIs 和 SLO,那么让我们根据特定的 SLI 和 SLO 级别来定义应用的可伸缩性、可靠性和性能特征。

根据 SLIs 和 SLO 定义应用需求

以下是对我们的应用的一些期望:

  • 一旦用户成功上传图像,它应该可以访问用户和他们的追随者 100%的时间,除非用户选择删除。

  • 至少有 50000 个不同的访问者应该能够在任何给定的时间访问该网站,并查看他们的饲料。

  • 99%的用户应该能够在不到 1 秒的时间内查看他们的提要。

  • 上传一张新图片后,它应该会在 15 分钟内出现在用户关注者的反馈中。

  • 用户应该能够上传潜在的成千上万的图像。(只要他们没有滥用服务)

由于我们的最终目的是学习系统设计,我们将任意限制系统的功能。这将有助于我们看到我们的目标,并保持我们的重点。

定义了我们系统的功能和期望之后,让我们快速勾画出一个初始设计。

Initial Application Sketch

到目前为止,所有的功能都驻留在一台服务器上,该服务器拥有所有这些功能的端点。我们将尝试构建一个满足我们的 SLO 的系统,能够服务 50k 个并发用户和大约一百万个用户。在这个尝试的过程中,我们将讨论一系列的概念,其中一些我们已经在本课程的第一阶段看到过。

警告

Note that the numbers we have picked in the following sections are completely arbitrary. They have been chosen to demonstrate thinking about system design in a non-abstract manner. They have not been benchmarked, and bear no real world resemblance. Do not use them in any real world systems that you may be designing. You should come up with your own numbers, using the guiding principles we have relied upon here.

估计资源需求

单机

如果我们希望在一台服务器上运行应用,我们需要在这台服务器上执行图表中的所有上述功能。让我们进行一些计算,找出我们将需要什么样的资源。

首先,我们需要存储关于用户、他们的上传、追随者信息和任何其他元数据的数据。我们将选择一个关系数据库来存储这些信息,比如 MySQL。请注意,我们在这里也可以选择使用 NOSQL 解决方案。这将需要一个类似的方法来计算需求。让我们像这样表示用户:

UserID(int)
UserName(varchar)
DisplayName(varchar)
YearOfBirth(year)
Email(varchar) 

照片可以这样表示:

PhotoID(int)
PhotoHash(varchar)
Uploadtime(datetime)
Location(varchar)
OptionalFlag(varchar) 

追随者可以这样表示:

Follower(int)
Followee(int) 

让我们快速估算一下总共一亿用户所需的存储。单个用户将需要 4B + 32B + 32B + 4B + 32B = 104 字节。一亿用户将需要 10.4 GB 的存储。一张照片将需要大约 4B + 20B + 4B + 32B + 4B = 64 字节的存储空间来存储与该照片相关的元数据。假设一天上传 100 万张照片,我们每天需要大约 64 MB 的存储空间,仅用于元数据。对于照片存储本身,假设平均照片大小为 300KB,我们每天将需要大约 300GB。

打开我们的应用的单个访问者在登录应用时只需点击我们的/get_feed 端点。让我们快速计算一下满足这一要求所需的资源。假设初始提要加载了 5 个图像(平均大小为 300 KB ),然后进行惰性加载以无限滚动,我们将需要为用户的初始调用发送大约 1.5 兆字节的图像。使用 1000 Mbps网络链接到服务器,在网络链接饱和之前,我们只能同时发送大约(1000/8)/1.5 或大约 83 个用户加载提要。如果我们需要每秒为 50k 个并发用户提供服务,假设我们在一秒钟内发送完所有 5 个图像,则每发送 5 个图像需要 1.550000*8 = 600000 Mbps 的网络吞吐量。如果我们从磁盘中读取所有数据,我们可能会在接近这个流量之前就达到磁盘吞吐量极限。

因此,为了满足我们的应用要求,我们需要一台服务器,它具有大约 310GB 的存储空间来存储一天的数据库和图像,大约 600 Gbps 的链路来同时为 50k 个用户提供服务,以及执行所有这些操作所需的 CPU。显然不是单个服务器的任务。

请注意,我们已经严格限制了存储在数据库中的信息。我们可能需要存储多一个数量级的信息。

虽然我们显然没有任何真实世界的服务器具有我们上面计算的资源,但是这个练习为我们提供了一些关于资源成本的有价值的数据点。有了这些信息,让我们通过系统设计来扩展我们的系统,使我们尽可能接近应用的目标。

*现代服务器甚至有数千兆位的链路,但如此庞大的服务器不太可能单独为我们的应用服务。现代云提供商的虚拟机也拥有数千兆的带宽,但它们通常在达到一定限制后会受到限制。

参考资料:

  1. SQL vs NoSQL 数据库
  2. 引入非抽象大系统设计

扩缩容

原文:https://linkedin.github.io/school-of-sre/level102/system_design/scaling/

在本课程的第一阶段,我们已经看到了 AKF scale cube 以及它如何帮助细分服务、定义微服务和扩展整体应用。我们将使用类似的策略来扩展我们的应用——同时使用上一节中的估计,这样我们就可以有一个数据驱动的设计,而不是任意选择扩展模式。

拆分应用

考虑到我们的应用可能产生的巨大流量,以及内存和 CPU 方面的相关资源需求,让我们将应用分成更小的块。最简单的方法之一就是沿着端点划分应用,并将它们作为独立的实例。实际上,这个决定可能会稍微复杂一点,最终可能会有多个端点从同一个实例运行。

图像可以存储在一个可以独立扩展的对象存储库中,而不是放在应用或数据库所在的服务器上。这将减少服务器的资源需求。

有状态服务与无状态服务

A stateless process or service doesn’t rely on stored data of it’s past invocations. A stateful service on the other hand stores its state in a datastore, and typically uses the state on every call or transaction. In some cases, there are options for us to design services in such a way that certain components can be made stateless and this helps in multiple ways. Applications can be containerized easily if they are stateless. Containerized applications are also easier to scale. Stateful services require you to scale the datastore with the state as well. However, containerizing databases or scaling databases is out of the scope of this module.

经过这样的工作负载分配后,最终的设计可能如下所示。

Microservices diagram

您可能会注意到该图也有多个数据库。我们将在接下来的分片部分看到更多的内容。

既然我们已经将应用分割成了更小的服务,我们需要考虑扩展每个端点的容量。流行的帕累托原理指出“80%的结果来自 20%的原因”。稍微修改一下,我们可以说 80%的流量将用于 20%的图像。上传的图片数量与用户看到的图片数量之间也有类似的偏差。用户更有可能每天查看图片,而不是上传新图片。

在我们的简单设计中,生成包含最初 5 张图片的 feed 页面只需要从该用户关注的其他用户中选择 5 张最近上传的图片。虽然我们可以从数据库中动态获取图像,并在用户登录后即时生成页面,但如果大量用户选择同时登录并加载他们的提要,我们可能很快就会淹没数据库。这里我们可以做两件事,一件是缓存,另一件是提前生成用户提要。

一个拥有 100 万追随者的用户可能会导致数十万次调用 DB,只是为了获取用户上传的最新 photoID。这可能会很快压倒任何数据库,并有可能导致数据库本身崩溃。

分片

解决数据库限制问题的一种方法是扩大数据库读写。分片是扩展数据库写入的一种方式,其中数据库将被分割成多个部分,驻留在运行于不同机器上的不同数据库实例中。正如我们在本模块的第 1 阶段中看到的那样,通过使用读取副本,可以类似地扩展数据库读取。

与普通用户上传的图片数量相比,产生的浏览量将是巨大的。在这种情况下,我们应该缓存用户上传的 photoIDs,在不必执行潜在的昂贵的 DB 调用的情况下返回。

让我们考虑应用中另一个名为/get_user_details的端点。它只是返回一个用户点击另一个用户的名字时看到的页面。该端点将返回用户创建的帖子列表。通常,对该端点的调用将涉及应用与 DB 的对话,获取用户所有帖子的列表并返回结果。如果某人的个人资料被查看了数千次,这意味着有数千次对数据库的调用——这可能会导致热键和热分区之类的问题。与所有其他系统一样,负载的增加可能会导致响应时间恶化,从而导致不一致和潜在的糟糕用户体验。这里一个简单的解决方案是一个缓存层——它可以返回包含文章的用户配置文件,而不必每次都调用数据库。

贮藏

缓存用于临时存储可能会被再次访问(通常是重复访问)的数据。当在高速缓存中找到所请求的数据时,它被称为“高速缓存命中”。“缓存未命中”是明显的补充。定位良好的缓存可以大大减少查询响应时间,并提高系统的可伸缩性。缓存可以放置在用户和应用之间的多个级别。在第 1 阶段,我们看到了如何使用缓存/cdn 为应用的静态资源提供服务,从而加快响应速度,减轻应用服务器的负担。让我们看看缓存可以发挥作用的更多情况。

内存缓存:

在内存缓存中,要缓存的信息保存在服务器的主内存中,检索速度比驻留在磁盘上的数据库快得多。我们缓存任意文本(可以是 HTML 片段,也可以是 JSON 对象)并快速取回。内存中缓存是添加 fast cache 层的最快方式,也可以选择保留到磁盘。

While caching can aid significantly in scaling up and improving performance, there are situations where cache is suddenly not in place. It might be that the cache was accidentally wiped, leading to all the queries falling through to the DB layer, often multiple calls for the same piece of information. It is important to be aware of this potential ‘thundering herd’ problem and design your system accordingly.

缓存代理:

有些情况下,您可能希望缓存整个网页/您需要响应请求的其他上游资源的响应。也有这样的情况,你想让你的上游告诉你缓存什么,缓存多长时间。在这种情况下,拥有一个理解缓存相关 HTTP 头的缓存解决方案可能是一个好主意。我们用例的一个例子是,当用户在我们的应用中搜索一个特定的术语时——如果对一个用户或术语的搜索足够频繁,那么在一段时间内缓存响应可能比每次都重新执行搜索更有效。

让我们回顾一下其中一个目标——至少有 50000 个独立访问者应该能够在任何给定的时间访问网站并查看他们的提要。随着缓存的实现,我们消除了一个潜在的瓶颈——数据库。我们还将整体结构分解成更小的块,提供单独的服务。离我们的目标又近了一步,就是简单地横向扩展订阅源查看所需的服务,并将它们放在负载平衡器之后。请回忆一下本模块第 1 阶段中讨论的扩展概念。

缓存管理

While caching sounds like a simple, easy solution for a hard problem, an even harder problem is to manage the cache efficiently. Like most things in your system, the cache layer is not infinite. Effective cache management means removing things from the cache at the right time, to ensure the cache hit rate remains high. There are many strategies to invalidate cache after a certain time period or below certain usage thresholds. It is important to keep an eye on cache-hit rate and fine tune your caching strategy accordingly.

参考

  1. 有许多可用的对象存储解决方案。 Minio 是一种自托管解决方案。也有供应商特定的云解决方案,如 Azure Blob storage亚马逊 S3
  2. 微服务架构风格- Azure 架构指南
  3. 内存缓存解决方案有很多。一些最受欢迎的包括 redismemcached 。云供应商也有他们的托管缓存解决方案。
  4. 一些最流行的代理包括 squidApache 流量服务器
  5. 雷兽问题——insta gram如何解决

扩展到数据中心之外

原文:https://linkedin.github.io/school-of-sre/level102/system_design/scaling-beyond-the-datacenter/

缓存静态资产

稍微扩展一下现有的缓存解决方案,我们就可以实现内容交付网络(cdn)。cdn 是离用户最近的缓存层。网页中提供的大量资源可能不会每小时甚至每天都发生变化。在这种情况下,我们希望在 CDN 级别缓存这些内容,以减轻我们的负担。cdn 不仅通过消除服务静态/带宽密集型资源的负担来帮助减少我们服务器上的负载,它们还通过存在点(pop)让我们更接近我们的用户。CDNs 还允许我们进行地理负载平衡,以防我们在世界各地有多个数据中心,并希望尽可能从最近的数据中心(DC)提供服务。

更进一步

通过将应用缓存和分发到更简单的服务中,我们解决了扩展到 50000 个用户的问题。但是,我们的用户可能分布在不同的地理位置,并且可能与我们的数据中心或云区域的距离不同。用户体验的一致性很重要,否则我们会将远离我们位置的用户排除在外,潜在地消除了大量的潜在用户。然而,将数据中心分布在世界各地,甚至分布在世界上的几个地方,并不是不切实际的。这就是 cdn 和 pop 出现的原因。

存在点

CDN POPs 是地理上分布的数据中心,旨在靠近用户。pop 通过从离用户最近的位置传送内容来减少往返时间。pop 通常可能没有所有的内容,但是有缓存静态资产的缓存服务器,并从应用实际驻留的源服务器获取剩余的内容。它们的主要功能是通过使内容更接近网站的访问者来减少往返时间。pop 还可以将流量路由到可能的多个来源 DC 之一。这样,可以利用 pop 来增加弹性和负载平衡。

现在,随着我们的图像共享应用日益流行,让我们假设并发用户已经达到 100,000。我们已经建立了另一个数据中心,预计流量将会增加。现在,我们需要能够以可靠的方式将服务路由到这两个数据中心,同时保留在两个数据中心之一出现问题时回退到单个数据中心的能力。这就是粘性路由发挥作用的地方。

粘性路由

当用户发送请求时,如果我们有多个 DC,或者在 DC 中有一个特定的服务器,我们可能希望从 DC 为特定用户的请求提供服务。我们还可能希望由一个数据中心来满足特定 POP 的所有请求。粘性路由帮助我们做到了这一点。它可能只是将所有用户锁定到特定的 DC,或者将特定的用户锁定到特定的服务器。这通常是从 POP 完成的,所以一旦用户进入到达我们的服务器,我们可以将他们路由到最近的 DC。

地理 DNS

当用户打开应用时,用户可以被定向到多个全球分布的 pop 之一。这可以通过使用地理域名来完成,简单来说,根据发出 DNS 请求的用户的位置,给出不同的 IP 地址(按地理位置分布)。GeoDNS 是将用户分配到不同位置的第一步-它不是 100%准确的,并且通常利用 IP 地址分配信息来猜测用户的位置。然而,对于> 90%的用户来说,它已经足够好了。在这之后,我们可以有一个粘性路由服务,它为每个用户分配一个特定的 DC,我们可以用它为这个用户分配一个 DC,并设置一个 cookie。当用户下次访问时,可以在 POP 中读取 cookie,以决定用户的流量必须被定向到哪个数据中心。

拥有多个 DC 并利用粘性路由不仅具有扩展优势,还增加了服务的弹性,尽管代价是增加了复杂性。

让我们考虑另一个用例,用户为自己上传新的个人资料图片。如果我们有多个不实时同步的数据中心或 pop,并非所有的数据中心或 pop 都有更新的图片。在这种情况下,在更新传播到所有地区之前,将该用户绑定到特定的 DC/地区是有意义的。粘性路由将使我们能够做到这一点。

参考

  1. cdn
  2. LinkedIn 的 TrafficShift 博客谈论粘性路由

伸缩

原文:https://linkedin.github.io/school-of-sre/level102/system_design/resiliency/

一个有弹性的系统是一个在逆境中仍能保持运转的系统。对于我们的应用来说,可能会有许多失败作为不利因素。网络级故障可能会导致整个数据中心瘫痪,机架级或服务器级可能会出现问题,或者云提供商可能会出现问题。我们也可能耗尽容量,或者可能有一个错误的代码推破坏了系统。我们将讨论几个这样的问题,并理解我们如何设计一个系统来解决这些问题。在某些情况下,解决方法可能是不可能的。然而,了解系统稳定性的潜在弱点仍然是有价值的。

弹性架构利用系统设计模式,如适度降级、配额、超时和断路器。让我们在这一节看看其中的一些。

定额

一个系统可能有一个组件或一个端点,由多个组件和端点使用。重要的是要有适当的东西来防止一个消费者或客户压倒这样的系统。配额是做到这一点的一种方法——我们简单地为每个组件分配一个特定的配额——通过指定单位时间的请求。违反配额的人要么被警告,要么被除名,这取决于执行情况。这样,我们自己的一个系统行为不当就不会导致对其他系统的拒绝服务。配额还有助于我们防止级联故障。

功能退化

当一个具有多个依赖项的系统在其中一个依赖项中遇到故障时,适度地降级到最小的可行功能要比使整个系统陷入停顿好得多。例如,假设我们的应用中有一个端点(服务或特定功能的 URL ),它的职责是从图像的元数据中解析用户上传的图像中的位置信息,并向用户提供位置标记的建议。与其让整个上传失败,还不如跳过这个功能,给用户一个手动标记位置的选项。优雅地降级总比彻底失败好。

超时设定

我们有时在应用中调用其他服务或资源,如数据库或 API 端点。当从我们的应用中调用这样的资源时,总是有一个合理的超时是很重要的。甚至不一定是资源对所有请求都失败。特定的请求可能属于高尾部延迟类别。合理的超时有助于保持用户体验的一致性——在某些情况下,失败比令人沮丧的长时间延迟要好。

指数后退

当服务端点失败时,重试是查看它是否是暂时失败的一种方式。但是,如果重试也会失败,那么无休止地重试就没有意义了。在足够大的规模下,重试可能会与新请求(很可能会按预期提供服务)竞争,并使系统饱和。为了避免这种情况,我们可以查看重试的指数回退。这实质上降低了客户端重试的速率,当遇到连续的重试失败时。

断路器

虽然指数回退是应对重试风暴的一种方式,但断路器可以是另一种方式。断路器可以防止故障渗透到整个系统。否则,流经系统的未减轻的故障可能导致错误警报,恶化平均检测时间(MTTD)和平均解决时间(MTTR)。例如,如果其中一个内存中的缓存节点出现故障,导致请求在缓存初始超时后到达数据库,可能会导致数据库过载。如果没有在缓存节点故障和数据库节点故障之间建立初始联系,则可能会导致实际原因的 MTTD 增加,从而导致 MTTR 增加。

自我修复系统

当超过阈值的实例停止响应请求时,具有多个实例的传统负载平衡应用可能会失败——要么是因为它们停机,要么是因为突然有大量请求涌入,导致性能下降。在这种情况下,自我修复系统会添加更多实例来替换失败的实例。当查询中突然出现峰值时,像这样的自动缩放也会有所帮助。如果我们的应用运行在公共云上,这可能只是增加更多的虚拟机的问题。如果我们在数据中心外进行内部部署,那么我们将需要更加仔细地考虑容量规划。无论我们如何处理额外容量的增加,简单的增加可能是不够的。我们还应该考虑可能遇到的其他潜在故障模式。例如,负载平衡层本身可能需要扩展,以处理新后端的涌入。

持续部署和集成

一个设计良好的系统还需要考虑尽可能模拟生产环境的适当试运行设置。还应该有一种方法让我们在暂存环境中重放生产流量,以彻底测试对生产的更改。

总结

原文:https://linkedin.github.io/school-of-sre/level102/system_design/conclusion/

我们从头开始设计系统,从一台服务器扩展到多个数据中心和数十万用户。然而,您可能已经(正确地!)认为系统设计比我们到目前为止所介绍的要多得多。本课程应该让你对任何系统设计过程的基本要素有一个大概的了解。实施的具体解决方案、使用的框架和流程编排系统发展迅速。然而,指导原则保持不变。我们希望这门课程能帮助你沿着正确的方向开始,并希望你在设计系统和解决有趣的问题中获得乐趣。

系统故障排除和性能调优

系统故障排除和性能调优

原文:https://linkedin.github.io/school-of-sre/level102/system_troubleshooting_and_performance/introduction/

先决条件

从本课程中可以期待什么

这个简短的课程试图提供一个关于如何解决系统问题的一般性介绍,例如分析 api 故障、资源利用、网络问题、硬件和操作系统问题。本课程还简要介绍了用于测量整体系统性能的分析和基准测试。

本课程不包括哪些内容

本课程不包括以下内容:

  • 系统设计和架构。
  • 编程实践。
  • 度量和监控。
  • 操作系统基础。

课程内容

介绍

故障排除是运营和开发的重要组成部分。它不能通过阅读一篇文章或完成一门在线课程来学习,它是一个持续的学习过程,一个人在以下过程中学习:-

  • 日常运营和开发。
  • 查找和修复应用错误。
  • 发现并修复系统和网络问题。
  • 性能分析和改进。
  • 还有更多。

从 SRE 的角度来看,他们应该预先了解某些主题,以便能够解决单个或分布式系统的问题。

  • 充分了解您的资源,了解主机规格,如 CPU、内存、网络、磁盘等。
  • 理解系统设计和架构。
  • 确保正确收集/呈现重要指标。

惠普创始人有一句名言- “被测量的就被固定”

如果彻底捕获了系统组件和性能指标,那么就很有可能尽早成功地解决问题。

范围

对不同类型的应用或服务没有通用的故障排除方法,故障可能发生在 it 的任何一层。我们将把这项工作的范围保持在 web api 服务类型上。

注意-: Linux 生态系统非常广泛,有数百种工具和实用程序可以帮助进行系统故障排除,每种工具和实用程序都有自己的优点和功能。我们将介绍一些已知的工具,或者是 Linux 中已经有的,或者是开源世界中已经有的。对本文档中提到的工具的详细解释超出了范围,请浏览互联网或手册页以获得更多的示例和相关文档。

故障排除

原文:https://linkedin.github.io/school-of-sre/level102/system_troubleshooting_and_performance/troubleshooting/

排除系统故障有时会很棘手或乏味。在本练习中,我们需要检查服务的端到端流及其所有下游,分析日志、内存泄漏、CPU 使用、磁盘 IO、网络故障、主机问题等。了解某些实践和工具有助于更快地发现和减少故障。以下是高级故障排除流程图:

故障排除流程图

一般惯例

不同的系统需要不同的方法来发现问题。这方面的范围是有限的,并给出了一个问题,可以有更多的点可以研究。以下几点将着眼于查找 webapp 故障和修复故障的一些高级实践。

重现问题

  • 尝试中断的请求以重现问题,例如尝试命中失败的 http/s 请求。
  • 检查请求的端到端流程,并寻找返回代码,主要是 3xx、4xx 或 5xx 。3xx 主要是关于重定向,4xx 是关于未授权、错误请求、禁止等,5xx 主要是关于服务器端问题。根据返回代码,您可以寻找下一步。
  • 客户端问题主要是关于静态内容的缺失或错误,比如 javascript 问题、坏图像、异步调用导致的 json 错误等,这些都会导致浏览器上的页面呈现不正确。

收集信息

  • 在应用日志中查找错误/异常,如“无法分配内存”或“内存不足”错误,或类似“磁盘 I/O 错误”的错误,或 DNS 解析错误。
  • 检查应用和主机指标,查找服务和主机图表中的异常。从 CPU 使用率增加的时候开始,从内存使用率增加的时候开始,从磁盘空间减少或磁盘 I/O 增加的时候开始,从平均负载开始上升的时候开始等等。请阅读 SRE 学院链接,了解有关指标和监控的更多详细信息。
  • 查找最近可能破坏系统的代码或配置更改。

理解问题

  • 尝试将收集的数据与最近的操作相关联,比如在配置/代码部署后日志中显示的异常。
  • 是由于 QPS 的增加吗?是糟糕的 SQL 查询吗?最近的代码更改需要更好还是更多的硬件?

找到解决方案并应用补丁

  • 基于上述发现,如果可能的话,寻找一个快速的解决方案,例如,如果错误/异常相关,就回滚更改。
  • 尝试修补或热修复代码,如果你想向前修复的话,可能是在阶段设置中。
  • 尝试纵向扩展系统,如果高 QPS 是系统故障的原因,则尝试根据需要添加资源(计算、存储、内存等)。
  • 如果需要,优化 SQL 查询。

验证完整的请求流程

  • 再次点击请求并确保返回成功(返回代码 2xx)。
  • 检查日志以确保不再出现之前发现的异常/错误。
  • 确保指标恢复正常。

一般主机问题

要了解主机运行状况是否良好,请查找任何硬件故障或其性能问题,可以尝试以下方法:

  • Dmesg -:显示内核最近抛出的错误/失败。这有助于了解硬件故障(如果有)
  • ls 命令-: lspci,lsblk,lscpu,lsscsi,这些命令列出了 pci,磁盘,cpu 信息。
  • /var/log/messages -:显示与系统应用/服务相关的错误/警告,还显示内核问题。
  • Smartd -:检查磁盘运行状况。

重要工具

原文:https://linkedin.github.io/school-of-sre/level102/system_troubleshooting_and_performance/important-tools/

重要的 linux 命令

了解以下命令将有助于更快地发现问题。详细阐述每个命令超出了范围,请查找手册页或在线获得更多信息和相同的例子。

  • 用于日志解析-: grep、sed、awk、cut、tail、head
  • 用于网络检查-: nc、netstat、traceroute/6、mtr、ping/6、route、tcpdump、ss、ip
  • 对于 DNS -: dig、host、nslookup
  • 用于跟踪系统调用-: strace
  • 对于 ssh 上的并行执行-: gnu parallel,xargs + ssh。
  • 对于 http/s 检查-: curl,wget
  • 对于打开文件的列表-: lsof
  • 用于修改系统内核的属性-: sysctl

在分布式系统的情况下,一些好的第三方工具可以帮助同时在许多主机上执行命令/指令,例如:

  • 基于 SSH 的工具
    • 集群 SSH :集群 SSH 可以帮助您同时在许多主机上并行运行一个命令。
    • Ansible :它允许你编写可以同时在成百上千台主机上运行的 Ansible 剧本。
  • 基于代理的工具
    • Saltstack :是一个配置、状态和远程执行框架,为用户一次在大量主机上执行模块提供了广泛的灵活性。
    • Puppet :是一个自动化的管理引擎,用于您的 Linux、Unix 和 Windows 系统,执行管理任务。

日志分析工具

这些可以帮助编写 SQL 类型的查询来解析、分析日志,并提供一个简单的 UI 界面来创建仪表板,该仪表板可以基于定义的查询呈现各种类型的图表。

  • ELK:elastic search,Logstash 和 Kibana,提供一套工具和服务,可以方便快捷地解析日志、索引日志和分析日志。一旦日志/数据通过 logstash 进行解析/过滤,并在 elasticsearch 中建立索引,人们就可以在几分钟之内在 Kibana 中创建动态仪表板。这提供了对应用错误/异常/警告的简单分析和关联。
  • Azure kusto 是一种基于云的服务,类似于 Elasticsearch 和 Kibana,它允许轻松索引大量日志,提供 SQL 类型的接口来编写查询,以及创建动态仪表板的接口。

性能调优

原文:https://linkedin.github.io/school-of-sre/level102/system_troubleshooting_and_performance/performance-improvements/

性能工具是开发/运营生命周期的重要组成部分,对于理解应用行为非常重要。SRE 通常使用这些工具来评估服务的表现,并相应地做出/建议改进。

性能分析命令

在对系统或服务进行性能分析时,这些命令中的大多数都是必须知道的。

  • top -:显示正在运行的系统、进程、线程等的实时视图。
  • htop -:类似于 top command,但是比它更具交互性。
  • iotop -:一个交互式磁盘 I/O 监控工具。
  • vmstat -:虚拟内存统计浏览器。
  • iostat -:用于设备和分区的输入/输出统计的监控工具。
  • free -:告诉物理内存和交换内存的信息。
  • sar -:系统活动报告,报告不同指标,如 cpu、磁盘、内存、网络等。
  • mpstat -:显示关于 CPU 利用率和性能的信息。
  • lsof -:提供关于打开文件列表的信息,由哪些进程打开。
  • 性能分析工具。

分析工具

分析是服务性能分析的重要组成部分。有各种各样的分析器工具,可以帮助找出最常见的代码路径、调试、内存分析等。这些可以生成热图,以了解负载下的代码性能。

  • Flame graph:Flame graph 是剖析软件的可视化,允许快速准确地识别最频繁的代码路径。
  • Valgrind :这是一个用于内存调试、内存泄漏检测和分析的编程工具。
  • Gprof : GNU profiler 工具混合使用了检测和采样。检测用于收集函数调用信息,采样用于收集运行时分析信息。

要了解 LinkedIn 如何对其服务进行按需分析,请阅读 LinkedIn 博客 ODP:按需服务分析的基础设施

标杆管理

这是一个衡量服务最佳性能的过程。比如 QPS 服务可以处理多少,负载增加时的延迟,主机资源利用率,负载平均值等。在将服务部署到生产环境之前,回归测试(即负载测试)是必须的。

一些已知的工具-:

  • Apache 基准测试工具 ab :,它模拟 webapp 上的高负载并收集数据进行分析
  • Httperf :它以指定的速率向 web 服务器发送请求并收集统计数据。增加,直到找到饱和点。
  • Apache JMeter :这是一个流行的开源工具,用来测量 web 应用的性能。JMeter 是一个基于 java 的应用,不仅仅是一个 web 服务器,你可以用它来对抗 PHP、Java、REST 等等。
  • 这是另一种现代的性能测量工具,它可以给你的网络服务器增加负载,给出延迟、每秒请求数、每秒传输数等等。细节。
  • Locust :易用、可脚本化、可扩展的性能测试工具。

限制-:

上述工具有助于进行综合负载或压力测试,但这并不能衡量实际的最终用户体验,It 无法了解最终用户资源将如何影响应用性能,这是由于内存、CPU 不足或互联网连接不畅造成的。

为了了解 LinkedIn 如何在其车队中进行负载测试。阅读:用全自动负载测试消除辛劳

了解 LinkedIn 如何利用实时监控(RUM)数据来克服负载测试的局限性,并帮助改善最终用户的整体体验。阅读:使用 RUM 数据可视化监控和提高 Web 性能

扩缩容

根据资源的可用性,优化设计的系统只能在一定限度内运行。持续优化总是需要的,以确保在高峰期对资源的最佳利用。随着 QPS 的增加,系统需要扩展。我们既可以纵向扩展,也可以横向扩展。垂直可扩展性有其局限性,因为只能将 cpu、内存、磁盘、GPU 和其他规格增加到一定的限度,而水平可扩展性可以在应用设计和环境属性的限制下轻松无限地增长。

扩展 web 应用需要以下部分或全部条件:

  • 通过添加更多主机来减轻服务器负载。
  • 使用负载平衡器在服务器之间分配流量。
  • 通过数据分片和增加读取副本来纵向扩展数据库。

这里有一篇关于 LinkedIn 如何扩展其应用堆栈的好文章LinkedIn 扩展简史

故障排除示例

原文:https://linkedin.github.io/school-of-sre/level102/system_troubleshooting_and_performance/troubleshooting-example/

在本节中,我们将看到一个问题的示例,并尝试对其进行故障排除,最后分享了几个著名的故障排除故事,这些故事是 LinkedIn 工程师早些时候分享的。

示例-内存泄漏:

通常情况下,内存泄漏问题会被忽视,直到服务在运行一段时间(几天、几周甚至几个月)后变得无响应,直到服务重新启动或修复错误,在这种情况下,服务内存使用量将在指标图中以递增的顺序反映出来,类似于下图。

内存泄漏是应用对内存分配的管理不善,不需要的内存没有被释放,在一段时间内,对象继续堆积在内存中,导致服务崩溃。一般来说,这种未释放的对象会被垃圾收集器自动分类,但有时会因为一个错误而失败。调试有助于判断应用存储内存的使用情况。然后,您开始跟踪并根据使用情况过滤所有内容。如果您发现对象没有被使用,但是被引用了,您可以通过删除它们来消除它们,以避免内存泄漏。在 python 应用的情况下,它带有内置的特性,如 tracemalloc 。这个模块可以帮助确定对象首先被分配到哪里。几乎每种语言都有一套工具/库(内置的或外部的),可以帮助发现内存问题。类似地,对于 Java,有一个著名的内存泄漏检测工具叫做 Java VisualVM

让我们看看一个基于虚拟 flask 的 web 应用如何存在内存泄漏错误,随着每个请求,它的内存使用量不断增加,以及我们如何使用 tracemalloc 来捕获泄漏。

假设-:创建了一个 python 虚拟环境,其中安装了 flask。

一个有 bug 的裸最小烧瓶代码,阅读评论了解更多信息

启动烧瓶 app

启动时,其内存使用量约为 26576 kb,即约 26MB

现在,随着每个后续的 GET 请求,我们可以注意到进程内存的使用继续缓慢增加。

现在让我们尝试 10000 个请求,看看内存使用是否会大幅增加。为了满足大量的请求,我们使用了一个名为“ab”的 Apache 基准测试工具。在 10000 次点击后,我们可以注意到 flask app 的内存使用量跃升了近 15 倍,即从最初的 26576 KB 到 419316 KB,即从大约 26 MB 到 419 MB ,对于这样一个小的 webapp 来说,这是一个巨大的飞跃。

让我们试着使用 python tracemalloc 模块来理解应用的内存分配。 Tracemalloc 在某个特定点拍摄内存快照,并对其执行各种统计。

在我们的 app.py 文件中添加最少的代码,fetchuserdata.py 文件没有变化,它将允许我们在命中/捕获 uri 时捕获 tracemalloc 快照。

在重新启动 app.py (flask run) 之后,我们将-首先点击 http://127.0.0.1:5000/capture -然后点击 http://127.0.0.1:5000/ 10000 次,以便发生内存泄漏。-最后再打 http://127.0.0.1:5000/capture 拍个快照就知道哪一行分配最多了。

在最后的快照中,我们注意到了发生大部分分配的确切模块和行号。即 fetchuserdata.py,第 6 行,在 10000 次点击之后,它拥有 419 MB 的内存。

总结

上面的例子显示了一个 bug 如何导致内存泄漏,以及我们如何使用 tracemalloc 来了解它在哪里。在现实世界中,应用要比上面的虚拟例子复杂得多,您必须明白,由于 tracemalloc 本身的开销,使用 tracemalloc 可能会在一定程度上降低应用的性能。请注意它在生产环境中的使用。

如果你有兴趣深入挖掘 Python 对象内存分配内部机制和调试内存泄漏,可以看看 PyCon India 2019 上 Sanket Patel 的一个有趣的演讲,调试 Python Flask 中的内存泄漏| Python 对象内存分配内部机制

总结

原文:https://linkedin.github.io/school-of-sre/level102/system_troubleshooting_and_performance/conclusion/

复杂系统有许多可能出错的因素。它可能是糟糕的设计和架构、糟糕的代码管理、围绕不同缓存的糟糕策略、糟糕的数据库查询或架构、资源的不当使用或糟糕的操作系统版本、监控不力的系统、数据中心问题、网络故障等等,任何这些都可能出错。

作为一名 SRE,了解重要的工具/命令、最佳实践、分析、基准测试和扩展可以帮助您更快地排除故障并提高整个系统的性能。

进一步阅读

这里有一些 LinkedIn 工程师写的 LinkedIn 工程博客的链接,关于他们做的消防工作,确保网站 24x7x365 不间断运行。

持续集成和持续交付

介绍

原文:https://linkedin.github.io/school-of-sre/level102/continuous_integration_and_continuous_delivery/introduction/

先决条件

  1. 软件开发和维护
  2. Docker 工人

从本课程中可以期待什么?

在本课程中,您将学习 CI/CD 的基础知识,以及它如何帮助推动组织中的 SRE 规则。它还讨论了 CI/CD 实践中的各种 DevOps 工具,以及一个关于基于 Jenkins 的管道的动手实验会议。最后,它将通过解释在不断发展的 SRE 哲学中的作用来结束。

本课程不包括哪些内容?

本课程不全面涵盖 DevOps 元素,如基础架构代码、持续监控应用和基础架构。

目录

什么是 CI/CD?

原文:https://linkedin.github.io/school-of-sre/level102/continuous_integration_and_continuous_delivery/introduction_to_cicd/

持续集成和持续交付,也称为 CI/CD,是一组过程,有助于以可靠的方式更快地集成软件代码变更和部署到最终用户。更频繁的集成和部署有助于缩短软件开发生命周期。CI/CD 中有三种实践:

  • 持续集成
  • 连续交货
  • 持续部署让我们在接下来的小节中详细了解一下其中的每一项。

CI/CD 的优势

  1. 集成问题显著减少。
  2. 团队可以更快地开发内聚的软件。
  3. 开发人员和运营团队之间改进的协作可以减少生产集成问题。
  4. 摩擦更少,新功能交付更快
  5. 更好地调试生产问题,并在下一个版本/补丁中修复它们。

简史

原文:https://linkedin.github.io/school-of-sre/level102/continuous_integration_and_continuous_delivery/cicd_brief_history/

CI/CD 的演变

传统的开发方法已经存在了很长时间。瀑布模型已经在大大小小的项目中广泛使用,并取得了成功。尽管取得了成功,但它也有很多缺点,如周期时间较长或交付时间较长。

当多个团队成员在项目中工作时,代码变更会累积起来,直到计划的构建日期才会被集成。构建通常以约定的周期进行,从一个月到一个季度不等。这导致了几个集成问题和构建失败,因为开发人员是在孤岛中工作的。

对于运营团队/任何人来说,将新的构建/发布部署到生产环境都是一个噩梦般的情况,因为缺乏关于每个变更和配置需求的适当文档。因此,要成功部署,通常需要热修复和即时补丁。

另一个巨大的挑战是协作。开发人员很少见到运营工程师,也不完全了解生产环境。所有这些挑战都增加了代码变更交付的周期时间。

敏捷方法规定了在多次迭代中交付特性的增量交付。因此,开发人员以较小的增量提交他们的代码更改,并更频繁地推出。每一次代码提交都会触发一次新的构建,集成问题会在更早的时候被发现。这改进了构建过程,从而减少了周期时间。这个过程被称为持续集成或 CI

随着组织适应开发运维规程和 SRE 规程的趋势的出现,开发人员和运营团队之间的巨大障碍已经被缩小了。开发人员和运营团队之间的协作得到了改善。此外,两个团队使用相同的工具和过程改善了协调,并避免了对过程的冲突理解。这方面的一个主要驱动因素是连续交付(CD) 过程,它确保较小变更的增量部署。在部署到生产环境之前,有多个生产前环境也称为暂存环境。

CI/CD 和 DevOps

术语 DevOps 代表开发(Dev)和运营(Ops)团队的组合。这将开发者和运营团队聚集在一起,进行更多的合作。开发团队通常希望引入更多的功能和变化,而运营团队则更关注生产中应用的稳定性。变更总是被运营团队视为威胁,因为它会动摇环境的稳定性。DevOps 被称为一种文化,它引入了减少开发人员和操作人员之间障碍的过程。

开发人员和运营人员之间的协作允许更好地跟进端到端生产部署和更频繁的部署。因此,CI/CD 是 DevOps 流程中的一个关键要素。

持续集成

原文:https://linkedin.github.io/school-of-sre/level102/continuous_integration_and_continuous_delivery/continuous_integration_build_pipeline/

CI 是一种软件开发实践,其中团队成员经常集成他们的工作。每个集成都由一个自动化构建(包括测试)来验证,以尽可能快地检测集成错误。

持续集成要求所有的代码变更都保存在一个单一的代码存储库中,所有的成员都可以定期地将变更推送到他们的特性分支。代码变更必须与代码的其余部分快速集成,自动构建应该发生并反馈给成员以尽早解决它们。

应该有一个 CI 服务器,当成员推送代码时,它可以立即触发构建。构建通常包括编译代码并将其转换为可执行文件,如 jar 或 dll 等。叫做包。它还必须用代码覆盖率执行单元测试。可选地,构建过程可以有额外的阶段,例如静态代码分析和漏洞检查等。

詹金斯特拉维斯 CIGitLab蔚蓝 DevOps 等。是少数流行的 CI 工具。这些工具提供了各种插件和集成,如 antmaven 等。用于建筑和包,以及 Junit、selenium 等。用于执行单元测试。sonar cube可用于静态代码分析和代码安全。

图 1:持续集成管道

图 2:持续集成过程

持续交付和部署

原文:https://linkedin.github.io/school-of-sre/level102/continuous_integration_and_continuous_delivery/continuous_delivery_release_pipeline/

持续交付意味着在非生产环境中更频繁地部署应用构建,如 SIT、UAT、INT 并自动执行集成测试和验收测试。

*在 CD 中,测试是在集成应用上执行的,而不是在基于微服务的应用的情况下在单个微服务上执行的。测试必须包括所有可能包含 UI 测试的功能测试和验收测试。构建本质上必须是不可变的,也就是说,必须在包括生产环境在内的所有环境中部署相同的包。

在执行额外的验收测试(如性能测试等)后,通常需要手动部署到生产环境中。因此,全自动部署到生产环境被称为 连续部署 (而CD——连续交付 不会自动部署到生产)。连续部署必须有一个特性切换,这样就可以在不需要重新部署代码的情况下关闭一个特性。

通常,部署涉及多个生产环境,例如在蓝绿色环境中,应用首先部署到蓝色环境,然后部署到绿色环境,因此不需要停机。

图 3:连续输送管道*

CI/CD 流水线:实践

原文:https://linkedin.github.io/school-of-sre/level102/continuous_integration_and_continuous_delivery/jenkins_cicd_pipeline_hands_on_lab/

基于 Jenkins 的 CI/CD 管道

Jenkins 是一个用于编排 CI/CD 管道的开源持续集成服务器。它支持与多个组件、基础设施(如 git、云等)的集成。这有助于完成软件开发生命周期。

在这个动手实验中,让我们:为一个简单的 java 应用创建一个构建管道(CI)。添加测试阶段以构建管道

本次实践基于在本地工作站 docker 上运行的 Jenkins,它是为 Windows 操作系统设计的。对于 Linux 操作系统,请遵循演示

注意:动手实验是由 docker 上的 Jenkins 设计的。但是,这些步骤也适用于在 windows 工作站上直接安装 docker。

安装 Git、Docker 和 Jenkins:

  • 在您的工作站上安装 git 命令行工具。(按照这个在本地安装 Git)
  • Docker Desktop for windows 安装在工作站上。按照说明安装 docker。
  • 确保您的 Docker for Windows 安装配置为运行 Linux 容器而不是 Windows 容器。有关切换到 Linux 容器的说明,请参见 Docker 文档。
  • 参考运行并设置 docker 上的 Jenkins。
  • 通过创建管理员用户等初始步骤配置 Jenkins。遵循安装向导。
  • 如果您已经在本地工作站上安装了 Jenkins,请确保安装了 maven 工具。按照这个来安装 maven。

派生示例 java 应用:

为了实际操作,让我们从 GitHubsimple-java-maven-app派生一个简单的 Java 应用。1.注册 GitHub 账号加入 GitHub GitHub 。注册后,进入登录。2.点击这个链接 3,打开 simple-java-maven-app。在右上角,点击“叉”创建一个项目的副本到你的 GitHub 帐户。(参见叉一个回购 ) 4。一旦分叉,将这个存储库克隆到您的本地工作站。

创建 Jenkins 项目:

  1. 使用之前在 Jenkins 设置期间创建的管理员帐户登录到 Jenkins 门户网站 localhost:8080
  2. 首次登录时,将出现以下屏幕。点击创建一个任务

图 4:詹金斯——创造一份工作

  1. 在下一个屏幕上,在输入项目名称字段中输入 simple-java-pipeline 。从项目列表中选择管道,点击确定

图 5:詹金斯-创建管道

  1. 点击页面顶部的管道选项卡,向下滚动到管道部分。
  2. 定义字段,选择来自 SCM 选项的管道脚本。该选项指示 Jenkins 从源代码控制管理(SCM)获取您的管道,这将是您本地克隆的 Git 存储库。
  3. SCM 字段中选择 Git
  4. 存储库 URL 字段中,从上面的派生示例 Java 应用部分指定本地克隆的存储库的目录路径。

输入详细信息后,屏幕如下所示。

图 6:詹金斯管道配置

使用 Jenkinsfile 创建生成管道:

Jenkinsfile 是一个脚本文件,包含管道配置和阶段以及 Jenkins 从文件创建管道的其他指令。该文件将保存在代码库的根目录下。1.使用您最喜欢的文本编辑器或 IDE,在本地simple-Java-maven-appGit 存储库的根目录下创建并保存一个名为 Jenkinsfile 的新文本文件。2.复制以下声明性管道代码,并将其粘贴到空的 Jenkinsfile 中。

pipeline {
    agent {
        docker {
            image 'maven:3.8.1-adoptopenjdk-11' 
            args '-v /root/.m2:/root/.m2' 
        }
    }
    stages {
        stage('Build') { 
            steps {
                sh 'mvn -B -DskipTests clean package' 
            }
        }
    }
} 

注意:如果您在没有 docker 的本地工作站上运行 Jenkins,请将代理更改为如下所示的 any ,以便它在本地主机上运行。请确保 maven 工具安装在您的本地工作站上。

pipeline {
    agent any

    stages {
        stage('Build') { 
            steps {
                sh 'mvn -B -DskipTests clean package' 
            }
        }
    }
} 

在上面的 Jenkinsfile 中:我们指定了管道应该运行的代理。代理部分中的“docker”指示使用指定的映像运行新的 docker 容器。在“阶段”部分,我们可以将多个步骤定义为不同的阶段。这里,我们有一个称为“构建”的阶段,使用 maven 命令来构建 java 应用。

  1. 保存您的 Jenkinsfile 并提交和推送至您的分叉存储库。从命令提示符运行以下命令。
cd <your local simple-java-maven-app repo cloned folder>
git add .
git commit -m "Add initial Jenkinsfile"
git push origin master 
  1. 在您的浏览器上进入 Jenkins portal,点击仪表板。打开 simple-java-pipeline ,从左侧菜单中点击 Build Now

图 7:詹金斯-建立管道

  1. 注意在 Build History 菜单下运行的构建。点击的建造号,它会显示各个阶段。

图 8: Jenkins -查看运行构建

  1. 我们已经成功地创建了一个包含单个阶段的构建管道并运行了它。我们可以通过点击控制台输出菜单来检查日志。

构建管道中的其他阶段:

在上一节中,我们已经创建了具有单个阶段的管道。通常,您的 CI 管道包含多个阶段,如构建、测试和其他可选阶段,如代码扫描等。在本节中,让我们向构建管道添加一个测试阶段并运行。

  1. 返回到您的文本编辑器/IDE,打开 Jenkinsfile 和下面显示的测试阶段。
stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        } 

添加测试阶段后,Jenkinsfile 如下所示。

pipeline {
    agent {
        docker {
            image 'maven:3.8.1-adoptopenjdk-11' 
            args '-v /root/.m2:/root/.m2' 
        }
    }
    stages {
        stage('Build') { 
            steps {
                sh 'mvn -B -DskipTests clean package' 
            }
        }
        stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        }
    }
} 
  • 这里添加了运行 maven 命令测试的阶段“Test”。
  • 后>总是部分确保该步骤总是在步骤完成后执行。测试报告可通过 Jenkins 的界面获得。

注意:如果您在没有 docker 的本地工作站上运行 Jenkins,请将代理更改为 any ,以便它在本地主机上运行。请确保 maven 工具安装在您的本地工作站上。

pipeline {
    agent any

    stages {…

    }
} 
  1. 保存您的 Jenkinsfile 并提交和推送至您的分叉存储库。从命令提示符运行以下命令。
cd <your local simple-java-maven-app repo cloned folder>
git add .
git commit -m "Test stage is added to Jenkinsfile"
git push origin master 
  1. 在您的浏览器上进入 Jenkins portal,点击仪表板。打开 simple-java-pipeline ,从左侧菜单中点击 Build Now。
  2. 注意构建和测试阶段显示在构建屏幕中。

图 9: Jenkins -查看包含测试阶段的运行构建

我们现在已经成功地创建了包含两个阶段的 CI 管道:构建和测试阶段。

总结

原文:https://linkedin.github.io/school-of-sre/level102/continuous_integration_and_continuous_delivery/conclusion/

SRE 角色中的应用

监控、自动化和消除辛劳是 SRE 纪律的一些核心支柱。作为一个 SRE,你可能需要花费大约 50%的时间来自动化重复的任务,以消除辛劳。CI/CD 管道是 SRE 的重要工具之一。他们有助于用更小的、定期的和更频繁的构建来交付高质量的应用。此外,CI/CD 指标,如部署时间、成功率、周期时间和自动化测试成功率等。是提高产品质量从而提高应用可靠性的关键。

  • 基础设施即代码是 SRE 自动化重复配置任务的标准实践之一。每个配置都作为代码进行维护,因此可以使用 CI/CD 管道进行部署。通过 CI/CD 管道将配置更改交付到生产环境非常重要,这样可以跨环境维护版本控制和更改的一致性,并避免手动错误。
  • 通常,作为一名 SRE,您需要审查应用 CI/CD 管道,并建议额外的阶段,如静态代码分析和代码中的安全性和隐私检查,以提高产品的安全性和可靠性。

总结

在本章中,我们研究了 CI/CD 管道,简要介绍了传统构建实践面临的挑战。我们还研究了 CI/CD 流水线如何增强 SRE 规程。在软件开发生命周期中使用 CI/CD 管道是 SRE 领域的一种现代方法,有助于实现更高的效率。

我们还使用 Jenkins 进行了创建 CI/CD 流水线的动手实验活动。

参考

  1. 持续集成(martinfowler.com)
  2. 微服务 CI/CD-Azure 架构中心|微软文档
  3. 基础蓝图 _ 2(devopsinstitute.com)
  4. 詹金斯用户文档

捐助

原文:https://linkedin.github.io/school-of-sre/CONTRIBUTING/

我们意识到,我们创建的初始内容只是一个起点,我们希望社区能够在完善和扩展内容的过程中提供帮助。

作为投稿人,您声明您提交的内容没有抄袭。通过提交内容,您(以及,如果适用,您的雇主)根据知识共享署名 4.0 国际公共许可证向 LinkedIn 和开源社区许可提交的内容。

资源库网址:【https://github.com/linkedin/school-of-sre T2】

投稿指南

确保您遵守以下准则:

  • 应该是关于可以应用于任何公司或个人项目的原则和概念。不要专注于特定的工具或技术(它们通常会随着时间而变化)。
  • 遵守行为准则。
  • 应该与 SRE 的角色和职责相关。
  • 应进行本地测试(参见测试步骤)并格式化。
  • 在提交拉取请求之前,最好先打开一个问题并讨论您的更改。这样,你甚至可以在开始之前就吸收别人的想法。

本地构建和测试

在打开 PR 之前,运行以下命令在本地构建和查看站点。

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
mkdocs build
mkdocs serve 

打开一个 PR

遵循 GitHub 公关工作流程投稿。

派生此回购,创建功能分支,提交您的更改并打开此回购的 PR。

行动守则

原文:https://linkedin.github.io/school-of-sre/CODE_OF_CONDUCT/

本行为准则概述了参与 LinkedIn 管理的开源社区的期望,以及报告不可接受行为的步骤。我们致力于为所有人提供一个受欢迎和鼓舞人心的社区。违反这一行为准则的人可能会被禁止进入社区。

我们的开源社区致力于:

  • 友好而耐心:记住,你可能不是在用别人的主要口语或编程语言交流,别人可能没有你的理解水平。
  • 欢迎:我们的社区欢迎并支持各种背景和身份的人。这包括但不限于任何种族、民族、文化、民族血统、肤色、移民身份、社会和经济阶层、教育水平、性别、性取向、性别认同和表达、年龄、大小、家庭状况、政治信仰、宗教以及精神和身体能力。
  • 尊重他人:我们是一个全球性的专业人士社区,我们以专业的方式行事。意见不一致不能成为不良行为和不礼貌的借口。不尊重和不可接受的行为包括但不限于:
    • 暴力威胁或语言。
    • 歧视性或贬损性的笑话和语言。
    • 张贴露骨的或暴力的内容。
    • 张贴或威胁张贴人们的个人身份信息(“doxing”)。
    • 侮辱,尤其是那些使用歧视性词语或诽谤的侮辱。
    • 可能被视为性关注的行为。
    • 提倡或鼓励任何上述行为。
  • 了解分歧:分歧,无论是社会上的还是技术上的,都是有用的学习机会。寻求理解其他观点,建设性地解决分歧。
  • 这段代码并不详尽或完整。它抓住了我们对高效协作环境的共同理解。我们希望该准则在精神上和文字上都得到遵守。

范围

本行为准则适用于 LinkedIn 管理的开源项目的所有回购和社区,无论回购是否明确要求使用本准则。当个人代表一个项目或其社区时,该准则也适用于公共场所。示例包括使用官方项目电子邮件地址、通过官方社交媒体帐户发帖,或作为在线或离线活动的指定代表。项目维护人员可以进一步定义和阐明项目的表示。

注意:一些 LinkedIn 管理的社区在本文档和问题解决流程之前就有行为准则。虽然不要求社区更改他们的代码,但是他们应该使用这里列出的解决流程。审查小组将与相关社区协调解决您的问题。

报告行为准则问题

我们鼓励所有社区尽可能自行解决问题。这建立了更广泛和更深入的理解,并最终建立了更健康的互动。如果问题无法在当地解决,请联系 oss@linkedin.com 报告您的问题。

请在您的报告中包括:

  • 您的联系信息。
  • 任何相关个人的姓名(真实姓名、用户名或假名)。如果有其他证人,也请包括他们。
  • 你对发生的事情的描述,如果你认为事件还在继续。如果有公开的记录(如邮件列表存档或公共聊天日志),请附上链接或附件。
  • 任何可能有帮助的附加信息。

所有报告都将由一个多人组成的团队进行审查,并根据具体情况做出必要且适当的回应。如果需要额外的观点,团队可以从具有相关专业知识或经验的其他人那里寻求见解。将始终为报告事件的人员保密。相关方从来不是审核小组的成员。

任何被要求停止不可接受行为的人都应该立即照办。如果个人参与了不可接受的行为,审查小组可以采取他们认为适当的任何行动,包括从社区中永久禁止。

本行为准则基于微软开源行为准则,该行为准则基于托多组织建立的模板,并被众多其他大型社区使用(例如脸书雅虎TwitterGitHub )以及贡献者契约版本 1.4 的范围部分。

SRE 社区

原文:https://linkedin.github.io/school-of-sre/sre_community/

我们为 SRE 学校建立了一个活跃的 LinkedIn 社区。

请通过:【https://www.linkedin.com/groups/12493545/ T2】加入群

该小组的成员在现场可靠性工程方面具有不同水平的经验。围绕现场可靠性工程的不同技术主题展开了活跃的对话。我们鼓励每个人都加入到对话中来,互相学习,在 SRE 空间中建立成功的职业生涯。

posted @ 2024-09-14 20:13  绝不原创的飞龙  阅读(52)  评论(0)    收藏  举报