现代网络负载平衡和代理简介

最近引起我注意的是,缺乏关于现代网络负载平衡和代理的介绍性教育材料。我心想:这怎么可能?负载平衡是构建可靠分布式系统所需的核心概念之一。当然必须有高质量的信息吗?我搜索并发现这些采摘确实很苗条。关于负载平衡代理服务器的维基百科文章包含一些概念的概述,但不是对主题的流畅处理,特别是因为它涉及现代微服务架构。一个谷歌搜索的负载均衡主要是轮番上涨是对细节的流行语和轻重供应商的网页。

在这篇文章中,我试图通过提供对现代网络负载平衡和代理的温和介绍来纠正缺乏信息。坦率地说,这是一个可能成为整本书主题的大型话题。为了保持这篇文章(有点)博客篇幅,我尝试将一组复杂的主题提炼成一个简单的概述; 根据兴趣和反馈,我将在稍后考虑更详细的关于个别主题的后续帖子。

有一些背景知道我为什么写这个 – 我们走了!

什么是网络负载平衡和代理?

Wikipedia 负载平衡定义为:

在计算中,负载平衡改善了跨多个计算资源(例如计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器)的工作负载分布。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间,并避免任何单个资源的过载。使用具有负载平衡而不是单个组件的多个组件可以通过冗余提高可靠性和可用性。负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务器进程。

以上定义适用于计算的所有方面,而不仅仅是网络。操作系统使用负载平衡来跨物理处理器调度任务,容器协调器(如Kubernetes)使用负载平衡来跨计算群集调度任务,网络负载平衡器使用负载平衡来跨可用后端调度网络任务。本文的其余部分仅涵盖网络负载平衡

图1:网络负载平衡概述

图1显示了网络负载平衡的高级概述。一些客户端正在从一些后端请求资源。负载均衡器位于客户端和后端之间,并且在高级别执行几项关键任务:

  • 服务发现:系统中有哪些后端可用?它们的地址是什么(即负载均衡器应该如何与它们通信)?
  • 健康检查:目前哪些后端健康且可以接受请求?
  • 负载平衡:应该使用什么算法来平衡健康后端的各个请求?

在分布式系统中正确使用负载平衡可带来以下好处:

  • 命名抽象:客户端可以通过预定义的机制解决负载均衡器,而不是每个客户端需要了解每个后端(服务发现),然后可以将名称解析行为委托给负载均衡器。预定义机制包括内置库和众所周知的DNS / IP /端口位置,并将在下面更详细地讨论。
  • 容错:通过运行状况检查和各种算法技术,负载均衡器可以有效地路由坏的或过载的后端。这意味着操作员通常可以在休闲时修复坏后端,而不是紧急情况。
  • 成本和性能优势:分布式系统网络很少是同质的。该系统可能跨越多个网络区域和区域。在区域内,网络通常以相对不足的方式构建。在区域之间,超额认购成为常态。(在此上下文中,/ underubscription指的是通过NIC消耗的带宽量占路由器之间可用带宽的百分比)。智能负载平衡可以尽可能地保持区域内的请求流量,从而提高性能(减少延迟)并降低整体系统成本(区域之间所需的带宽和光纤更少)。

负载均衡器与代理

在谈论网络负载平衡器时,术语负载平衡器代理在业内大致可互换使用。这篇文章也将这些条款视为一般等同。(小心并非所有代理都是负载均衡器,但绝大多数代理都将负载均衡作为主要功能)。

有些人可能会争辩说,当负载均衡作为嵌入式客户端库的一部分完成时,负载均衡器实际上并不是代理。但是,我认为区别会给已经令人困惑的话题带来不必要的复杂性。负载平衡器拓扑的类型将在下面详细讨论,但是这篇文章将嵌入式负载均衡器拓扑视为代理的特殊情况; 应用程序通过嵌入式库进行代理,该库提供与应用程序进程之外的负载均衡器相同的抽象。

L4(连接/会话)负载平衡

在讨论当今整个行业的负载平衡时,解决方案通常分为两类:L4L7这些类别涉及OSI模型的第4层第7层由于我在讨论L7负载平衡时会变得明显的原因,我认为这些是我们使用的术语是不幸的。OSI模型是负载平衡解决方案的复杂性的非常差的近似,其包括传统的第4层协议(例如TCP和UDP),但通常最终包括在各种不同OSI层的位和协议。即,如果L4 TCP负载均衡器也支持TLS终端,它现在是L7负载均衡器吗?

图2:TCP L4终端负载平衡

图2显示了传统的L4 TCP负载均衡器。在这种情况下,客户端与负载均衡器建立TCP连接。负载均衡器终止连接(即直接响应SYN),选择后端,并与后端建立新的TCP连接(即发送新的SYN)。该图的细节并不重要,将在下面专门讨论L4负载平衡的部分中详细讨论。

本节的关键点是L4负载均衡器通常仅在L4 TCP / UDP连接/会话级别运行。因此,负载均衡器大致来回抽取字节,并确保来自同一会话的字节在同一后端结束。L4负载均衡器不知道它正在混洗的字节的任何应用程序细节。字节可以是HTTP,Redis,MongoDB或任何其他应用程序协议。

L7(应用程序)负载平衡

L4负载平衡很简单,仍然可以广泛使用。L4负载平衡有哪些缺点需要投资L7(应用程序)负载平衡?以下面的L4特定案例为例:

  • 两个GRPC / HTTP2客户希望,使他们通过L4负载均衡器连接到跟一个后端。
  • L4负载均衡器为每个传入的TCP连接建立单个传出TCP连接,从而产生两个传入和两个传出连接。
  • 但是,客户端A通过其连接每分钟发送1个请求(RPM),而客户端B通过其连接发送每秒50个请求(RPS)。

在上一个场景中,选择处理客户端A的后端将处理大约3000倍的负载,然后选择后端来处理客户端B这是一个大问题,并且通常首先会破坏负载平衡的目的。另请注意,任何多路复用保持活动协议都会出现此问题多路复用意味着通过单个L4连接发送并发应用程序请求,并且保持活动意味着在没有活动请求时不关闭连接)。由于效率原因,所有现代协议都在发展为多路复用和保持活动(创建连接通常很昂贵,尤其是当使用TLS加密连接时),因此L4负载平衡器阻抗不匹配随着时间的推移变得越来越明显。此问题由L7负载平衡器修复。

图3:HTTP / 2 L7终端负载平衡

图3显示了L7 HTTP / 2负载均衡器。在这种情况下,客户端与负载均衡器建立单个HTTP / 2 TCP连接。然后负载平衡器继续进行两个后端连接。当客户端向负载均衡器发送两个HTTP / 2流时,流1被发送到后端1,而流2被发送到后端2.因此,即使多路复用具有非常不同的请求负载的客户端也将在后端有效地平衡。这就是L7负载平衡对于现代协议如此重要的原因。(L7负载平衡由于其检查应用程序流量的能力而产生了大量额外的好处,但这将在下面更详细地介绍)。

L7负载均衡和OSI模型

正如我在上面关于L4负载平衡的部分所述,使用OSI模型来描述负载平衡功能是有问题的。原因是L7,至少如OSI模型所描述的那样,本身包含多个离散的负载平衡抽象层。例如,对于HTTP流量,请考虑以下子层:

  • 可选的传输层安全性(TLS)。请注意,网络人员争论TLS属于哪个OSI层。为了便于讨论,我们将考虑TLS L7。
  • 物理HTTP协议(HTTP / 1或HTTP / 2)。
  • 逻辑HTTP协议(标头,正文数据和预告片)。
  • 消息传递协议(gRPC,REST等)。

复杂的L7负载平衡器可以提供与上述每个子层相关的特征。另一个L7负载均衡器可能只有一小部分功能将其置于L7类别中。简而言之,从功能比较的角度来看,L7负载均衡器的格局要比L4类别复杂得多。(当然,本节刚刚介绍了HTTP; Redis,Kafka,MongoDB等都是受益于L7负载平衡的L7应用协议的例子)。

负载平衡器功能

在本节中,我将简要总结负载平衡器提供的高级功能。并非所有负载平衡器都提供所有功能。

服务发现

服务发现是负载均衡器确定可用后端集的过程。方法多种多样,一些例子包括:

健康检查

运行状况检查是负载均衡器确定后端是否可用于提供流量的过程。健康检查通常分为两类:

  • 活动:负载均衡器以固定间隔(例如,对/healthcheck端点的HTTP请求)向后端发送ping,并使用它来衡量运行状况。
  • 被动:负载均衡器从主数据流中检测健康状态。例如,如果一行中存在三个连接错误,则L4负载均衡器可能会判定后端是不健康的。如果连续存在三个HTTP 503响应代码,则L7负载均衡器可能会判定后端运行状况不佳。

负载均衡

是的,负载平衡器必须实际平衡负载!给定一组健康的后端,如何选择后端来提供连接或请求?负载平衡算法是一个活跃的研究领域,范围从简单的算法,如随机选择和循环,到考虑可变延迟和后端负载的更复杂的算法。鉴于其性能和简单性,最流行的负载平衡算法之一被称为2个最小请求负载平衡的功能

粘性会议

在某些应用程序中,同一会话的请求到达相同的后端非常重要这可能与缓存,临时复杂构造状态等有关。会话的定义各不相同,可能包括HTTP cookie,客户端连接的属性或某些其他属性。许多L7负载均衡器对粘性会话有一些支持。顺便说一句,我会注意到会话粘性本质上是脆弱的(托管会话的后端可能会死),所以在设计依赖它们的系统时要小心。

TLS终止

TLS的主题及其在边缘服务和保护服务到服务通信中的作用值得自己发表。话虽如此,许多L7负载均衡器进行了大量的TLS处理,包括终止,证书验证和固定,使用SNI的证书服务等。

观测

正如我在会谈中所说的那样:“可观察性,可观察性,可观察性。”网络本质上是不可靠的,负载均衡器通常负责导出统计数据,跟踪和日志,帮助运营商找出问题所在,以便他们能够解决问题。负载平衡器的可观察性输出差异很大。最先进的负载平衡器提供丰富的输出,包括数字统计,分布式跟踪和可自定义的日志记录。我要指出,增强的可观察性不是免费的; 负载均衡器必须做额外的工作来生产它。但是,数据的好处大大超过了相对较小的性能影响。

安全和DoS缓解

尤其是在边缘部署拓扑(见下文),负载平衡器通常实现的各种安全功能,包括速率限制,认证和DoS缓解(例如,IP地址标记和识别,缓送等)。

配置和控制平面

需要配置负载平衡器。在大型部署中,这可能成为一项重大任务。通常,配置负载平衡器的系统称为“控制平面”,并且在其实现中变化很大。有关此主题的更多信息,请参阅我在服务网格数据平面与控制平面上的帖子

还有更多

本节刚刚介绍了负载均衡器提供的功能类型。有关L7负载平衡器的部分,请参见其他讨论。

负载均衡器拓扑的类型

现在我已经介绍了负载均衡器的概况,L4和L7负载均衡器之间的差异以及负载均衡器功能的摘要,我将继续讨论部署负载均衡器的各种分布式系统拓扑。(以下每种拓扑适用于L4和L7负载平衡器)。

中间代理

图4:中间代理负载平衡拓扑

图4中所示的中间代理拓扑可能是获得大多数读者负载平衡的最熟悉的方法。此类别包括Cisco,Juniper,F5等硬件设备; 亚马逊的ALB和NLB以及谷歌的云负载均衡器等云软件解决方案和纯软件自托管解决方案,如HAProxyNGINXEnvoy中间代理解决方案的专家是用户简单性。通常,用户通过DNS连接到负载均衡器,无需担心其他任何问题。中间代理解决方案的一个问题是代理(即使是集群)是单点故障以及扩展瓶颈。中间代理通常也是黑盒子,使操作变得困难。客户端是否存在问题?在物理网络中?在中间代理?在后端?这很难说。

边缘代理

图5:边缘代理负载平衡拓扑

边缘代理拓扑如图5所示实际上只是中间代理拓扑的一种变体,可以通过Internet访问负载均衡器。在这种情况下,负载均衡器通常必须提供额外的“API网关”功能,例如TLS终止,速率限制,身份验证和复杂的流量路由。边缘代理的优缺点与中间代理相同。需要注意的是,在面向Internet的大型分布式系统中部署专用边缘代理通常是不可避免的。客户端通常需要使用服务所有者无法控制的任意网络库通过DNS访问系统(使以下部分中描述的嵌入式客户端库或sidecar代理拓扑不能直接在客户端上运行)。另外,

嵌入式客户端库

图6:通过嵌入式客户端库进行负载平衡

为了避免中间代理拓扑中固有的单点故障和扩展问题,更复杂的基础架构已经转向通过库将负载均衡器直接嵌入到服务中,如图6所示图书馆在支持的功能方面差异很大,但这一类中最知名且功能最丰富的一些是FinagleEureka / Ribbon / HystrixgRPC(松散地基于称为Stubby的内部Google系统)。基于库的解决方案的主要优势在于它将负载均衡器的所有功能完全分配给每个客户端,从而消除了先前描述的单点故障和扩展问题。基于库的解决方案的主要目标是,库必须以组织使用的每种语言实现。分布式架构正变得越来越“多语言”(多语言)。在这种环境下,以多种不同语言重新实现极其复杂的网络库的成本可能会变得令人望而却步。最后,在大型服务架构中部署库升级可能会非常痛苦,因此很可能会在生产中同时运行许多不同版本的库,

综上所述,上述图书馆已经成功地为那些能够限制编程语言扩散并克服库升级难度的公司提供了帮助。

边车代理

图7:通过sidecar代理进行负载平衡

嵌入式客户端库负载平衡器拓扑的变体是图7中所示的边车代理拓扑近年来,这种拓扑结构已经被推广为“服务网格”。边车代理背后的想法是,通过跳转到不同的进程而导致轻微的延迟损失,嵌入式库方法的所有好处都可以是没有任何编程语言锁定获得。在撰写本文时最受欢迎的边车代理负载均衡器是EnvoyNGINXHAProxyLinkerd有关边车代理方法的更详细的处理,请参阅我的博客文章介绍Envoy以及我的在服务网格数据平面与控制平面上发布

不同负载均衡器拓扑的总结和优缺点

  • 中间代理拓扑通常是最容易使用的负载平衡拓扑。由于单点故障,缩放限制和黑盒操作,它不足。
  • 边缘代理拓扑类似于中间代理,但通常无法避免。
  • 嵌入式客户端库拓扑提供了最佳性能和可伸缩性,但是需要以每种语言实现库以及跨所有服务升级库的需要。
  • sidecar代理拓扑的性能不如嵌入式客户端库拓扑,但不受任何限制。

总的来说,我认为sidecar代理拓扑(服务网格)正在逐步取代所有其他拓扑以进行服务到服务通信。在流量进入服务网格之前,始终需要边缘代理拓扑。

L4负载平衡的当前技术水平

L4负载平衡器是否仍然相关?

这篇文章已经讨论了L7负载平衡器对于现代协议的优势,并将在下面进一步详细介绍L7负载平衡器功能。这是否意味着L4负载平衡器不再相关?没有!虽然在我看来L7负载平衡器最终将完全取代用于服务到服务通信的 L4负载平衡器,但L4负载平衡器在边缘仍然非常相关因为几乎所有现代大型分布式架构都使用双层L4 / L7负载平衡架构用于互联网流量。在边缘部署中在L7负载平衡器之前放置专用L4负载平衡器的好处是:

  • 由于L7负载平衡器执行应用程序流量的更复杂的分析,转换和路由,因此它们可以处理相对较小部分的原始流量负载(以每秒数据包数和每秒字节数衡量),而不是优化的L4负载均衡器。这一事实通常使L4负载平衡器成为处理某些类型的DoS攻击(例如,SYN泛洪,通用数据包泛洪攻击等)的更好位置。
  • L7负载平衡器往往更积极地开发,更频繁地部署,并且比L4负载平衡器具有更多错误。在L7负载平衡器部署期间,前面有L4负载平衡器可以进行健康检查和排放,这比现代L4负载平衡器使用的部署机制要容易得多,后者通常使用BGP和ECMP(下面有更多内容)。最后,因为L7负载平衡器更容易出现缺陷,纯粹是由于其功能的复杂性,拥有可以绕过故障和异常的L4负载平衡器可以使整个系统更加稳定。

在下面的部分中,我将介绍中/边缘代理L4负载平衡器的几种不同设计。以下设计通常不适用于客户端库和边车代理拓扑。

TCP / UDP终端负载均衡器

图8:L4端接负载平衡器

仍在使用的第一种L4负载平衡器是终端负载平衡器,如图8所示这与我们在上面的L4负载平衡介绍中看到的负载均衡器相同。在这种类型的负载均衡器中,使用两个离散的TCP连接:一个在客户端和负载均衡器之间,一个在负载均衡器和后端之间。

L4终端负载平衡器仍然使用有两个原因:

  1. 它们实施起来相对简单。
  2. 对客户端的近距离(低延迟)连接终止具有重大的性能影响。具体地,如果终端负载平衡器可以靠近使用有损网络(例如,蜂窝网络)的客户端放置,则在数据被移动到可靠光纤传输到其最终位置之前,重传可能更快发生。换句话说,这种类型的负载平衡器可以在用于原始TCP连接终止的存在点(POP)场景中使用。

TCP / UDP直通负载均衡器

图9:L4直通负载平衡器

第二种L4负载平衡器是直通负载平衡器,如图9所示在这种类型的负载均衡器中,负载均衡器不会终止TCP连接而是在连接跟踪和网络地址转换(NAT)发生后,将每个连接的数据包转发到选定的后端首先,让我们定义连接跟踪和NAT:

  • 连接跟踪:是跟踪所有活动TCP连接状态的过程。这包括诸如握手是否已完成,是否已收到FIN,连接已空闲多长时间,已为连接选择了哪个后端等数据。
  • NAT:NAT是使用连接跟踪数据在数据包遍历负载均衡器时更改数据包的IP /端口信息的过程。

使用连接跟踪和NAT,负载均衡器可以通过从客户端到后端的大多数原始TCP流量。例如,假设客户端正在与之通信,1.2.3.4:80并且所选择的后端位于10.0.0.2:9000客户端TCP数据包将到达负载均衡器1.2.3.4:80然后,负载均衡器将交换数据包的目标IP和端口10.0.0.2:9000它还将交换数据包的源IP和负载均衡器的IP地址。因此,当后端响应TCP连接时,数据包将返回负载均衡器,在负载均衡器中发生连接跟踪,NAT可以反向再次发生。

为什么使用这种类型的负载平衡器代替上一节中描述的终端负载平衡器,因为它更复杂?原因如下:

  • 性能和资源使用情况:由于直通负载均衡器不会终止TCP连接,因此它们不需要缓冲任何TCP连接窗口。每个连接存储的状态量非常小,通常通过有效的哈希表查找来访问。因此,直通负载平衡器通常可以处理比终止负载平衡器大得多的活动连接数和每秒数据包数(PPS)。
  • 允许后端执行自定义拥塞控制TCP拥塞控制是Internet上端点限制发送数据以便不会压倒可用带宽和缓冲区的机制。由于直通负载均衡器未终止TCP连接,因此它不参与拥塞控制。这一事实允许后端根据其应用用例使用不同的拥塞控制算法。它还允许更容易地进行拥塞控制变更的实验(例如,最近的BBR推出)。
  • 形成直接服务器返回(DSR)和集群L4负载平衡的基线:更高级的L4负载平衡技术(例如DSR和具有分布式一致性散列的集群)需要直通负载平衡(将在以下各节中讨论)。

直接服务器返回(DSR)

图10:L4直接服务器返回(DSR)

直接服务器返回(DSR)负载均衡器如图10所示DSR建立在上一节中描述的直通负载均衡器之上。DSR是一种优化,其中只有入口/请求数据包遍历负载均衡器。出口/响应数据包在负载均衡器周围直接返回客户端。执行DSR有趣的主要原因是,在许多工作负载中,响应流量使请求流量相形见绌(例如,典型的HTTP请求/响应模式)。假设10%的流量是请求流量,90%的流量是响应流量,如果DSR正在使用1/10的负载均衡器容量可以满足系统的需要。由于历史上负载平衡器非常昂贵,因此这种类型的优化会对系统成本和可靠性产生重大影响(总是更好)。DSR负载平衡器扩展了直通负载均衡器的概念,具体如下:

  • 负载平衡器通常仍执行部分连接跟踪。由于响应数据包不会遍历负载均衡器,因此负载均衡器将不会知道完整的TCP连接状态。但是,负载均衡器可以通过查看客户端数据包和使用各种类型的空闲超时来强烈推断状态。
  • 负载均衡器通常使用通用路由封装(GRE)来封装从负载均衡器发送到后端的IP数据包,而不是NAT 因此,当后端接收封装的数据包时,它可以对其进行解封装并知道客户端的原始IP地址和TCP端口。这允许后端直接响应客户端,而响应数据包不会流经负载均衡器。
  • DSR负载均衡器的一个重要部分是后端参与负载均衡后端需要具有正确配置的GRE隧道,并且根据网络设置的低级细节可能需要其自己的连接跟踪,NAT等。

请注意,在直通负载均衡器和DSR负载均衡器设计中,可以通过负载均衡器和后端设置连接跟踪,NAT,GRE等多种方式。不幸的是,该主题超出了本文的范围。

通过高可用性对实现容错

图11:通过HA对和连接跟踪的L4容错

到目前为止,我们一直在考虑单独设计L4负载平衡器。passthrough和DSR负载均衡器都需要在负载均衡器本身中进行一定量的连接跟踪和状态。如果负载均衡器死了怎么办?如果负载平衡器的单个实例死亡,则将切断遍历负载平衡器的所有连接。根据应用程序的不同,这可能会对应用程序性能产生重大影响。

从历史上看,L4负载平衡器是从典型供应商(Cisco,Juniper,F5等)购买的硬件设备。这些设备非常昂贵并且处理大量流量。为了避免单个负载平衡器故障切断所有连接并导致严重的应用程序中断,负载平衡器通常部署在高可用性对中,如图11所示典型的HA负载平衡器设置具有以下设计:

  • 一对HA边缘路由器服务于一定数量的虚拟IP(VIP)。这些边缘路由器使用边界网关协议(BGP宣告VIP 主边缘路由器的BGP权重高于备份,因此在稳定状态下,它为所有流量提供服务。(BGP是一个极其复杂的协议;出于本文的目的,只考虑BGP一种机制,通过该机制,网络设备宣布它们可用于从其他网络设备获取流量,并且每个链路可以具有优先考虑链路流量的权重)。
  • 类似地,主L4负载均衡器向具有比备份更高的BGP权重的边缘路由器宣告自己,因此在稳定状态下它正在为所有流量服务。
  • 主负载均衡器交叉连接到备份,并共享其所有连接跟踪状态。因此,如果主模块死亡,则备份可以接管处理所有活动连接。
  • 两个边缘路由器和两个负载平衡器都是交叉连接的这意味着如果其中一个边缘路由器或其中一个负载平衡器死亡,或者由于某些其他原因而撤销其BGP通知,则备份可以接管所有流量。

上面的设置是今天仍然有多少高流量的互联网应用程序。但是,上述方法存在很大的缺点:

  • 考虑到容量使用情况,必须在HA负载均衡器对之间正确分片VIP。如果单个VIP增长超过单个HA对的容量,则VIP需要分成多个VIP。
  • 系统的资源使用率很低。50%的容量处于稳定状态。鉴于历史上硬件负载平衡器非常昂贵,这导致大量闲置资本。
  • 现代分布式系统设计比主动/备份提供更好的容错能力。例如,最佳地,系统应该能够遭受多个同时发生的故障并继续运行。如果活动和备份负载平衡器同时死亡,则HA负载平衡器对容易发生完全故障。
  • 供应商提供的专有大型硬件设备非常昂贵,导致供应商锁定。通常希望用使用商用计算服务器构建的水平可扩展软件解决方案来替换这些硬件设备。

通过具有分布式一致性散列的集群进行容错和扩展

图12:通过集群负载平衡器和一致性散列的L4容错和扩展

上一节介绍了通过HA对的L4负载均衡器容错以及该设计中固有的问题。从2000年代早期到中期,大型互联网基础设施开始设计和部署新的大规模并行L4负载平衡系统,如图12所示这些系统的目标是:

  • 减轻上一节中描述的HA对设计的所有缺点。
  • 从供应商的专有硬件负载平衡器转向使用标准计算服务器和NIC构建的商品软件解决方案。

此L4负载平衡器设计最好称为容错和通过群集和分布式一致性散列进行扩展它的工作原理如下:

  • N个边缘路由器以相同的BGP权重宣布所有Anycast VIP。等价多路径路由(ECMP)用于确保通常来自单个流的所有分组到达相同的边缘路由器。流通常是源IP /端口和目标IP /端口的4元组。(简而言之,ECMP是一种使用一致哈希在一组相同加权的网络链路上分发数据包的方法)。虽然边缘路由器本身并不特别关心哪些分组到达那里,但是通常优选的是来自流的所有分组遍历同一组链路,以避免乱序性能降低性能的分组。
  • N L4负载均衡器机器以与边缘路由器相同的BGP权重通告所有VIP。再次使用ECMP,边缘路由器通常会为流选择相同的负载平衡器机器。
  • 每个L4负载均衡器机器通常会执行部分连接跟踪,然后使用一致性散列来选择流的后端。GRE用于封装从负载均衡器发送到后端的数据包。
  • 然后,DSR用于通过边缘路由器将数据包直接从后端发送到客户端。
  • L4负载均衡器使用的实际一致性哈希算法是一个活跃的研究领域。在权衡负载,最小化延迟,最小化后端更改期间的中断
    以及最小化内存开销方面存在权衡对该主题的完整讨论超出了本文的范围。

让我们看看上述设计如何减轻HA对方法的所有缺点:

  • 可根据需要添加新的边缘路由器和负载平衡器。在添加新计算机时,每层都使用一致的哈希来尽可能减少受影响流的数量。
  • 系统的资源使用可以根据需要运行,同时保持足够的突发容限和容错。
  • 边缘路由器和负载平衡器现在都可以使用商用硬件构建,而成本只是传统硬件负载平衡器的一小部分(下面将详细介绍)。

通常被问到这个设计的一个问题是“边缘路由器为什么不通过ECMP直接与后端通信?为什么我们需要负载均衡器?“其原因主要是围绕DoS缓解和后端操作简便性。如果没有负载均衡器,每个后端都必须参与BGP,并且执行滚动部署的难度要大得多。

所有现代L4负载平衡系统都在朝着这种设计(或其某些变体)发展。最着名的两个例子是Google的Maglev亚马逊网络负载均衡器(NLB)目前没有任何OSS负载均衡器可以实现这种设计,但是,我知道有一家公司计划在2018年向OSS发布一个。我对这个版本感到非常兴奋,因为现代L4负载均衡器是一个至关重要的部分在网络空间中缺少OSS。

L7负载平衡的当前技术水平

确实是的。最近几年L7负载均衡器/代理开发出现了复苏。这与分布式系统中对微服务架构的持续推动非常吻合。从根本上说,当更频繁地使用时,固有故障的网络变得更难以有效地操作。此外,自动扩展,容器调度程序等的兴起意味着在静态文件中供应静态IP的日子早已不复存在。系统不仅更多地利用网络,它们变得更加动态,需要负载平衡器中的新功能。在本节中,我将简要总结现代L7负载平衡器中发展最多的领域。

协议支持

现代L7负载平衡器正在为许多不同的协议添加明确的支持。负载均衡器对应用流量的了解越多,它在可观察性输出,高级负载平衡和路由等方面就可以做得越复杂。例如,在撰写本文时,Envoy明确支持L7协议解析和路由。对于HTTP / 1,HTTP2,gRPC,Redis,MongoDB和DynamoDB。未来可能会添加更多协议,包括MySQL和Kafka。

动态配置

如上所述,分布式系统的日益动态的性质需要在创建动态和反应控制系统方面进行并行投资。Istio就是这种系统的一个例子。有关此主题的更多信息,请参阅我在服务网格数据平面与控制平面上的帖子

高级负载平衡

L7负载平衡器现在通常内置支持高级负载平衡功能,如超时,重试,速率限制,断路,阴影,缓冲,基于内容的路由等。

观测

如上面关于一般负载平衡器功能的部分所述,正在部署的越来越动态的系统变得越来越难以调试。强大的协议特定可观察性输出可能是现代L7负载平衡器提供的最重要的功能。现在,任何L7负载平衡解决方案几乎都需要输出数字统计,分布式跟踪和可自定义日志记录。

可扩展性

现代L7负载平衡器的用户通常希望轻松扩展它们以添加自定义功能。这可以通过编写加载到负载均衡器中的可插入过滤器来完成。许多负载平衡器也支持脚本,通常通过Lua

容错

我写了很多关于L4负载均衡器容错的文章。L7负载均衡器容错怎么样?通常,我们将L7负载平衡器视为可消耗和无状态的。使用商用软件可以轻松地水平缩放L7负载平衡器。此外,L7负载平衡器执行的处理和状态跟踪比L4复杂得多。尝试建立L7负载均衡器的HA配对在技术上是可行的,但这将是一项重大任务。

总的来说,在L4和L7负载均衡域中,业界正逐渐从HA配对转向通过一致散列融合的水平可扩展系统。

和更多

L7负载平衡器正在以惊人的速度发展。有关Envoy提供的示例,请参阅Envoy的架构概述

全局负载均衡和集中控制平面

图13:全局负载平衡

负载平衡的未来将越来越多地将各个负载平衡器视为商品设备。在我看来,真正的创新和商业机会都在控制平面内。图13显示了全局负载平衡系统的示例在这个例子中,发生了一些不同的事情:

  • 每个边车代理与三个不同区域(A,B和C)中的后端通信。
  • 如图所示,90%的流量被发送到区域C,而5%的流量被发送到区域A和B.
  • sidecar代理和后端都向全局负载均衡器报告周期性状态。这允许全局负载平衡器做出考虑延迟,成本,负载,当前故障等的决策。
  • 全局负载平衡器周期性地为每个边车代理配置当前路由信息。

全局负载均衡器将越来越能够完成任何单个负载均衡器无法独立完成的复杂事物。例如:

  • 自动检测并绕过区域性故障。
  • 应用全局安全和路由策略。
  • 使用机器学习和神经网络检测和缓解包括DDoS攻击在内的流量异常。
  • 提供集中的UI和可视化,使工程师能够聚合地理解和操作整个分布式系统。

为了实现全局负载平衡,用作数据平面的负载平衡器必须具有复杂的动态配置功能。有关此主题的更多信息,请参阅我在Envoy的通用数据平面API以及服务网格数据平面与控制平面帖子

从硬件到软件的演变

到目前为止,这篇文章仅简要提到了硬件与软件,主要是在历史L4负载均衡器HA对的上下文中。这个领域的行业趋势是什么?

之前的推文是一种幽默的夸张,但仍然总结了很多趋势,它们是:

  • 从历史上看,路由器和负载平衡器已被提供为极其昂贵的专有硬件。
  • 越来越多的大多数专有L3 / L4网络设备正在被商用服务器硬件,商用NIC以及基于IPVSDPDKfd.io等框架构建的专用软件解决方案所取代成本低于5千美元的现代数据中心机器可以使用Linux和使用DPDK编写的自定义用户空间应用程序轻松地使用非常小的数据包使80Gbps网卡饱和。与此同时,能够以惊人的总带宽和数据包速率进行ECMP路由的廉价且基本的路由器/交换机ASIC被打包为商品路由器。
  • 复杂的L7软件负载平衡器,如NGINX,HAProxy和Envoy,也在快速迭代和侵占之前的F5等供应商领域。因此,L7负载平衡器也在积极地转向商用软件解决方案。
  • 与此同时,整个行业向主要云提供商推动IaaS,CaaS和FaaS的转变意味着越来越少的工程师需要了解物理网络的工作原理(这些是“黑魔法“和”我们不再需要知道蹲下的“上面的部分”。

结论和负载平衡的未来

总而言之,这篇文章的主要内容是:

  • 负载平衡器是现代分布式系统中的关键组件。
  • 有两种通用类型的负载平衡器:L4和L7。
  • L4和L7负载平衡器都与现代架构相关。
  • L4负载平衡器正朝着可水平扩展的分布式一致性散列解决方案发展。
  • 由于动态微服务架构的激增,L7负载平衡器最近投入巨资。
  • 全局负载平衡以及控制平面和数据平面之间的分离是负载平衡的未来,并且可以找到大多数未来的创新和商业机会。
  • 该行业正在积极地转向用于网络解决方案的商用OSS硬件和软件。我相信像F5这样的传统负载平衡供应商将首先被OSS软件和云供应商所取代。传统路由器/交换机供应商,如Arista / Cumulus /等。我认为在内部部署方面有更大的发展,但最终也将被公共云供应商和他们自己开发的物理网络取代。

总的来说,我认为这是计算机网络的一个迷人时刻!大多数系统向OSS和软件的转变正在将迭代速度提高几个数量级。此外,随着分布式系统通过“无服务器”范例继续向动态迈进,底层网络和负载平衡系统的复杂性将需要相应增加。

人永远不够用——在复旦大学分享SRE团队组织和管理

从10月底到12月初, 数人云与复旦大学合作开授了面向复旦大学软件工程学院软件工程硕士的《信息系统工程概论(SRE:大规模应用运维实践)》系列选修课程,今天小数为大家带来此次选修课上有关SRE团队建设的精彩分享。

源于Google的SRE有助于解决传统运维模式上的问题,SRE是在运维模式上的全新探索,也是DevOps思想在运维方面的真正实践。SRE代表了一套先进的、完整的运维体系,作为Google最早提出,又经由Google发展完善的一个崭新概念,SRE已成为一个涵盖运维理念、思路、组织架构、和具体实践的完整体系。

SRE团队的建设和管理是SRE体系中重要的部分,今天我们来介绍一下SRE团队组织和管理,其中包括SRE工程师的特点,SRE的团队组织和工作原则,SRE的内部沟通机制,SRE的新人培训,SRE团队学习演练和总结。

SRE是这样一种人

SRE(Site Reliability Engineer)即站点可靠性工程师,是一种和传统系统管理员以及普通软件工程师有所区别的新型职业类型。从这张表里我们可以看到这三类人群从工作内容、关注点、技能特长和思维特征都不尽相同。

关于程序员、系统管理员、SRE在关注事项上的区别我们可以用一个例子来说明。比如图上这是一个标准的三层结构网站,对于这样一个结构的网站,程序员的着眼点是如何处理前端HTTP的request和生成response,如何构建数据库表的结构,通过API来访问数据库以及如何优化SQL语句来提高查询的效率。

系统管理员则关注的是如何承载业务压力,规划容量和保证日常运维工作的顺利开展。这包括服务器和网络的配置是什么,如何配置和对接监控和收集日志,该使用哪种版本的中间件和数据库,防火墙和iptable的设置等等。

而一个SRE人员关注的是什么呢?重点是如何在系统地灵活性和可靠性之间找到一个平衡。比如Web服务器的负载均衡策略是什么;数据库的高可用该选择什么样的方案;如果数据库未来需要扩容,当前方案是否支持;是否要跨地域多中心地部署,相应的流量引导和数据同步问题如何解决,评估系统变化对于可靠性和可扩展性的影响等等。

所以,综上所述可以归纳出SRE应该是这样的人。他们关注问题发生的根本原因,更够通过现象看本质,能够将复杂的问题切分成很多部分,这就是我们常说的决策树。再针对这些拆分的部分提出假设,并进行测试。不断深入不同的分支,直到找到根本的原因。他们能够根据大量信息进行归纳和抽象,以便进行深入的调查。基于现有数据和经验进行判断,拒绝主观的臆断。他们不拘泥于现成的“最佳方案”而是根据实际情况追求各方诉求的动态平衡。不但解决眼前出现的问题,还会预见未来的风险和扩展可能性,从而设计出有长远目标的实施方案。最后他们不默守陈规,勇于拥抱变化,不断打破旧的经验,重复造轮。

SRE的团队组织和工作原则

下面我们来介绍一下Google的团队组织和工作原则。Google在团队组建的时候秉承的是多样化原则。团队组织成员如果过于专业化虽然能够提高成熟度,但是只有多样化才能不断解决新的问题。Google SRE团队中有着包括“技术负责人”(TL)、“SRE经理”(SRM)和“项目经理”(PM/TPM/PGM)等多种角色。

很多时候组织内部是一个动态的环境,各种角色之间可以动态地协商切换责任。一般来说,越动态的团队成员的个人能力越强,每个人都要能写代码,每个人都要具备通用的工程能力。但是动态的团队不得不面临在沟通上需要花费更多时间的问题,因此这就要求团队持续进行沟通用以平衡多样化带来的弊端。

虽然团队的角色是多样化的,但是每一项工作内容要求专业化,明确区分系统性和值班化的工作,每个阶段都必须要有一个单一的目标,确保专注做好每件事情。

SRE的内部沟通机制

Google SRE一般是通过生产会议(production meeting)来进行内部的有效沟通。会议组织者一般由相关的SRE进行轮值,项目经理、所有SRE、开发团队代表、商务等任何和项目相关的成员都会被邀请参加会议。一般这个会议一周一次,一次一个小时左右。会议的议程包括变更预告、SLO review、故障的事后总结、警报紧急评估等相关议题。

SRE的新人培训

如何培养一个合格的SRE,Google也积累了一些内容和方法。这张图内包含了SRE团队可以采用的几个培训新员工的最佳实践,同时保证老员工不会落伍。从下面描述的很多个工具中,我们可以从中选择最适合团队的几个来使用。

这张图中包含两个轴 :

  • X 轴代表了工作类型的范围,从抽象的,一直到具体的工作;
  • Y 轴代表了时间,从上至下,新加入的SRE通常对系统和服务知识了解很少。

阅读之前故障的事后总结对他们很有帮助。新的SRE也可以试图从基本元素出发反向工程整个系统,因为他们本来对系统也没有任何了解。当学员对系统有一定程度的了解,并且已经进行了一些实际操作时,SRE就可以参与见习on-call值班了,同时可以修订文档中不完善或者过时的部分。

阅读上述图表的一些建议 :

  • 正式参加on-call值班是SRE新员工的一个重要里程碑,在这之后,学习过程将基本靠自己主导,是未定义的——所以SRE参与on-call值班之后的培训计划都是用虚线标注的;
  • 三角形的“项目工作”意味着新项目刚开始都很小,随着时间推移复杂程度逐渐增大,所需投入也在增加,很有可能在参与on-call值班之后还会继续;
  • 这里的某些活动是抽象性的,还有些是被动性的。其他的一些活动,则是非常具体和非常具有主动性的,还有一些活动则是混合型的,这样的安排是为了满足不同学习方式的人,让他们都能找到合适自己的活动;
  • 为了使培训效果最优,培训课程应该节奏合理:有些可以立即开始,有些则应该在SRE正式参见on-call之前开始,而其他的则应该是持续性的,同时要求SRE老员工也参与的,在SRE正式参加on-call之前,应该处于持续不断的学习过程中。

SRE的团队学习演练

故障处理分角色演习

当面对一个经验各异、能力各异的SRE团队时,如何能够将所有人紧密结合在一起启发他们互相学习是一个挑战。同时,如何将SRE文化——不断解决问题的文化——传授给新员工,同时保证老员工始终能跟上不断变化的环境和服务发展也是一个挑战。Google的SRE团队通过一个老传统——“故障处理分角色演习”来解决这些问题。这个活动同时也被称为“不幸之轮”(Wheel of misfortune)或者“走木板”(Walk the plank)等。这个活动能很好地帮助全体成员每周共同学习并且富有趣味。具体过程很简单,和桌上RPG游戏类似:“主持人”(GM)选择两个团队成员成为主on-call和副on-call;

这些SRE与GM同时坐在房间的最前面。主持人宣布某个警报发生了,这个on-call团队就需要进行调查和现场处理该报警。

GM事先准备一个故障场景,这个场景可能是某个以前发生过的故障,新成员可能没有经历过,老成员可能已经忘记了。或者该场景是某个新功能或者马上上线的功能的假想故障场景,这样参与的所有人都不知道如何处理。

在接下来的30~60分钟内,主on-call和副on-call要试着寻找问题的根源所在。GM会随着问题的展开而提供更多的信息,例如可能会告知大家某个监控图表的走势等。如果该问题需要向其他团队寻求帮助,GM会假扮成其他团队成员回答问题。

当灾难演习RPG运转成功时,每个人都会从中学到一点东西:可能是一个新工具、新技巧,或者解决问题的另外一个角度,或者(对新员工来说)对成功解决某个问题的认可。也许这项练习可以鼓励团队成员面对下周的挑战,甚至成为接下来某一周的GM。

总结

我们已经讲过构建一个合理的错误预算是非常重要的,极端的可靠性会带来成本的大幅提升,这也包括SRE团队的人力成本。因此对SLO要有一个量化的评估,以确保和人力水平相匹配。要从根源上解决问题就是要减少琐事,将重复性工作自动化,消除运维负载,否则人永远不够用。

http://blog.shurenyun.com/shurenyun-sre-203/

SRE系列教程 | 孙宇聪:来自Google的DevOps理念及实践(下)

上一期孙宇聪老师关于SRE基本概念和核心原理的线上分享一经推出就引起了小伙伴们的热烈关注,看来大家对SRE的相关内容很感兴趣呀。

今天小数继续为大家带来孙老师的第二次线上分享内容,探讨SRE的一些最佳实践和成功标准,希望大家阅读愉快并持续关注我们后续的SRE内容:)

接下来聊一聊SRE的一些最佳实践,我认为Google做得比较好的几点。

SRE的最佳实践

建设平台化服务体系

首先, Google现在是一个六万人的公司,涉及到的产品线可能一百多个,各个部门之间差距很大,而且Google全球几百个数据中心,有很多机器,它如何管理?如果按照国内公司的方式去管理早就累死了。因为国内很多运维部门从上到下什么都管,从买机器开始,一直到最上面安装服务器、调试,配网络,所以业务线、运维部门经常好几千人。Google做得比较好的一点就是它把一个东西横向切分,因为它很早之前就意识到很多部门或者很多人之间有共性?像现在国内有的公司也开始讲的,运维部门要输出能力,公司内部也要服务化,因为只有服务化才能让每个团队更加专业化。

所以回到Google这个平台上,我认为它实际上是不停的在切分,就是横向切分。首先最底下是所谓的资源供给层,就是相当于把数据中心这件事情真的当成了一个资源,可以服于用户。就是用户需要什么样的机器,配置架构怎么样,怎么设计数据中心,这些东西它都帮用户做好。有一个专门的团队去做这件事情,这个团队也有自己的研发,也有自己的运维,也有自己的operation、PM,什么都有。

往上是技术架构,技术架构是大家经常听说的Borg系统等,让一些比较通用的技术或者通用的架构都能形成平台式的东西。

再往上才是产品线,每一层实际上都有自己的SRE部门、运维部门,都是一个项目。所以把这个平台搭起来之后,上层的人可以越来越少关心底下的细节问题,一定程度的减少了他很多精力、减少了很多官僚主义上的问题。需要计算资源的时候就给资源,不是还要先去审批又买机器,什么样的机器,什么样的配置都不一样,所以整个公司是一个非常同质化的公司,很多业务底下共享的东西很多。工作在越底层的人如果能服务的人越多,就会产生一个所谓的放大效应。可能大公司都是这样的,它有平台化效应,底下的人可以搞出一个世界最好的数据中心,可以同时服务几十个产品线的业务;搞出一个更好的数据库,所有人都可以用,这是Google做得比较好的一点。

容量规划和容量管理

然后大家会发现在做一个业务层运维的时候,可以关注更高级的东西,不是关心买什么样机器,而是更多关心到底需要多少容量,这些容量应该在什么地方。在YouTube我们经常在办公室摆一个世界地图,大家经常会讨论这里有一个数据中心,那里有一个数据中心,然后讨论在这边放多少容量,在那边放多少容量,它们之间如何灾备,我们可以考虑这些更高级的、更抽象的东西。这样的好处是可以真正的做到容灾,就是所谓的N+M。就是如果平时需要的峰值流量是N,M是作为灾备流量或者是这个冗余流量。N和M到底是什么?很多公司连自己的N都不知道,从来没有说过我们到底要处理多少流量,有些领导说我们“双11”想来多大量的就来多大量,这怎么能搞好?

这个问题是运维部门独特的功能或者独特的角色,要负责将把这个东西确定下来,我们到底要承担多大的流量,要有多少冗余。接下来就是验证这件事情,到底有没有这样的能力,能不能处理这么大的流量或者这么大的需求? Google有一个内部指标就是130%,比如可以处理1秒交易量是一百万,实际上集群的峰都是按照一百万的130%来处理。130%是负载均衡或者是一些外界波动导致的,它实际上是不平均的。我们可以说它是一百万条交易的负荷,但实际上不可能说一百万零一条这个系统就崩溃了。可以留一下窗口,留一些冗余量来处理一些操作中的未知性,还有一些特殊意外情况,所以130%是一个我们常用的指标。

在Google里面已经很少提灾备这件事情,就是对我们来说我们没有灾备容量,都是平均负载均衡的。可能有一些冗余,比如一个系统只能一千台机器,这一千台机器并不是说我有十台是不接受业务处理的,而是我们所有机器都是接受业务处理,只不过他们处理能力可能没有把所有的资源都用完。这也是Google有很多经验教训,如果一个东西老是不用的话,它就是坏的,你平时再怎么演习、怎么用,一到关键时刻它就过不去、它就是有问题,所以更多的时候压根不讨论灾备的问题,所有东西永远都是在线的,这也是为什么说想把Google.com给弄坏是一件非常困难的事情,得全球几百个数据中心同时出问题,才可能会出现不可用的情况。所以Google全球业务是不可能中断的,不管出现多大的自然灾害,它这个业务都是不可能中断的。可能只有局部地区受损,只有基础设施受损的地方,它才会有一些问题,所以这就是灾备。

实战演习

另外一个更关键的一点是做实战演习。刚才也提到了,SRE以业务小组为单位,每周都会做实战演习,整个公司实际上每年也会做一次非常大的实战演习。我可以举几个例子,Google很多地方都有办公室,有一年某个办公室食堂的菜有问题,导致所有人都拉肚子进了医院。这是Google总部啊,一万人、两万人这样。于是我们就提出这样一个问题,说如果这个地方没有人来上班了,网站到底还能不能正常运行啊?我也曾经问过百度、腾讯,他们所有人都在一个大楼里,如果大楼突然断网了,公司还运转不运转?这是一个很大的问题,不管是地质灾害问题、自然灾害、人文灾害,这些虽然听起来好像比较极端,但确实能考验出一个组织的业务持续能力。实际上这是Google做得比较好的一点。刚才说的都是比较夸张的例子,是比较大范围的。一些比较小的例子,比如这个系统就是你这个小组负责,你们这个小组到底有没有单点故障,这个人是不是能休假,如果一旦出现问题是不是所有人都能去解决这个问题。我们经常互相出题去做这种测试,然后去分享一些知识。我想这更多是一种风气吧。首先你认同这个目标,目标当然就是把这个系统建设得更可靠。认同了这个目标,接下来就是不停地去考验还有哪些漏洞,并确保整个团队其他人也有同样的知识,同样的技能去解决这个问题。

其实说到Google在这一点上,也有所谓的运动式演练。每年1、2月份都会组织一次运动式演练,整个公司所有部门都要参与。在这一个星期的时间里实际上公司是不干什么正经事的,所有人都想出各种各样的方法去测试或者去提高系统的可靠性。

ONCALL的正确姿势

刚才说的这种比较大的所谓实战演习,具体到工作的时候也有几个,就是我们的轮值制度值班。国内小公司都是没有轮值制度的,所有人手机24小时开机,随时打电话,随时得解决问题,一个箭步从被窝里爬出来,赶紧上去解决问题。实际上这跟Google不一样。Google的值班方式更多的是八个人每人值一个星期,值一个星期,剩下的时间你就自己去写程序、做工程研发。但是在这一个星期里,你必须能处理生产上发生的一切问题,这才是真正值班。只有你值班,别人休假了,这才是值班,否则就不叫休假,也不叫值班。所以Google有一个非常明确的规定,Google认为一个事故的正确处理或从发生到解决到事后解决需要六个小时,它认为需要六个小时。运维人员每次值班一般都是值十二个小时的班,大概从早上五点到晚上五点或者是从早上十点到晚上十点。因为它所有的值班都是由两地互相倒的,在美国有一部分,在欧洲有一部分,我们上班的时候我们值班,他们上班的时候他们值班。Google认为其实一天最多只能发生两次事件。不管什么样的系统问题,首先要保证一定要有足够的时间去处理问题。因为如果问题发生太频繁了,就像有些互联网公司,每天一上班这手机就开始“嗡嗡”在桌子上不停的响。一旦有一会儿不响了,就开始担心说这个监控系统到底是是不是坏了。

如果处理太多了,实际上就变成什么呢?两个比较重要的因素,第一个因素是你没有办法好好处理,你处理相当于就是上去敲一个命令,没有时间去想到底这个东西为什么会出现这个问题,以后怎么避免这个问题。所以这个叫(狼来了)效应,你on call的时候已经没有时间去思考了。第二个会发生“狼来了”事件。本来可能是两次完全不一样的事故,但是你上一次处理的时候,你发现重启就行了,下一次你就条件反射,出现这个问题的之后你又去重启了,但它实际上可能是另外一个问题,可能是完全不相关的问题,你重启可能导致这问题更糟糕。所以如果你总是用这种模式处理问题的话必然会出问题,早晚这个灾难会升级。本来是一个很小的问题,结果可能变成一个很大的问题。

运维重要一点是解决线上问题。很多软件工程师做运维会钻牛角尖,这个线上系统出问题了,比如商城里不能购买了,这时候如果钻到这个程序里考虑要这么写还是那么写,实际上是不解决线上的问题。作为运维这个职业或者作为运营这个职业来说,它唯一的目标就是要保证系统的正常。有的时候需要用一些比较low的手段或者是方式。比如在项目初期机器有问题,我们就把它们都停了,然后使用一些新的服务器重新搭起来。事实上也不知道这个东西为什么坏了,就把它放在这儿,先去解决生产上的实际问题。实际上我认为这是运维最大的价值。运维部门目标就是保证业务的持续性。

事后总结

接着是做总结,写一些事后总结。Google的事后总结都是非常专业的,是非常对事不对人的,它会非常详细地列出来在什么时间出现了什么问题,谁去操作的,他执行了什么操作,这个操作到底是解决问题还是没有解决问题,如果没有解决问题的话该怎么去确保不会去执行这个操作。这是一个循环往复的过程,是一个不停锤炼的过程。把解决问题当成一个职业来对待的话,所有事情都很好办了。这回出现这个问题,解决了一遍,然后发现执行了某些地方可能是系统给出错误的信号,可能是文档有问题,把它都一一解决了。下回再执行的时候,可能换了一拨人来执行这个,也能保证不会出现问题。这就是事后总结带来的最大利益。

SLO预估

最后说说SLO。SLO是运维部门的一个关键工具。服务质量实际上是运维部门唯一负责的事情。公司要求员工达到某某指标,那员工怎么去达到这一点?第一,要先帮助制定SLO,要用事实、数据去说明白达到这个服务质量到底需要多少投入、需要多少流程改进、需要多少系统改进。第二,要确保达到这个服务质量不会影响创新速度。这要有一个平衡的取舍,要用数据去说话,一个每天只能down一分钟的系统和一个每天可以down四个小时的系统,它所能承受的更新频率是不一样的,部署的要求和方式肯定都是不一样的,所以要围绕着这个去做,要把这些理念推行到研发部门和产品部门。最后就是把可靠性当成产品的一个重要组成部分,研发也得关心可靠性,他在写代码的时候得知道这个东西一定是要可靠的。把可靠性一直推到产品设计或者是业务层次去,它才能贯彻到底层的研发、运维,才能把它做好。

SRE模型成功的标志

最后就是说到底SRE成功还是不成功,实际上就是看这两条曲线。上面这条线是部署规模,大家都知道互联网的业务都是爆发式增长,它是指数型的。如果说按照常规的那种招聘曲线,直线性的,那么永远赶不上这个规模,所以运维事务必须要把它压下来。Google经常做这种统计,到底我们业务规模扩大之后,扩大了多少工单数量,然后出现了多少事故,造成了多大问题。实际上只有统计这个事情,才能知道你到底做得好不好。当这个系统成熟到一定程度之后,SRE的运维速度是固定的,甚至是越来越少的。只有做到这一点,才相当于把运维这个事情做好,剩下的时间或者剩下的精力才能去接手更多的业务、做更多的技术研发。

我分享的东西也到此结束了,谢谢大家!

SRE系列教程 | 孙宇聪:来自Google的DevOps理念及实践(上)

http://blog.shurenyun.com/shurenyun-sre-189/

SRE系列教程 | 孙宇聪:来自Google的DevOps理念及实践(上)

SRE(Site Reliability Engineering)是最早由Google提出,又经由Google发展完善的一个崭新运维理念。如今SRE已成为一个涵盖运维理念、思路、组织架构和具体实践的完整体系。数人云推出SRE系列教程,由SRE经验丰富的技术大牛们为大家分享运维一线的独家干货,揭示SRE背后的秘密。

今天为系列教程第一期,我们邀请了前Google SRE、《SRE Google运维解密》的译者孙宇聪与大家进行了线上分享。本文为上篇,讲述了SRE的基本概念和核心原理。与孙老师本人一样风趣幽默的文章,小数希望大家阅读愉快:)

今天与大家分享的内容是关于最近我翻译的这本书,据说反响还不错,今天借这个机会聊一聊书中的内容,并与大家分享一下我回国两年多以来,Google经验在国内的一些思考和落地实践。

什么是SRE?

很多时候国内把DevOps的范围定得有点狭窄, DevOps这件事情在国外更多是整个行业内的一个趋势。DevOps是一种模式,主要是让IT相关的东西与商业结合得更紧密一些,迭代速度变得更快一些,所以它适用于各个行业。今天说的SRE,我认为也是在运维行业上的一部分。

概括来说,我认为《SRE Google运维解密》这本书是一个文集。GoogleSRE全球一千多人,这个组织在公司里相对比较小众,但又是一个比较重要的部门,整个Google所有业务线的运维环境都由SRE来负责。SRE是一个非常分散的组织,每个业务线、每个部门其实都有自己的SRE小团队。这本书里共有一百多个作者联合写成,其中也包括我以前所在的团队,我们做过的一些Project也在书中也有提到,所以它是一本文集。我与原著的三个编辑聊天时,他们说成书最大的难处就是删减内容,当时征集来的内容大概有一千多页,最后删到了五百多页。这也是这本书比较有意思的一个花絮。

回到这本书的宗旨, SRE到底是什么?SRE是Google发明的一个词语或者新定义的一个职业。以前这个运维角色,大家叫运维,美国叫Operation。现在Google把这个职位扩展为SRE,就是用软件工程师的方法和手段,招了一些软件工程师来解决运维的难题,这是SRE的官方定义。

传统运维模式的弱点

现在传统的计算机行业的运维方式,大部分都是采用系统管理员的模式。大家最熟悉的运维方式是这样:招聘一些系统管理员,他们有负责采购机器的,有负责维护数据中心的,也有专门维护数据库的等等。系统管理员模式有几个特点,他们只是把一些现成的组件组装起来,并不会自己开发和创造新的系统,比如拿了MySQL把它跑起来,或是研发部门开发出来的新代码组装成之后提供这样一个服务。这是运维部门的一个特色,负责把这个东西运行好。

举一个例子,在美国的时候我们经常自嘲,说自己是流水线上的工人。因为这个流水线实际上是别人设计出来的,总得有人去操作这个机器,而我们就是一线的操作流水线的工人。又比如,我们好像是发电站里的工作人员,又或者是飞机驾驶员。飞机驾驶员就是开别人造出来的飞机,这和运维部门的职责很像。

那么这样一个运维部门的职责包括哪些呢?首先最重要的是应急事件的处理,这是重中之重,也是最唯一的职责。其次是常规更新,现在的业务发展越来越快,每周都有新的东西上线,比如说今天要买新机器,明天要改IP地址,大家可能80%的投入都是在这些事上,这就是系统管理员或者是现在运维行业的工作模式。

但是系统管理员模式有一个最大的弊端,按照传统的组织架构模式或者是这种运维模式运行会导致这个团队持续扩张,业务越来越多,需要不停的招人去应付各种各样的事。刚开始接手生产的时候,也许一周就出一次事或者是需要更新一次。因为人的沟通能力总是有限的,招了五个人之后,这五个人之间的传达问题就形成了一个困难。当你把一个精神传达给这五个人,他们事后执行出来的结果都不一样,这就是传统模型一直想要解决的问题。但是这种模型也有好处,就是市场招聘比较容易。

Google有几个比较重要的特点,首先它的部署规模非常大。Google到今天已经十八年了,刚开始前几年公司所有的人平时写代码,周末去机房接机器。因为它扩展速度特别快,部署规模非常大。如果按照传统的系统管理员的那种模式操作,这个机柜归你,这个机柜归他,再下一个归另外一个人,那么Google招人的速度一定赶不上机器增加的速度,所以Google是被逼迫创造了这样的职位,因为没有办法安排团队做如此大规模的运维。

传统的运维模式还有一个更大的问题,它过于强调专业化。比如一个人是做网络的,他只做网络其他都不管,全公司可能只有他懂网络,因为他不停的在网络上投入时间,集中力气把这个事情做好。这样一个结果就是会发现运维部门没人能休假,一出事只有一个人能解决问题。不仅仅是网络,特殊硬件、一些第三方服务都存在这个问题。这就导致了知识没法共享,人灵活性受到限制,整个组织的灵活性也受限制。这个问题,我认为它最终形成了一个负反馈的循环,每个人之间越是互相隔离,越是没有办法提高,导致服务质量上不去。最大的问题是,招来更多的人其实也不解决问题,因为这个部署规模不断扩大,人之间的知识不能共享,所以招来的人只能运维新的设备,旧的设备还是这些人在做。

这是一个怪圈。回国之后我与很多公司的朋友都聊过这个问题。以前大家讲Oracle这样的公司存在老DBA,说老DBA都是难得一见的,深居简出,但是你有什么问题,只有他能解决,其实这在Google这个语境里这是一个比较不健康的状态。SRE的一大特点就是想请假的时候随时请假,每一个人都可以请假;当出现紧急情况的时候,当天值班的人真的可以处理他负责的这个服务所有的问题。

Google SRE的起源与特点

回到最开始,Google SRE的VP叫Ben Treynor,他是一个资深的软件开发经理。2003年他加入公司第一个任务,是组建一个7人的“生产运维小组”。很快他发现如果想把这件事情做好,也就是把搜索服务运维好的话,按照Google机器增加的速度,传统的模式绝对是不可能的。机器增加的速度,系统复杂度增加的速度远比人增加的速度要多得多。所以他组建的团队有以下三个特点,注意,这里我认为其实更多的是事后的总结。首先,他的执行方式是像组建一个研发团队一样来组建这个运维团队。他招了很多他熟悉的研发工程师,这些研发工程师从开发能力上没有任何问题,用现在流行的话就是全栈工程师,什么都会做。第二点,这些人对系统管理比较有热情,懂一些Linux内核知识、网络层的知识。第三点,最关键的是这些人鄙视重复性劳动,码农最痛恨的是什么事,就是反复做同一件事。他把这些人聚到一块,然后让他们执行以前传统公司运维人员来做的事情,很自然这些人不愿意手动干,于是就写程序干。多快好省,同时写程序还有一个好处,就是可以把一些最佳实践、方式、流程、方法都固化成代码,用这种方式去应对规模性的扩张,去应对复杂度的上升。

这些是SRE跟传统的运维模式最不同的一点,就是招的人研发为主,做的事也是以研发为主。这是当时SRE成立背后的故事,这些年来我认为他们做得最好的一点是一直在维持了一种平衡。将运维部门从传统执行部门往上提升,打破了传统的界限。就像刚才说的DevOps,很多人理解为就是让研发部门做运维的事,或者运维部门做研发的事情,但实际上DevOps在国外的定义更宽泛一点。DevOps的思想更多的是说把整个开发流程的界限打通,产品有的时候也要干一些研发的事,研发有时候把这个信息要很快的反馈给这个产品,开发和运维或者QA和运维之间的界限也打通。所以现在去搜DevOps的图片,会发现IBM这些人都在讲圈圈,说以前是产品研发都是一条线直着来,而现在都是转圈的,这就是DevOps理论。

按照这个理论来说,SRE就是DevOps的思想在开发和运维之间的一个平衡。

SRE的工作职责

这个图是我发明的,书中没有提到。书里大概有二十多章的内容是在讲SRE的各种日常工作,简单提了一下它的金字塔模型,于是我归纳总结了一下。这里是由下至上,下面的事份额比较大一点,上面的事份额比较小一点,分了三类。第一类,运维部门最重要的是应急响应这个问题,因为业务越来越大,与运营的结合越来越紧密,很多时候要处理的事情更多的是商业和运营上的事,也包括软件上的问题,这个部门最特殊或者最唯一的职责就是应急响应。之上是日常运维,保证机器能够正常更新、快速迭代。再往上是输出一些工程研发,无论是做工具,还是做高可用架构、提高可靠性,这些都是最上层的东西,只有把底下全部做好了才能说到上面。

应急响应

应急响应是运维部门在公司最独特的一点,表现为当公司出现问题时,应该找谁或者流程应该是怎样的。我回国之后见了不少初创企业,他们网站出问题了,往往是CEO先发现,CEO打电话“哎,这个到底是怎么回事啊”,然后每一个人都说“不知道啊,不是我负责呀,我得找谁谁”。不管多大一件事都得传遍整个公司,整个效率非常混乱。

我在Google待了八年时间,这样的流程也经历过,但是最近这几年Google非常重视这一点,建立了一整套应急事件处理方式。首先要有全面监控,监控这件事情是持久不断的,重中之重。SRE所有人都要非常了解整个监控系统在所有业务中的部署实施,其实这是我们平时花精力最多的地方。监控系统里面对整个系统所有方面都有监控,不光包括业务指标,也包括性能指标、效率指标。监控应该平台化、系统化,不停的往上积累,多做一些模板,同质化的系统就可以用同样的方法去做监控。

第二点是应急事务处理,应急事务处理分两部分,第一部分是演习,另外一部分是真正的处理流程。如何把它做好?实际上就是要不停的去演习、去做这个事情。像刚才举的例子,网站挂了,首先不应该CEO先发现,而应该是监控系统或者报警系统先告警,在发现之前就很应该明确这个东西应该谁排查,谁处理,这个信息应该早就发给合适的人去处理,甚至他应该早就在做了。如果发生特别大的,需要跨部门之间协作的问题,那不应该只是领导现场调配,而是整个组织每个人都明白这个流程应该是怎么样的,直接就做。Google甚至可以做到在一次事故中间两地交班,某个团队处理一半,然后我交接给另外一边团队,就下班回家了,持续不停的有人继续跟踪处理这件事情,而不会出现问题。这样一个模式是我觉得非常值得我们思考的。

处理完问题之后,要总结。之前听过的一个故事是,某公司业务出现了一个事故,大家加班加点,十几个小时没睡觉把这事搞定,然后领导过来就说了一句“大家辛苦了,回家睡觉吧”。但是,其实在这个时候我要说,领导光说这个其实恰恰是不够的。领导在这里应该问:为什么加班啊?这个事情为什么会发生啊,下次能不能不发生,大家能不能不加班,能不能不熬夜?这样才对, 能做到事后总结这个事情很难,但只有把这个做好了,才能降低以后问题发生的几率。

日常运维

日常运维做得最多的可能是变更管理。业务现在发展非常快,迭代速度、迭代周期非常快。其实这件事情能做好,能够做到无缝、安全、不停的变更管理,是运维部门能给公司做的最大贡献。

第二个,容量规划,当规模大到一定程度的时候,就需要有人来回答这个问题——到底要买多少新机器,能否保证明年的性能、效率,那谁来负责这件事呢?SRE部门提出这些方案,然后要确保这些指标、这些东西是有数据支撑的,确实能解决问题的。

工程研发

工程研发虽然做得少,但是工作很关键。SRE在工程研发上主要的工作,首先是帮产品部门确定一个SLO。SLO是一个服务指标,每一个产品都有一个服务指标。任何系统都不可能是百分之百可靠的,也没有必要做到百分之百可靠。这里得有一个目标,比如说可以每个月中断几分钟。这件事情是要产品部门考虑清楚的。比如我之前在YouTube做视频存储、视频点播的时候,要考虑每个视频到底是存一份还是存两份的问题,将这种问题放到一个非常大的部署规模里面的时候,只有产品部门能够拍板。说到底是要不要花这个预算,要不要花这么多钱去提高0.1%的可靠性或者0.01%的可靠性。

另外一点是无人化运维。大家都看过《黑客帝国》吧?一醒来发现大家都是电池,都是为机器服务的。其实把这个比喻放在运维部门非常合适。因为如果不停的开发出需要人来操作运维的系统,结果大家最后都是电池,明显是不可持续的。如果不停的产生这种需要人来操作的东西,不停的招人,最后就变成不停的运维这个东西。把整个流程自动化,建立一个能够应对复杂业务的平台,这就是工程研发上最需要的东西。

SRE模型成功的关键要素

SRE在Google有十几年的历史了。这个模型是如何成功的?我总结如下几点:

职业化

运维行业从来都说不清楚自己是干嘛的,这是不对的。很多人认为会操作Linux,或者是DBA、会配网络,就算运维了。实际上运维的范围要比这个大得多。运维应该是负责公司业务正常运转的角色,这才是真正的运维。在出问题的时候能解决问题,保障业务连续性,甚至避免问题发生,这才是运维职业的定义。

具体如何做呢?推演和演习。

推演是给你一套系统,你要分析出来它会有什么样的失败模式。我们当时经常在黑板上画系统图,大家一起讨论如果这个组件出问题了会发生什么情况,用户到底还能不能看视频了,用户购买流程还能不能走通。实际上这些过程很多时候软件开发是不考虑的,但是如何拆分、如何去保证每个环节的可靠,这才反是运维这个行业最关键的一点,所以一定要做这种推演。只有这种推演才能输出改变,让系统更可靠。

第二点是演习。我们当时每周都会进行一次小型灾难演习,例如把以前出现的问题拿出来一个,让新加入团队的人去演习,所有其他的人也都要去参加。这里主要是观察新人到底是怎么思考这个系统的,新人做出的决定到底是不是正确的。因为一个人做出的决定是不是正确的实际上取决于系统给的反馈到底是不是对的。Google认为运维复杂系统不是一个靠智商和记忆力就能解决的问题,不能依赖人一定要知道这段话或这个知识点,而是要知道一种方法,知道如何去排除问题或排查问题。运维系统应该提供足够的信息,让轮值的人能够用正确的方法去处理问题。这很像是背英语辞典和会用英语聊天的区别,你再怎么背辞典关键时刻也是要查辞典的,但是真正能运用这些信息解决问题,是比较难的。

此外,要区分责任和指责。责任和指责是两个事情,但是很多公司的运维经常分不清楚。什么叫责任,就是这个事到底谁负责。但是指责是另外一回事。例如一个员工敲错了一个命令,大家说 “都是因为他的错,给他扣工资、扣奖金,让他三天不吃饭”,但这其实并不真正解决问题。再例如,比如说一个系统设计电源插座,没有仔细考虑,很容易被人踢到,结果有人真踢到了,整个机房断电了出了很大的事故。那么从Google的理念来说这里不是人的问题,而是系统设计的问题。这里是不是应该有两套电源,是不是应该有保护?只有从系统设计问题的角度出发才能真正解决问题,而指责这个踢到插座的人,让他一个月不上班,甚至当时开除也并不能解决系统的设计问题,下回总会还有人踢到。

说一个故事,故事的内容是一个事故。某个数据中心有一排机器要断电,数据中心的人发了一个工单告诉操作员要把这个开关给关了。然后这个操作员去关,他关掉了开关,但是发现这一排机器的灯没灭,另外一排的灯却灭了——按错开关了。他检查一下发现按错了,“啪”把另外一个开关也关了,然后再把这一排机器给启动,结果由于启动时候过载导致整个数据中心都断电了,扩大了问题。如果单纯只是指责,这个人肯定完了,起码奖金没有了,能不能保证工作都不知道。但是Google 更关注的是这个东西为什么会容易出错,要么是开关颜色不对,要么是相同机器的操作方式靠得太近了,会让人产生这种错误的判断。所以你看Google的机房里都是五颜六色的,因为这样确实有用,比如热水管是红色的,制冷管是蓝色的,所以查起来很容易,区分起来很容易,尽量减少了这个问题。这个设计的思想在SRE日常工作里贯彻得非常深,每人在流程或工作的时候都要考虑到有没有被误用的可能,然后如何避免误用。

专业化

专业化体现在什么程度呢?要真正的去写代码,要能给业务系统或者给研发写的东西挑出问题,提高可靠性。

第一,减少琐事。运维中有很多虚假的工作。每天很忙,然而又不解决问题,做了很多假的工作。大家看起来好像很忙,一个屏幕上十几个窗口,各种刷屏,但完全不解决问题。更好的方式是用自动化、系统化、工具化的方式去消除这种琐事的存在。如果永远靠人工,那永远都闲不下来。

第二,回到SRE,SRE制度里有一条红线,运维的人只能把一半的时间花在运维上,另外一半的时间必须搞工程上、研发上的东西。研发可以是写工具,可以是参与系统设计,参与可靠性的提高,但是要保证运维不能只干运维。

第三点,我认为也是比较缺少的,运维部门光有责任没有决策权,所以大家都说一出事故,运维就背黑锅。怎么不背黑锅呢?说改这儿、改那儿,然后发现没有人批准改动,这是最大的问题。SRE做的最好的一点是管理层对SRE的工作方式非常认可、非常支持,他们认为服务质量是服务的一个重要指标。一旦上升到这个高度,SRE部门提出一些要求就比较容易理解,得到支持,因为他们是有事实根据的。当GoogleSRE发现生产出现问题的时候,标准的解决办法就是暂停所有更新,确保业务稳定。举个比较极端的例子,像刚才说的如果发现线上系统有问题的情况下,SRE是有权利拒绝接受业务更新的,只允许研发部门修bug,不允许加新功能。这个争议我在过去八年见过为数不多的几次,开发可以一直闹到 VP,SVP 这个级别。每一次都是听SRE的。

打通与产品团队的反馈回路

所有东西不都是百分之百稳定的,稳定性的提高要消耗成本,要增加更多的冗余,更多的容量,甚至只能花钱解决。运维部门的任务就是提供这些数据和方案。比如搞三个9、四个9,要如何达到,这在投入和系统设计上有很大区别。这个部分公司里没有其他人可以提出,必须要由运维部门提出。如果没有这个反馈回路的话,你会发现大家都很痛苦,很多时候做出的决定都是违背自然规律的。我看过很多这样的案例,上面拍脑门决定某个业务要100%稳定,完全不管下面怎么搞,由于反馈回路不存在或者这个反馈回路的信息流动不够顺畅,导致了这个东西最终实际做不好,这是SRE模型相当关键的一个地方。

http://blog.shurenyun.com/shurenyun-sre-188/

10位技术领袖告诉你趟过的微服务那些坑和最佳实践

切换到微服务架构似乎很容易,但技术领导者往往低估了项目的复杂性,并犯下灾难性的错误。此文对来自以色列和美国等5个国家的技术领袖进行了13次采访。这篇文章很长,内容包括如下一些方面:

• 微服务是什么 • 微服务架构优劣势分析 • 微服务面临的挑战和应对解决方案 • 微服务落地要避开的坑 • 来自技术领导型企业的微服务架构最佳实践 • 如何选择微服务当中的技术栈? • 实用的技术建议 为什么转向微服务? 企业容易犯的最大错误是在没有明确目标的情况下,转向微服务架构。需要了解并有真正的理由表明为什么要这样做。

“人们盲目进入很多领域:Docker很酷,微服务很伟大!但它可能不适合你的体系构建,你需要了解为什么要这么做。” – 来自Steven McCord, ICX Media(一家企业营销视频制作众包平台 )创始人兼CTO。

如果你的系统工作正常,那有什么动力去改变它?

如果只是因为微服务被炒作,这并不意味着你需要跳入潮流。它不一定是企业软件的最佳技术选择。

“确定原因至关重要。”这是David Dawson,Steven McCord和Avi Cavale 所强调的。

“当客户要求我实施微服务时,我会问的第一个问题是,为什么?我正在寻找的答案是,“希望更快地改变系统”和“希望利用云技术”。微服务其实比建立单一的系统更昂贵和困难。微服务在数据模型中引入网络,可以随时进行任意分割,但也可能伴随数据丢失,让企业暴露在分布式计算的恐惧之中。“ – 系统架构师 David Dawson说道。 明确定义一个微服务

“我不一定选择微服务。我倾向中型服务,所以不是从单体架构转到上百种的微服务,而是与工程团队和业务保持一致的更大的服务。” – 来自 Daniel Ben-Zvi , SimilarWeb(网站和应用追踪分析公司) 研发副总裁。

如何做?一个围观案例研究

“我们通过查看哪些代码(如果更改的话)最终确定了指数测试案例,从而确定了一个微服务。我们的目标是减少对每次改变的测试次数。如果这是你的目标,那么微服务的定义就和”计费就是一个微服务”没有什么不同。”Shippable 联合创始人兼CEO Avi Cavale 说道。 微服务架构优劣势分析

微服务显著优势 可扩展性:分析小块的应用,看每块的要求,每部分可以分别伸缩应用程序的不同部分。

“另外一个好处是,可以在任何虚拟机之外扩展容器。容器可以放置在任何形式的配置中,应用程序具有完全的可移植性。“ – ICX Media 创始人兼CTO Steven McCord说道。

更简单的可维护性:不同的团队以不同方式独立处理不同的组件。

独立部署和配置:部署和配置每个服务时,不会影响其他服务。多个团队可以将多个结果投放到生产中,不会彼此干扰。

问题隔离:更容易隔离和监测问题。

易于招聘:寻找开发人员或第三方供应商时,只需培训他们系统的一部分。

清晰的责任:一个团队负责特定的微服务。

深厚的知识:团队从内到外了解相关知识。

多种编程语言:可以使用不同的编程语言,这取决于微服务的目的。

更易于监督和理解:将庞大的代码分割成更小的项目,利于团队更好地理解。

更容易开放组件:当边界和接口被明确定义时,向新的业务单元开放组件或现有功能更容易。

微服务劣势

部署和互操作性:这是首要问题。

编程语言太多:会限制代码的可重用性以及可维护性,并且维护更加复杂。

组件一起工作:要确保服务是以一种协同工作的方式组成。只考虑改变单一的端点,会打破旧版本的其他依赖服务。

与单体系统相比,更难以对整个系统进行集成测试。

架构必须从一开始就深思熟虑:如果服务之间的凝聚力过大,也会失去大部分优势。

加大通信力度:在服务之间的通信方面,需要进行投入。服务的通信之间容易发生故障。

难以监控整个系统:大量组件对监控来说,是噩梦。

花时间学习:使用微服务需要学习,这需要时间。

复杂性:越来越多的微服务使整个系统更加复杂,难以监控。

“所有这些东西都散在周围。如果没有很好的工程流程,企业最终获得一大堆东西,然而根本不会使用。” – Shippable联合创始人兼CEO Avi Cavale说道。

“在基于微服务的平台上调试生产问题是完全不同的操作。如果没有相应的监测,记录和跟踪设施,系统的复杂性会显著增加。这就像迷宫一样。工程实践和标准化至关重要。” – SimilarWeb研发副总裁 Daniel Ben-Zvi 说道。

“记录到一个地方有挑战性。Loggly,Splunk或Heroku等第三方日志聚合服务是非常好的解决方案,但价格非常高。根据我的经验,遥测特别集中的日志是最大的难题。必须考虑每个服务的详细程度。否则,企业可能要花费50-60%的成本进行记录。”-来自微软公司SRE工程师 Sonu Kumar。 微服务面临的挑战和解决方案

当转向微服务时,如下这些是技术领导者和开发团队面临的最大挑战。 • 挑战1:一次切换所有系统 • 挑战2:拆分系统 • 挑战3:组织认同 • 挑战4:团队

> 挑战1:一次切换所有系统

“从单体架构切换到微服务架构不是一次就可以完成的。如果企业有单体服务器,那么其周围可能被存储库,部署任务,监控和其他许多事情包围。一起更改并不容易。” – AdRoll软件工程师Brujo Benavides说道。

“如果一个公司从未有任何微服务经验,即使是新建,也会比想象的更难。” – LogMeIn DevOps工程师 Viktor Tusa 说道。

white_check_mark:可能的解决方案

“那时候我们做的是保留单体服务器,但是任何新的服务都是通过微服务来开发的。”(Brujo Benavides)

挑战2:拆分系统

“如果组件和服务聚集在一起,隔离起来相当具有挑战性。(Robert Aistleitner)。需要定义各个部分之间的交互和流程。如果没有很好的定义,系统会产生更多问题。”- StyleSage高级开发人员 Jose Alvarez 表示。

“将系统拆分成微服务有许多不同的规则,没有特定的模式,没人会告诉你,如何在应用程序中使用它。而且,没有两个相同的微服务”。 – Recart 首席架构师大卫·帕普说道。

white_check_mark:可能的解决方案

“把单体系统分解成微服务的唯一方法,是首先检查单体系统,看看它最“痛”在哪里。将这些部分拿出来并转化成微服务“。 – Emarsys工程副总裁Andras Fincza表示。

监控所有部分是如何工作的以及他们在做什么。监控过程中,可以很容易地发现和解决问题。(Jose Alvarez)

模块by模块渐进地分离单片系统是最好的方法。想一次做所有事情,一定会失败的。

监控工具提示: • New Relic • Datadog • Influxdb • Grafana

挑战3:组织的支持

“获得组织认同可能是最难的部分。” – 来自 Steven McCord ,ICX Media创始人兼CTO。

这不是一个技术决定。需要清楚说明微服务架构的好处,从而说服企业重新分配资源。在企业接受变革之前,这是一个漫长而乏味的过程,组织规模越大,决策的时间越长。

white_check_mark:可能的解决方案

说服组织改用微服务的最佳方式,是将非核心部分转换为微服务。通过这种方式,来展示微服务的优势。

挑战4:团队

“团队本身面临着最大的挑战,它需要不同的思考。” “开发人员必须花费更多时间来了解什么是端到端场景。他们需要熟悉这些技术,需要转换思维方式。”

“对于一个在端到端测试的世界中工作的人来说,突然把它分解成小块,是不舒服的,这更多是文化上的变化。”-Shippable 联合创始人兼CEO Avi Cavale说道。

white_check_mark:可能的解决方案

从非常小的可以真正受益的方面开始,并选择应用程序的非关键部分。获得一个小团队的支持,并将这部分转换为微服务。一方面来证明微服务的优势,另一方面逐步向企业扩展(Avi Cavale)。

微服务落地要避开的坑

“避免同时将整个系统切换到微服务。” – Emarsys工程副总裁 Andras Fincza 说道。

“你能犯的最大的错误就是,没有创建一个微服务架构变化可能带来的影响概览。在实际开始实施新方法之前,必须包括大量移动组件。“ – Usersnap工程副总裁Robert Aistleitner说道。

“单体架构很容易改变内部接口。只需重构代码,然后运行测试。使用微服务,API必须可靠,你不一定知道你所有的客户。如果没有API的话,会给未来带来许多麻烦。此外,确保有分布式跟踪系统。”-来自 Daniel Ben-Zvi ,Similar Web研发副总裁。

“不要在没有搞清楚平台和依赖关系的情况下,尝试切换到微服务。此外,也要避免认为微服务都不错,因为每一个微服务可以用不同的语言来编写是一个不好的做法。” – 来自 Viktor Tusa ,LogMeIn DevOps工程师 。

“处理数据至关重要。搞砸数据非常容易,但是很难恢复。数据迁移需要更多步骤。” – Emarsys工程副总裁Andras Fincza表示。

“在微服务之间共享数据是一个很大的禁忌。如果两个服务操纵相同的数据,将遇到一致性问题,并消除所有权。“ – Daniel Ben-Zvi&Varun Villait二者共同认为。

“把应用程序分解成太多太小的东西,或者强迫把系统转变成微服务,这不应该是微服务 – 仅仅是炒作”。- 来自 Doctusoft首席开发Csaba Kassai 的观点。 来自技术领导型企业的微服务架构最佳实践

创建微服务之间的隔离,可以根据需要快速更改它们。这通常需要在几个层面进行隔离:

运行时流程:这是最明显的,也是普遍采用的过程。以前只有一个流程,而现在有很多。这里的主要成本是采用某种形式的分布式计算,这很难做到。会导致采用容器化,事件架构,各种http管理方法,服务网格和断路器。

团队/文化:分离团队,给予自主权,意味着划分人与人之间的沟通。这往往会导致知识孤岛和工作重叠(解决选择性与资源效率的选择)。

数据:采用像微服务这样的分布式计算最大的影响是它影响企业的数据。以某种形式对数据进行划分,需要在系统级别重新整合,以给出“一个系统”的印象。这在伸缩方面有潜在好处,但也需要相比简单的单一数据架构方法的更多想法。(来自David Dawson) 如何选择微服务当中的技术栈?

这是不同意见开始碰撞的地方…

一方面,人们认为使用什么技术和编程语言并不重要。

“几乎所有的问题都可以用任何技术解决。人们花费太多时间寻找正确的技术,如果以迭代的方式来做,你就有时间思考,并看到它的实际应用。错误的决策也可以得到缓解。” – Andras Fincza ,Emarsys 工程副总裁表示。

“大多数现代语言(Python,Java,C#,Node / JavaScript)同样快速且可扩展。从这个角度来看,语言无关紧要。每种语言都有其优点和缺点。大部分时间,语言选择是根据个人的喜好,而不是技术参数。” -Andras Fincza , LogMeIn DevOps 工程师说道。

花费大量的时间来选择最好的技术是不值得的,因为差异很小。

“选择技术的重要性被高估了。如果运行成本很重要,那么就可以接受,对我们来说没那么重要。” – Andras Fincza , Emarsys 工程副总裁。

“如果是新建项目,选择程序员最了解的语言。如果不是,选择客户端上最佳覆盖业务系统的语言。” -Viktor Tusa , LogMeIn DevOps 工程师 。

“微服务的好处在于它被封装在一个微服务中,只需要给外部的接口来谈论这件事。只要有一个界面就够了。“ -Steven McCord , ICX Media创始人兼CTO 。

选择合适的技术不仅仅是技术问题,也是一个决策。如果选择一种具有10种不同编程语言的微服务架构,要确保团队能够处理该问题。

“我不推荐混合太多的编程语言,因为招聘会变得更加困难。而且,程序员的上下文切换会减慢开发速度。“ – Robert Aistleitner , Usersnap工程副总裁。

“必须有意识地选择想要建立的开发团队类型。如果想使用许多不同的编程语言,需要建立一个能够使用和学习不同编程语言的动态团队。“ – Steven McCord , ICX Media创始人兼CTO 。 实用的技术建议 “我强烈建议在Google云端平台中使用管理服务,如App Engine。这将肩负很大的负担。此外,选择语言/技术时/框架时,选择合适的针对特定微服务的使用情况是重要的,不要因为熟悉它,而强迫选它。” – Csaba Kassai ,Doctusoft 首席开发。

以下来自Brujo Benavides:

一些技术领导者乐于推荐一些技术,这些技术可以很好地适用于服务特定角色的微服务。在选择微服务技术时,建议考虑: • 可维护性 • 容错 • 可扩展性 • 架构成本 • 易于部署 Brujo团队的一些微服务框架/技术示例: 
• Scrapy for web crawling • Celery + RabbitMQ用于微服务通信 • NLTK + Tensorflow(以及其他一些)用于机器学习部分 • AWS服务 如何选择合适的技术/语言?

在为微服务选择编程语言/技术时,需要考虑很多事情。

其中最重要的就是看你的开发人员具备哪些能力,以及语言/技术背后有多大的支持(工具,社区……)。根据我的经验,公司倾向于根据其开发人员的能力选择一种编程语言。“ – Csaba Kassai , Doctusoft首席开发人员。

“使用技术背后有很多支持(资源和活跃的社区)。我推荐Ruby和JavaScript,可以得到很多支持,如果出问题,很多人都可以提供帮助。只要确定有很多人使用它,选择语言不应该是问题。如果团队不具备这些知识,可以依靠外部资源。“ – Varun Villait,Industry CEO。

“另一个因素可能是图书馆可以用来加速项目的语言。你理想的语言的某些东西可能图书馆没有,不得不自己发明,这是另外的时间流失。容错和可扩展性也是重要因素。如果从现在开始的几个月内,你不得不重新编写一些东西,因为最初的选择无法扩展,那不如放弃。这一切都归结到一个特定的团队情况,他们愿意进行投入。” – Greg Neiheisel , Astronomer联合创始人兼 CTO 。

Emarsys就是这样看待这个过程的:

在Emarsys,如果他们想应用一种新的编程语言,开发人员需要提供真实的,合乎逻辑的理由,并咨询主要开发人员。团队聚集在一起讨论技术的优缺点。

他们总是用不同的技术创造一个尖峰解决方案。这可以让他们试验一个给定技术的边界,看看它是否可以应用于给定的微服务。这对于发现技术的局限性是完美的。

“建议使用您的团队已经熟悉的语言。这样,他们可以工作更舒适,进展较快。” –来自 Andras Fincza, Emarsys 公司工程副总裁 。

这是他们在SimilarWeb上所做的:

作为一家大数据和分析公司,我们面临着非常大的挑战,这增加了选择错误技术的风险和影响。单线程框架(如NodeJS)虽然适用于网络绑定服务,但在处理实时密集型数据处理时不会扩展。

工程师通过平衡战术和战略需求,同时考虑技术和组织的约束条件,来确定使用哪种技术。企业正处于快速成长阶段吗?服务是否需要处理大量数据?是否希望将新技术添加到堆栈中,是因为相信它的生态系统,还是使用我们已经掌握的现有技术?想要试验吗?能找到对此充满激情的工程师吗?是否愿意长期致力于这项技术?技术的生态系统是一个主要因素。我们希望与开源社区合作,使用和贡献现有的框架,而不是重新发明。

定义明确的指导方针甚至是清单可以帮助促进健康的决策过程,缩小可能的技术选择范围,从而选择最适合的团队和产品方案。

David Dawson提出的选择建议:

1.从数据架构的角度来看,需要一些可以轻松地将数据同步到服务之间的网络,并保持一致的可用状态。有很多种方法,这正是微服务部署中所需要的。可以观察实现这些模式的各种框架和技术。

2.一旦确定了模式和方法,就可以使用可用的资源来分析。如果已经决定采用大量反应式编程的数据流方法,并且拥有Java开发人员,那么选择Spring,Spring Cloud Data Flow和Kafka并且部署到某种形式的Cloud Foundry上(如果可以得到它!)。

如果需要大量更重的数据转换,请带上Spark或Kafka Streams 来解决这个问题。如果有JavaScript 开发人员,那么这个问题是没有道理的。相反,你会希望在JS运行时(clojurescript等)采用一些功能语言,再次使用一些类似的反应式集成技术(比如Kafka),并从那里采取。

关键要点: • 不要强调完美的技术,采取迭代的实验方法。 • 每个微服务架构都是独一无二的; 所选择的技术要与系统需求保持一致。 • 太多不同的技术使招聘更加复杂。 结论: 切换到微服务架构时,有很多挑战。在将系统转换为微服务之前,请确定要实现这一目的的真实原因。优点和缺点的分析会是一个很大的帮助。首先考虑系统的特性,而并非仅仅改变那些伤害最大的系统部分。不建议从头开始使用微服务架构,因为从一开始就明确界定微服务的边界是困难的。

如果决定切换到微服务,请采取渐进式方法,并从系统中取出非关键的一小部分,来了解它是如何工作的。这也是获得更多微服务的好办法。

对微服务来说,没有最好的方式可以选择完美的技术。每个与技术有关的决定都受到团队当前知识的影响,也受到公司未来招聘计划的影响。在某些情况下,选择微服务技术更多的是一个招聘决定,这取决于将来要建立一个什么样的开发团队。

为了缩窄可能的技术范围,来自Emarsys 的Andras Fincza,SimilarWeb的 Daniel BenZvi和David Dawson提供的经验值得借鉴。

文章来源: https://www.tuicool.com/articles/zaMnIz3

http://blog.shurenyun.com/10wei-ji-zhu-ling-xiu-gao-su-ni-tang-guo-de-wei-fu-wu-na-xie-keng-he-zui-jia-shi-jian/

那些没说出口的研发之痛,做与不做微服务的几大理由

创建一种新的软件项目架构,来封装离散服务,对于全新的项目来说,这是非常简单的。但是,对于大多数软件开发者来说,谁又有大把的奢侈时间一直用在全新项目上呢?

大多数软件开发人员职责更多是维护或增加现有软件系统的功能。但是,如果问开发人员究竟是愿意构建全新的项目,还是维护一个现有的系统,那么支持新项目的呼声肯定会成为压倒性的声音。事实上,希望与新技术或新项目合作也是开发人员离职的原因之一。为什么呢?

1

识别问题容易,但修复很难

维护现有系统时,很容易识别架构的问题。为什么?因为基于良好的架构,系统很容易调整。

当需要去调整一个没有设计封装波动的已有系统时,架构的弱点就不言自明。即使是最小的表层变化也会给整个系统的其他部分带来复杂的涟漪:新的依赖看似要无止境地延续下去,通过臃肿的方法签名获得更多的参数,自动化测试的规模和复杂性爆炸,同时降低了实际效用。

这些问题是不是听起来很熟悉?你企业的架构是这样的吗?

如果答案是肯定的,那么你有一个单体架构。单体架构是大多数软件开发者遇到的最常见架构。

这个单体架构来自那些根本没有设计封装波动的系统,但是随着业务需求和时间的推移,变得越来越复杂。

那么用单体架构做什么呢?

每个人在单体架构中工作时都会感到痛苦,开发和业务人员也是如此。开发者讨厌臃肿的单体架构,因为开发的难度会随着新开发动作的增加而增加。一旦单体架构达到临界值,如何改变会成为一个真正可怕的命题。这会导致生产力和团队士气下降,业务受到影响。企业需要快速行动,单体架构却会随着时间的推移而变得越来越慢。

许多开发人员都希望把已有的架构丢掉,重新开始,但是这种想法无法和业务一起成长。“最好的软件是目前就让企业赚钱的软件,无论设想中的新版本多么伟大!”

所以新的计划不能完全抛弃旧有的单体架构,业务要继续,但不会再增加单体架构的复杂度。

微服务?

微服务是一个流行的词汇,它模糊地表达了一个面向服务的架构,其中包含许多小的离散服务。

从表面上看,微服务似乎是单体架构的对立面(每个人都讨厌单体架构),许多微服务通过提出新的特性请求,并以独立服务的形式出现。这里的问题是:当单体架构封装所有系统的波动性,解耦的独立服务并不能使企业免于任何波动。

以下是用微服务实现单个功能架构,它大概像这个样子:

单体应用变得小了一点,新功能清晰地从系统的其余部分解耦。这很好吗?

当下一个功能请求进入时会发生什么?

有两个功能,我们已经看到一个问题。第二个功能建立在第一个功能之上,所以不能完全隔离。

如果随着功能请求的进入,简单地创建新的微服务,而不是封装整个波动区域:

有改善吗?来看看原始单体应用旁边的微服务:

如果仔细观察,会发现,所有服务依赖线模糊在一起,这只是发明了一个更复杂的单体架构。

小小的改变在整个系统中仍然会带来复杂的涟漪。整个系统的行为改变将涉及到改变多个微服务。所有相同的问题再次出现,甚至可能更糟糕,这加剧了依赖关系难以追踪的事实,而且,精心策划的多服务部署比庞大的单体应用更加可怕。

什么地方出了错?

问题源于微服务本身不是架构。微服务就是一个简单的词,描述了作为独立服务运行的系统,而不是一个单体应用。软件架构的实际实践包括仔细规划,在哪里划分离散服务之间的界限,从而包含波动区域。当简单地拿出一个单体应用,作为独立服务来实施时,就没有必要来考虑整个系统的封装波动。

把系统看作一个整体,才能谈架构

因此,如果单体应用,功能驱动的微服务太小,该怎么做应对?

要知道想去的方向

要像从头开始创建一样,为整个系统设计理想的架构。

企业不能一下子从一个单体架构直接进入微服务架构,但是如果第一次启动的时候,不清楚想达成的方向,那么永远也不会到达那里。

给所有希望拆分现有单体应用的软件开发者提供一些建议,但实际情况是这个路线图对于每个系统都是独一无二的。

Tips

如果只是设计新的功能而忽略已有的单体应用,则无法创建出色的架构;

如果不考虑整个系统,单体应用就不能有效分解;

微服务只是一个流行词。更小并不总是更好。精心拆分服务边界很重要;

2

微服务与团队:康威定律

微服务架构是独特的,随着时间的推移仍然保持灵活性,在一个项目的组织架构中时时发生影响 。对于大多公司而言,这非常具有挑战性,因为它要求企业重新考虑组织模式。当准备开始微服务架构时,可以先问自己:“企业的组织能力是什么?“在早期,先决条件应该是预先准备会遇到的困难,并思考应对之策。

微服务与康威定律:企业需要与团队协同的架构

当涉及到组织团队和微服务,著名的康威定律经常被提到。这项定律,越来越被广泛地接受。

这一定律的缺陷在于,它更多是一种社会学规律,而不是纯粹的科学规律,事实上,它总是以实证、实例的方式,而不是纯粹的科学逻辑来论证。一般来说,社会学的结果很难证明,因为这些论证很大程度上基于假想中的思考和概念,只能通过更多的实例来加以验证。

“组织的系统设计…往往受限于组织架构的产品设计和通信的副本。”从这个规律,可以得出一些简单的结论:

如果想要特定的结构,需要一个与组织团队协同的架构。

如果经常改变架构,组织团队也需要经常修改。

这两个断言,对于康威定律的原则,有着深远的影响。首先是一个企业的适应能力,避免了野心家的倾向,对变革的抵制等等,也引发了机器取代人力的哲学思考。

基于以上结论,要上微服务架构的第一个问题是:“组织团队如何适应这种架构?” Netflix 和亚马逊的情况,当然是很正向的,但是否你的企业是否准备好了?其中重要的是,挖掘技巧和发现问题时的“刹车”措施来规避风险。

其中的技巧能迅速提升团队的能力。在创建一个功能时,负责功能实现的团队汇集了很多不同的技巧。当架构进入微服务模式时,将出现更多的协调性需求。

另一个窍门是开源技术的治理模式。开源项目由于其分散的结构,使它能够创建高度松耦合的软件,这是微服务架构的优点之一。它因此成为与其他团队的协作方式,并推动具有代码能力的小团队,在代码中实现变化。

但是,这个逻辑和组织变革在公司的接受度如何?这些技巧是否足够在全公司范围内协调、积累经验和知识?分散的组织构建松耦合的代码,但技术或功能性的知识和技能不可能极端的解耦。否则,这就像拆东墙补西墙,是在用拆掉的墙来构建松耦合的架构。

真正的僵局会出现在文化和管理风格上,这点在最近几年有了好转。

一个比较好的例子是Spotify的框架(虽然我们应该限制自己使用meta frameworks,原因不再赘述)。Spotify采用通过使用开源组件来架构功能和治理,使用这些工具在一定规模下实现了灵活性矩阵模型。矩阵式组织必须确保知晓不同人具备的知识或技能。

最近流行的新管理方法已初见影响,特别是在那些寻求实现微服务的团队组织中。

Holacracy管理模式:满足业务模式前提下,完成微服务最佳实践

上面谈到了企业文化、主体、和变革的阻力。第一种类型的管理,来源于 Holacracy 管理模式。

Holacracy分为自治和独立,并链接比自己更高的实体。这些圈子以闭环的形式,可以互相重叠,具有自组织而被上层管理的特殊性。每个圈子对于性质和组成的变化非常敏感。

可以想象,例如,底层圈子是微服务的开发队伍,而上一层是架构和产品负责人,最顶端是应用的客户业务线。这将让产品和架构负责人要能在满足业务需求的前提下,才能保证架构的最佳实践。

这种架构方式也是开发者、软件架构师的典型方式。所有可能来自不同或重叠的圈子组织。建立这种类型的组织是为了提高知识传输和构建架构的时间效率。

我们可能会认为,这种管理比较符合传统的层级组织。事实上,即使层次是扁平的,它仍然存在,可以限制其项目团队。总之,最好的方式就是简化人与人之间的链接。

原文链接:

1、Microservices and monoliths: getting service-oriented architectures just right

https://www.tuicool.com/articles/VBzUFfJ

2、Executive Insights on the Current and Future State of Microservices

https://www.tuicool.com/articles/RfuAJn2

http://blog.shurenyun.com/na-xie-mei-shuo-chu-kou-de-yan-fa-zhi-tong-zuo-yu-bu-zuo-wei-fu-wu-de-ji-da-li-you/

实录分享|微服务落地践行渐进,4个Q&A一窥金融微服务现状

1月13日,中国双态运维用户大会在北京举办。来自银行、保险、证券、政府、央企等多个行业的330多位企业用户参加,其中工商银行信息科技部副总经理张艳,国泰君安信息技术部总经理俞枫、海关总署科技发展司运行安全处处长张芳、平安科技系统运营部总经理陈亚殊等分别发表了演讲。本文为数人云CEO王璞在双态运维用户大会DevOps、容器与微服务分论坛上的演讲实录。演讲结束,与在座金融客户展开了精彩的Q&A分享。

容器、微服务、DevOps三者,业内的共识是密不可分。没有微服务,DevOps落地不下去,没有容器,DevOps也无法真正实现敏捷运维、自动化运维。DevOps、容器、微服务为更好的构建PaaS提供了方法论和技术手段。

1、PaaS之承上启下

PaaS作为云计算的承上启下要素,向上支撑各环境应用,向下跟IaaS、计算环境、计算资源对接,是企业云化的必由之路。

PaaS三大技术趋势

1.应用容器化,容器正在成为云计算原生应用的标准交付方式。

2.微服务网格化,随着企业对微服务的认知越来越深入,下一代微服务着重把应用管理作为核心。因为企业应用一定要有很强的管理在微服务架构上,不能让应用去“裸奔”。数人云没有提微服务化,因为微服务化已经是不争的事实。应用微服务缺乏强大的管理,需要服务网格这样的下一代微服务技术。

3.行业生态化,PaaS技术本质上是支持应用的,应用跟业务紧密结合,所以PaaS最终是要和业务层面融合,行业需要生态化。

PaaS落地三大要素:

PaaS要在企业客户方面落地不可或缺三要素:规模化、统一化、标准化。企业客户落地云计算平台、技术,本质上是希望提高效率,对业务有更好的敏捷支撑。

所有应用,比如容器应用、微服务应用,都实现标准化。标准化以后进行统一化管理,包括部署、发布、故障恢复、监控告警等都实现统一化管理。最后实现模块化,整个系统都是轻量的,微小模块化的。只有基于这三点的PaaS平台和云计算平台,才能够让IT系统真正实现敏捷轻量,提高IT对业务支撑的效果。

2、企业IT架构转型之开发&运维

企业客户目前在架构转型应用中面临的现状是,企业里大量传统应用,客户希望先实现轻量的单体架构,即摆脱很多中间件,摆脱外部服务,MVC架构、单体复杂架构等首先实现轻量化。

数人云日常接触的客户中,走的比较靠前的客户已经在用Spring Cloud、Dubbo等架构,部分客户相当数量的应用已经微服务化,不过处于中间状态,正在考虑评估微服务架构的客户比例还是最大。总之,企业目前的现状是为服务应用、轻量单体应用,以及传统的巨石应用并存。

在架构转型过程中,正确和常态的路径一定是一步步走过来,而不是传统架构丢掉直接上微服务。

DevOps和容器@轻量单体应用架构

在单体应用架构下,DevOps、容器帮助企业实现敏捷IT。首先,持续集成持续交付CI/CD,只要应用是相对轻量的,就能加快中间件应用。CI/CD其中重要的一点是变更发布管理。

数人云某客户上了容器的应用都是轻量化的,基于 Tomcat 和微服务的应用。当基于容器实现快速发布以后,企业发现,所有发布里有一半的发布失败是由于配置不正确引起的。所以,如果没有发布变更管理,发布失败的中间环节有方方面面的因素。

当基于容器实现快速发布之后,容器对环境的异构做了一层屏蔽,这时如果出现处理的问题就是配置管理的问题了,由于涉及不同的环境和应用,配置环境变成应用发布很容易出错的环节。

DevOps和容器@微服务应用架构

数人云做了企业客户微服务落地状况的调研(微服务2017年度报告出炉:4大客户画像,15%传统企业已领跑),在报告中,有15%左右的企业引入了Spring Cloud、Dubbo。微服务在企业里首当其冲的是敏捷开发,因为微服务是一种切实的敏捷开发的方法。

敏捷开发在IT界已经推广多年,但很多时候敏捷开发推的都是方法论,比如Scrum。微服务是一套切实能够落地到IT人员、开发人员开发过程中的实践方法,这是微服务首当其冲的好处,很多企业的开发部门对微服务非常欢迎。不过,15%还是偏小的一个采用比例,微服务还不是企业客户主流的IT架构。

开发人员都比较欢迎微服务,因为能够提升开发效率,落地敏捷开发,但微服务的阻碍还是不小的,微服务对开发运维来说,带来的复杂度急剧上升。传统运维管理的服务器数量、应用数量有限。企业决定采用微服务本身就表明业务很复杂,单体应用做传统的瀑布式开发效率太低,微服务将应用拆分成较小的模块,因此微服务应用一旦上线,程序的数量呈现爆炸式增长。

例如,数人云某个传统企业的客户,目前部署了微服务相关的应用,基于Spring Cloud、Spring Boot,跑在几千个容器上,几千个容器如果通过传统运维方式去管理的话几乎是不可能的。这就是很多微服务无法落地的原因——很多企业客户缺乏相应的运维能力,没有相应的平台、工具、方式、方法管理微服务应用。

微服务落地的必要条件

微服务应用落地,首当其冲是配套工具链的完善。开发人员采用微服务的影响相对改变小一些。采用SpringCloud或者Dubbo、gRPC等,只是开发框架上的并更。其他开发流程如代码托管、代码审查、测试等并不涉及,所以开发流程相对简单。但微服务对运维功能的要求就会复杂,相应的快速配置能力、完备的监控能力、快速部署能力等对传统运维来说都是缺失的,容器能够补足这方面的能力,让运维部门具有DevOps的能力。

关于微服务的拆分,其实是业务部门需要真正解决的问题。微服务对组织上也有变更,将团队化整为零。通常每个单独的微服务程序都由7-10人的小团队来负责维护,这些都是微服务落地的必要条件。

对于数人云来说,直接能够给客户提供的帮助,首先是工具链方面,数人云产品层面具备丰富的微服务配套工具链,从监控、日志、调度、故障自动化修复等等都有完备的工具链。在落地方法上,数人云搭建了自己的生态圈,和很多合作伙伴合作,例如跟埃森哲公司在合作,帮助企业客户落地微服务,进行业务的梳理。

容器和微服务共生

容器技术补齐了微服务相关的工具链,对企业全面向云计算转型提供了很大帮助。应用架构是微服务分布式的,相应的运维也要有自动化、敏捷运维的能力。微服务跑在容器上才能发挥它最好的特性。容器是目前最流行的应用环境,基于容器的微服务部署和更新更快,更轻量,服务之间的调用、服务发现、负载均衡等更灵活。

不过,微服务不是万能的。简单的业务场景单体应用其实足够,微服务一定是应用在复杂的业务场景下,只有复杂的业务场景才有很大的维护成本、维护压力,微服务是用来降低复杂业务场景的维护成本。

基于容器云的微服务运行时管理体系

一个完整的微服务管理体系,除了开发框架之外,对运维部门来说,运维微服务应用最基本的路由、负载均衡等功能,容器可以提供,不过容器提供的只是一部分跟微服务相关的能力和工具链。周围还有一大批需要配套的工具,比如配置管理、API网关、注册发现、应用监控等等。这里的监控不是容器CPU内存的监控,而是业务逻辑的监控,更准确一点是全链路跟踪的全链路监控。容器满足了微服务运行时管理的需求,不过周边许多权限、网关、配置等尚无余力满足。

统一配置中心是微服务体系的核心

统一配置管理,是微服务落地时很核心的点。要在平台工具上落地微服务首先要具备快速配置能力,因为客户采用微服务和容器平台以后,很快会发现50%以上的发布失败是因为配置没搞对,因此配置管理是微服务里首当其冲的问题。

因为每个企业客户都有开发环境、测试环境、生产环境等很多环境,同一个应用不同版本在不同环境下的配置不同。几何级数的配置项、配置元素的增长会导致配置管理的复杂度急剧上升,需要统一的配置中心进行管理。数人云在帮助企业客户落地微服务时,首先会做的是把配置搞定,没有灵活快速的配置管理能力,微服务运行不起来。

变更发布管理(灰度发布 v.s. 蓝绿部署)

在发布管理方面,数人云帮助企业落地的发布管理主要是蓝绿部署,因为很多企业的应用本身不支持灰度发布。蓝绿部署也是切切实实的快速发布,发布用变更窗口的方式来实现。

例如,周五晚上12点起进行发布变更,12点就要停服务中心。蓝绿部署可以显著地缩短服务不可用的变更窗口。怎么做呢?客户在线上有两个版本,蓝版本和绿版本。现在负载均衡器将流量指向对外提供服务的绿版本,蓝版本作为备用的方案。同时,新程序往蓝版本上部署推送,更新时只需要把流量切换到蓝版本。发布流程最后简化为只需要进行流量的切换。流量可以快速切换,中间的窗口期只有短短几分钟,如果流量切换过来一切正常发布即完成,如果流量切换过来发现问题,可以再将流量切回去。这样开发人员、运维人员不必当场熬夜去修复,极大地减轻了发布的压力。

传统发布方式下,每次变更窗口有好几个应用排队发布,一个应用发布完成后才可以发布下一个应用,一旦中间某一个应用发布失败现场修复的压力非常大,短短的发布窗口需要几个小时内完成抢修,非常不可控,团队经常需要晚上熬夜排队。而结果往往等了半天,前面的应用没发布成功,后面的还得继续排队等。

3、金融行业之践行渐进

数人云在金融、能源、制造、快消、政企等行业的基础上,继续深耕强监管、强安全,高复杂度的金融行业。以某商业银行为例,数人云帮助落地了大规模微服务容器平台。该商业银行近年来互联网业务发展迅猛,原有系统架构无法支撑其未来规划。2016年6月开始全面实施应用微服务化,已实现蓝绿发布。

首先,营销系统全部是轻量化的应用,基于Spring Boot、Tomcat、SpringCloud等,跑在容器平台上。该银行对外营销频次非常高,通过线上微信公众号、手机APP、线上门户、合作伙伴等渠道,每月对外营销达上百场。

每次营销活动或多或少都对IT系统有变更,哪怕是配置变更,因此每次营销活动对IT系统都是一次不小的挑战。发布的时候仅仅靠容器是不够的,需要实现模板的批量发布。每次发布看起来只是一个个的容器程序,实则不然,其实是一组组一批批的容器,只有帮客户做到批量的应用发布,才能显著提升发布效率。

蓝绿部署方面,该银行密集的线上营销中,每一天会有一个重点营销活动,那么营销活动的流量如何分到特别的人群、区域?在后台应用的上千个实例中,并不是每一个实例都分配同等的流量,要通过流量分发,做线上流量控制。数人云借鉴Google做灰度发布的方式为客户提供图形化的流量控制,这和微服务实施后的限流分流是息息相关的。

另外,该银行客户的数据流量非常大,对日志收集带来非常大的的压力。数人云建议客户将应用程序的日志全部交给Kafka采集,Kafka可以做到很大数据流量的分布式消息应用。

分布式数据传输分布式消息应用很难保证每一个消息都可靠地传递。Kafka有两种模式:一种保证消息传递至少一次,但也可能多次,对很大的日志量来说偶尔丢一两条可以忽略不计。Kafka的并发量很大,可能带来偶尔很小的数据量丢失,也可能带来日志的乱序,这在分布式系统下都是可以容忍的,“鱼和熊掌不可兼得”。

关于快速建立支撑微服务体系,数人云有几点总结:

1.开发框架不能用重量级的应用体系,要么是轻量化单体架构的Tomcat等,要么采用Spring Cloud等微服务架构。

2.要有微服务平台,具备快速配置管理能力、部署能力、监控能力、应用管理能力等配套管理能力。很多企业的痛点是,开发人员快速学习微服务开发技术,基于Spring Cloud做业务系统后,业务系统无法上线,因为运维部门缺乏配套的工具、平台支撑微服务线上运行管理。

3.DevOps融合,平台管理需要把链条全打通,实现快速发布、快速上线、自动修复等。容器经过几年的普及企业已经相对了解,但容器本身是纯技术平台,基于容器、DevOps的落地还有很长的路要走。

数人云微服务On PaaS 产品体系

数人云现在的重点是微服务、轻量单体应用。以前数人云帮企业客户落地重应用的容器平台,但后来发现价值不大,反而对企业来说,除了维护重的应用外还需要维护容器,容器平台并不能实现自动化运维。经过几年的实践和摸索,数人云跟企业客户达成的共识是,传统应用不经过改造无法上到云PaaS平台。

轻量架构下的应用如何基于PaaS平台支撑?以敏捷开发为例,企业客户通常选择 Spring Cloud、gRPC 等主流的开发框架,然后在微服务工具链层面配置监控、报警、部署、快速发布等方方面面的能力,最下面承载的则是容器平台。

数人云现在还可以帮助客户落地服务网格化技术。它能够进行异构架构的兼容,gRPC就是服务网格的一部分,Google推的 Istio,Linkerd的Kubernetes 都支持 gRPC,gRPC成为通讯协议的一部分。基于通讯协议相应周边的管理,在服务网格这一层可以做灰度发布、A/B测试、流量控制、高级熔断、加密、白/黑名单机制、权限访问控制等等。

服务网格被称作下一代的微服务,因为用了服务网格以后,所有微服务管理的诉求都自动化地满足了。80%-90%的应用管理需求都在服务网格里自动涵盖。这对开发人员来讲,微服务开发的门槛急剧降低,不需要考虑未来应用上线时流量控制、灰度发布等等,只需要考虑业务。数人云微服务On PaaS 目的就是帮助企业客户降低微服务架构、上云转型的门槛。

Q&A

Q1:感觉对DevOps的理解不太到位,能不能具体地讲一下? 
A1:DevOps准确来讲,现在业内还没有统一的认识。互联网公司的DevOps目前是比较统一的,比如Goolge,但是互联网公司的DevOps,我个人理解没办法在企业直接落地。

在Google,程序员不止要负责应用的开发,还要负责相应的测试,单元测试、集成测试等等。另外,应用的部署、发布、上线也是开发人员自己做。所以互联网公司讲DevOps,更多讲的是开发运维的融合。我之前在Google时,不仅要做代码开发,也要把测试的代码全写出来。

Google有一个理念,开发人员每写一行业务代码,测试代码要写十行。然后,开发人员利用各种发布平台定期发布,比如每周做发布,在Google 运维的人员叫“SRE”。SRE部门准备好各种平台,开发人员可以用这些平台做发布、监控、日志管理等工作。

Google目前有三万名左右的IT人员,其中SRE的运维人员只有一千多,比例很低。所以在Google运维人员不可能帮每一个开发人员或者业务部门做上线。像传统IT开发人员提工单给运维,在Google是不可能的。Google这种做法,它让开发做更多的事情,运维人员很少,只是负责维护平台。所以,Google一千多人管理着几百万台服务器,平均每人管两千台。

但传统企业目前不是这样,传统企业开发和运维之间壁垒比较大。数人云帮助客户落地DevOps 时,基于的理念是,不要破坏现有开发的流程。DevOps应该是开发和运维深度融合才能做到的。讲DevOps,首先要讲理念、组织的变革,但是要想把文化变革、组织变革打破要很长时间。

从落地的角度,DevOps更多落地在运维部门,很具象的工作就是,帮助运维部门去实现DevOps的能力,比如快速部署、快速上线,应用的快速配置,自动化管理能力、故障的自动化处理等等。把以前的运维工作尽可能的自动化,提高效率,这是狭义的DevOps理念,也是我们现在接触到的。数人云不会帮客户落地像互联网公司那样的DevOps,开发做很多事情,运维可做的很少,并不是这样的。

Q&A

Q2:微服务适合复杂的场景,那么一个简单的促销是不是适合?微服务有多“微”呢?微服务和ESB 服务相比,有什么差别? 
A2:第一个促销场景,促销场景本身有些条件,促销很重要一点就是必须特别频繁,促销内容在平台要发生变化。比如,今天的促销内容和明天的不太一样,或者这周的促销和下周的不太一样,业务平台需要频繁变更,这时候微服务是适合的。

因为微服务是一种敏捷开发的落地实践方法,只要业务频繁变更,对开发的要求就必须敏捷开发,快速实现。所以,只要业务场景在不停地快速变化,促销又是互联网线上的方式,肯定是适合的。

关于复杂性,如果业务逻辑简单,逻辑变化少,并不适合微服务。比如数人云和很多银行客户合作,银行核心系统很复杂,但是银行系统并不是需求频繁变化的场景。很多银行在做“瘦核心系统”,就是银行核心系统的功能越来越单一,越来越瘦,并不是把复杂的周边的业务也放到银行核心系统里。银行核心系统虽然复杂,但业务不会频繁变化,也不一定要上到微服务场景下。复杂的业务系统,业务需求又不停变化,这种场景适合微服务。

第二个问题是和ESB 比,服务网格和 ESB 有很多相像的地方。ESB有业务逻辑串起来,很多不同的业务系统都上到ESB,互相的权限通过ESB打通。从功能角度讲,ESB和服务网格之间很相像,不同点在于ESB是传统架构下的,并没有考虑频繁迭代、流量集中爆发等问题。

但是微服务情况下,整个之间的互相请求、依赖、通讯等等都会进行统一的管理,这种情况下也很像ESB把不同业务之间的流量进行统一管理,但是服务网格更看重的是面向大规模的控制,那流量突发怎么做限流,或者突然故障怎么做熔断等等。最本质的问题是类似的,但是具体的问题表象和需求不同。 Q&A

Q3:在实际部署过程中,PaaS平台在底层资源的调用一定要用分布式云架构,传统主机是否可以?两者在最后效果上有没有什么异同? 
A3:数人云当初两种情况都有,有些场景比如业务量比较大,企业客户为了减少复杂度,容器PaaS平台直接落地到物理服务器上。还有客户为了方便管理,把PaaS落地到IaaS上,两种情况都有。

这其中的考虑是,首先业务量大如果再引入虚拟化这一层会引来额外的复杂度,此时用物理服务器更好。其次,客户有很大规模的物理服务器,直接在上面部署PaaS,在物理服务器上去调用。

第三种,资源动态的调整或资源频繁调配,这个场景很常见,需要IaaS。比如银行客户,内部业务系统分不同的域,不同域的业务复杂性随时间变化经常会发生变化,需要不停地做资源动态的调整。如果用物理机太麻烦,企业客户会选择下面有一层IaaS来做。

基于PaaS也能做一部分的资源动态调配,但是调配维度不同。数人云帮客户落地PaaS时会做资源的整合。从划分的维度,PaaS平台是按照应用程序来划分,IaaS的资源划分是按照业务系统。

Q&A

Q4:微服务重新开发,最佳的开发框架或者实践有什么可以分享的?第二,旧有的系统改造到微服务这块有没有什么经验?第三,DevOps以前也有很多像敏捷开发的方法论,它们之间有没有什么关系? 
A4:首先第一个问题,微服务的开发框架。企业客户在做选择时都希望降低风险,选最主流的框架,现在看最主流的开发框架就是Spring cloud,这也是业界的自然选择结果。其他语言也都有些微服务开发,但是用的人少一些。如果是Java应用,目前比较好的选择是Spring Cloud,也有很多客户用了Dubbo,其他架构都是偏小众的架构,主要还是看客户自己的需求。

第二个问题,传统业务要转到微服务架构上,一定要循序渐进。比如Java应用,首先Java中间件的应用,先脱掉,不要再基于这么重的Java中间件。目前相对流行的是Spring Boot这套逻辑。

有了轻量的单体化应用之后(基于Tomcat),往后走基于微服务的框架,上到Spring Boot,再上到Spring Cloud,这是比较平滑的方式。Spring Boot 在很企业客户中用的非常多,是很方便的一套单体开发架构。

企业客户目前的现状是老的应用很多,不会一次就改造完,传统的应用可以先选择一部分容易转的转到轻量单体架构上,然后再转到微服务框架上。目前企业客户是轻量的单体架构、微服务架构,以及大量传统的架构应用并存。老的架构应用目前上不到PaaS平台,只有轻量的单体化加微服务应用才能上到PaaS平台。

现在业内的共识是,微服务、容器、DevOps这三者是密不可分的。微服务更多是针对开发人员,是一种真正落地的云开发方法。很多企业客户也讲敏捷开发,派团队成员学习敏捷开发的方法论,但是敏捷开发仍然无法在企业当中落地。

这是因为,只学会了方法,但没办法落地到具体的编程,即开发环节上去,自然没办法做到敏捷开发。很多开发者回来写的程序依然是J2EE。J2EE 编程的理念和方法并不是敏捷开发的,是偏向于瀑布式的。

微服务是具体的开发环节上的敏捷开发方法,开发能力化整为零,每个团队做简单、具象、单一的逻辑。微服务首先是一个具像的敏捷开发方法,实践方法。

微服务在落地时,比如程序运行时,复杂度很高,因为不是一个程序,是一批程序一起运行,对运维的管理就比较复杂,这时候可以利用容器实现微服务应用的自动化管理。微服务一般都会上到容器,因为微服务应用不再是单体的部署方式,不再是部署到Java中间件上。基于微服务架构,几百个进程进来,用容器的方式实现快速部署动态调度,微服务部署到容器上,实现基础的轻量化运维。

轻量化运维,快速部署、自动化调度,逐步往DevOps方向走。DevOps更多强调自动化的运维能力,提高运维的效率,快速部署,出了问题自动化修复。需要用到工具和平台,这就是数人云现在帮客户去做的。

把微服务业务在运行时缺失的管理方式方法、工具平台,工具链补齐。首先是配置管理能力、完备的监控能力等等,普及之后运维人员就有能力来管微服务应用。这其实是DevOps里面最狭义的,让运维的能力变得轻量。

如果要真正实现DevOps,就像目前一些互联网公司做到的,开发和运维真正的深度融合在一起。企业目前的运维一般不具有编程能力,所以真正的DevOps还需要很长时间去落地。

HTTP直播HTTP Live Streaming (HLS)

增加EXT-X-MEDIA-SEQUENCE或EXT-X 
      -DISCONTINUITY-SEQUENCE标签的值(第6.2.2节)。

      添加或删除EXT-X-STREAM-INF标签或EXT-XI-FRAME-STREAM-INF 
      标签(第6.2.4节)。请注意,客户端不需要
      重新加载主播放列表文件,因此更改它们可能不会
      立即生效。

      将EXT-X-ENDLIST标记添加到播放列表(第6.2.1节)。

   此外,播放列表文件可以包含EXT-X-PLAYLIST-TYPE标记
   ,其值为EVENT或VOD。如果标签存在且
   值为EVENT,则服务器不得更改或删除任何部分
   播放列表文件(尽管它可以向其添加行)。如果标签
   存在且值为VOD,则播放列表文件不得更改。

   播放列表中的每个媒体片段都必须应用EXTINF标记,以
   指示媒体片段的持续时间。

   媒体播放列表中的每个片段都具有整数不连续
   序列号。
   除了媒体内的时间戳之外,还可以使用不连续序列号来
   跨不同的再现来同步媒体段。Pantos&May将于2014年10月16日到期[第23页]

 
Internet-Draft HTTP Live Streaming 2014年4月

 
   段的不连续序列号是EXT-X 
   -DISCONTINUITY-SEQUENCE标记的值(如果没有,则为零)加上
   URI行之前的播放列表中的EXT-X-DISCONTINUITY标记的数量
   细分市场。

   包含EXT-X-PLAYLIST-TYPE标记的媒体播放列表,其
   值为EVENT或VOD,不得包含EXT-X-DISCONTINUITY- 
   SEQUENCE标记。

   服务器可以
   通过对其应用EXT-X-PROGRAM-DATE-TIME标记将绝对日期和时间与媒体段相关联。这
   定义了(挂钟)日期和时间的信息映射
   由标签指定给段中的第一媒体时间戳,
   其可以用作寻找,显示或用于其他
   目的的基础。如果服务器提供此映射,它应该将
   EXT-X-PROGRAM-DATE-TIME 
   标记应用于应用了EXT-X-DISCONTINUITY标记的每个段。

   如果媒体播放列表包含
   演示文稿的最终媒体段,则播放列表文件必须包含EXT-X-ENDLIST 
   标记。

   如果媒体播放列表不包含EXT-X-ENDLIST标记,则
   服务器必须使新版本的播放列表文件可用,
   其中包含至少一个新媒体段。它必须可用
   相对于以前版本的播放列表文件
   可用的时间:不早于该时间
   之后的目标持续时间的一半,并且不晚于该时间
   之后的目标持续时间的1.5倍。

   如果服务器希望删除整个演示文稿,则必须使
   播放列表文件对客户端不可用。它应该确保
   播放列表文件中的所有媒体段
   至少在删除时播放列表文件的持续时间内仍然可供客户端使用。

6.2.2。现场播放列表

   服务器可以通过
   从播放列表文件中删除媒体段来限制媒体段的可用性(第6.2.1节)。如果
   要删除媒体段,播放列表文件必须只包含
   一个EXT-X-MEDIA-SEQUENCE标记。对于
   从播放列表文件中删除的每个媒体段,其值必须递增1 。

   媒体片段必须按照
   它们在播放列表中出现的顺序从播放列表文件中删除。

   如果
   播放列表文件的持续时间减去段的持续时间
   小于目标持续时间的三倍,则服务器不得从播放列表文件中删除媒体段。

Pantos&May将于2014年10月16日到期[第24页]
 
Internet-Draft HTTP Live Streaming 2014年4月

 
   当服务器从播放列表中删除媒体段时,
   相应的媒体URI应该对客户端保持可用
   的时间段,该时间段等于段的持续时间加上
   分发的最长播放列表文件的持续时间。包含
   该段的服务器。

   如果服务器希望从
   包含EXT-X-DISCONTINUITY标签的媒体播放列表中删除段,则播放列表必须包含
   EXT-X-DISCONTINUITY-SEQUENCE标记。

   如果服务器从媒体
   播放列表中删除EXT-X-DISCONTINUITY标记,它必须增加EXT-X-DISCONTINUITY-的值 –
   SEQUENCE标记,以便
   仍然在播放列表中的段的不连续序列号保持不变。

   如果服务器计划在
   通过HTTP 将媒体段传递给客户端后将其删除,则应该确保HTTP响应包含
   反映计划生存时间的Expires标头。

   实时播放列表不得包含EXT-X-PLAYLIST-TYPE标记。

如何使用FFmpeg连接两个MP4文件

我正在尝试用ffmpeg连接3个MP4文件。我需要这是一个自动的过程,因此我选择了ffmpeg。我正在将这3个文件转换成.ts文件,然后将它们连接起来,然后尝试对连接的.ts文件进行编码。这些文件是H 264和AAC编码的,我希望尽可能保持质量不变或接近原版。

FFmpeg有三种级联方法。

1.级联视频滤波器

ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv \ -filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] concat=n=3:v=1:a=1 [v] [a]" \ -map "[v]" -map "[a]" output.mkv

请注意,此方法执行重新编码。

2.凹式破碎机

$ cat mylist.txt
file '/path/to/file1' 
file '/path/to/file2' 
file '/path/to/file3' 
$ ffmpeg -f concat -i mylist.txt -c copy output

Windows操作系统:

(echo file ../../../../1.mp4 & echo file ../../../../2.mp4 )>%tmp%/list.txt
ffmpeg -safe 0 -f concat -i %tmp%/list.txt -c copy c:/output.mp4

3.COAT协议

ffmpeg -i "concat:input1|input2" -codec copy output

该方法不适用于许多格式,包括MP4,因为这些格式的性质以及该方法执行的简单级联。

该用哪一个

  • 级联滤波器:如果输入没有相同的参数(宽度、高度等),或者格式/编解码不相同,或者要执行任何筛选,则使用。
  • 凹式破碎机:当想避免重新编码并且你的格式不支持文件级连接时使用(一般用户使用的大多数文件不支持文件级连接)。
  • COAT协议:使用支持文件级连接的格式(MPEG-1,MPEG-2 PS,DV).不要与MP4一起使用。

如果有疑问,可以试试减刑演示程序。