万字雄文讲透现代网络负载均衡和代理技术,终于弄懂负载均衡那点事

小数 发表了文章 • 0 个评论 • 327 次浏览 • 2018-01-11 16:48 • 来自相关话题

作者:Matt Klein

译者:杨泽

原题:Introduction to modern network load balancing and proxying






关于现代网络负载均衡和代理(proxy)的介绍性资料很少,这件事引起了我的注意。为什么会这样呢?构建一个可靠的分布式系统时,负载均衡是一个非常核心的概念。但可惜的是,搜索发现关于负载均衡和服务代理的内容很少。维基百科文章只包含了一些概念,没有对该主题的详细介绍,尤其是与现代微服务架构相关的。


本文试图通过对现代网络负载均衡和代理的简单介绍,来弥补这部分信息的缺乏。为了保持文章的长度,尽量将复杂的话题浓缩成简单的概述。


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


维基百科这样定义负载均衡:

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

以上定义适用于计算的各个方面,而不仅仅是网络。操作系统使用负载均衡在物理处理器之间安排任务,诸如Kubernetes之类的容器编排者使用负载均衡来计划跨计算集群的任务,网络负载均衡通过调用可用后端来平衡网络任务。以下内容仅涵盖网络负载均衡。






图 1: 网络负载均衡描述


图1展示了网络负载均衡高层次的概览。一些客户端从后端请求资源。负载均衡器位于客户端和后端之间,在更高层次执行关键任务:

服务发现:在系统中哪些后端可用?地址是多少?(换句话说,负载均衡器如何与它们通信?)

健康检查:在系统中目前哪些后端是健康的,可以接受请求?

负载均衡:用什么样的算法把独立的个人请求发给健康的后端?


在分布式系统中正确使用负载均衡会带来如下好处:

命名抽象:客户端可以通过预定义的机制来寻址负载均衡器,而不是每个客户端都需要了解每个后端(服务发现),然后将名称解析的任务委托给负载均衡器。预定义的机制包括内置库和众所周知的DNS/IP/端口地址,后面会有详细的讨论。

容错:通过健康检查和各种算法技术,负载均衡器的路由方法可以绕过坏的或者超负载的后端。这也意味着运维人员可以随时优先修复后端错误。

低成本和高性能:分布式系统网络一致性比较差。系统可能会横跨不同的网络区域。在一个区域内,网络之间通常以相对小的带宽建立的。而在不同的区域之间,网络大带宽成为常态(带宽的大小是指通过NIC使用的带宽量占路由器之间可用带宽的百分比)。智能的负载均衡可以尽可能保持区域内的请求流量,从而提高性能(低延迟)并降低整体系统成本(减少区域间的带宽和光纤)。



负载均衡器VS代理

在谈论到网络负载均衡器,Load Balancer 和 Proxy 两个术语在行业内可以互换使用。在本文中也把两者视为一致的表达。(不过,不是所有的代理都是负载均衡器,但绝大多数代理都将负载均衡作为主要功能)。


一些人会争辩说,当负载均衡器作为嵌入式客户端库的一部分实现时,这种负载均衡器并不是真正的代理。这种区分其实添加了不必要的复杂性。本文会详细讨论负载均衡器的拓扑类型,嵌入式负载均衡器是代理的一个特例,应用通过嵌入式库进行代理,嵌入式库与应用进程外的负载均衡器整体抽象是一致的。



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

业界讨论负载均衡时,解决方式往往分为两类:L4 和 L7。指的是OSI模型的第四层和第七层。OSI模型包括传统的第四层协议(如TCP和UDP),还包含各种不同OSI层的协议。换句话说,如果 L4 TCP负载均衡器也支持 TLS 终止,这不就是 L7负载均衡器么?






图2:TCP L4 终止负载平衡

图2展示了传统的L4 TCP负载均衡器。在这种情况下,客户端与负载均衡器建立TCP连接,负载均衡器终止连接(即直接响应SYN),选择一个后端,并与后端建立新的TCP连接(即发起新的SYN)。


本节的关键是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)。


在上述场景中,后端选择处理客户端B请求是选择客户端A请求负载的大约3000倍。这是一个很大的问题,打破了负载均衡的目的。需要注意的是这个问题发生在任何复用,保持存活状态的协议。(复用意味着通过单个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本身包含多个离散的负载均衡抽象层。例如,对于HTTP流量,请考虑以下子层:


可选的传输层安全性(TLS)。网络界对于TLS 属于OSI模型哪一层有争论。为了方便,我们考虑将TLS放在 L7。

物理HTTP协议(HTTP / 1或HTTP / 2)。

逻辑HTTP协议(Header、Body 和 Trailer)。

消息传递协议(gRPC,REST等)。


一个复杂的L7负载均衡器要提供与上述每个子层有关的功能。另L7负载均衡器可能只有一小部分功能属于OSI模型中L7层。简而言之,L7负载平衡器的功能远比L4类型复杂得多。(HTTP、 Redis、Kafka、MongoDB等都是应用L7 协议的例子,它们受益于L7负载均衡)。



2负载均衡器功能


在本节中将总结负载均衡器提供的高级功能,并非所有负载均衡器都提供全部功能。


服务发现

服务发现是负载平衡器确定可用后端的过程,实现的方式有很多种,一些例子包括:


静态配置文件。

DNS。

Zookeeper,Etcd,Consul等。

Envoy的通用数据平面API。


健康检查

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

主动式:负载平衡器将定期发送ping(例如,对/healthcheck端点的HTTP请求)到后端,并用它来衡量健康状况。

被动式:负载均衡器从主数据流中检测健康状况。例如,如果连续出现三个连接错误,则L4负载均衡器会认为后端是不健康的。如果一行中有三个HTTP 503响应代码,则L7负载均衡器会认为后端是不健康的。



负载均衡

负载均衡器必须实际平衡负载!当给定一组健康的后端时,选择哪个后端处理请求?负载平衡算法是一个活跃的研究领域,从简单的算法(如随机选择和循环算法)到考虑可变延迟和后端负载的更复杂的算法。考虑到其性能和简单性,最流行的负载均衡算法是二节点最小请求负载均衡(power of 2 least request load balancing)。 


粘滞会话(Sticky sessions)

在某些应用中,同一会话的请求到达相同的后端是很重要的。这与缓存,临时复杂状态等有关。会话的定义各不相同,可能包括HTTP Cookie,客户端连接的配置或其他属性。许多L7负载平衡器支持会话粘连。会话粘性本质上是脆弱的(后端保存的会话可能会失效),所以在设计系统的时候减少对它们的依赖。



TLS终止

关于TLS,它在边缘服务和服务间通信方面值得肯定。因此,许多L7负载均衡器会执行大量的TLS处理,包括终止,证书验证和保存,使用SNI的证书服务等。



可观察性

正如谈话中所强调的:“可观察性,可观察性,可观察性”。网络本质上是不可靠的,负载均衡器通常负责导出统计信息,跟踪信息和记录日志,帮助运营人员找出问题所在,从而解决问题。最先进的负载平衡器可观察性输出包括数字统计,分布式跟踪和可定制的日志记录。增强的可观察性不是免费的; 负载平衡器必须做很多附加的工作来完成它。至于,负面影响,相对带来的好处,几乎不值一提。


安全性和DoS防范

特别是在边缘部署拓扑(见下文)中,负载均衡器通常实施各种安全功能,包括速率限制,身份验证和DoS防范(例如,IP地址标记和识别,缓送Tarpitting等)。



配置和控制面板

负载平衡器需要配置。在大规模部署中,这是一项重要工作。一般来说,配置负载均衡器的系统被称为“控制面板”,并且在其实现中变化很大。
 
3负载均衡器拓扑的类型

前面介绍了负载平衡器的概要,L4和L7负载平衡器之间的区别以及负载均衡器特性,接下来将转向部署负载均衡器的各种分布式系统拓扑。(以下每种拓扑均适用于L4和L7负载均衡器)。



中间代理






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

图4所示的中间代理拓扑是大多数读者最熟悉的负载均衡一种方式。这一类包括Cisco,Juniper,F5等硬件设备; 云软件解决方案,如亚马逊的ALB和NLB以及Google的 Cloud Load Balancer ; 以及HAProxy,NGINX和Envoy等纯软件自主托管解决方案。中间代理解决方案使用简单。通常,用户通过DNS连接到负载均衡器,不需要担心其他任何事情。中间代理解决方案的特点是代理(即使是集群)是单一的故障点,也是扩展的瓶颈。中间代理通常是一个让运维变得困难的黑匣子。当问题出现时,是在客户端还是物理网络?在中间代理还是后端?这很难说。



边缘代理






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

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



嵌入式客户端库






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

为了避免中间代理拓扑中固有的单点故障和扩展问题,更复杂的基础设施已经开始将负载均衡器直接嵌入到服务库中,如图6所示。支持的功能库有很大的不同,但是这个类别中最知名和最丰富的功能包括Finagle,Eureka / Ribbon / Hystrix和gRPC(松散地基于称为Stubby的内部Google系统)。基于库的解决方案的主要功能是将负载均衡器的所有功能完全分配给每个客户端,从而消除之前描述的单点故障和扩展问题。基于客户端库的解决方案的主要内容是客户端库必须每种语言调用。分布式架构正变得越来越“多语言”(多语言)。在这样的环境下,用许多不同的语言来重新实现一个非常复杂的网络库的成本会变得过高。最后,在大型服务体系结构中部署库升级可能会非常痛苦,这使得很多不同版本的库将在生产中同时运行,

综上所述,上面提到的这些库对于那些能够限制编程语言扩散并克服库升级难题的公司来说是成功的。



Sidecar代理






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

嵌入式客户端库负载平衡器拓扑的一个变种是图7中所示的辅助代理拓扑。近年来,这种拓扑已经被普遍推广为“服务网格”(Service Mesh)。Sidecar代理背后的思路是,以跳过一个不同的过程的代价来承担轻微的延迟,嵌入式库的所有好处都可以在没有任何编程语言锁定的情况下获得。在撰写本文时,最受欢迎的sidecar代理负载平衡器是Envoy,NGINX,HAProxy和Linkerd。



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

中间代理拓扑是最简单的负载平衡拓扑。缺点是:单点故障,伸缩瓶颈和黑箱操作。


边缘代理拓扑与中间代理类似,但通常无法避免。


嵌入式客户端库拓扑提供了最好的性能和可扩展性,但是需要在每种语言中实现该库,并跨所有服务升级库。


Sidecar代理拓扑性能比嵌入式客户端库拓扑弱,但不受任何限制。

总体而言,sidecar代理拓扑(服务网格)正在逐渐取代所有其他的服务。流量进入服务网格之前,始终需要边缘代理拓扑。



4L4负载均衡的现状


L4负载均衡器还有用吗?

本文讨论了L7负载平衡器如何用于现代协议,后面还会讨论L7负载平衡器的特性。这是否意味着L4负载平衡器没用了?没有!尽管在我看来,L7负载均衡器最终将完全取代L4负载均衡器进行服务间通信,但是L4负载均衡器对边缘通信仍然很重要。因为几乎所有现代大型分布式架构都使用两层L4 / L7负载平衡架构处理互联网流量。在L7负载均衡器之前在边缘部署中部署专用L4负载均衡器的好处是:


L7负载均衡器执行的应用程序流量的分析,转换和路由选择要复杂得多,所以它们可以处理相对于经过优化的L4负载均衡器能够处理的相对较小的原始流量负载(以每秒数据包和每秒字节数衡量)。这一现实通常使得L4负载平衡器成为处理某些类型的DoS攻击(例如,SYN flood,通用包flood攻击等)的更好位置。


L7负载均衡器往往比L4负载平衡器更积极地开发,部署更频繁,并且具有更多的缺陷。有一个L4负载均衡器,可以在L7负载平衡器部署期间执行健康检查和排空,这比现代L4负载平衡器(通常使用BGP和ECMP)(以下更多)中使用的部署机制要容易得多。最后,因为L7负载平衡器功能的复杂性更容易出现错误,所以使用绕开故障和异常的L4负载平衡器产生更稳定的整体系统。


下面将介绍几种不同的中间/边缘代理L4负载均衡器的设计。这些设计不适用于客户端库和Sidecar拓扑。



TCP / UDP终端负载均衡器





图8:L4终端负载均衡器


仍在使用的第一类L4负载均衡器是图8所示的终端负载均衡器。这类负载均衡器,使用两个离散的TCP连接:一个在客户端和负载均衡器之间,另一个在负载均衡器和后端之间。


L4终端负载均衡器仍然有两个原因:

实现相对简单。

靠近客户端的连接终端(低延迟)对性能有很大的影响。具体来说,如果终端负载均衡器可以放置在使用有损网络(例如蜂窝)的客户端附近,那么在将数据转移到可靠的光纤传输到其最终位置之前,容易发生重传。换句话说,这种负载平衡器适用于存在点(POP)场景下的原始TCP连接。




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数据包将到达负载均衡器at 1.2.3.4:80。然后负载均衡器将交换数据包的目标IP和端口10.0.0.2:9000。它还会将数据包的源IP与负载均衡器的IP地址进行交换。因此,当后端在TCP连接上响应时,数据包将返回到负载平衡器,在那里进行连接跟踪并且NAT可以在反向再次发生。


为什么会使用这种负载均衡器来代替上一节中描述的终端负载均衡器呢?几个原因:


性能和资源使用:由于直通负载均衡器不是终止TCP连接,所以不需要缓冲任何TCP连接窗口。每个连接存储的状态量非常小,通常通过高效的散列表查找来访问。因此,直通负载均衡器通常可以处理比终端负载均衡器大得多的活动连接数和数据包数(PPS)。


允许后端执行拥塞控制:TCP拥塞控制是因特网上的端点节制发送数据的机制,从而不会压倒可用带宽和缓冲区。由于直通负载均衡器不会终止TCP连接,因此不参与拥塞控制。这个事实允许后端根据他们的应用使用情况使用不同的拥塞控制算法。它还可以更容易地进行拥塞控制变更的实验(例如,最近的BBR部署)。


形成直接服务器返回(DSR)和群集L4负载平衡的基准:更高级的L4负载平衡技术(如DSR和使用分布式一致性散列的群集(以下各节中讨论))需要直通负载平衡。


直接服务器返回(Direct Server Return,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负载平衡器的设计。直通和DSR负载平衡器都需要负载均衡器本身的一些连接跟踪和状态。如果负载平衡器死了怎么办?如果负载平衡器的单个实例死亡,则所有通过负载平衡器的连接将被切断。取决于应用程序,这可能会对应用程序性能产生重大影响。


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


一对HA边缘路由器为虚拟IP(VIP)提供服务。这些边缘路由器使用边界网关协议(BGP)宣布虚拟IP 。主边缘路由器具有比备份更高的BGP权重,因此在稳定状态下,它服务所有流量。(BGP是一个非常复杂的协议; 就本文而言,考虑BGP是网络设备宣布可以从其他网络设备获取流量的机制,并且每个链路都可以具有优先考虑链路流量的权重)。


同样,主L4负载均衡器向边缘路由器宣布自己的BGP权重高于备份,因此在稳定状态下,它将服务所有流量。

主负载均衡器交叉连接到备份,并共享其所有连接跟踪状态。因此,如果主负载宕机,备份可以接管处理所有活动的连接。


两台边缘路由器和两台负载均衡器都是交叉连接的。这意味着如果其中一个边缘路由器或负载平衡器中的一个死亡,或者由于某种其他原因撤消BGP通知,备份可以接管所有通信。


上面的设置是目前具有高流量的互联网应用还在使用的方式。但是,上述方法有很大的缺点:

考虑到容量使用情况,虚拟 IP (VIP)必须在HA负载平衡器对之间正确分片。如果单个VIP超出单个HA对的容量,则需要将VIP分成多个VIP。


系统的资源使用情况很差。50%的容量在稳定状态下闲置。鉴于历史上硬件负载平衡器非常昂贵,这导致大量闲置资本。

现代分布式系统设计比主动/备份提供更高的容错能力。例如,最佳地,系统应该能够同时遭受多个故障并继续运行。如果主动和备用负载均衡器同时死亡,则HA负载均衡器对可能会发生完全故障。


来自供应商的专有大型硬件设备非常昂贵,并导致供应商锁定。通常希望用可商购计算服务器构建的可横向扩展的软件解决方案替代这些硬件设备。



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






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

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


减轻上一节中描述的HA对设计的所有缺点。

从供应商的专有硬件负载平衡器转移到使用标准计算服务器和NIC构建的商品软件解决方案。

这个L4负载均衡器设计最好称为容错和扩展,通过集群和分布式一致的散列。它的工作原理如下:

N个边缘路由器以相同的BGP权重宣布所有Anycast VIP。等价多路径路由(ECMP)用于确保通常来自单个流的所有数据包到达相同的边缘路由器。流程通常是源IP /端口和目标IP /端口的四元组。(简而言之,ECMP是一种使用一致散列在一组相同加权的网络链路上分发数据包的方法)。尽管边缘路由器本身并不特别关心哪个分组到达哪里,但是通常优选的是,来自一个流的所有分组都经过相同的一组链路,以避免乱序分组,从而降低性能。

N个L4负载均衡器机器以与边缘路由器相同的BGP权重宣布所有的VIP。再次使用ECMP,边缘路由器将通常为流选择相同的负载平衡器机器。

每个L4负载均衡器机器通常会执行部分连接跟踪,然后使用一致的哈希来为流选择一个后端。GRE用于封装从负载均衡器发送到后端的数据包。

DSR然后被用来通过边缘路由器直接从后端发送数据包到客户端。

L4负载均衡器使用的实际一致性散列算法是一个活跃的研究领域。主要围绕均衡负载进行权衡,最小化延迟,最大限度地减少后端更改期间的中断, 并最大限度地减少内存开销。关于这个主题的完整讨论超出了本文的范围。


让我们看看上面的设计是如何缓解HA对方法的所有缺点的:

新的边缘路由器和负载平衡器机器可以根据需要添加。在添加新机器时,每层都使用一致的散列来尽可能减少受影响的流量。
 
系统的资源使用可以按照需要高速运行,同时保持足够的突发容限和容错。

边缘路由器和负载平衡器现在都可以使用商用硬件来构建,而传统硬件负载平衡器的成本只是其中的一小部分(下面会详细介绍)。


通常被问及这个设计的一个问题是“为什么边缘路由器不通过ECMP直接与后端对话?为什么我们需要负载平衡器?“其原因主要是减少DoS和后端操作的简化。如果没有负载平衡器,每个后端都必须参与BGP,并且执行滚动部署的时间将更加困难。


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


5L7负载平衡的现有技术状态

在过去的几年中,L7负载平衡器/代理的发展已经复苏。随着分布式系统中的微服务架构的不断推进,这方面也在不断进步。从根本上说,固有故障的网络在使用更频繁时变得更加难以有效地运行。而且,自动扩展,容器调度等等的出现意味着在静态文件中配置静态IP的日子早已不复存在。系统不仅要利用网络,还要变得更加动态,需要负载平衡器的新功能。本节将简要概述在现代L7负载平衡器的最新发展。


协议支持

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



动态配置

如上所述,分布式系统越来越具有动态性,需要并行投资来创建动态和反应式控制系统。Istio就是这样一个例子。


高级负载平衡

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



可观察性

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



可扩展性

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



容错

L7负载均衡器的容错性如何?一般来说,我们把L7负载平衡器视为可消耗和无状态的。使用商业软件就能够对L7负载平衡器轻松水平扩展。此外,L7负载平衡器执行的处理和状态跟踪比L4复杂得多。试图建立一个L7负载平衡器的HA配对在技术上是可能的,但非常繁杂。


总的来说,在L4和L7负载平衡领域,业界正在从HA配对转向通过一致的哈希聚合横向水平可扩展系统。


更多

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


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







图13:全局负载平衡

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

每个Sidecar代理正在与三个不同区域(A,B和C)的后端进行通信。

如图所示,90%的流量正被发送到区域C,而5%的流量正被发送到区域A和B。

Sidecar代理和后端均向全局负载均衡器报告周期性状态。这允许全局负载均衡器做出考虑延迟,成本,负载,当前故障等的决定。

全局负载均衡器使用当前路由信息周期性地配置每个边车代理。

全球负载均衡器越来越能够做复杂的事情。例如:

自动检测并绕过区域故障。

应用全局安全和路由策略。

使用机器学习和神经网络检测和减轻流量异常,包括DDoS攻击。

提供集中的用户界面和可视化,使工程师能够理解和操作整个分布式系统。

为了实现全局负载均衡,用作数据平面的负载平衡器必须具有复杂的动态配置能力。



7从硬件到软件的演变


本文只是简单地提到了硬件和软件,主要是在L4负载平衡器HA对的历史背景下。这方面的业界趋势又是怎样呢?

历史上的路由器和负载平衡器都是昂贵的专有硬件。

越来越多的专有L3 / L4网络设备正在被商用服务器硬件,商用网卡和基于IPVS,DPDK和fd.io等框架的专业软件解决方案取代。价格低于5K美元的现代数据中心机器可以使用Linux和自定义的基于DPDK的 user-space 应用,轻松饱和具有非常小数据包的80Gbps NIC。与此同时,廉价的路由器/交换机ASIC可以以惊人的总带宽和数据包速率进行ECMP路由选择,正在被打包成商品路由器。

像NGINX,HAProxy和Envoy这样先进的L7软件负载平衡器也在迅速地迭代和侵入之前像F5这样的供应商领域。因此,L7负载平衡器也在积极地向商品软件解决方案迈进。

与此同时,整个行业向主流云提供商推动的IaaS,CaaS和FaaS意味着越来越多的工程师需要了解物理网络是如何工作的


8结论和负载均衡的未来


这篇文章的主要内容是:

负载平衡器是现代分布式系统中的关键组件。

有两种负载均衡器:L4和L7。

L4和L7负载平衡器都与现代架构中相关。

L4负载均衡器正朝着横向可扩展的分布式一致哈希水平扩展解决方案迈进。

由于动态微服务体系结构的激增,L7负载平衡器最近发展迅速。

全局负载平衡和控制平面与数据平面之间的分离,是负载平衡的未来,存在大量商业机会。

业界正在积极向商用OSS硬件和软件提供网络解决方案。相信像F5这样的传统负载均衡厂商将首先被OSS软件和云供应商所取代。传统的路由器/交换机厂商,如Arista / Cumulus /等。短期会有好的发展,但最终也将被公有云供应商和自研物理网络所取代。

总的来说,现在是计算机网络的一个激动人心的时代!大多数系统开始向OSS和软件方向转变,迭代速度加快。分布式系统向“无服务器”计算发展,必须继续充满活力,底层网络和负载平衡系统的复杂性也将齐头并进。

原文:https://blog.envoyproxy.io/int ... 80236 查看全部
作者:Matt Klein

译者:杨泽

原题:Introduction to modern network load balancing and proxying

3_(4).png


关于现代网络负载均衡和代理(proxy)的介绍性资料很少,这件事引起了我的注意。为什么会这样呢?构建一个可靠的分布式系统时,负载均衡是一个非常核心的概念。但可惜的是,搜索发现关于负载均衡和服务代理的内容很少。维基百科文章只包含了一些概念,没有对该主题的详细介绍,尤其是与现代微服务架构相关的。


本文试图通过对现代网络负载均衡和代理的简单介绍,来弥补这部分信息的缺乏。为了保持文章的长度,尽量将复杂的话题浓缩成简单的概述。


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


维基百科这样定义负载均衡:

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

以上定义适用于计算的各个方面,而不仅仅是网络。操作系统使用负载均衡在物理处理器之间安排任务,诸如Kubernetes之类的容器编排者使用负载均衡来计划跨计算集群的任务,网络负载均衡通过调用可用后端来平衡网络任务。以下内容仅涵盖网络负载均衡。


1.png

图 1: 网络负载均衡描述


图1展示了网络负载均衡高层次的概览。一些客户端从后端请求资源。负载均衡器位于客户端和后端之间,在更高层次执行关键任务:

服务发现:在系统中哪些后端可用?地址是多少?(换句话说,负载均衡器如何与它们通信?)

健康检查:在系统中目前哪些后端是健康的,可以接受请求?

负载均衡:用什么样的算法把独立的个人请求发给健康的后端?


在分布式系统中正确使用负载均衡会带来如下好处:

命名抽象:客户端可以通过预定义的机制来寻址负载均衡器,而不是每个客户端都需要了解每个后端(服务发现),然后将名称解析的任务委托给负载均衡器。预定义的机制包括内置库和众所周知的DNS/IP/端口地址,后面会有详细的讨论。

容错:通过健康检查和各种算法技术,负载均衡器的路由方法可以绕过坏的或者超负载的后端。这也意味着运维人员可以随时优先修复后端错误。

低成本和高性能:分布式系统网络一致性比较差。系统可能会横跨不同的网络区域。在一个区域内,网络之间通常以相对小的带宽建立的。而在不同的区域之间,网络大带宽成为常态(带宽的大小是指通过NIC使用的带宽量占路由器之间可用带宽的百分比)。智能的负载均衡可以尽可能保持区域内的请求流量,从而提高性能(低延迟)并降低整体系统成本(减少区域间的带宽和光纤)。



负载均衡器VS代理

在谈论到网络负载均衡器,Load Balancer 和 Proxy 两个术语在行业内可以互换使用。在本文中也把两者视为一致的表达。(不过,不是所有的代理都是负载均衡器,但绝大多数代理都将负载均衡作为主要功能)。


一些人会争辩说,当负载均衡器作为嵌入式客户端库的一部分实现时,这种负载均衡器并不是真正的代理。这种区分其实添加了不必要的复杂性。本文会详细讨论负载均衡器的拓扑类型,嵌入式负载均衡器是代理的一个特例,应用通过嵌入式库进行代理,嵌入式库与应用进程外的负载均衡器整体抽象是一致的。



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

业界讨论负载均衡时,解决方式往往分为两类:L4 和 L7。指的是OSI模型的第四层和第七层。OSI模型包括传统的第四层协议(如TCP和UDP),还包含各种不同OSI层的协议。换句话说,如果 L4 TCP负载均衡器也支持 TLS 终止,这不就是 L7负载均衡器么?


2.png

图2:TCP L4 终止负载平衡

图2展示了传统的L4 TCP负载均衡器。在这种情况下,客户端与负载均衡器建立TCP连接,负载均衡器终止连接(即直接响应SYN),选择一个后端,并与后端建立新的TCP连接(即发起新的SYN)。


本节的关键是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)。


在上述场景中,后端选择处理客户端B请求是选择客户端A请求负载的大约3000倍。这是一个很大的问题,打破了负载均衡的目的。需要注意的是这个问题发生在任何复用,保持存活状态的协议。(复用意味着通过单个L4连接多次发送应用程序请求,保持存活就是没有活动请求时不关闭连接)。出于效率的考虑,所有现代协议都在不断发展,既要复用也要存活(创建连接通常是昂贵的,特别是用TLS进行加密连接时),所以L4负载均衡器随着时间的推移,负载失衡的情况更加明显。这个问题在L7负载均衡器中得到解决。


3.png


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

图3展示了L7 HTTP/2负载平衡器。客户端与负载均衡器只建立一个 HTTP/2 TCP连接,连接两个后端。当客户端向负载均衡器发送两个HTTP/2 流时,流1被发送到后端1,流2被发送到后端2。因此,即使差别很大的请求负载的多路复用客户端也将被有效地平衡到不同的后端。这就是L7负载平衡对于现代协议的重要性所在。(L7负载平衡由于能够检查应用流量,而产生大量好处,后面会更详述)。



L7负载均衡和OSI模型

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


可选的传输层安全性(TLS)。网络界对于TLS 属于OSI模型哪一层有争论。为了方便,我们考虑将TLS放在 L7。

物理HTTP协议(HTTP / 1或HTTP / 2)。

逻辑HTTP协议(Header、Body 和 Trailer)。

消息传递协议(gRPC,REST等)。


一个复杂的L7负载均衡器要提供与上述每个子层有关的功能。另L7负载均衡器可能只有一小部分功能属于OSI模型中L7层。简而言之,L7负载平衡器的功能远比L4类型复杂得多。(HTTP、 Redis、Kafka、MongoDB等都是应用L7 协议的例子,它们受益于L7负载均衡)。



2负载均衡器功能


在本节中将总结负载均衡器提供的高级功能,并非所有负载均衡器都提供全部功能。


服务发现

服务发现是负载平衡器确定可用后端的过程,实现的方式有很多种,一些例子包括:


静态配置文件。

DNS。

Zookeeper,Etcd,Consul等。

Envoy的通用数据平面API。


健康检查

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

主动式:负载平衡器将定期发送ping(例如,对/healthcheck端点的HTTP请求)到后端,并用它来衡量健康状况。

被动式:负载均衡器从主数据流中检测健康状况。例如,如果连续出现三个连接错误,则L4负载均衡器会认为后端是不健康的。如果一行中有三个HTTP 503响应代码,则L7负载均衡器会认为后端是不健康的。



负载均衡

负载均衡器必须实际平衡负载!当给定一组健康的后端时,选择哪个后端处理请求?负载平衡算法是一个活跃的研究领域,从简单的算法(如随机选择和循环算法)到考虑可变延迟和后端负载的更复杂的算法。考虑到其性能和简单性,最流行的负载均衡算法是二节点最小请求负载均衡(power of 2 least request load balancing)。 


粘滞会话(Sticky sessions)

在某些应用中,同一会话的请求到达相同的后端是很重要的。这与缓存,临时复杂状态等有关。会话的定义各不相同,可能包括HTTP Cookie,客户端连接的配置或其他属性。许多L7负载平衡器支持会话粘连。会话粘性本质上是脆弱的(后端保存的会话可能会失效),所以在设计系统的时候减少对它们的依赖。



TLS终止

关于TLS,它在边缘服务和服务间通信方面值得肯定。因此,许多L7负载均衡器会执行大量的TLS处理,包括终止,证书验证和保存,使用SNI的证书服务等。



可观察性

正如谈话中所强调的:“可观察性,可观察性,可观察性”。网络本质上是不可靠的,负载均衡器通常负责导出统计信息,跟踪信息和记录日志,帮助运营人员找出问题所在,从而解决问题。最先进的负载平衡器可观察性输出包括数字统计,分布式跟踪和可定制的日志记录。增强的可观察性不是免费的; 负载平衡器必须做很多附加的工作来完成它。至于,负面影响,相对带来的好处,几乎不值一提。


安全性和DoS防范

特别是在边缘部署拓扑(见下文)中,负载均衡器通常实施各种安全功能,包括速率限制,身份验证和DoS防范(例如,IP地址标记和识别,缓送Tarpitting等)。



配置和控制面板

负载平衡器需要配置。在大规模部署中,这是一项重要工作。一般来说,配置负载均衡器的系统被称为“控制面板”,并且在其实现中变化很大。
 
3负载均衡器拓扑的类型

前面介绍了负载平衡器的概要,L4和L7负载平衡器之间的区别以及负载均衡器特性,接下来将转向部署负载均衡器的各种分布式系统拓扑。(以下每种拓扑均适用于L4和L7负载均衡器)。



中间代理


4.png

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

图4所示的中间代理拓扑是大多数读者最熟悉的负载均衡一种方式。这一类包括Cisco,Juniper,F5等硬件设备; 云软件解决方案,如亚马逊的ALB和NLB以及Google的 Cloud Load Balancer ; 以及HAProxy,NGINX和Envoy等纯软件自主托管解决方案。中间代理解决方案使用简单。通常,用户通过DNS连接到负载均衡器,不需要担心其他任何事情。中间代理解决方案的特点是代理(即使是集群)是单一的故障点,也是扩展的瓶颈。中间代理通常是一个让运维变得困难的黑匣子。当问题出现时,是在客户端还是物理网络?在中间代理还是后端?这很难说。



边缘代理

5.png


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

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



嵌入式客户端库

6.png


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

为了避免中间代理拓扑中固有的单点故障和扩展问题,更复杂的基础设施已经开始将负载均衡器直接嵌入到服务库中,如图6所示。支持的功能库有很大的不同,但是这个类别中最知名和最丰富的功能包括Finagle,Eureka / Ribbon / Hystrix和gRPC(松散地基于称为Stubby的内部Google系统)。基于库的解决方案的主要功能是将负载均衡器的所有功能完全分配给每个客户端,从而消除之前描述的单点故障和扩展问题。基于客户端库的解决方案的主要内容是客户端库必须每种语言调用。分布式架构正变得越来越“多语言”(多语言)。在这样的环境下,用许多不同的语言来重新实现一个非常复杂的网络库的成本会变得过高。最后,在大型服务体系结构中部署库升级可能会非常痛苦,这使得很多不同版本的库将在生产中同时运行,

综上所述,上面提到的这些库对于那些能够限制编程语言扩散并克服库升级难题的公司来说是成功的。



Sidecar代理

7.png


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

嵌入式客户端库负载平衡器拓扑的一个变种是图7中所示的辅助代理拓扑。近年来,这种拓扑已经被普遍推广为“服务网格”(Service Mesh)。Sidecar代理背后的思路是,以跳过一个不同的过程的代价来承担轻微的延迟,嵌入式库的所有好处都可以在没有任何编程语言锁定的情况下获得。在撰写本文时,最受欢迎的sidecar代理负载平衡器是Envoy,NGINX,HAProxy和Linkerd。



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

中间代理拓扑是最简单的负载平衡拓扑。缺点是:单点故障,伸缩瓶颈和黑箱操作。


边缘代理拓扑与中间代理类似,但通常无法避免。


嵌入式客户端库拓扑提供了最好的性能和可扩展性,但是需要在每种语言中实现该库,并跨所有服务升级库。


Sidecar代理拓扑性能比嵌入式客户端库拓扑弱,但不受任何限制。

总体而言,sidecar代理拓扑(服务网格)正在逐渐取代所有其他的服务。流量进入服务网格之前,始终需要边缘代理拓扑。



4L4负载均衡的现状


L4负载均衡器还有用吗?

本文讨论了L7负载平衡器如何用于现代协议,后面还会讨论L7负载平衡器的特性。这是否意味着L4负载平衡器没用了?没有!尽管在我看来,L7负载均衡器最终将完全取代L4负载均衡器进行服务间通信,但是L4负载均衡器对边缘通信仍然很重要。因为几乎所有现代大型分布式架构都使用两层L4 / L7负载平衡架构处理互联网流量。在L7负载均衡器之前在边缘部署中部署专用L4负载均衡器的好处是:


L7负载均衡器执行的应用程序流量的分析,转换和路由选择要复杂得多,所以它们可以处理相对于经过优化的L4负载均衡器能够处理的相对较小的原始流量负载(以每秒数据包和每秒字节数衡量)。这一现实通常使得L4负载平衡器成为处理某些类型的DoS攻击(例如,SYN flood,通用包flood攻击等)的更好位置。


L7负载均衡器往往比L4负载平衡器更积极地开发,部署更频繁,并且具有更多的缺陷。有一个L4负载均衡器,可以在L7负载平衡器部署期间执行健康检查和排空,这比现代L4负载平衡器(通常使用BGP和ECMP)(以下更多)中使用的部署机制要容易得多。最后,因为L7负载平衡器功能的复杂性更容易出现错误,所以使用绕开故障和异常的L4负载平衡器产生更稳定的整体系统。


下面将介绍几种不同的中间/边缘代理L4负载均衡器的设计。这些设计不适用于客户端库和Sidecar拓扑。



TCP / UDP终端负载均衡器

8.png

图8:L4终端负载均衡器


仍在使用的第一类L4负载均衡器是图8所示的终端负载均衡器。这类负载均衡器,使用两个离散的TCP连接:一个在客户端和负载均衡器之间,另一个在负载均衡器和后端之间。


L4终端负载均衡器仍然有两个原因:

实现相对简单。

靠近客户端的连接终端(低延迟)对性能有很大的影响。具体来说,如果终端负载均衡器可以放置在使用有损网络(例如蜂窝)的客户端附近,那么在将数据转移到可靠的光纤传输到其最终位置之前,容易发生重传。换句话说,这种负载平衡器适用于存在点(POP)场景下的原始TCP连接。




TCP / UDP直通负载均衡器


9.png


图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数据包将到达负载均衡器at 1.2.3.4:80。然后负载均衡器将交换数据包的目标IP和端口10.0.0.2:9000。它还会将数据包的源IP与负载均衡器的IP地址进行交换。因此,当后端在TCP连接上响应时,数据包将返回到负载平衡器,在那里进行连接跟踪并且NAT可以在反向再次发生。


为什么会使用这种负载均衡器来代替上一节中描述的终端负载均衡器呢?几个原因:


性能和资源使用:由于直通负载均衡器不是终止TCP连接,所以不需要缓冲任何TCP连接窗口。每个连接存储的状态量非常小,通常通过高效的散列表查找来访问。因此,直通负载均衡器通常可以处理比终端负载均衡器大得多的活动连接数和数据包数(PPS)。


允许后端执行拥塞控制:TCP拥塞控制是因特网上的端点节制发送数据的机制,从而不会压倒可用带宽和缓冲区。由于直通负载均衡器不会终止TCP连接,因此不参与拥塞控制。这个事实允许后端根据他们的应用使用情况使用不同的拥塞控制算法。它还可以更容易地进行拥塞控制变更的实验(例如,最近的BBR部署)。


形成直接服务器返回(DSR)和群集L4负载平衡的基准:更高级的L4负载平衡技术(如DSR和使用分布式一致性散列的群集(以下各节中讨论))需要直通负载平衡。


直接服务器返回(Direct Server Return,DSR)



10.png


图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.png


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

到目前为止,我们一直在考虑L4负载平衡器的设计。直通和DSR负载平衡器都需要负载均衡器本身的一些连接跟踪和状态。如果负载平衡器死了怎么办?如果负载平衡器的单个实例死亡,则所有通过负载平衡器的连接将被切断。取决于应用程序,这可能会对应用程序性能产生重大影响。


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


一对HA边缘路由器为虚拟IP(VIP)提供服务。这些边缘路由器使用边界网关协议(BGP)宣布虚拟IP 。主边缘路由器具有比备份更高的BGP权重,因此在稳定状态下,它服务所有流量。(BGP是一个非常复杂的协议; 就本文而言,考虑BGP是网络设备宣布可以从其他网络设备获取流量的机制,并且每个链路都可以具有优先考虑链路流量的权重)。


同样,主L4负载均衡器向边缘路由器宣布自己的BGP权重高于备份,因此在稳定状态下,它将服务所有流量。

主负载均衡器交叉连接到备份,并共享其所有连接跟踪状态。因此,如果主负载宕机,备份可以接管处理所有活动的连接。


两台边缘路由器和两台负载均衡器都是交叉连接的。这意味着如果其中一个边缘路由器或负载平衡器中的一个死亡,或者由于某种其他原因撤消BGP通知,备份可以接管所有通信。


上面的设置是目前具有高流量的互联网应用还在使用的方式。但是,上述方法有很大的缺点:

考虑到容量使用情况,虚拟 IP (VIP)必须在HA负载平衡器对之间正确分片。如果单个VIP超出单个HA对的容量,则需要将VIP分成多个VIP。


系统的资源使用情况很差。50%的容量在稳定状态下闲置。鉴于历史上硬件负载平衡器非常昂贵,这导致大量闲置资本。

现代分布式系统设计比主动/备份提供更高的容错能力。例如,最佳地,系统应该能够同时遭受多个故障并继续运行。如果主动和备用负载均衡器同时死亡,则HA负载均衡器对可能会发生完全故障。


来自供应商的专有大型硬件设备非常昂贵,并导致供应商锁定。通常希望用可商购计算服务器构建的可横向扩展的软件解决方案替代这些硬件设备。



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


12.png

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

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


减轻上一节中描述的HA对设计的所有缺点。

从供应商的专有硬件负载平衡器转移到使用标准计算服务器和NIC构建的商品软件解决方案。

这个L4负载均衡器设计最好称为容错和扩展,通过集群和分布式一致的散列。它的工作原理如下:

N个边缘路由器以相同的BGP权重宣布所有Anycast VIP。等价多路径路由(ECMP)用于确保通常来自单个流的所有数据包到达相同的边缘路由器。流程通常是源IP /端口和目标IP /端口的四元组。(简而言之,ECMP是一种使用一致散列在一组相同加权的网络链路上分发数据包的方法)。尽管边缘路由器本身并不特别关心哪个分组到达哪里,但是通常优选的是,来自一个流的所有分组都经过相同的一组链路,以避免乱序分组,从而降低性能。

N个L4负载均衡器机器以与边缘路由器相同的BGP权重宣布所有的VIP。再次使用ECMP,边缘路由器将通常为流选择相同的负载平衡器机器。

每个L4负载均衡器机器通常会执行部分连接跟踪,然后使用一致的哈希来为流选择一个后端。GRE用于封装从负载均衡器发送到后端的数据包。

DSR然后被用来通过边缘路由器直接从后端发送数据包到客户端。

L4负载均衡器使用的实际一致性散列算法是一个活跃的研究领域。主要围绕均衡负载进行权衡,最小化延迟,最大限度地减少后端更改期间的中断, 并最大限度地减少内存开销。关于这个主题的完整讨论超出了本文的范围。


让我们看看上面的设计是如何缓解HA对方法的所有缺点的:

新的边缘路由器和负载平衡器机器可以根据需要添加。在添加新机器时,每层都使用一致的散列来尽可能减少受影响的流量。
 
系统的资源使用可以按照需要高速运行,同时保持足够的突发容限和容错。

边缘路由器和负载平衡器现在都可以使用商用硬件来构建,而传统硬件负载平衡器的成本只是其中的一小部分(下面会详细介绍)。


通常被问及这个设计的一个问题是“为什么边缘路由器不通过ECMP直接与后端对话?为什么我们需要负载平衡器?“其原因主要是减少DoS和后端操作的简化。如果没有负载平衡器,每个后端都必须参与BGP,并且执行滚动部署的时间将更加困难。


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


5L7负载平衡的现有技术状态

在过去的几年中,L7负载平衡器/代理的发展已经复苏。随着分布式系统中的微服务架构的不断推进,这方面也在不断进步。从根本上说,固有故障的网络在使用更频繁时变得更加难以有效地运行。而且,自动扩展,容器调度等等的出现意味着在静态文件中配置静态IP的日子早已不复存在。系统不仅要利用网络,还要变得更加动态,需要负载平衡器的新功能。本节将简要概述在现代L7负载平衡器的最新发展。


协议支持

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



动态配置

如上所述,分布式系统越来越具有动态性,需要并行投资来创建动态和反应式控制系统。Istio就是这样一个例子。


高级负载平衡

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



可观察性

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



可扩展性

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



容错

L7负载均衡器的容错性如何?一般来说,我们把L7负载平衡器视为可消耗和无状态的。使用商业软件就能够对L7负载平衡器轻松水平扩展。此外,L7负载平衡器执行的处理和状态跟踪比L4复杂得多。试图建立一个L7负载平衡器的HA配对在技术上是可能的,但非常繁杂。


总的来说,在L4和L7负载平衡领域,业界正在从HA配对转向通过一致的哈希聚合横向水平可扩展系统。


更多

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


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


13.png


图13:全局负载平衡

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

每个Sidecar代理正在与三个不同区域(A,B和C)的后端进行通信。

如图所示,90%的流量正被发送到区域C,而5%的流量正被发送到区域A和B。

Sidecar代理和后端均向全局负载均衡器报告周期性状态。这允许全局负载均衡器做出考虑延迟,成本,负载,当前故障等的决定。

全局负载均衡器使用当前路由信息周期性地配置每个边车代理。

全球负载均衡器越来越能够做复杂的事情。例如:

自动检测并绕过区域故障。

应用全局安全和路由策略。

使用机器学习和神经网络检测和减轻流量异常,包括DDoS攻击。

提供集中的用户界面和可视化,使工程师能够理解和操作整个分布式系统。

为了实现全局负载均衡,用作数据平面的负载平衡器必须具有复杂的动态配置能力。



7从硬件到软件的演变


本文只是简单地提到了硬件和软件,主要是在L4负载平衡器HA对的历史背景下。这方面的业界趋势又是怎样呢?

历史上的路由器和负载平衡器都是昂贵的专有硬件。

越来越多的专有L3 / L4网络设备正在被商用服务器硬件,商用网卡和基于IPVS,DPDK和fd.io等框架的专业软件解决方案取代。价格低于5K美元的现代数据中心机器可以使用Linux和自定义的基于DPDK的 user-space 应用,轻松饱和具有非常小数据包的80Gbps NIC。与此同时,廉价的路由器/交换机ASIC可以以惊人的总带宽和数据包速率进行ECMP路由选择,正在被打包成商品路由器。

像NGINX,HAProxy和Envoy这样先进的L7软件负载平衡器也在迅速地迭代和侵入之前像F5这样的供应商领域。因此,L7负载平衡器也在积极地向商品软件解决方案迈进。

与此同时,整个行业向主流云提供商推动的IaaS,CaaS和FaaS意味着越来越多的工程师需要了解物理网络是如何工作的


8结论和负载均衡的未来


这篇文章的主要内容是:

负载平衡器是现代分布式系统中的关键组件。

有两种负载均衡器:L4和L7。

L4和L7负载平衡器都与现代架构中相关。

L4负载均衡器正朝着横向可扩展的分布式一致哈希水平扩展解决方案迈进。

由于动态微服务体系结构的激增,L7负载平衡器最近发展迅速。

全局负载平衡和控制平面与数据平面之间的分离,是负载平衡的未来,存在大量商业机会。

业界正在积极向商用OSS硬件和软件提供网络解决方案。相信像F5这样的传统负载均衡厂商将首先被OSS软件和云供应商所取代。传统的路由器/交换机厂商,如Arista / Cumulus /等。短期会有好的发展,但最终也将被公有云供应商和自研物理网络所取代。

总的来说,现在是计算机网络的一个激动人心的时代!大多数系统开始向OSS和软件方向转变,迭代速度加快。分布式系统向“无服务器”计算发展,必须继续充满活力,底层网络和负载平衡系统的复杂性也将齐头并进。

原文:https://blog.envoyproxy.io/int ... 80236

年度盘点2017之Service Mesh:群雄逐鹿烽烟起

小数 发表了文章 • 0 个评论 • 1038 次浏览 • 2017-12-29 14:21 • 来自相关话题

 
 敖小剑/数人云资深架构师

十五年软件开发经验,微服务专家,专注于基础架构,Cloud Native拥护者,敏捷实践者。曾在亚信,爱立信,唯品会和PPmoney任职。


前言
在过去的2016年和2017年,微服务技术得以迅猛普及,和容器技术一起成为这两年中最吸引眼球的技术热点。而以Spring Cloud为代表的传统侵入式开发框架,占据着微服务市场的主流地位,它甚至一度成为微服务的代名词。

直到2017年年底,当非侵入式的Service Mesh技术终于从萌芽到走向了成熟,当Istio/Conduit横空出世,人们才惊觉:微服务并非只有侵入式一种玩法,更不是Spring Cloud的独角戏!

这一次的新生力量,完全不按照常理出牌,出场就霸道地掀翻桌子,直接摆出新的玩法:Service Mesh,下一代微服务!这一场大战,在 2017 年的最后一个月,终于上演到白热化,被摆上了台面,受到越来越多人关注。往日霸主 Spring Cloud,此时只能沦为看客。

2017 年的 Service Mesh 历程,在平淡中开始,如戏剧般结束,留给我们一个充满想象和憧憬的 2018。让我们一起来回顾这堪称精彩的一年。
 
Service Mesh 的萌芽期
在我们正式开始 2017 年回顾之前,我们将时间稍微放前一点,回到 2016 年,有些故事背景需要预先交代一下。

虽然直到 2017 年年底,Service Mesh 才开始较大规模被世人了解,这场微服务市场之争也才显现,但是其实 Service Mesh 这股微服务的新势力,早在 2016 年年初就开始萌芽:

2016 年 1 月 15 日,离开 Twitter 的基础设施工程师 William Morgan 和 Oliver Gould,在 GitHub 上发布了 Linkerd 0.0.7 版本,他们同时组建了一个创业小公司 Buoyant,业界第一个 Service Mesh 项目诞生。

2016 年,Matt Klein 在 Lyft 默默地进行 Envoy 的开发。Envoy 诞生的时间其实要比 Linkerd 更早一些,只是在 Lyft 内部不为人所知。

在 2016 年年初,“Service Mesh”还只是 Buoyant 公司的内部词汇,而之后,它开始逐步走向社区:

2016 年 9 月 29 日在 SF Microservices 上,“Service Mesh”这个词汇第一次在公开场合被使用。这标志着“Service Mesh”这个词,从 Buoyant 公司走向社区。

2016 年 10 月,Alex Leong 开始在 Buoyant 公司的官方 Blog 中连载系列文章“A Service Mesh for Kubernetes”。随着“The Services must Mesh”口号的喊出,Buoyant 和 Linkerd 开始 Service Mesh 概念的布道。

在这一年中,第一代的 Service Mesh 产品在稳步推进:

2016 年 9 月 13 日,Matt Klein 宣布 Envoy 在 GitHub 开源,直接发布 1.0.0 版本。

2016 年下半年,Linkerd 陆续发布了 0.8 和 0.9 版本,开始支持 HTTP/2 和 gRPC,1.0 发布在即;同时,借助 Service Mesh 在社区的认可度,Linkerd 在年底开始申请加入 CNCF。

而在这个世界的另外一个角落,Google 和 IBM 两位巨人,握手开始合作,他们联合 Lyft,启动了 Istio 项目。这样,在第一代 Service Mesh 还未走向市场主流时,以 Istio 为代表的第二代 Service Mesh 就迫不及待地上路。

现在我们可以进入主题,开始 2017 年 Service Mesh 发展历程的回顾。
 
急转而下的 Linkerd
 
2017 年,Linkerd 迎来了一个梦幻般的开局,喜讯连连:

2017 年 1 月 23 日,Linkerd 加入 CNCF。

2017 年 3 月 7 日,Linkerd 宣布完成千亿次产品请求。

2017 年 4 月 25 日,Linkerd 1.0 版本发布。

可谓各条战线都进展顺利:产品完成 1.0 release,达成最重要的里程碑;被客户接受并在生产线上成功大规模应用,这代表着市场的认可;进入 CNCF 更是意义重大,这是对 Linkerd 的极大认可,也使得 Linkerd 声名大噪,一时风光无量。

需要特别指出的是,Linkerd 加入 CNCF,对于 Service Mesh 技术是一个非常重要的历史事件:这代表着社区对 Service Mesh 理念的认同和赞赏,Service Mesh 也因此得到社区更大范围的关注。

趁热打铁,就在 Linkerd 1.0 版本发布的同一天,创作者继续 Service Mesh 的布道:

2017 年 4 月 25 日,William Morgan 发布博文“What’s a service mesh? And why do I need one?”。正式给 Service Mesh 做了一个权威定义。

然而现实总是那么残酷,这个美好的开局,未能延续多久就被击碎:

2017 年 5 月 24 日,Istio 0.1 release 版本发布,Google 和 IBM 高调宣讲,社区反响热烈,很多公司在这时就纷纷站队表示支持 Istio。

Linkerd 的风光瞬间被盖过,从意气风发的少年一夜之间变成过气网红。当然,从产品成熟度上来说,linkerd 作为业界仅有的两个生产级 Service Mesh 实现之一,暂时还可以在 Istio 成熟前继续保持市场。但是,随着 Istio 的稳步推进和日益成熟,外加第二代 Service Mesh 的天然优势,Istio 取代第一代的 Linkerd 只是个时间问题。

面对 Google 和 IBM 加持的 Istio,Linkerd 实在难有胜算:

Istio 作为第二代 Service Mesh,通过控制平面带来了前所未有的控制力,远超 Linkerd。

Istio 通过收编和 Linkerd 同为第一代 Service Mesh 的 Envoy,直接拥有了一个功能和稳定性与 Linkerd 处在一个水准的数据平面(也就是作为 sidecar 模式部署的 proxy)。

基于 C++ 的 Envoy 在性能和资源消耗上本来就强过基于 Scala/JVM 的 Linkerd。

Google 和 IBM 组合在人力、资源和社区方面的影响力远非 Buoyant 这样的小公司可以比拟。

Linkerd 的发展态势顿时急转而下,未来陷入一片黑暗。出路在哪里?

在一个多月后,Linkerd 给出一个答案:和 Istio 集成,成为 Istio 的数据面板:

2017 年 7 月 11 日,Linkerd 发布版本 1.1.1,宣布和 Istio 项目集成。Buoyant 发表博文“Linkerd and Istio: like peanut butter and jelly”。

这个方案在意料之中,毕竟面对 Google 和 IBM 的联手威胁,选择低头和妥协是可以理解的,只是这里边存在两个疑问:

1、和 Envoy 相比,Linkerd 并没有特别优势,考虑编程语言的天生劣势,Linkerd 想替代 Envoy 难度非常之大。

2、即使替代成功,在 Istio 的架构下,只是作为一个数据平面存在的 Linkerd,可以发挥的空间有限。这种境地的 Linkerd,是远远无法承载起 Buoyant 的未来的。

Linkerd 的这个谜团,直到 2017 年即将结束的 12 月,在 Conduit 发布之后才被解开。
 
波澜不惊的 Envoy
自从在 2016 年决定委身于 Istio 之后,Envoy 就开始波澜不惊地平稳发展,这和 Linkerd 的跌宕起伏完全不同。

在功能方面,由于定位在数据平面,因此 Envoy 无需考虑太多,很多工作在 Istio 的控制平面完成就好,Envoy 从此专心于将数据平面做好,完善各种细节。在市场方面,Envoy 和 Linkerd 性质不同,不存在生存和发展的战略选择,也没有正面对抗生死大敌的巨大压力。Envoy 在 2017 年有条不紊地陆续发布了 1.2、1.3、1.4 和 1.5 版本,稳步地完善自身,表现非常稳健。

稳扎稳打的 Envoy 在 2017 年一方面继续收获独立客户,一方面伴随 Istio 一起成长。作为业界仅有的两个生产级 Service Mesh 实现之一,Envoy 随后收获了属于它的殊荣:

2017 年 9 月 14 日,Envoy 加入 CNCF,成为 CNCF 的第二个 Service Mesh 项目。

可谓名至实归,水到渠成。作为一个无需承载一家公司未来的开源项目,Envoy 在 2017 年的表现,无可挑剔。
 
背负使命的 Istio
 
从 Google 和 IBM 联手决定推出 Istio 开始,Istio 就注定永远处于风头浪尖,无论成败。

Istio 背负了太多的使命:

建立 Google 和 IBM 在微服务市场的统治地位。

为 Google 和 IBM 的公有云打造杀手锏级特性。

在 k8s 的基础上,延续 Google 的战略布局。

Google 在企业市场的战略布局,是从底层开始,一步一步向上,一步一步靠近应用。刚刚大获全胜的 k8s 为 Istio 准备了一个非常好的基石,而 Istio 的历史使命,就是继 k8s 拿下容器编排之后,更进一步,拿下微服务!

2017 年,Istio 稳步向前,先后发布四个版本:

2017 年 5 月 24 日,Istio 0.1 release 版本发布。

2017 年 10 月 4 日,Istio 0.2 release 版本发布。

2017 年 11 月 30 日,Istio 0.3 release 版本发布。

2017 年 12 月 15 日,Istio 0.4 release 版本发布。

在社区方面,Istio 借助 Google 和 IBM 的大旗,外加自身过硬的实力、先进的理念,很快获得了社区的积极响应和广泛支持。包括 Oracle 和 Red Hat 在内的业界大佬都明确表示对支持 Istio。

在平台支持方面,Istio 的初期版本只支持 k8s 平台,从 0.3 版本开始提供对非 k8s 平台的支持。从策略上说,Istio 借助了 k8s,但是没有强行绑定在 k8s 上。

Istio 面世之后,赞誉不断,尤其是 Service Mesh 技术的爱好者,可以说是为之一振:以新一代 Service Mesh 之名横空出世的 Istio,对比 Linkerd,优势明显。同时产品路线图上有一大堆令人眼花缭乱的功能。假以时日,如果 Istio 能顺利地完成开发,稳定可靠,那么这会是一个非常美好、值得憧憬的大事件,它的意义重大:

重新定义微服务开发方式,让 Service Mesh 成为主流技术。

大幅降低微服务开发的入门门槛,让更多的企业和开发人员可以落地微服务。

统一微服务的开发流程,标准化开发 / 运维方式。

奈何,事情的发展总是不会这么简单地如人所愿。Istio 发布之后,试用中就被发现问题较多,0.1 版本时还比较容易被接受,但是接下来的 0.2、0.3 和 0.4,Istio 在可用性上并没有明显的改观,导致迄今在全球范围内都几乎没有听到 Istio 上生产的案例,公司都将其停留在简单试用阶段。

此时再看 Istio 琳琅满目的各种功能,不禁让人疑惑 Istio 的产品策略:为什么一开场就将摊子铺的如此之大?以至于开发时间长达一年 (注意,虽然开源才半年多,但是开源前已经在开发),却无法得到一个稳定可用的版本。

这有悖于互联网产品的开发理念。下边这个经典图片相信大家并不陌生:

从目前情景看,Istio 已经在图上“不应该”的产品迭代路径上走了一年。从 5 月份 0.1 版本发布开始,我们就满心期待,却陷入“过尽千帆皆不是”的尴尬境地:每一次新版本试用后的结果,都不理想。

身处局外,无法了解 Istio 项目开发的背景和真实情况,也自然无法得知为何会如此,我们只能由衷地希望,Istio 能在 2018 年尽快完成计划中的产品开发,实现生产可用。个人意见:哪怕推迟某些特性的实现,也希望能做到主体部分尽快完善。

2018 年 Service Mesh 的整体走势,很大程度取决于 Istio:如果 Istio 能在 2018 年上半年实现生产可用,哪怕是牺牲部分高级特性,也足以推动整个 Service Mesh 向前大步迈进。反之如果进展不顺,市场会呈现观望和等待的态势,也会给竞争对手机会,比如说,下面将要出场的 Conduit。
 
背水一战的 Conduit
 
2017 年底的 KubeConf,在 Service Mesh 成为大会热点、Istio 备受瞩目时,Buoyant 公司出人意料地给了踌躇满志又稍显拖沓的 Istio 重重一击:

2017 年 12 月 5 日,Conduit 0.1.0 版本发布,Istio 的强力竞争对手亮相 KubeConf。

Conduit 的整体架构和 Istio 一致,借鉴了 Istio 数据平面 + 控制平面的设计,同时别出心裁地选择了 Rust 编程语言来实现数据平面,以达成 Conduit 宣称的更轻、更快和超低资源占用。

继 Isito 之后,业界第二款第二代 Service Mesh 产品就此诞生。话说得有些拗口,但是一场大战就此浮出水面。Buoyant 在 Linkerd 不敌 Istio 的恶劣情况下,绝地反击,祭出全新设计的 Conduit 作为对抗 Istio 的武器。

需要额外指出的是,作为一家初创型企业,在第一款主力产品 Linkerd 被 Istio 强力阻击之后,Buoyant 已经身陷绝境,到了生死存亡之秋,作为背负公司期望,担负和 Istio 正面抗衡职责的 Conduit,可谓压力巨大。

从目前得到的信息分析,Conduit 明显是有备而来,针对 Istio 当前状况,针锋相对的:

编程语言:为了达成更轻、更快和更低资源消耗的目标,考虑到 Istio 的数据面板用的是基于 C++ 语言的 Envoy,Conduit 跳过了 Golang,直接选择了 Rust,颇有些剑走偏锋的意味。不过,单纯以编程语言而言,在能够完全掌握的前提下,Rust 的确是做 proxy 的最佳选择。考虑到 Envoy 在性能方面的良好表现,Conduit 要想更进一步,选择 Rust 也是可以理解。

架构设计:在借鉴 Istio 整体架构的同时,Conduit 做了一些改进。首先 Conduit 控制平面的各个组件是以服务的方式提供功能的,极富弹性。另外,控制平面特意为定制化需求进行了可扩展设计,可以通过编写 gPRC 插件来扩展 Conduit 的功能而无需直接修改 Conduit,这对于有定制化需求的客户是非常便利的。

产品演进:这是最重要的一点!Conduit 完全吸取了 Istio 的教训,因此它的产品迭代路径会是我们最期待的方式。在本文撰写期间,笔者特意和 Conduit 的 CEO William 深入探讨过这个话题,得到了一个非常令人欣慰的答复:Minimal feature set,prod ready as quickly as possible。

然而,要抗衡 Istio 和其身后的 Google 与 IBM,谈何容易。Conduit 2018 年的发展道路,注定是充满挑战的,艰难险阻可想而知。但是,不得不佩服 Buoyant 公司,以及以 CEO William 为首的那支充满挑战精神的团队,有理想、有追求、有魄力、有勇气!期待他们在 2018 年的表现。

让我们回到 Istio 和 Conduit 的竞争格局。从目前局面看,Istio 先天优势明显,但是产品策略上的选择给了 Conduit 一个难得的机会。接下来的 2018 年,在 Conduit 的威胁和刺激下,希望 Istio 能打起精神,给出一份令大家满意的答卷。期待 Istio 和 Conduit 能在 2018 年形成良性竞争,共同引领 Service Mesh 的大潮。
 
低调的参与者
 
2017 年的 Service Mesh,除了业界先驱 Linkerd/Envoy,和后起之秀 Istio/Conduit,还有一些其它的竞争者进入这个市场,只是它们都非常低调。

首先是 nginMesh,来自大名鼎鼎的 Nginx:

2017 年 9 月,在美国波特兰举行的 nginx.conf 大会上,Nginx 宣布了 nginMesh。随即在 GitHub 上发布了 0.1.6 版本。

2017 年 12 月 6 日,nginMesh 0.2.12 版本发布。

2017 年 12 月 25 日,nginMesh 0.3.0 版本发布。

nginMesh 的定位是作为 Istio 的服务代理,也就是替代 Envoy,思路和 Linkerd 之前和 Istio 集成很相似。nginMesh 在发布后的两个多月,GitHub 上提交非常少,直到最近突然发力,先后发布了 0.2 和 0.3 版本。不过 nginMesh 极度低调,GitHub 上的 star 也只有不到 100。

然后是 Kong,但是这个比默默无闻的 nginMesh 更加低调,只是曾经有传闻 Kong 有意 Service Mesh,但是后来没了下文。不过 Kong 的 GitHub 项目介绍里,悄悄地加上了 Service Mesh 的字样:Kong is a ××× Microservice Abstraction Layer (also known as an API Gateway, API Middleware or in some cases Service Mesh)。

在 2017 年,这些低调的参与者,几乎没有引起外界任何注意,也无法预期他们在 2018 年会如何表现。从社区的角度,还是希望有更多的参与者进入 Service Mesh 市场,以推动整个市场的健康发展。
 
 
快速升温的国内
 
2017 年,随着 Servic Mesh 的发展,国内技术社区也开始通过新闻报道 / 技术文章等接触 Service Mesh,但是传播范围和影响力都非常有限。直到年底才剧烈升温,开始被国内技术社区关注:

2017 年 10 月 16 日,在 2017 QCon 上海大会上,我做了一个“Service Mesh:下一代微服务”的演讲,成为 Service Mesh 技术在国内大型技术峰会上的第一次亮相。

2017 年 11 月,国内第一个 Service Mesh 技术社区“Service Mesh 中文网”(http://servicemesh.cn) 成立。

2017 年 12 月,在全球架构师峰会(ArchSummit)2017 北京站上,来自华为的田晓亮做了名为“Service Mesh 在华为云的实践”的分享。

2017 年 12 月 16 日,来自新浪微博的周晶做了名为“微博 Service Mesh 实践”的演讲,分享了 Service Mesh 在微博的落地情况。

此外,作为 Servic Mesh 国内最早的开发和实践者的华为和新浪微博,都积极参与开源。其中新浪微博 Service Mesh 的核心实现,跨语言通信和服务治理已经在 Motan 系列项目中提供,而华为也将稍后开源他们基于 Golang 的 Service Mesh 代码实现。

特别要指出的是,华为目前已经在公有云上将 Service Mesh 作为公共服务提供,这在国内公有云中是第一家。预计随着 Service Mesh 的落地和普及,公有云提供生产级别的 Service Mesh 服务将成为标配。在国外 Google/IBM/Amazon 等公有云都有提供 Service Mesh 的计划,相信国内公有云也会陆续跟进。
 
展望 2018
 
2017 年的 Service Mesh 市场,从 Linkerd 的风光无限开始,到 Istio 的横空出世,最后止于 Conduit 的绝地反击,可谓一波三折;产品也经历从第一代的 Linkerd/Envoy,跨越性的演化出第二代的 Istio/Conduit;同时,技术社区的态度也从年初的逐步接受发展到年底的热烈追捧,下面这张 KubeConf 上的图片非常有代表性地展示了社区的热切期望:

然而 Service Mesh 终究是一个新兴的技术,尤其作为未来主流的 Istio/Conduit 迄今还没有实现产品级别可用,因此 2018 年对 Service Mesh 而言,必然不是一帆风顺,必然是充满荆棘和坎坷的。如何实现从技术理念到产品落地,如何实实在在地解决实践中遇到的各种问题,将会是这一年中至关重要的事情。

衷心祝愿 Istio 和 Conduit(也许还有其他的产品)可以在 2018 年快速成长,实现社区期待的功能和可用性,可以真正地实现降低微服务门槛的目标,让 Service Mesh 成为名副其实的下一代微服务。

2018 年的 Service Mesh,值得期望! 查看全部

微信图片_20171229142127.jpg

 
 敖小剑/数人云资深架构师

十五年软件开发经验,微服务专家,专注于基础架构,Cloud Native拥护者,敏捷实践者。曾在亚信,爱立信,唯品会和PPmoney任职。


前言
在过去的2016年和2017年,微服务技术得以迅猛普及,和容器技术一起成为这两年中最吸引眼球的技术热点。而以Spring Cloud为代表的传统侵入式开发框架,占据着微服务市场的主流地位,它甚至一度成为微服务的代名词。

直到2017年年底,当非侵入式的Service Mesh技术终于从萌芽到走向了成熟,当Istio/Conduit横空出世,人们才惊觉:微服务并非只有侵入式一种玩法,更不是Spring Cloud的独角戏!

这一次的新生力量,完全不按照常理出牌,出场就霸道地掀翻桌子,直接摆出新的玩法:Service Mesh,下一代微服务!这一场大战,在 2017 年的最后一个月,终于上演到白热化,被摆上了台面,受到越来越多人关注。往日霸主 Spring Cloud,此时只能沦为看客。

2017 年的 Service Mesh 历程,在平淡中开始,如戏剧般结束,留给我们一个充满想象和憧憬的 2018。让我们一起来回顾这堪称精彩的一年。
 
Service Mesh 的萌芽期
在我们正式开始 2017 年回顾之前,我们将时间稍微放前一点,回到 2016 年,有些故事背景需要预先交代一下。

虽然直到 2017 年年底,Service Mesh 才开始较大规模被世人了解,这场微服务市场之争也才显现,但是其实 Service Mesh 这股微服务的新势力,早在 2016 年年初就开始萌芽:

2016 年 1 月 15 日,离开 Twitter 的基础设施工程师 William Morgan 和 Oliver Gould,在 GitHub 上发布了 Linkerd 0.0.7 版本,他们同时组建了一个创业小公司 Buoyant,业界第一个 Service Mesh 项目诞生。

2016 年,Matt Klein 在 Lyft 默默地进行 Envoy 的开发。Envoy 诞生的时间其实要比 Linkerd 更早一些,只是在 Lyft 内部不为人所知。

在 2016 年年初,“Service Mesh”还只是 Buoyant 公司的内部词汇,而之后,它开始逐步走向社区:

2016 年 9 月 29 日在 SF Microservices 上,“Service Mesh”这个词汇第一次在公开场合被使用。这标志着“Service Mesh”这个词,从 Buoyant 公司走向社区。

2016 年 10 月,Alex Leong 开始在 Buoyant 公司的官方 Blog 中连载系列文章“A Service Mesh for Kubernetes”。随着“The Services must Mesh”口号的喊出,Buoyant 和 Linkerd 开始 Service Mesh 概念的布道。

在这一年中,第一代的 Service Mesh 产品在稳步推进:

2016 年 9 月 13 日,Matt Klein 宣布 Envoy 在 GitHub 开源,直接发布 1.0.0 版本。

2016 年下半年,Linkerd 陆续发布了 0.8 和 0.9 版本,开始支持 HTTP/2 和 gRPC,1.0 发布在即;同时,借助 Service Mesh 在社区的认可度,Linkerd 在年底开始申请加入 CNCF。

而在这个世界的另外一个角落,Google 和 IBM 两位巨人,握手开始合作,他们联合 Lyft,启动了 Istio 项目。这样,在第一代 Service Mesh 还未走向市场主流时,以 Istio 为代表的第二代 Service Mesh 就迫不及待地上路。

现在我们可以进入主题,开始 2017 年 Service Mesh 发展历程的回顾。
 
急转而下的 Linkerd
 
2017 年,Linkerd 迎来了一个梦幻般的开局,喜讯连连:

2017 年 1 月 23 日,Linkerd 加入 CNCF。

2017 年 3 月 7 日,Linkerd 宣布完成千亿次产品请求。

2017 年 4 月 25 日,Linkerd 1.0 版本发布。

可谓各条战线都进展顺利:产品完成 1.0 release,达成最重要的里程碑;被客户接受并在生产线上成功大规模应用,这代表着市场的认可;进入 CNCF 更是意义重大,这是对 Linkerd 的极大认可,也使得 Linkerd 声名大噪,一时风光无量。

需要特别指出的是,Linkerd 加入 CNCF,对于 Service Mesh 技术是一个非常重要的历史事件:这代表着社区对 Service Mesh 理念的认同和赞赏,Service Mesh 也因此得到社区更大范围的关注。

趁热打铁,就在 Linkerd 1.0 版本发布的同一天,创作者继续 Service Mesh 的布道:

2017 年 4 月 25 日,William Morgan 发布博文“What’s a service mesh? And why do I need one?”。正式给 Service Mesh 做了一个权威定义。

然而现实总是那么残酷,这个美好的开局,未能延续多久就被击碎:

2017 年 5 月 24 日,Istio 0.1 release 版本发布,Google 和 IBM 高调宣讲,社区反响热烈,很多公司在这时就纷纷站队表示支持 Istio。

Linkerd 的风光瞬间被盖过,从意气风发的少年一夜之间变成过气网红。当然,从产品成熟度上来说,linkerd 作为业界仅有的两个生产级 Service Mesh 实现之一,暂时还可以在 Istio 成熟前继续保持市场。但是,随着 Istio 的稳步推进和日益成熟,外加第二代 Service Mesh 的天然优势,Istio 取代第一代的 Linkerd 只是个时间问题。

面对 Google 和 IBM 加持的 Istio,Linkerd 实在难有胜算:

Istio 作为第二代 Service Mesh,通过控制平面带来了前所未有的控制力,远超 Linkerd。

Istio 通过收编和 Linkerd 同为第一代 Service Mesh 的 Envoy,直接拥有了一个功能和稳定性与 Linkerd 处在一个水准的数据平面(也就是作为 sidecar 模式部署的 proxy)。

基于 C++ 的 Envoy 在性能和资源消耗上本来就强过基于 Scala/JVM 的 Linkerd。

Google 和 IBM 组合在人力、资源和社区方面的影响力远非 Buoyant 这样的小公司可以比拟。

Linkerd 的发展态势顿时急转而下,未来陷入一片黑暗。出路在哪里?

在一个多月后,Linkerd 给出一个答案:和 Istio 集成,成为 Istio 的数据面板:

2017 年 7 月 11 日,Linkerd 发布版本 1.1.1,宣布和 Istio 项目集成。Buoyant 发表博文“Linkerd and Istio: like peanut butter and jelly”。

这个方案在意料之中,毕竟面对 Google 和 IBM 的联手威胁,选择低头和妥协是可以理解的,只是这里边存在两个疑问:

1、和 Envoy 相比,Linkerd 并没有特别优势,考虑编程语言的天生劣势,Linkerd 想替代 Envoy 难度非常之大。

2、即使替代成功,在 Istio 的架构下,只是作为一个数据平面存在的 Linkerd,可以发挥的空间有限。这种境地的 Linkerd,是远远无法承载起 Buoyant 的未来的。

Linkerd 的这个谜团,直到 2017 年即将结束的 12 月,在 Conduit 发布之后才被解开。
 
波澜不惊的 Envoy
自从在 2016 年决定委身于 Istio 之后,Envoy 就开始波澜不惊地平稳发展,这和 Linkerd 的跌宕起伏完全不同。

在功能方面,由于定位在数据平面,因此 Envoy 无需考虑太多,很多工作在 Istio 的控制平面完成就好,Envoy 从此专心于将数据平面做好,完善各种细节。在市场方面,Envoy 和 Linkerd 性质不同,不存在生存和发展的战略选择,也没有正面对抗生死大敌的巨大压力。Envoy 在 2017 年有条不紊地陆续发布了 1.2、1.3、1.4 和 1.5 版本,稳步地完善自身,表现非常稳健。

稳扎稳打的 Envoy 在 2017 年一方面继续收获独立客户,一方面伴随 Istio 一起成长。作为业界仅有的两个生产级 Service Mesh 实现之一,Envoy 随后收获了属于它的殊荣:

2017 年 9 月 14 日,Envoy 加入 CNCF,成为 CNCF 的第二个 Service Mesh 项目。

可谓名至实归,水到渠成。作为一个无需承载一家公司未来的开源项目,Envoy 在 2017 年的表现,无可挑剔。
 
背负使命的 Istio
 
从 Google 和 IBM 联手决定推出 Istio 开始,Istio 就注定永远处于风头浪尖,无论成败。

Istio 背负了太多的使命:

建立 Google 和 IBM 在微服务市场的统治地位。

为 Google 和 IBM 的公有云打造杀手锏级特性。

在 k8s 的基础上,延续 Google 的战略布局。

Google 在企业市场的战略布局,是从底层开始,一步一步向上,一步一步靠近应用。刚刚大获全胜的 k8s 为 Istio 准备了一个非常好的基石,而 Istio 的历史使命,就是继 k8s 拿下容器编排之后,更进一步,拿下微服务!

2017 年,Istio 稳步向前,先后发布四个版本:

2017 年 5 月 24 日,Istio 0.1 release 版本发布。

2017 年 10 月 4 日,Istio 0.2 release 版本发布。

2017 年 11 月 30 日,Istio 0.3 release 版本发布。

2017 年 12 月 15 日,Istio 0.4 release 版本发布。

在社区方面,Istio 借助 Google 和 IBM 的大旗,外加自身过硬的实力、先进的理念,很快获得了社区的积极响应和广泛支持。包括 Oracle 和 Red Hat 在内的业界大佬都明确表示对支持 Istio。

在平台支持方面,Istio 的初期版本只支持 k8s 平台,从 0.3 版本开始提供对非 k8s 平台的支持。从策略上说,Istio 借助了 k8s,但是没有强行绑定在 k8s 上。

Istio 面世之后,赞誉不断,尤其是 Service Mesh 技术的爱好者,可以说是为之一振:以新一代 Service Mesh 之名横空出世的 Istio,对比 Linkerd,优势明显。同时产品路线图上有一大堆令人眼花缭乱的功能。假以时日,如果 Istio 能顺利地完成开发,稳定可靠,那么这会是一个非常美好、值得憧憬的大事件,它的意义重大:

重新定义微服务开发方式,让 Service Mesh 成为主流技术。

大幅降低微服务开发的入门门槛,让更多的企业和开发人员可以落地微服务。

统一微服务的开发流程,标准化开发 / 运维方式。

奈何,事情的发展总是不会这么简单地如人所愿。Istio 发布之后,试用中就被发现问题较多,0.1 版本时还比较容易被接受,但是接下来的 0.2、0.3 和 0.4,Istio 在可用性上并没有明显的改观,导致迄今在全球范围内都几乎没有听到 Istio 上生产的案例,公司都将其停留在简单试用阶段。

此时再看 Istio 琳琅满目的各种功能,不禁让人疑惑 Istio 的产品策略:为什么一开场就将摊子铺的如此之大?以至于开发时间长达一年 (注意,虽然开源才半年多,但是开源前已经在开发),却无法得到一个稳定可用的版本。

这有悖于互联网产品的开发理念。下边这个经典图片相信大家并不陌生:

从目前情景看,Istio 已经在图上“不应该”的产品迭代路径上走了一年。从 5 月份 0.1 版本发布开始,我们就满心期待,却陷入“过尽千帆皆不是”的尴尬境地:每一次新版本试用后的结果,都不理想。

身处局外,无法了解 Istio 项目开发的背景和真实情况,也自然无法得知为何会如此,我们只能由衷地希望,Istio 能在 2018 年尽快完成计划中的产品开发,实现生产可用。个人意见:哪怕推迟某些特性的实现,也希望能做到主体部分尽快完善。

2018 年 Service Mesh 的整体走势,很大程度取决于 Istio:如果 Istio 能在 2018 年上半年实现生产可用,哪怕是牺牲部分高级特性,也足以推动整个 Service Mesh 向前大步迈进。反之如果进展不顺,市场会呈现观望和等待的态势,也会给竞争对手机会,比如说,下面将要出场的 Conduit。
 
背水一战的 Conduit
 
2017 年底的 KubeConf,在 Service Mesh 成为大会热点、Istio 备受瞩目时,Buoyant 公司出人意料地给了踌躇满志又稍显拖沓的 Istio 重重一击:

2017 年 12 月 5 日,Conduit 0.1.0 版本发布,Istio 的强力竞争对手亮相 KubeConf。

Conduit 的整体架构和 Istio 一致,借鉴了 Istio 数据平面 + 控制平面的设计,同时别出心裁地选择了 Rust 编程语言来实现数据平面,以达成 Conduit 宣称的更轻、更快和超低资源占用。

继 Isito 之后,业界第二款第二代 Service Mesh 产品就此诞生。话说得有些拗口,但是一场大战就此浮出水面。Buoyant 在 Linkerd 不敌 Istio 的恶劣情况下,绝地反击,祭出全新设计的 Conduit 作为对抗 Istio 的武器。

需要额外指出的是,作为一家初创型企业,在第一款主力产品 Linkerd 被 Istio 强力阻击之后,Buoyant 已经身陷绝境,到了生死存亡之秋,作为背负公司期望,担负和 Istio 正面抗衡职责的 Conduit,可谓压力巨大。

从目前得到的信息分析,Conduit 明显是有备而来,针对 Istio 当前状况,针锋相对的:

编程语言:为了达成更轻、更快和更低资源消耗的目标,考虑到 Istio 的数据面板用的是基于 C++ 语言的 Envoy,Conduit 跳过了 Golang,直接选择了 Rust,颇有些剑走偏锋的意味。不过,单纯以编程语言而言,在能够完全掌握的前提下,Rust 的确是做 proxy 的最佳选择。考虑到 Envoy 在性能方面的良好表现,Conduit 要想更进一步,选择 Rust 也是可以理解。

架构设计:在借鉴 Istio 整体架构的同时,Conduit 做了一些改进。首先 Conduit 控制平面的各个组件是以服务的方式提供功能的,极富弹性。另外,控制平面特意为定制化需求进行了可扩展设计,可以通过编写 gPRC 插件来扩展 Conduit 的功能而无需直接修改 Conduit,这对于有定制化需求的客户是非常便利的。

产品演进:这是最重要的一点!Conduit 完全吸取了 Istio 的教训,因此它的产品迭代路径会是我们最期待的方式。在本文撰写期间,笔者特意和 Conduit 的 CEO William 深入探讨过这个话题,得到了一个非常令人欣慰的答复:Minimal feature set,prod ready as quickly as possible。

然而,要抗衡 Istio 和其身后的 Google 与 IBM,谈何容易。Conduit 2018 年的发展道路,注定是充满挑战的,艰难险阻可想而知。但是,不得不佩服 Buoyant 公司,以及以 CEO William 为首的那支充满挑战精神的团队,有理想、有追求、有魄力、有勇气!期待他们在 2018 年的表现。

让我们回到 Istio 和 Conduit 的竞争格局。从目前局面看,Istio 先天优势明显,但是产品策略上的选择给了 Conduit 一个难得的机会。接下来的 2018 年,在 Conduit 的威胁和刺激下,希望 Istio 能打起精神,给出一份令大家满意的答卷。期待 Istio 和 Conduit 能在 2018 年形成良性竞争,共同引领 Service Mesh 的大潮。
 
低调的参与者
 
2017 年的 Service Mesh,除了业界先驱 Linkerd/Envoy,和后起之秀 Istio/Conduit,还有一些其它的竞争者进入这个市场,只是它们都非常低调。

首先是 nginMesh,来自大名鼎鼎的 Nginx:

2017 年 9 月,在美国波特兰举行的 nginx.conf 大会上,Nginx 宣布了 nginMesh。随即在 GitHub 上发布了 0.1.6 版本。

2017 年 12 月 6 日,nginMesh 0.2.12 版本发布。

2017 年 12 月 25 日,nginMesh 0.3.0 版本发布。

nginMesh 的定位是作为 Istio 的服务代理,也就是替代 Envoy,思路和 Linkerd 之前和 Istio 集成很相似。nginMesh 在发布后的两个多月,GitHub 上提交非常少,直到最近突然发力,先后发布了 0.2 和 0.3 版本。不过 nginMesh 极度低调,GitHub 上的 star 也只有不到 100。

然后是 Kong,但是这个比默默无闻的 nginMesh 更加低调,只是曾经有传闻 Kong 有意 Service Mesh,但是后来没了下文。不过 Kong 的 GitHub 项目介绍里,悄悄地加上了 Service Mesh 的字样:Kong is a ××× Microservice Abstraction Layer (also known as an API Gateway, API Middleware or in some cases Service Mesh)。

在 2017 年,这些低调的参与者,几乎没有引起外界任何注意,也无法预期他们在 2018 年会如何表现。从社区的角度,还是希望有更多的参与者进入 Service Mesh 市场,以推动整个市场的健康发展。
 
 
快速升温的国内
 
2017 年,随着 Servic Mesh 的发展,国内技术社区也开始通过新闻报道 / 技术文章等接触 Service Mesh,但是传播范围和影响力都非常有限。直到年底才剧烈升温,开始被国内技术社区关注:

2017 年 10 月 16 日,在 2017 QCon 上海大会上,我做了一个“Service Mesh:下一代微服务”的演讲,成为 Service Mesh 技术在国内大型技术峰会上的第一次亮相。

2017 年 11 月,国内第一个 Service Mesh 技术社区“Service Mesh 中文网”(http://servicemesh.cn) 成立。

2017 年 12 月,在全球架构师峰会(ArchSummit)2017 北京站上,来自华为的田晓亮做了名为“Service Mesh 在华为云的实践”的分享。

2017 年 12 月 16 日,来自新浪微博的周晶做了名为“微博 Service Mesh 实践”的演讲,分享了 Service Mesh 在微博的落地情况。

此外,作为 Servic Mesh 国内最早的开发和实践者的华为和新浪微博,都积极参与开源。其中新浪微博 Service Mesh 的核心实现,跨语言通信和服务治理已经在 Motan 系列项目中提供,而华为也将稍后开源他们基于 Golang 的 Service Mesh 代码实现。

特别要指出的是,华为目前已经在公有云上将 Service Mesh 作为公共服务提供,这在国内公有云中是第一家。预计随着 Service Mesh 的落地和普及,公有云提供生产级别的 Service Mesh 服务将成为标配。在国外 Google/IBM/Amazon 等公有云都有提供 Service Mesh 的计划,相信国内公有云也会陆续跟进。
 
展望 2018
 
2017 年的 Service Mesh 市场,从 Linkerd 的风光无限开始,到 Istio 的横空出世,最后止于 Conduit 的绝地反击,可谓一波三折;产品也经历从第一代的 Linkerd/Envoy,跨越性的演化出第二代的 Istio/Conduit;同时,技术社区的态度也从年初的逐步接受发展到年底的热烈追捧,下面这张 KubeConf 上的图片非常有代表性地展示了社区的热切期望:

然而 Service Mesh 终究是一个新兴的技术,尤其作为未来主流的 Istio/Conduit 迄今还没有实现产品级别可用,因此 2018 年对 Service Mesh 而言,必然不是一帆风顺,必然是充满荆棘和坎坷的。如何实现从技术理念到产品落地,如何实实在在地解决实践中遇到的各种问题,将会是这一年中至关重要的事情。

衷心祝愿 Istio 和 Conduit(也许还有其他的产品)可以在 2018 年快速成长,实现社区期待的功能和可用性,可以真正地实现降低微服务门槛的目标,让 Service Mesh 成为名副其实的下一代微服务。

2018 年的 Service Mesh,值得期望!

明星分分合合的洪荒点击量,微博Mesh服务化改造如何支撑?(附PPT下载)

小数 发表了文章 • 4 个评论 • 551 次浏览 • 2017-12-26 18:48 • 来自相关话题

 周晶,微博平台研发技术专家、OpenResty 社区委员会成员,高性能 OpenResty 开发框架 Vanilla 作者,开源爱好者,目前主要负责微博平台服务化框架的研发。


大家好,我今天的分享主要围绕以下几点,首先跟大家简要介绍一下微博服务化的演进过程,其次是微博自研跨语言RPC 框架 Motan 实现的一些关键技术要点,主要是跨语言方面,再次,结合目前市面上的一些Service Mesh 实现对比,给出基于 Motan-Go 的更符合微博场景的Weibo Mesh 实现。


最后,是我个人对于面向未来泛服务化架构的一些思考。一些同学对Service Mesh比较感兴趣,也想在生产上做一些实践,如果没有历史包袱,新开发一个项目用什么架构,怎么实现都是可以的。由架构去取舍,看我们更迫切需要的是什么,所追求的是性能还是其它高扩展性等等,目前也有一些现成的解决方案。但是如果没有做任何服务化,或者服务化过程中历史包袱比较重,可能很难找到一种可以直接实施的现成方案,因为需要考虑的往往会更多。本次分享更多是关于操作性内容,希望对大家有一定的借鉴意义。



微博平台服务化演进

我们先看微博平台服务化的演进过程。

微博2009年上线,在业务高速发展的初期是传统的模块化单体服务,每个小的业务都有可能随时爆发成长为一个核心业务。我们的目标很简单,就是满足业务快速发展的需求,并且在突发流量增长时保证服务的高可用。随着业务的扩张,单体架构各个模块严重耦合,致使相互的影响越来越大,请求成功率得不到保障,长尾问题严重。为了解决这一系列问题,微博从 2013 年开发了Java 语言的 Motan RPC 框架,并基于此完成了服务化改造。Motan 从2013年上线至今经历过每次热点事件、三节高峰的严峻考验,稳定性和可靠性都得到了实际场景的验证。这些经历之下微博 Motan 也积累了一套服务治理型 RPC 的服务化体系。


除了Motan,2015年开始,为了应对越来越猛的流量洪峰,更合理的对资源进行整合利用,开发了Open DCP 弹性云计算平台。实现了动态的弹性扩缩容,告别了以往花费动辄几千万的资源成本,以及节前几个月就要开始的劳民伤财为三节做准备的日子,也不需要在为了一个个的热点事件提心吊胆。


上图是当时微博平台技术体系的概貌,是一个基于 Open DCP 弹性云计算平台和 Motan RPC 的服务化架构,经过几年的运营和考验,我们已经在混合云的服务化方向有了丰富的经验和积累。但在解决了微博平台内部服务高可用、高性能的问题后,业务方平台服务调用的问题开始显现出来。比如调用链路过长,导致坑多性能差,又比如,每个业务方都需要做高可用和服务治理,而这些事情平台已经有丰富的积累,大家都再做一遍特别重复且浪费。当想把在平台上的技术积累服务到微博更多的业务方时,平台内部基于 Java 的服务化体系已经不能完成任务,所以我们需要一个跨语言的解决方案。从2016年起,我们开始了跨语言服务化改造之路。



跨语言RPC要点

异构系统如何做整体服务化的解决方案,也是今天探讨的一个主题。

服务化经历了前面几个阶段后,需要构建一个跨语言的服务化体系,将原来在 Java 体系积累的经验加以总结,给其它的技术栈业务赋能,更好的维护微博整体的稳定和高可用。

上图我简单列举跨语言 RPC 的几个技术要点,最下面是可靠性和易用性,比如我们的 Motan 有 Cluster 的概念,每次调用都是从这个 Cluster 里面通过负载均衡(LB)策略来找出可用的节点(Endpoint),再通过一种高可用的策略(HA)完成调用。整个过程的各种理念可复用,各种语言照章实现就好。各种策略也是可以按需根据实际情况进行扩展的。而传输、I/O、进程线程模型等各个语言都不一样,需要根据语言自身的特性来选择。


协议和序列化,这是解决跨语言比较重要的一点,因为要让各种语言互相理解对方,互相沟通。

上图的故事大家可能都有所耳闻,人类很狂妄地说,我要建一个塔直通到天堂。但是上帝听到以后觉得很不爽,所以让人类说不同的语言。因为语言不通,导致塔建歪了,整个工程就失败了,这是说交流的重要性。要做跨语言服务化,负责数据通信的RPC 框架跨语言是重中之重的基础设施。而协议和序列化如何取舍,很关键。

Motan的Java版,所要解决的是微博平台内部 Java 服务之间的调用,因此 Motan1 协议时,其实并没有考虑到跨语言的问题,用的是对Java比较友好的 Hessian。后期在跨语言方面,motan1的协议显得对跨语言不是很友好,motan2 的协议就给了一个足够容易理解的协议,是一个简单的TCP描述。比如,要请求一些方法、服务的分组,或Body,请求发过去,对方语言收到后,怎么样让这个语言理解呢?关键一点就在于序列化。

现在 Motan 使用简单序列化的方式(Simple),只支持几种简单的类型。不过我们一直都在迭代中,也正在以前支持更复杂的类型上做扩充。但本质上,它仍是简单的协议,我们会尽量保证它的简单。只有足够的简单,才能在跨语言上降低成本,开发成本还好,主要是语言沟通起来解析的成本,比如,编译型语言往往有各种明确的强类型,而解释性语言往往并不需要强制类型约束,如何让他们很好的沟通,这就需要做取舍。

这里给出一个 MotanRPC 框架简图,微博有一个自研的注册中心叫 Vintage,也支持其它像ZK等一些注册中心。图中给出了 Motan RPC 关键的一些组件和他们之间的调用关系。如果对Motan 感兴趣的,欢迎大家到GitHub 搜索关注,我们有更详细的文档,大家也可以网上搜索。为什么要说这些?因为Weibo Mesh 是基于Motan来做的。希望大家对Motan有个整体的认识。

现有实现跨语言,支持不同语言的Motan,最下面是Java版,就是最开始的一版,现在支持Golang(Motan-go)、Openresty-Lua(Motan-OpenResty)、PHP(Motan-PHP)。


基于 Motan-Go的 Weibo-Mesh

下一个话题:基于motango的Weibo-Mesh。数人云敖小剑老师扛着ServiceMesh大旗已经冲了一段时间了。刚开始我们也看到这一点,其实大家的想法都一样,因为需求和痛点基本是一样的。所以我们严重认同ServiceMesh是下一代微服务,当然不同人都有自己的理解,通过初步的实践,如果一个很复杂的架构,大家在做服务化,服务化到一定程度,会由于微服务的力度和规模慢慢增大,出现依赖复杂度的增加带来流量交错,难以管控以及服务治理更加困难等一序列的问题。为了解决这些就需要一个东西很好的管控这些服务和流量,这就是为什么会有Mesh。


看一下现在业界公认最牛的 Mesh Istio是怎么玩的。这里我希望大家关注两点,一个是 Istio 有一个基于Envoy 的数据传输层,另外是控制面板,Istio 通过这个控制面板来完成流量调度,鉴权,服务治理等工作。这是 Istio 现在的做法,那微博怎么做的呢?


首先,我们从2016年开始做跨语言的服务化改造,那时还没有 Service Mesh ,刚开始很简单,只想做跨语言,想解决跨语言调用链路过长的问题。比如,原来所有的跨语言服务都是通过 Restful 接口提供的,每个请求都需要层层转发,尤其现在是混合云的架构。举个极端又及其常见的例子 , A 机房的服务依赖一个Restful 接口,请求发出后,内部 DNS 解析说这个域名在 B 机房提供服务,你到B 机房后,HA 告诉你,这个请求应该去C 机房的一个Member 上去完成,绕了一大圈,很有可能发现那个 C 机房在公有云上,链路特别长。所以,希望通过实现跨语言的 Motan RPC,Client 对Server 发起直连,通过点对点的通信来解决链路过长的问题。而后来的演进,后面再细说。


今天讲的这个可能比较简单,目的是希望大家能更好的入戏,更好的理解。可以用直连的方式,或用任何其它方式,像我们用了 Motan。


微博从2016年开始做这个事情踩了很多坑 。微博做跨语言,刚才在后面跟老师们交流大家还说 GRPC 把跨语言带跑偏了,当时做跨语言的时候就是想GRPC已经做的很好,就想通过Motan支持GRPC 协议的方式来实现Motan的跨语言调用。大家可以去翻 Motan 的开源,里面是有GRPC支持的,现在也还有(不过最早支持的是PHP,对接的是鸟哥写的那个Yar的RPC框架, 最早 Motan还支持Yar协议。)。


所以当时想法很简单,想依托GRPC来解决跨语言的问题,所以是上面这样的一个结构,用GRPC来搞。


这个结构出来以后,我们开始拿线上的业务来摸索改造。发觉需要把原来的Restful 接口完全重写成GRPC的服务,这样的改造避免不了大范围的代码重写。硬着头皮改了一些后,发觉性能也没有像宣称的那么好。

大家平时可能都会上微博,我们一条微博数据里面可能有百十个字段,所以基于GRPC 改造就需要把这些字段和服务都用PB 进行定义,完了以后发现最终的Proto文件写下来一大坨。虽然说请求过程并不需要传递这些proto 数据,但是请求数据回来以后需要解析组装。跨语言的时候,比如说PHP来解析那个对象,性能就比较差了,所以这种方案应对微博这种场景最终被淘汰了,而且就算勉强接受性能的损失,这里也只是基于GRPC 解决了跨语言的部分。那另外一个很重要的部分 --- 服务治理呢?


因为我们多年服务化演进,Motan整个体系在服务治理方面做了很多工作,有很多积累。但是基于 Motan 支持GRPC 协议来完成跨语言的服务化的服务治理怎么做呢?比如说这个时候PHP 怎么去做服务发现?PHP 每一个过来,都是一次处理整个过程就结束了,没有一个常驻的可用存储每次请求状态的地方来实现服务发现、服务治理这类似的事情。


但是我们也做了很多尝试,比如通过一个本机的后台进程来做服务发现,或者在Nginx 上基于OpenResty 的timer 来实现服务发现,并发结果写到PHP 的$_SERVER 变量中,让PHP 能直接使用(上面右图那样)等,但是实践的效果并不理想。


所以整体通过 GRPC 来做跨语言这个方案做下来,效果不是很理想,这并不适合我们的场景。所以我们就走到WeiboMesh的原形(如下图),我们想既然解释性语言的跨语言服务化由于语言本身的特性和我们的特殊场景(主要是改造成本、性能等方面的考量)下,并不适合直接通过语言本身来实现,那这样的话,还不如去做一个代理。这个代理可能就是WeiboMesh的一个雏形,类似现在ServiceMesh 中的SideCar。


比如说Java启动一个服务,通常情况下,比如 Java Client 访问这个服务是这样的一个流程:Java Client 启动的时候会根据配置去注册中心订阅自己需要访问的服务,请求过程中会有一个线程不断的从注册中心去发现当前可用的节点列表回来,组成Client 端的一个Cluster而完成的调用(如前面Motan 请求处理简图所示的那样),而如果是PHP 需要通过Motan RPC 访问这个服务呢?PHP没法做服务发现,它就把它的请求扔给Go Agent,服务订阅、发现、治理这些事情让Motan Go Agent 来做,其他的都一样。我们做这个的时候,还没有ServiceMesh这个东西呢,所以一路踩了很多坑。


继续往下想,如果反过来 PHP要做server的时候呢?之前说 RPC 跨语言所要解决的一堆技术问题,比较重要的是传输模型,怎么选一个比较靠谱的模型来作为Server 处理请求呢?现在也有很多很好的现成的解决方案,但是我们没有从中选哪一套来做。主要因为微博业务实在是很庞杂,里面有很多 PHP 的业务,如果把原来基于 LNMP 的服务架构改成 PHP 直接做Server的话,涉及到排山倒海的业务重写,PHP 同学可能会要了我们的命,他们是不会接受的(我要是他们,我也不会干)。所以我们就想,怎么能更简单的把这个事情做了,因为已经有了前面 PHP 通过 Motan Go Agent 去请求RPC 服务,我们就继续在上面扩展了一下。

PHP 要做SERVER,我们使用Motan-Go-Agent来帮助PHP做服务的导出,这个就不是简单的请求调通了,因为 Motan-Go-Agent 除了负责请求的连通,还负责Server 端 PHP 服务的注册。Motan-Go-Agent的角色更像是是一个Motan Server。启动的时候他会把需要导出的PHP的服务,比如注册中心完整导出,并保持像注册中心服务状态的上报更新。导出后,假如说一个Java的Client 需要调动这个服务,Java-Client 会订阅这些服务,请求过程中会通过服务发现回来的节点对它发起调用。Motan-Go-Agent 接到请求后,它把这个请求转给后端的PHP 处理,它之间可能是基于CGI或者是HTTP协议完成的,回来这个请求就完成了。

服务化以后,最直接的感受,原来服务调用时依赖一些 lib 库、Jar 包,或者Restful接口,现在变成依赖一些服务。在服务调用时,不再是倒入某个包或者Curl 某个接口,而是直接去注册中心订阅和发现某个服务,这是一个本质的改变。

这个本质的改变提高了服务依赖和复用的效率,但是原来的很多服务都通过这种方式暴露了,也直接提升了服务治理的复杂度,服务治理成本变得相对较高。

但是这一切都是值得的,因为这一来我们统一了服务治理的方式,高可用等各种保障,通用逻辑的封装等实现起来都更轻松自然。


我们基于 Motan-Go-Agent提出对像 PHP 这样不方便实现服务化的语言,通过正向、反向代理的方式来实现跨语言服务化,Java、Golang这样很方便实现服务化的语言,有简单的Motan实现,或者也可以直接通过Motan-Go 导出服务,这样就只需要实现一个简单的Motan-Client 来完成服务调用即可。


我们服务化做到这个阶段,发现性能已经符合预期,但是当想扩大规模的时候,发现节点和服务数量少。服务化规模很小的时候,比如平台提供几个服务,供几个业务方来调用,可能人工确认,事先配好就没问题。但服务化规模大了之后,就没法人工确认来解决,我们的做法是通过扩展注册中心的功能来解决。


在我们一筹莫展的时候,发现Service Mesh这个概念出现了,而且解决的问题和面临的挑战都一样,都是解决跨语言服务化的问题,也都面临流量、服务管控和治理复杂化的挑战。而且,那么多大牛公司在后面做背书,所以我们就马上转到这个方向上来,希望实现一套更符合微博现状的Weibo Mesh。


要更符合微博现状,首先我们在 Motan RPC、服务治理上有很多积累,这是已有的,不想抛弃的,这是宝贵的技术资源。另一个目标,要做跨语言。所以,一体化的解决方案更符合微博的结构。


另外,微博是混合云架构,弹性云计算平台已经有了。如果新起一个项目,没有任何历史包袱,任何方案都可以。但假如有历史包袱,就不一样了。


这就是基于微博现状做的 Weibomesh。这里给大家详细的说一下,一个是Mesh,跟Istio就很像。但是不一样的地方是说,微博体系里除了一些编译型语言,还有一些解释型语言。只有解释型语言需要走用Mesh来导出服务的方式。比如Java 就不需要,因为有比较好的原生积累。Istio宣称不需要业务方改任何一行代码。但是我们这里需要一个简单的薄薄的client层,算是我们对自己业务的一点牺牲,对后面的收益极大。

其它都一样,包括服务注册、发现、调用。另外,决策系统好比 Istio 里的控制面板一样,负责发指令。跟Istio不一样的地方是,Istio 中是通过一些请求的 Header 的数据,通过一些规则来做基于 iptables 的流量转发,而Weibo Mesh不需要转发,因为服务都是通过发现回来的,要调什么服务,就发现什么服务。调用是明确的,出门之前就知道自己要去哪儿,不需要转发。只是有一点,可能发现回来是一堆节点,需要把控的是怎么让流量更均匀,更好的控制流量,所以有一个自动流量调度和弹性扩容。


弹性扩容本身就有,为了应对峰值流量,应对节日。比如原来为了过年,要提前三个月准备好几千万的服务器。

服务治理是Motan体系的积累,服务传输就是通过它来收发请求,流量过来,因为请求都经过Mesh层,所以通过时时调用的信息,来时时调配流量,对整体系统进行保障。


这就解决了刚才说的,如果微服务力度大,服务划分很细,Services 规模大到一定程度,多个服务之间,怎么互联互通。


这是微博自动台调动体系,分为几个关键点。容量评估模型、是自动化压测容量评估系统。弹性调动要解决的问题,一个是调配集群的流量,一个是控制集群的规模。怎么调配?首先要度量,度量系统包括:它什么时候是正常的,健康的,什么时候是冗余的。一个系统的冗余度是怎么度量出来的。

通过上面这个公式来度量集群的冗余度,还评估了集群是否需要扩容,流量是否需要调动。

下面这里有几条水位线的概念,一个是安全线,一个是警戒线,一个是危险线,红色的就是危险线,这个时候就需要扩容了。大家可以理解为水库,一个水库能蓄多少水,什么时候水位上来,扛不住了就会发生洪灾。

通过对整个集群的流量评估,可以知道这个集群是否空闲,是否安全。当集群流量扛不住,是否把这些流量切到其它集群,支撑整个弹性调动和动态容量调动。


Weibo Mesh改造收益

WeiboMesh改造,通用于任何异构系统。有些操作比如解释型语言,因为某些语言特性,不能实现那个功能,但是用Mesh的方式,可以在 Mesh 层实现。比如, PHP 请求一个接口,如果接口响应慢,通常的做法是重试,这样会带来危险,因为原来走的都是集群的转发。但是如果直连,如果一个节点慢了,一直重试可能就试挂了。如果重试三次不可以,就不再往这里调了,把它从可用节点里摘掉,解决宕机的问题。

监控里会经常看到一些长尾的调动,发现系统性很好。但是真正跑起来,因为网络或者机器的因素,可能会导致后面的长尾特别长,特别占资源。如果在 Mesh上,时间长于某一个阈值的时候,就再给发一个,如果后发的请求响应先回来的话,可以把前面的请求抛掉。

体系化是说,不需要在每一套语言里都实现一套。这跟通用的ServiceMesh方案一样,大家都是为了通用和统一。

这是微博搜索,接入这个系统之后生产当中的一些数据,也经过了一些实验的验证。比如,这是薛之谦和前妻复合事件,这个图同事在很多场合都讲过,原来运营发一个 PUSH ,大家都提心吊胆。在新浪如果遇到爆炸性的新闻,运营在发 PUSH 之前,都要通知到所有技术。但是现在不需要这样,比如说那次运营发了一个PUSH,大家可以想象一下山洪爆发,调动系统发现已经过了黄色警戒线了,已经需要扩容了,它就自动扩了,冗余就上来了,这是动态扩容。弹性调动也是如此,用的同一个技术体系。


面向未来架构,重新定义服务化

在开发过程中会遇到很多问题,原来做服务化,所提供的是一些Lib、Jar包或是像接口之类的,但是现在已经不再依赖那些,现在依赖的是服务,Service Mesh 里甚至都没有Client和Server的概念了,都是Service。但是在Motan里面,是有Client和Server的。它有两端,因为要去发调动,两端的处理不一样。调动不是通盘都按Service来讲的,是通过服务发现,然后对Server 发起直连。这个过程导致需要每一个实现跨语言的地方,都需要一些特殊的处理。

首先通用性方面,使用Motan来刻画一个服务,现在不再依赖包,而依赖于服务。提供的时候,告诉这个服务,注册到那个分组下,调动那个分组下面的服务就可以了,一个很简单的RPC服务调用的方式,上面会有协议,节点和版本号类似的数据,用URL来唯一刻画一个服务。

微博有历史包袱,希望已有的系统不要改动太多,以最小的成本得到最大的收益。所以,我们对原来基于 Jersey 开发的 Cedrus Restful 框架进行了适配,在Motan框架层面把原来所有的Restful 接口自动导出为Motan RPC 服务,通过这种方式减少改造的成本。原来改造的时候,需要把所有 Restful 服务都重写成RPC服务,成本特别高。

支持协议,比如支持GRPC,前面有GPRC可以去调,现在支持HTTP,HTTP对等的是Cedrus(其实就是Servlet)。它其实中间传输的是Motan协议,但是可以按照HTTP的方式调动一个Motan服务,这样的话,Client也不需要改任何一行代码。

我们对WeiboMesh 的一些思考,Weibo Mesh 跟通常的Service Mesh 有本质的不同,我们对服务的调用是通过服务发现后直连的,不是通过拦截和转发。通常Service Mesh 不能直接满足我们的需求,可能大家也有很多类似的场景。所以这些思考希望能给大家一些借鉴的意义。

Weibo Mesh的服务调用需要更轻薄的Motan Client,一个原因是降低已有架构的改造成本,一个是泛服务化的概念。比如访问微博,需要调动用户的服务、微博的服务,评论的服务,但是后端的底层资源,比如说MC,Kafka等的资源都是服务,如果把这些资源用 Motan 协议来实现资源服务化,只需要一个Client就能完成所有的服务调用。而且服务治理体系,流量管控体系都可以复用,解决了大家在开发的时候面对各种资源的不同Client实现而各种调研,选型。微博基于OpenResty 实现了 Motan-OpenResty 版本,就是想以此来对OpenResty 社区在资源服务化方面实现复用,提供更多更方便的服务。

基于泛服务化理念,通过轻薄的Client,就可以调所有服务。虽然改造的时候需要改一点代码。泛服务化跟 Istio的思路不一样之处还在于,泛服务化不止针对自己开发的应用级服务,还有一些底层服务,资源的服务。他们都可以通过封装为简单的 Motan2 协议来进行简单的访问,所有功能都是可编程可扩展的。用过Motan的人都知道,Motan在做扩展的时候特别简单,比如说要加一个通用的逻辑,无论是扩展一个Filter 还是新增一种HA策略,这个架构是一个可编程,泛服务化的架构。

Weibo Mesh后期规划

微博是混合云架构,如果是新的公司可能就直接上云了,所以我们后期也考虑在云原生计算方面做一些支持。出于微博本身的技术需要,我们还会在服务治理的整体方案方面做更多的尝试。我们也希望Weibo Mesh 能做成更通用化的服务方案,让更多团队受益。

另外,Motan还有Motan—Openresty 版本。出于我个人对OpenResty的理解,我认为OpenResty 可能是目前唯一称得上服务器应用开发平台,把Nginx 作为一个开发平台,在上面开发各种服务,而且是基于极其简单、表现力极强的Lua开发。最令人欣喜若狂的是,重启维护的Stream-lua 模块让OpenResty不止能开发 HTTP 服务,同样能开发 TCP、UDP 服务。基于此的 Motan-OpenResty 可以复用 OpenResty 积累的一切,我希望能在Openresty方面做一些事情。

因为就Mesh体系来讲,大家可能都是有包袱的。当有既有技术体系的时候,Java应用或者其他应用,前面都挂着Nginx,从Nginx 到OpenResty 的迁移成本几乎为零。在整个流量分发当中,它起到比较关键的作用,如果能在这一层上做一些事情,那是不是把很多改造的工作又减轻掉了,平台自己来解决很多问题,应用级别就不需要搞,因为现在比Istio,感觉需要强化一点在于说,有一个Client,需要大家改一点代码,但是又希望能不能更少的成本,所以我需要做这样的一些事情,这是我自己后期的一个摸索的方向。希望同样对这种思路感兴趣的同学能一起参与,本身整个体系都是开源的,欢迎大家有什么想法或者是有什么问题提出来,一起来做。

因为觉得在这个方面走的也不算特别早,也不晚,现在在业务场景上真正落地的Mesh的,微博应该是比较早的,而那个Motan-Openresty版本可能是基于最新的Openresty Stream模块开发的。那个现在也作为Openresty社区比较标准版的Stream模块开发样板项目,也希望大家多多的关注,我今天的分享就到这,谢谢大家。

关注Service Mesh中文网公众号,回复1216,即可下载本次演讲实录PPT.






  查看全部
周晶照片.jpg

 周晶,微博平台研发技术专家、OpenResty 社区委员会成员,高性能 OpenResty 开发框架 Vanilla 作者,开源爱好者,目前主要负责微博平台服务化框架的研发。


大家好,我今天的分享主要围绕以下几点,首先跟大家简要介绍一下微博服务化的演进过程,其次是微博自研跨语言RPC 框架 Motan 实现的一些关键技术要点,主要是跨语言方面,再次,结合目前市面上的一些Service Mesh 实现对比,给出基于 Motan-Go 的更符合微博场景的Weibo Mesh 实现。


最后,是我个人对于面向未来泛服务化架构的一些思考。一些同学对Service Mesh比较感兴趣,也想在生产上做一些实践,如果没有历史包袱,新开发一个项目用什么架构,怎么实现都是可以的。由架构去取舍,看我们更迫切需要的是什么,所追求的是性能还是其它高扩展性等等,目前也有一些现成的解决方案。但是如果没有做任何服务化,或者服务化过程中历史包袱比较重,可能很难找到一种可以直接实施的现成方案,因为需要考虑的往往会更多。本次分享更多是关于操作性内容,希望对大家有一定的借鉴意义。



微博平台服务化演进

我们先看微博平台服务化的演进过程。

微博2009年上线,在业务高速发展的初期是传统的模块化单体服务,每个小的业务都有可能随时爆发成长为一个核心业务。我们的目标很简单,就是满足业务快速发展的需求,并且在突发流量增长时保证服务的高可用。随着业务的扩张,单体架构各个模块严重耦合,致使相互的影响越来越大,请求成功率得不到保障,长尾问题严重。为了解决这一系列问题,微博从 2013 年开发了Java 语言的 Motan RPC 框架,并基于此完成了服务化改造。Motan 从2013年上线至今经历过每次热点事件、三节高峰的严峻考验,稳定性和可靠性都得到了实际场景的验证。这些经历之下微博 Motan 也积累了一套服务治理型 RPC 的服务化体系。


除了Motan,2015年开始,为了应对越来越猛的流量洪峰,更合理的对资源进行整合利用,开发了Open DCP 弹性云计算平台。实现了动态的弹性扩缩容,告别了以往花费动辄几千万的资源成本,以及节前几个月就要开始的劳民伤财为三节做准备的日子,也不需要在为了一个个的热点事件提心吊胆。


上图是当时微博平台技术体系的概貌,是一个基于 Open DCP 弹性云计算平台和 Motan RPC 的服务化架构,经过几年的运营和考验,我们已经在混合云的服务化方向有了丰富的经验和积累。但在解决了微博平台内部服务高可用、高性能的问题后,业务方平台服务调用的问题开始显现出来。比如调用链路过长,导致坑多性能差,又比如,每个业务方都需要做高可用和服务治理,而这些事情平台已经有丰富的积累,大家都再做一遍特别重复且浪费。当想把在平台上的技术积累服务到微博更多的业务方时,平台内部基于 Java 的服务化体系已经不能完成任务,所以我们需要一个跨语言的解决方案。从2016年起,我们开始了跨语言服务化改造之路。



跨语言RPC要点

异构系统如何做整体服务化的解决方案,也是今天探讨的一个主题。

服务化经历了前面几个阶段后,需要构建一个跨语言的服务化体系,将原来在 Java 体系积累的经验加以总结,给其它的技术栈业务赋能,更好的维护微博整体的稳定和高可用。

上图我简单列举跨语言 RPC 的几个技术要点,最下面是可靠性和易用性,比如我们的 Motan 有 Cluster 的概念,每次调用都是从这个 Cluster 里面通过负载均衡(LB)策略来找出可用的节点(Endpoint),再通过一种高可用的策略(HA)完成调用。整个过程的各种理念可复用,各种语言照章实现就好。各种策略也是可以按需根据实际情况进行扩展的。而传输、I/O、进程线程模型等各个语言都不一样,需要根据语言自身的特性来选择。


协议和序列化,这是解决跨语言比较重要的一点,因为要让各种语言互相理解对方,互相沟通。

上图的故事大家可能都有所耳闻,人类很狂妄地说,我要建一个塔直通到天堂。但是上帝听到以后觉得很不爽,所以让人类说不同的语言。因为语言不通,导致塔建歪了,整个工程就失败了,这是说交流的重要性。要做跨语言服务化,负责数据通信的RPC 框架跨语言是重中之重的基础设施。而协议和序列化如何取舍,很关键。

Motan的Java版,所要解决的是微博平台内部 Java 服务之间的调用,因此 Motan1 协议时,其实并没有考虑到跨语言的问题,用的是对Java比较友好的 Hessian。后期在跨语言方面,motan1的协议显得对跨语言不是很友好,motan2 的协议就给了一个足够容易理解的协议,是一个简单的TCP描述。比如,要请求一些方法、服务的分组,或Body,请求发过去,对方语言收到后,怎么样让这个语言理解呢?关键一点就在于序列化。

现在 Motan 使用简单序列化的方式(Simple),只支持几种简单的类型。不过我们一直都在迭代中,也正在以前支持更复杂的类型上做扩充。但本质上,它仍是简单的协议,我们会尽量保证它的简单。只有足够的简单,才能在跨语言上降低成本,开发成本还好,主要是语言沟通起来解析的成本,比如,编译型语言往往有各种明确的强类型,而解释性语言往往并不需要强制类型约束,如何让他们很好的沟通,这就需要做取舍。

这里给出一个 MotanRPC 框架简图,微博有一个自研的注册中心叫 Vintage,也支持其它像ZK等一些注册中心。图中给出了 Motan RPC 关键的一些组件和他们之间的调用关系。如果对Motan 感兴趣的,欢迎大家到GitHub 搜索关注,我们有更详细的文档,大家也可以网上搜索。为什么要说这些?因为Weibo Mesh 是基于Motan来做的。希望大家对Motan有个整体的认识。

现有实现跨语言,支持不同语言的Motan,最下面是Java版,就是最开始的一版,现在支持Golang(Motan-go)、Openresty-Lua(Motan-OpenResty)、PHP(Motan-PHP)。


基于 Motan-Go的 Weibo-Mesh

下一个话题:基于motango的Weibo-Mesh。数人云敖小剑老师扛着ServiceMesh大旗已经冲了一段时间了。刚开始我们也看到这一点,其实大家的想法都一样,因为需求和痛点基本是一样的。所以我们严重认同ServiceMesh是下一代微服务,当然不同人都有自己的理解,通过初步的实践,如果一个很复杂的架构,大家在做服务化,服务化到一定程度,会由于微服务的力度和规模慢慢增大,出现依赖复杂度的增加带来流量交错,难以管控以及服务治理更加困难等一序列的问题。为了解决这些就需要一个东西很好的管控这些服务和流量,这就是为什么会有Mesh。


看一下现在业界公认最牛的 Mesh Istio是怎么玩的。这里我希望大家关注两点,一个是 Istio 有一个基于Envoy 的数据传输层,另外是控制面板,Istio 通过这个控制面板来完成流量调度,鉴权,服务治理等工作。这是 Istio 现在的做法,那微博怎么做的呢?


首先,我们从2016年开始做跨语言的服务化改造,那时还没有 Service Mesh ,刚开始很简单,只想做跨语言,想解决跨语言调用链路过长的问题。比如,原来所有的跨语言服务都是通过 Restful 接口提供的,每个请求都需要层层转发,尤其现在是混合云的架构。举个极端又及其常见的例子 , A 机房的服务依赖一个Restful 接口,请求发出后,内部 DNS 解析说这个域名在 B 机房提供服务,你到B 机房后,HA 告诉你,这个请求应该去C 机房的一个Member 上去完成,绕了一大圈,很有可能发现那个 C 机房在公有云上,链路特别长。所以,希望通过实现跨语言的 Motan RPC,Client 对Server 发起直连,通过点对点的通信来解决链路过长的问题。而后来的演进,后面再细说。


今天讲的这个可能比较简单,目的是希望大家能更好的入戏,更好的理解。可以用直连的方式,或用任何其它方式,像我们用了 Motan。


微博从2016年开始做这个事情踩了很多坑 。微博做跨语言,刚才在后面跟老师们交流大家还说 GRPC 把跨语言带跑偏了,当时做跨语言的时候就是想GRPC已经做的很好,就想通过Motan支持GRPC 协议的方式来实现Motan的跨语言调用。大家可以去翻 Motan 的开源,里面是有GRPC支持的,现在也还有(不过最早支持的是PHP,对接的是鸟哥写的那个Yar的RPC框架, 最早 Motan还支持Yar协议。)。


所以当时想法很简单,想依托GRPC来解决跨语言的问题,所以是上面这样的一个结构,用GRPC来搞。


这个结构出来以后,我们开始拿线上的业务来摸索改造。发觉需要把原来的Restful 接口完全重写成GRPC的服务,这样的改造避免不了大范围的代码重写。硬着头皮改了一些后,发觉性能也没有像宣称的那么好。

大家平时可能都会上微博,我们一条微博数据里面可能有百十个字段,所以基于GRPC 改造就需要把这些字段和服务都用PB 进行定义,完了以后发现最终的Proto文件写下来一大坨。虽然说请求过程并不需要传递这些proto 数据,但是请求数据回来以后需要解析组装。跨语言的时候,比如说PHP来解析那个对象,性能就比较差了,所以这种方案应对微博这种场景最终被淘汰了,而且就算勉强接受性能的损失,这里也只是基于GRPC 解决了跨语言的部分。那另外一个很重要的部分 --- 服务治理呢?


因为我们多年服务化演进,Motan整个体系在服务治理方面做了很多工作,有很多积累。但是基于 Motan 支持GRPC 协议来完成跨语言的服务化的服务治理怎么做呢?比如说这个时候PHP 怎么去做服务发现?PHP 每一个过来,都是一次处理整个过程就结束了,没有一个常驻的可用存储每次请求状态的地方来实现服务发现、服务治理这类似的事情。


但是我们也做了很多尝试,比如通过一个本机的后台进程来做服务发现,或者在Nginx 上基于OpenResty 的timer 来实现服务发现,并发结果写到PHP 的$_SERVER 变量中,让PHP 能直接使用(上面右图那样)等,但是实践的效果并不理想。


所以整体通过 GRPC 来做跨语言这个方案做下来,效果不是很理想,这并不适合我们的场景。所以我们就走到WeiboMesh的原形(如下图),我们想既然解释性语言的跨语言服务化由于语言本身的特性和我们的特殊场景(主要是改造成本、性能等方面的考量)下,并不适合直接通过语言本身来实现,那这样的话,还不如去做一个代理。这个代理可能就是WeiboMesh的一个雏形,类似现在ServiceMesh 中的SideCar。


比如说Java启动一个服务,通常情况下,比如 Java Client 访问这个服务是这样的一个流程:Java Client 启动的时候会根据配置去注册中心订阅自己需要访问的服务,请求过程中会有一个线程不断的从注册中心去发现当前可用的节点列表回来,组成Client 端的一个Cluster而完成的调用(如前面Motan 请求处理简图所示的那样),而如果是PHP 需要通过Motan RPC 访问这个服务呢?PHP没法做服务发现,它就把它的请求扔给Go Agent,服务订阅、发现、治理这些事情让Motan Go Agent 来做,其他的都一样。我们做这个的时候,还没有ServiceMesh这个东西呢,所以一路踩了很多坑。


继续往下想,如果反过来 PHP要做server的时候呢?之前说 RPC 跨语言所要解决的一堆技术问题,比较重要的是传输模型,怎么选一个比较靠谱的模型来作为Server 处理请求呢?现在也有很多很好的现成的解决方案,但是我们没有从中选哪一套来做。主要因为微博业务实在是很庞杂,里面有很多 PHP 的业务,如果把原来基于 LNMP 的服务架构改成 PHP 直接做Server的话,涉及到排山倒海的业务重写,PHP 同学可能会要了我们的命,他们是不会接受的(我要是他们,我也不会干)。所以我们就想,怎么能更简单的把这个事情做了,因为已经有了前面 PHP 通过 Motan Go Agent 去请求RPC 服务,我们就继续在上面扩展了一下。

PHP 要做SERVER,我们使用Motan-Go-Agent来帮助PHP做服务的导出,这个就不是简单的请求调通了,因为 Motan-Go-Agent 除了负责请求的连通,还负责Server 端 PHP 服务的注册。Motan-Go-Agent的角色更像是是一个Motan Server。启动的时候他会把需要导出的PHP的服务,比如注册中心完整导出,并保持像注册中心服务状态的上报更新。导出后,假如说一个Java的Client 需要调动这个服务,Java-Client 会订阅这些服务,请求过程中会通过服务发现回来的节点对它发起调用。Motan-Go-Agent 接到请求后,它把这个请求转给后端的PHP 处理,它之间可能是基于CGI或者是HTTP协议完成的,回来这个请求就完成了。

服务化以后,最直接的感受,原来服务调用时依赖一些 lib 库、Jar 包,或者Restful接口,现在变成依赖一些服务。在服务调用时,不再是倒入某个包或者Curl 某个接口,而是直接去注册中心订阅和发现某个服务,这是一个本质的改变。

这个本质的改变提高了服务依赖和复用的效率,但是原来的很多服务都通过这种方式暴露了,也直接提升了服务治理的复杂度,服务治理成本变得相对较高。

但是这一切都是值得的,因为这一来我们统一了服务治理的方式,高可用等各种保障,通用逻辑的封装等实现起来都更轻松自然。


我们基于 Motan-Go-Agent提出对像 PHP 这样不方便实现服务化的语言,通过正向、反向代理的方式来实现跨语言服务化,Java、Golang这样很方便实现服务化的语言,有简单的Motan实现,或者也可以直接通过Motan-Go 导出服务,这样就只需要实现一个简单的Motan-Client 来完成服务调用即可。


我们服务化做到这个阶段,发现性能已经符合预期,但是当想扩大规模的时候,发现节点和服务数量少。服务化规模很小的时候,比如平台提供几个服务,供几个业务方来调用,可能人工确认,事先配好就没问题。但服务化规模大了之后,就没法人工确认来解决,我们的做法是通过扩展注册中心的功能来解决。


在我们一筹莫展的时候,发现Service Mesh这个概念出现了,而且解决的问题和面临的挑战都一样,都是解决跨语言服务化的问题,也都面临流量、服务管控和治理复杂化的挑战。而且,那么多大牛公司在后面做背书,所以我们就马上转到这个方向上来,希望实现一套更符合微博现状的Weibo Mesh。


要更符合微博现状,首先我们在 Motan RPC、服务治理上有很多积累,这是已有的,不想抛弃的,这是宝贵的技术资源。另一个目标,要做跨语言。所以,一体化的解决方案更符合微博的结构。


另外,微博是混合云架构,弹性云计算平台已经有了。如果新起一个项目,没有任何历史包袱,任何方案都可以。但假如有历史包袱,就不一样了。


这就是基于微博现状做的 Weibomesh。这里给大家详细的说一下,一个是Mesh,跟Istio就很像。但是不一样的地方是说,微博体系里除了一些编译型语言,还有一些解释型语言。只有解释型语言需要走用Mesh来导出服务的方式。比如Java 就不需要,因为有比较好的原生积累。Istio宣称不需要业务方改任何一行代码。但是我们这里需要一个简单的薄薄的client层,算是我们对自己业务的一点牺牲,对后面的收益极大。

其它都一样,包括服务注册、发现、调用。另外,决策系统好比 Istio 里的控制面板一样,负责发指令。跟Istio不一样的地方是,Istio 中是通过一些请求的 Header 的数据,通过一些规则来做基于 iptables 的流量转发,而Weibo Mesh不需要转发,因为服务都是通过发现回来的,要调什么服务,就发现什么服务。调用是明确的,出门之前就知道自己要去哪儿,不需要转发。只是有一点,可能发现回来是一堆节点,需要把控的是怎么让流量更均匀,更好的控制流量,所以有一个自动流量调度和弹性扩容。


弹性扩容本身就有,为了应对峰值流量,应对节日。比如原来为了过年,要提前三个月准备好几千万的服务器。

服务治理是Motan体系的积累,服务传输就是通过它来收发请求,流量过来,因为请求都经过Mesh层,所以通过时时调用的信息,来时时调配流量,对整体系统进行保障。


这就解决了刚才说的,如果微服务力度大,服务划分很细,Services 规模大到一定程度,多个服务之间,怎么互联互通。


这是微博自动台调动体系,分为几个关键点。容量评估模型、是自动化压测容量评估系统。弹性调动要解决的问题,一个是调配集群的流量,一个是控制集群的规模。怎么调配?首先要度量,度量系统包括:它什么时候是正常的,健康的,什么时候是冗余的。一个系统的冗余度是怎么度量出来的。

通过上面这个公式来度量集群的冗余度,还评估了集群是否需要扩容,流量是否需要调动。

下面这里有几条水位线的概念,一个是安全线,一个是警戒线,一个是危险线,红色的就是危险线,这个时候就需要扩容了。大家可以理解为水库,一个水库能蓄多少水,什么时候水位上来,扛不住了就会发生洪灾。

通过对整个集群的流量评估,可以知道这个集群是否空闲,是否安全。当集群流量扛不住,是否把这些流量切到其它集群,支撑整个弹性调动和动态容量调动。


Weibo Mesh改造收益

WeiboMesh改造,通用于任何异构系统。有些操作比如解释型语言,因为某些语言特性,不能实现那个功能,但是用Mesh的方式,可以在 Mesh 层实现。比如, PHP 请求一个接口,如果接口响应慢,通常的做法是重试,这样会带来危险,因为原来走的都是集群的转发。但是如果直连,如果一个节点慢了,一直重试可能就试挂了。如果重试三次不可以,就不再往这里调了,把它从可用节点里摘掉,解决宕机的问题。

监控里会经常看到一些长尾的调动,发现系统性很好。但是真正跑起来,因为网络或者机器的因素,可能会导致后面的长尾特别长,特别占资源。如果在 Mesh上,时间长于某一个阈值的时候,就再给发一个,如果后发的请求响应先回来的话,可以把前面的请求抛掉。

体系化是说,不需要在每一套语言里都实现一套。这跟通用的ServiceMesh方案一样,大家都是为了通用和统一。

这是微博搜索,接入这个系统之后生产当中的一些数据,也经过了一些实验的验证。比如,这是薛之谦和前妻复合事件,这个图同事在很多场合都讲过,原来运营发一个 PUSH ,大家都提心吊胆。在新浪如果遇到爆炸性的新闻,运营在发 PUSH 之前,都要通知到所有技术。但是现在不需要这样,比如说那次运营发了一个PUSH,大家可以想象一下山洪爆发,调动系统发现已经过了黄色警戒线了,已经需要扩容了,它就自动扩了,冗余就上来了,这是动态扩容。弹性调动也是如此,用的同一个技术体系。


面向未来架构,重新定义服务化

在开发过程中会遇到很多问题,原来做服务化,所提供的是一些Lib、Jar包或是像接口之类的,但是现在已经不再依赖那些,现在依赖的是服务,Service Mesh 里甚至都没有Client和Server的概念了,都是Service。但是在Motan里面,是有Client和Server的。它有两端,因为要去发调动,两端的处理不一样。调动不是通盘都按Service来讲的,是通过服务发现,然后对Server 发起直连。这个过程导致需要每一个实现跨语言的地方,都需要一些特殊的处理。

首先通用性方面,使用Motan来刻画一个服务,现在不再依赖包,而依赖于服务。提供的时候,告诉这个服务,注册到那个分组下,调动那个分组下面的服务就可以了,一个很简单的RPC服务调用的方式,上面会有协议,节点和版本号类似的数据,用URL来唯一刻画一个服务。

微博有历史包袱,希望已有的系统不要改动太多,以最小的成本得到最大的收益。所以,我们对原来基于 Jersey 开发的 Cedrus Restful 框架进行了适配,在Motan框架层面把原来所有的Restful 接口自动导出为Motan RPC 服务,通过这种方式减少改造的成本。原来改造的时候,需要把所有 Restful 服务都重写成RPC服务,成本特别高。

支持协议,比如支持GRPC,前面有GPRC可以去调,现在支持HTTP,HTTP对等的是Cedrus(其实就是Servlet)。它其实中间传输的是Motan协议,但是可以按照HTTP的方式调动一个Motan服务,这样的话,Client也不需要改任何一行代码。

我们对WeiboMesh 的一些思考,Weibo Mesh 跟通常的Service Mesh 有本质的不同,我们对服务的调用是通过服务发现后直连的,不是通过拦截和转发。通常Service Mesh 不能直接满足我们的需求,可能大家也有很多类似的场景。所以这些思考希望能给大家一些借鉴的意义。

Weibo Mesh的服务调用需要更轻薄的Motan Client,一个原因是降低已有架构的改造成本,一个是泛服务化的概念。比如访问微博,需要调动用户的服务、微博的服务,评论的服务,但是后端的底层资源,比如说MC,Kafka等的资源都是服务,如果把这些资源用 Motan 协议来实现资源服务化,只需要一个Client就能完成所有的服务调用。而且服务治理体系,流量管控体系都可以复用,解决了大家在开发的时候面对各种资源的不同Client实现而各种调研,选型。微博基于OpenResty 实现了 Motan-OpenResty 版本,就是想以此来对OpenResty 社区在资源服务化方面实现复用,提供更多更方便的服务。

基于泛服务化理念,通过轻薄的Client,就可以调所有服务。虽然改造的时候需要改一点代码。泛服务化跟 Istio的思路不一样之处还在于,泛服务化不止针对自己开发的应用级服务,还有一些底层服务,资源的服务。他们都可以通过封装为简单的 Motan2 协议来进行简单的访问,所有功能都是可编程可扩展的。用过Motan的人都知道,Motan在做扩展的时候特别简单,比如说要加一个通用的逻辑,无论是扩展一个Filter 还是新增一种HA策略,这个架构是一个可编程,泛服务化的架构。

Weibo Mesh后期规划

微博是混合云架构,如果是新的公司可能就直接上云了,所以我们后期也考虑在云原生计算方面做一些支持。出于微博本身的技术需要,我们还会在服务治理的整体方案方面做更多的尝试。我们也希望Weibo Mesh 能做成更通用化的服务方案,让更多团队受益。

另外,Motan还有Motan—Openresty 版本。出于我个人对OpenResty的理解,我认为OpenResty 可能是目前唯一称得上服务器应用开发平台,把Nginx 作为一个开发平台,在上面开发各种服务,而且是基于极其简单、表现力极强的Lua开发。最令人欣喜若狂的是,重启维护的Stream-lua 模块让OpenResty不止能开发 HTTP 服务,同样能开发 TCP、UDP 服务。基于此的 Motan-OpenResty 可以复用 OpenResty 积累的一切,我希望能在Openresty方面做一些事情。

因为就Mesh体系来讲,大家可能都是有包袱的。当有既有技术体系的时候,Java应用或者其他应用,前面都挂着Nginx,从Nginx 到OpenResty 的迁移成本几乎为零。在整个流量分发当中,它起到比较关键的作用,如果能在这一层上做一些事情,那是不是把很多改造的工作又减轻掉了,平台自己来解决很多问题,应用级别就不需要搞,因为现在比Istio,感觉需要强化一点在于说,有一个Client,需要大家改一点代码,但是又希望能不能更少的成本,所以我需要做这样的一些事情,这是我自己后期的一个摸索的方向。希望同样对这种思路感兴趣的同学能一起参与,本身整个体系都是开源的,欢迎大家有什么想法或者是有什么问题提出来,一起来做。

因为觉得在这个方面走的也不算特别早,也不晚,现在在业务场景上真正落地的Mesh的,微博应该是比较早的,而那个Motan-Openresty版本可能是基于最新的Openresty Stream模块开发的。那个现在也作为Openresty社区比较标准版的Stream模块开发样板项目,也希望大家多多的关注,我今天的分享就到这,谢谢大家。

关注Service Mesh中文网公众号,回复1216,即可下载本次演讲实录PPT.

微信图片_20171220120849.jpg


 

演讲实录 | Service Mesh 时代的选边与站队(附PPT下载)

小数 发表了文章 • 3 个评论 • 1203 次浏览 • 2017-12-20 19:03 • 来自相关话题

敖小剑/数人云资深架构师

十五年软件开发经验,微服务专家,专注于基础架构,Cloud Native拥护者,敏捷实践者。曾在亚信,爱立信,唯品会和PPmoney任职。

Service Mesh 时代下的选边与战队

在2017年,Service Mesh技术在快速成长。我们看到在年中的时候,Istio非常霸气的登场。如果大家有关注Service Mesh这个技术,就会知道大概10天前,Conduit这个产品突然发布了。实际上在这过去的一年当中,Service Mesh历经了非常多的事情。在经过2017年的酝酿过程后,Service Mesh技术接近一个爆发的状态。而2018年很有可能就是Service Mesh全面爆发的一年,它的目标其实就是一个:重新塑造整个微服务市场。

在今年十月份的时候,我在QCon做了一个演讲,叫“Service Mesh——下一代微服务”。这个口号十月份喊出来的时候,还是有蛮多反对的声音。有个挺有意思的事情,我一直当成玩笑来说。当时QCon在转我的演讲实录文章的时候,在我的标题后面,在“Service Mesh:下一代微服务”后面打了一个问号,那个问号是InfoQ的编辑加的。我的理解是,小编觉得如果这个标题由他们发出来,可能有InfoQ的印号。所以为了避嫌,在后面打了一个问号。

大概是在一个星期前,KubeConf刚刚召开,Service Mesh非常的火,而这个时候InfoQ做了一个事情,把之前QCon的视频处理好了发出来。视频的标题是”Service Mesh:下一代微服务”,后面再也没有问号了。这是很小的插曲,非常深刻的表明过去的几个月当中,Service Mesh技术快速的变化,以及大家对它认知的变化。

我们开始今天的主题,站队和选边。上面有一句话叫”新一轮的江湖厮杀又一次开始了”,有个小问题,为什么要说"又"字?大家觉得上一轮江湖厮杀是什么内容?我们来问一个问题,在大家的认知当中,IT领域的上一轮厮杀是谁对谁。

(备注: 现场互动,有同学指出,容器,K8S,Mesos,Swarm)

这场厮杀的结果如何?K8S笑到了最后。那现在开始,我们来看看新一轮的厮杀是什么样的结果。


Bouyant

让我们从 Buoyant 这家小公司开始。

Buoyant是一家名不见经传的小公司,但这家公司是Service Mesh的先驱,是Linkerd的公司,而Linkerd是业界第一个Service Mesh。这家是初创型的小公司,今年七月份刚拿到A轮的一千万美元融资,开发团队不到20人,我在他网站主页数了一下也就17、18个左右的样子。

创始人是两个前Twitter的基础设施工程师,CEO是William Morgan。因为融资的关系,A轮融了1000万美元,最近也在招兵买马,招了一些高手进来。这里我们单独列了一位大牛,如果大家有印象的话,他曾写了一篇文章叫《模式:Service Mesh》,那篇文章基本上是目前介绍Service Mesh最好的、最经典的文章之一。大家可以看到,中间这位同学,William,这个人是它的CEO,Service Mesh全球第一个布道师: 他定义了Service Mesh,开始在全球讲Service Mesh。右图这张图是在2016年九月份第一次使用这个词汇。

但是,先驱有个问题:先驱和先烈只差一个字。一个常见的说法是:领先一步是先驱,领先两步,可能就变成先烈了。

就在Linkerd和William还在布道的时候,让业界慢慢开始接受Service Mesh这个概念,发现后来,有一堆新人出来了。

新的Service Mesh,在2017年,噌噌噌的来了。第一个,Envoy,这是业界第二个Service Mesh,在今年九月份的时候,同样加入了CNCF。

Envoy还好,基本上属于同质竞争,就是大家都在一个层次上,至少还有的打。

但很不幸,Istio杀出来了——大家可以看到Istio发布的时间点还是很快的,5月,10月,12月,就0.3了。Isito从架构,从功能上,比Linkerd和Envoy是上了一个层次。这个就头疼了,属于下一代打这一代。按照《三体》的说法,这属于降维攻击:只要对手完成,基本上就是等死。

我们来看一下整个的时间表:Linkerd加入CNCF是一月,这是一个很关键点的,当时CNCF在类别上写了一个Service Mesh。当时看到这个词时还不知道Service Mesh是什么概念。但它对Linkerd特别重要,因为业界已经接受了Service Mesh的概念,且又被CNCF认可了。

而后Linkerd1.0发布不到一个月,Istio就出来了,紧接着Envoy在九月份杀入CNCF。时间点上可以看到非常近,可谓是“江山代有才人出,各领风骚几个月”。整个2017年,Service Mesh的风头就是以一个月一个月的方式在做变化。现在我们可以看到事情有多残酷:前脚还很悠闲的做先驱,做布道,眼看就要变成先烈了。

Istio缘何这么强?主要是三位创造Istio的大佬,Google、IBM、另外一位 Lyft在前面两位这里算是小的。所以对于Linkerd来说会有种一时瑜亮的感叹:Linkerd刚出来很强,跨了一个时代的感觉,但脚还没站稳,就让人给揍了回来。

而Istio这个产品不仅后台过硬,社区支持够强,人也够多,能力也足,最重要的是它还特别努力。Isito在今年2700多个Commits,数量远远超过了Linkerd,可以说在产品上,Istio做的非常努力。而在人手上,整个Linkerd公司才不到20人,Istio的Working Groups的Leader就已经23位了,怎么玩?这就有一个很要命的问题:对方不仅强,还很努力。


接下来有一个关键的问题:到底怎么办?

现在Google带着Istio出来了,还叫上了一堆IBM,Lyft这样的助手,以及社区。对于Linkerd以及它的Service Mesh类的产品,就要面对一个问题:到底是想跪着生?还是站着死?

如果你有勇气和它对抗,那你站着,但若面对的是这样的竞争对手,胜算在哪里?如果没有勇气直面,接下来该怎么办?出路在哪里?这个问题困扰了我一段时间,因为我们数人云也在考虑要不要做一个Service Mesh的产品,这个问题细想起来,真的会很纠结。



Google

我们来看看Istio身后的Google。

Google是我个人是最崇拜的公司,没有之一,它做了很多让我感觉是真的在推动人类文明往前走的事情,比如它前段时间发表的论文。

我们回到容器、云的领域,Google非常的强,可以说是“剑在手 问天下谁是英雄”。

左边,Kuberentes,屠龙宝刀已成,现在是“号令天下 莫敢不从”,整个领域都没人敢说不。

右边,Istio,现在还在磨砺,虽然还未成功,但有勇气跟它竞争的人已经不多了。

这是目前我个人的判断,因为个人原因我比较关注这几个点。

GCP是Google云平台的缩写,下面是四个旗下的产品:

其中Kuberentes很熟悉了,它已经搞定整个容器,而且是Done的状态,基本上已经是事实标准了。

Isito按照我的理解是准备出来搞定下一代微服务的,仍在路上,但等成熟稳定后,基本上很难有强劲的竞争对手。

后面两个可能相对偏门一点,但对我比较特殊,我可能是国内第一批对gRPC进行研究的。如果大家对gRPC这个技术有所了解,可能会知道我的名字。这个东西基本上是搞定下一代的RPC通讯了,大家没有知觉的情况下,下一代的RPC基本上在它那里了。目前这个市场用的不是特别多,仍在培育当中,但也没有强劲的竞争对手。

而HTTP/2现在已经是W3C的标准,搞定了下一代HTTP:大家还停留在HTTP1.1上争夺的时候,Google已经偷偷摸摸的直接把HTTP/2搞定了。

这四个产品加在一起的有什么感觉?我的想法是GCP在下一盘很大的棋,若将它们串联在一起,接下来在容器、微服务、通信这个领域,都在Google的范围之内——它已经把路完全铺好了。

底层操作系统,中间的容器,可能有一部分的PaaS系统,类似GCP这种,都是从Kuberentes这边走,已经搞定。服务间各种通讯,通讯机制如HTTP/2以及gRPC,这两个已经是事实标准了,搞定。现在全力以赴做微服务,Istio,准备继续往上做。

大家注意这张图,Google现在是从底层一步步向上做,趋势非常明显。我们现在回头看这个布局。现在我不敢确定说Google是否真的在下这么一盘棋,但若真的有人在刻意下棋,只能说明这个棋手的能力太强了。现在要跟Google去争,如何去争?直接帮你将后面的东西全部铺好了。

当然,这里还有一个小小的悬念,如果一两年之内,Istio有能力将微服务这一块完全搞定,那么它的下一个目标会是什么?不出意外的话Google会继续往上走,继续往业务上走,但会是什么现在还想不明白。

这里留一个悬念,两年之后大家再来看这个图,就可以知道这个问好是什么。

OK,是不是有种阴谋论的感觉?

回到微服务,在Service Mesh这个领域,Google这一次没有直接自己单干,而是搞了一套Istio,然后这次找了IBM。这里面有一个象征意义的东西,Google其实是标准互联网典型代表,但IBM是传统企业,虽然也一直在往互联网上走,一直往这方面做,但企业形象还是偏重传统。他的目标用户也是偏向传统企业用户,它们的合作象征意义是非常大的。

上面我一直在推一个概念,我们现在这个世界,这个技术潮流,有一个很重要的趋势是:传统企业用户向互联网技术做转型,大家注意到这个趋势,会非常明显。如果你在互联网工作,是没什么感觉的。但是如果看传统企业用户,会发现他们现在的技术完全是往互联网这边走,往微服务、容器、敏捷走,现在基本上他们都开始陆陆续续放弃weblogic、EJB、ESB,这个趋势非常明显。

这样的一个合作很有意思。

Google在Istio之前是有一些项目的,当时做了一个Google Service Control,如果熟悉Envoy,会发现这个功能点和现在istio的功能点非常像。实际上当时的一个重要的事情是这样的,IBM的一个VP在Istio出来之后发表的一篇文章,意思是说Google和IBM各自在各自的领域做了一些事情,后来他们彼此间了解之后,发现相互之间是可以互补的,而且方向一致。所以做了很重要的一个决策:各自放弃吧,合起来一起做一个。刚好套上Service Mesh的概念,就这样一拍即合,搞定。

可以想象Google和IBM的影响力,一起合作是什么概念?我们可以看到Istio在社区里得到了非常积极的响应。这些东西是在0.1版本的时候就已经开始在响应了,0.1是在今年五月份。

这里面很重要的一个是Oracle。容器:K8S,这不出意外。微服务直接选Istio,这个有点出乎我意料。Serverless是直接收购了一个FN的项目。这里面很明确的是,他们的微服务就是Istio,这是它的战略决策。

Redhat就比较好理解,它一直跟Google和Kubernetes跟的很紧,所以它选择Istio完全可以理解。

反而是最后这一位,Pivotal,它的Cloud Foundry非常明确要支持Istio。但是这里面有点古怪的地方是,这家公司本身是好像有点跟Google对着干的感觉。

后面几家公司相对比较小一点,但是它们各自领域都是比较特殊的。但是这几家公司除了Ambassador时间不确认,剩下五家公司都是在0.1版本出来的,今年五月份出来,就明确要支持。

这也体现了Google在社区可怕的号召力:一个新的开源产品才发布0.1版本,别人就已经开始站队,这是什么概念。

左边这张图,大家应该看过了,前一段时间在网上非常火,因为这个代表今年KubeCon非常标志性的一个东西,就是Service Mesh在这次会议上非常火爆。2018年预测它会全面的爆发,至少这个技术会在大多数的领域会被人关注、使用、探索,不排除落地,如果它的release版本发布足够快。

Istio应该会在2018年发布,我还顺便问过0.3版本,按照它的说法,是已经接近了Production Ready。但是根据我们测试的结果,不行。这里面还有一些小障碍,可能0.4、0.5可能会,但是从目前看,差距不是特别远,但2018年这个产品肯定会发布的,具体是上半年还是下半年不好说。

 
IBM

再来看看IBM。

刚才说它有一个产品的,现在非常明确,这个产品已经停止演进。

现在的战略其实非常的明确,它自己的公有云改成基于Kubernetes,接下来会支持Istio,它的云服务商会推广。

而且听说已经在公有云上上线了,但是没有找到,不过很明显它接下来会直接在公有云上直接支持Istio。

这里面有一张图是Istio的Working Group,可以看到这个图上的leader,23位leader,基本上都是IBM和Google的人。而且这里面可以非常明确的看到一点,IBM在这个项目当中是属于深度参与的状态。它基本上和Google一对一了,基本上所有的团队都在,和Google平起平坐。目对于IBM来说也是投入非常大,也是非常重视的一个项目。

前面说到Istio有三位创始人,这里谈到两位,整个Working Group里只看到这两个公司,Lyft哪里去了?Lyft一直都没有出现。


Lyft


Lyft的贡献完全在Envoy代理,这张图是很经典的Istio架构的图,红色箭头对应的位置是Envoy,它是做底层的数据平面。Lyft所有的贡献都是集中在Envoy代理里面。其它的东西是Google和IBM在做,而这个地方是Lyft在做。

这里面有一些比较有意思的东西,有点阴谋论的感觉。

首先在Envoy这个角色上,它是扮演数据平面的角色。第二个是它的控制平面是通过API来跟数据平面交互,没有绑死,是一个明确的API。底层数据平面的具体实现和核心的控制平面是解耦的,是通过一个定义好的API来做这个约束。所以理论上有一个可能性,只要兼容这个API,Istio可以和任何一个数据平面集成。这是可以替换,当前默认集成是Envoy——这个地方有没有感觉到,似曾相识?

大家想一下K8S和Docker的关系,还有OCI规范,你会发现好像有这么回事。但是现在默认的是Envoy,但是这里面存在微妙的感觉,就是说它存在替换的可能性。有一些事情只要有可能,就有可能会发生,对不对?那会在什么情况下发生呢?

这个地方很有意思,Istio其实是给其他Service Mesh留了一条活路。Istio是来换代的,理论上它来了后,其他Service Mesh就死了,只有它能成,但是它还是留了一条活路。这个考虑,不太清楚,我个人的理解应该是“节约时间快速推出产品”,所以它刚刚出道的时候,选择了没有自己做数据平面而是集成。Istio出来时选择了集成Envoy,Envoy是c++。按照Google的习惯,做这种底层的东西,肯定是自己都做的。但是它选择集中精力去做控制平面,把数据平面给Envoy去做。所以这个地方,原配是Envoy,但是原配是原配,没有说一定要白头偕老。Linkerd就发现这个问题,只要努力就有机会,没有挖不动的墙角,只有不努力的小三。Linkerd就干了这个事情,他在1.2、1.3的版本当中,从半年前开始,他就开始做Istio的集成,努力的满足Google的API要求,往那边去走。这个兼容它一直在做,非常努力的在做,被我成为努力的小三。

有努力的小三,就意味着还有一个不努力的小三——nginmesh。今年大概九月份的时候,nginx突然宣布要搞出一个Service Mesh来。当时我个人很兴奋,当时它写了一篇文章,我就去翻译这些文档。文中说它要和Istio集成,当时以为有一场好戏看,两个小三开始打原配了。结果后来发现这个项目开源三个多月,它几乎没提交。非常的不努力,不知道发生了什么事情。

接下来,在看Istio的核心模块,控制面板上面有三个核心模块,上面这三个模块都是Google自己在做,唯独留了下面Sidecar。四个东西做三个,留一个,大家能想到什么成语吗?

围三阙一,又名叫“围师必阙”,这是孙子兵法里的一条,打仗的八个原则之一。它的意思是,如果你要全面合围敌人的话,有可能会让对方的指挥官定下拼死一搏的决心。反而你故意留一个缺口,对方就会在到底是逃跑还是死战之间摇摆不定,同时会使对方的军心和斗志涣散。

现在有没有这种感觉,四个东西故意留了一个,给其他Service Mesh一条活路。但是这有点阴谋论,我也不确定它们是不是真的这么玩。如果是真的,只能说Google的"心机"太可怕了。但是感觉上是这样的,因为对其它的Service Mesh而言,这个事情上就有选择。到底要不要跟Istio联手,到底要不要做这个小三。

这种事情因人而异,对不对?

对于Envoy和Lyft来说,好啊好啊,就像图中一样握手。女神说,你要不要来啊,来啊来啊,搞定。所有Envoy很开心,Lyft也很开心,Lyft直接把整个Envoy贡献出来了,整个团队干这个事。

但是有一个问题,对于右边这个图,对于Linkerd来说,这是荣幸吗?右边这个图是韩信当年的跨下之辱。同样是跟Istio联手,对于大家的选择是完全不一样的,为什么?你的屁股决定了你的脑袋。

这家公司是一家初创型的公司,现在才十几个人。它是一家技术型的创业公司,它不是Lyft。Lyft是做租车的,Envoy是它的一个开源项目,它不靠这个挣钱的,它把Envoy白送给Google,它有损失吗?它打车的市场会因为这个原因损失百分之一的份额吗?没有任何问题,所以它很开心,没问题。

但是对于Buoyant这家公司来说,这是命根子,它创业的根基就在这里,它能把自己的根基扔出去吗?所以说,彼之蜜糖,吾之砒霜。Lyft扔可以,Lyft可以扔掉Envoy,白送都行啊,我还贴个团队给你做,没问题。但是Linkerd能这么干吗?Linkerd如果只是跟Istio做集成,如果它的未来只是做集成,它还是以小三的身份,它都不是原配,那还有什么前途可言。

所以这个事情,后面一直困扰我,我看到它1.2版本做Istio集成之后,我就没想明白这个事。一直到后来……

这里有一个很有意思的典故,三国中曹操大军压境,赤壁大战之前,当时孙权犹豫到底是投降还是反抗。鲁肃当时劝孙权,说我们可以投降,没问题,我们投降还是可以继续荣华富贵,将军迎操,欲安所归?你孙权投降曹操,你想怎么样,你还能是头?

道理是一样的,现在是Istio大军压境,Linkerd考虑到底是战还是降。关键是你降了之后你能干什么?所以这个地方一直困扰我,因为我看到Linkerd一直在投降,死命的在兼容,死命的做努力的小三,对方还不理你。我看到Istio从来没有提过Linkerd,Linkerd那边死命的说我要跟Istio集成,标准的热脸贴冷屁股的感觉。

回到刚才那个问题,到底是想跪着生还是想站着死?因为站着真的会死,如果没有这个勇气,出路在哪里。很明显跟Istio做集成,这是一个非常温柔的陷阱,进去了,差不多就死在里面了,仅此而已。能做的空间很有限。它直接把天花板搁在那里了,剩下的东西它都做了,你只能做到这里而已,没有空间可言。

如果你看到这条死路,你就只能硬挺着跟它干一仗,但胜算在哪里?

如果没有想好这个问题,如果没有想好有什么机会,千万别跟Istio争了。

但是很明显,有个家伙想好了,这是非常令人惊讶的。至少对于我而言,当我第一次看到这个产品的时候,感觉突然兴奋了一把:真的有人搞出来了?

Conduit这个产品,是Buoyant的绝地大反击。在12月5号的时候,它突然发布了这个产品。先看看这个产品是什么?

首先它是从头开始的,除了还是这个公司之外,它跟Linkerd没有一毛钱关系。

然后它的目标是成为最快、最轻、最简单、最安全的Service Mesh。最简单不好说,因为大家都刚开始,最安全我也没有测过,但是最轻和最快这两个词是比较容易做体验的。

它为了达到这两个目标,它使用了Rust这个编程语言。这个语言是很偏门的语言。

(注:现场互动环节,听过Rust同学请举手。只有5个人)

这个语言是个非常偏门的语言,但是它最大的好处是性能超好,资源占用超级低,蛮梦幻的语言。除了有代码写的方式有点反人类之外,我之前说要学这个Rust的时候,他们说告诉我说你小心,反人类哦。这个语言好处是你真的把它吃透了,它应该是目前最适合拿来做proxy的一个语言,资源消耗非常低。

Conduit还有一个很重要的事情,就是它吸收了过去的经验。就是过去18个月,在Linkerd上沉淀了各种真实的经验。因为Linkerd是生产级的,而且Linkerd很多企业直接上生产,这一点非常重要。

可以看到这个Rust的过人之处。

后面三条数据不直白,但是第一条太明显了,Conduit代理用不到十兆实际内存,P99在分毫秒之内,这个可能不是太敏感,但是十兆应用太敏感了。proxy是跟每一个应用都直接对应启动起来,要启动N份,这个资源消耗其实是蛮大的。

这个时候的关键点就在于2018年,2018年Service Mesh这个市场几乎是蛮荒时代,除了Linkerd和Envoy有一小部分企业用户之外。大部分人都在等,等一个足够让大家放心的产品再用,市场基本上是空白的,但是要拿到这个市场有一个非常重要的事情:一定要用自己的实际表现说服大家,让大家觉得Service Mesh可以落地,可以做商用,可以上线。

这点很重要!

2018年最重要的事情就是:谁能第一个达到这个目标,让大家敢用,敢在生产上用。

大家如果有注意的话,会注意到,Istio在发自己的release note的时候,都写了一句话:不要用,不要用,不要用……很搞笑的,你能想象吗?他自己发的release note,特别注明不要用它。

在这里面Istio基本上就算一个贵族了,背景非常深厚,自己能力也很出众,盟友众多。基本上可以看到Istio只要它自己不犯错,它这个地位非常难撼动。现在的唯一的悬念就是说它的1.0或者是它的Production Ready版本什么时候发布,它如果今天马上发布的话,这个市场基本上没有什么悬念可言。它如果拖到明年、后年发布,那就没它什么事了。拖到年底,如果Conduit够快,也很难说。

所以这里面有非常大的悬念,谁先搞定第一个生产可用的版本。

Buoyant算是江湖草莽吧,一个小公司但是一身傲骨。之前看它俯低做小伺候Istio的时候感觉还很奇怪,但是突然之间把Conduit拿出来。前面那个行为现在感觉有点变质了,有点像当年勾践卧薪尝胆的感觉,卧薪尝胆,然后突然间憋出一个大招来了。

Conduit还是有一些优势的,首先这家公司因为Linkerd的原因,它一直是摸爬滚打在Service Mesh的第一线,它是少有的几个真正在线上跑过的Service Mesh,这一点是没人比的过的。它是最懂Service Mesh的,这是它最大的优势。人也不多,但是不多的几个人里面,有几个真的是高手,这也是一个优势。因为人不多,所以只能做简单一点,做的接地气一点,实用一点,基本上是可以预料的。但是现在打一个问号,我是预判的,实际是不是这样,还要看它产品真实表现。

最近也看到有人给了Conduit一个标签,叫做穷人的Service Mesh,因为它的资源消耗非常低,也比较简单,所以有这么一个标签。但是究竟是不是,接下来2018年,我们能看到。

右边写了一个问号,这么大的一个市场,会不会有新的竞争者进来,这个不好说,说不定哪天就有人蹦进来了。但是跟Istio集成的就不算,没有什么意思,如果进来只是为了做一个小三就没意思了。对于Service Mesh是一开局,开局就是红海,左边这两位已经在刀对刀的在拼杀了,所以如果是庸人,只能进来做个小三,打个酱油,基本上可以不用进来了。




Service Mesh 大浪潮下的应对


我们将整个Service Mesh的大潮,和市场,过了一遍。接下来我们看一下这个大潮下的应对。

首先这个东西是个革命,革命就是两个问题:

第一谁革命,大家都知道Service Mesh要革命。

第二个问题是革谁的命,这是比较有意思的。

Service Mesh号称下一代的微服务,下一代的微服务概念是什么,当前的微服务是谁?大家很清楚,当前主流微服务框架是左边Spring Cloud,基本上首选。现在刀架在脖子上,Pivotal这个公司会怎么样,是会顺应潮流,说那也好,我们也搞Service Mesh吧。搞个spring cloud on service mesh,或者干脆砍掉整个Spring Cloud,说觉得Spring Cloud没意思,直接spring on service mesh。

其实后者我挺喜欢的。Spring Boot是很清爽的东西,觉得它的设计,实现,包括资源消耗是很好的。如果Spring Boot能跑到Service Mesh上,真的是很清爽的搭配。但是,这个毕竟只是我的主意,也许他们不为所动,说不定他们就不玩Service Mesh。

为什么会有这个想法,因为去年曾经给它们提议,让他们支持RPC,被拒绝了。Spring Cloud说我喜欢rest。就是这么固执,不好说它最后做什么决策,2018年我们可以看,它也许有动作,也许没动作。

OK,这个地方革命的对象非常明确,就是以新一代微服务的身份,把整个微服务这条路走过去:走别人的路,让别人无路可走。只要它把微服务全部搞定了,自然就没有上一代啥事了。

Service Mesh实际上有一些天然的盟友,有一种类型的微服务框架它是比较容易向Service mesh靠拢的,即原来就是Sidecar模式,或者它有比较好的意愿可以快速转成Sidecar。

可以看到今年的全球架构师峰会上,华为在讲它的那个Mesh。它们原来有一个Golang sdk,最近好像是被我勾引了一把,他们快速堆出了一个Go版的Service Mesh出来,现在看还挺成功的。

还有Motan,这个我就不细说了,一会另外一位讲师周晶同学会做详细的分享。

多说一下,其实很多企业用户,有没有开源的产品。在某些企业里,也有一些典型的服务化框架,比如说唯品会的OSP框架,它就是一个很典型的。内部一个Sidecar模式在跑。对它而言,如果想向Service Mesh靠拢是非常简单的,因为本身和Service Mesh的方式非常相似。但是这里面有一个小悬念,它现在是基于Java的,那未来是不是还会基于Java还是把Java改掉,这就是一个悬念了。往后面看,看白衣到底是改不改。

现在来看谁会拥抱Service Mesh?咱们只谈国内,不谈国外。

在国内有一大批初创企业,典型的就是某某云,包括我们数人云。这些企业大部分是做容器、云、或者大数据。有一个共同点:单只做云这一块东西稍微有点薄,而且离最终的业务应用有点远。所以,向Google看齐,向上做,这是一条出路。其实很多公司都有这样的共识,只是多少的问题,有些人可能选,有些人可能不选。

但是如果选择向上做,那微服务基本上是一个很自然的选择。业界也是公认的:微服务和容器的搭配非常的合适。但是选微服务是不是选择Service Mesh,这是另外的事情。可以选择Spring Cloud,也可以选择Dubbo。

我们数人云算是率先走出第一步的。一方面会继续在Spring Cloud基础上提供稳定的服务,另外一个会积极的落地Service Mesh的方案,这是我们接下来会做的事情,我们走了第一步了。现在不知道2018年还会有谁跟进,我们预计肯定会有初创的公司跟我们一起走这条路的。现在的悬念就是说谁是第二个,第三个,会有多少个。

还有一些就是所谓的公有云的大鳄,它提供公有云的服务。Service Mesh对于公有云而言,这是一个神兵利器,这个暂时只有我说这个话,相信时间越久就会有更多的认可。因为一旦Service Mesh成熟,它会变成公有云的一个杀手锏的特性,到时候有没有Service Mesh的功能,会是公有云非常重要的标识。这一点在2018年或者是2019年会变成一个大概率的事件,大家可以等着来挖坟,万一到时候Service Mesh没成功,那就打我脸好了。暂时这是我的一个判断。

我们现在能看到的是,华为的公有云已经抢先出击了,提供了微服务的服务,它们是第一家。现有的公有云里华为现在动作最快,既提供传统架构的ServiceComb,也有基于Service Mesh的CSE mesher的。

华为第一家出来没问题,问题是后面还有没有跟进,阿里云会不会跟,腾讯会不会跟,这个应该是2018年小小悬念:他们会不会跟?

然后神仙打架,会殃及池鱼。

一旦Service Mesh成为主流,有一些领域会受到一些冲击,典型的像反向代理如Nginx、HAproxy,还有像API gateway。因为如果Service Mesh成主流之后,没必要用反向代理了,直接Service Mesh就好。也包括API gateway,有一部分功能其实Istio会往上面去做。这两个领域会有一些冲击。

我们看到Nginx曾经喊着说自己做Service Mesh,但是也没有下文。其它的像Zuul、Kong这些,之前了解到有一个朋友说Kong曾经也在想,要不要做Service Mesh。但是想了半天,最后没下决心,估计也卡在我刚才说的问题。大家还记得吧?如果要做的话,怎么干掉Google,如果没有信心干掉它的话,做它干什么?

但是这两个领域,如果有人站出来,也是个好事,可能会多一个选择。

我们今天的内容到此就结束了。

最后,“2018, The Year of Service Mesh”,我们期待这样一个时刻的到来。

今天的演讲到此结束,非常感谢大家。 查看全部
敖小剑/数人云资深架构师

十五年软件开发经验,微服务专家,专注于基础架构,Cloud Native拥护者,敏捷实践者。曾在亚信,爱立信,唯品会和PPmoney任职。

Service Mesh 时代下的选边与战队

在2017年,Service Mesh技术在快速成长。我们看到在年中的时候,Istio非常霸气的登场。如果大家有关注Service Mesh这个技术,就会知道大概10天前,Conduit这个产品突然发布了。实际上在这过去的一年当中,Service Mesh历经了非常多的事情。在经过2017年的酝酿过程后,Service Mesh技术接近一个爆发的状态。而2018年很有可能就是Service Mesh全面爆发的一年,它的目标其实就是一个:重新塑造整个微服务市场。

在今年十月份的时候,我在QCon做了一个演讲,叫“Service Mesh——下一代微服务”。这个口号十月份喊出来的时候,还是有蛮多反对的声音。有个挺有意思的事情,我一直当成玩笑来说。当时QCon在转我的演讲实录文章的时候,在我的标题后面,在“Service Mesh:下一代微服务”后面打了一个问号,那个问号是InfoQ的编辑加的。我的理解是,小编觉得如果这个标题由他们发出来,可能有InfoQ的印号。所以为了避嫌,在后面打了一个问号。

大概是在一个星期前,KubeConf刚刚召开,Service Mesh非常的火,而这个时候InfoQ做了一个事情,把之前QCon的视频处理好了发出来。视频的标题是”Service Mesh:下一代微服务”,后面再也没有问号了。这是很小的插曲,非常深刻的表明过去的几个月当中,Service Mesh技术快速的变化,以及大家对它认知的变化。

我们开始今天的主题,站队和选边。上面有一句话叫”新一轮的江湖厮杀又一次开始了”,有个小问题,为什么要说"又"字?大家觉得上一轮江湖厮杀是什么内容?我们来问一个问题,在大家的认知当中,IT领域的上一轮厮杀是谁对谁。

(备注: 现场互动,有同学指出,容器,K8S,Mesos,Swarm)

这场厮杀的结果如何?K8S笑到了最后。那现在开始,我们来看看新一轮的厮杀是什么样的结果。


Bouyant

让我们从 Buoyant 这家小公司开始。

Buoyant是一家名不见经传的小公司,但这家公司是Service Mesh的先驱,是Linkerd的公司,而Linkerd是业界第一个Service Mesh。这家是初创型的小公司,今年七月份刚拿到A轮的一千万美元融资,开发团队不到20人,我在他网站主页数了一下也就17、18个左右的样子。

创始人是两个前Twitter的基础设施工程师,CEO是William Morgan。因为融资的关系,A轮融了1000万美元,最近也在招兵买马,招了一些高手进来。这里我们单独列了一位大牛,如果大家有印象的话,他曾写了一篇文章叫《模式:Service Mesh》,那篇文章基本上是目前介绍Service Mesh最好的、最经典的文章之一。大家可以看到,中间这位同学,William,这个人是它的CEO,Service Mesh全球第一个布道师: 他定义了Service Mesh,开始在全球讲Service Mesh。右图这张图是在2016年九月份第一次使用这个词汇。

但是,先驱有个问题:先驱和先烈只差一个字。一个常见的说法是:领先一步是先驱,领先两步,可能就变成先烈了。

就在Linkerd和William还在布道的时候,让业界慢慢开始接受Service Mesh这个概念,发现后来,有一堆新人出来了。

新的Service Mesh,在2017年,噌噌噌的来了。第一个,Envoy,这是业界第二个Service Mesh,在今年九月份的时候,同样加入了CNCF。

Envoy还好,基本上属于同质竞争,就是大家都在一个层次上,至少还有的打。

但很不幸,Istio杀出来了——大家可以看到Istio发布的时间点还是很快的,5月,10月,12月,就0.3了。Isito从架构,从功能上,比Linkerd和Envoy是上了一个层次。这个就头疼了,属于下一代打这一代。按照《三体》的说法,这属于降维攻击:只要对手完成,基本上就是等死。

我们来看一下整个的时间表:Linkerd加入CNCF是一月,这是一个很关键点的,当时CNCF在类别上写了一个Service Mesh。当时看到这个词时还不知道Service Mesh是什么概念。但它对Linkerd特别重要,因为业界已经接受了Service Mesh的概念,且又被CNCF认可了。

而后Linkerd1.0发布不到一个月,Istio就出来了,紧接着Envoy在九月份杀入CNCF。时间点上可以看到非常近,可谓是“江山代有才人出,各领风骚几个月”。整个2017年,Service Mesh的风头就是以一个月一个月的方式在做变化。现在我们可以看到事情有多残酷:前脚还很悠闲的做先驱,做布道,眼看就要变成先烈了。

Istio缘何这么强?主要是三位创造Istio的大佬,Google、IBM、另外一位 Lyft在前面两位这里算是小的。所以对于Linkerd来说会有种一时瑜亮的感叹:Linkerd刚出来很强,跨了一个时代的感觉,但脚还没站稳,就让人给揍了回来。

而Istio这个产品不仅后台过硬,社区支持够强,人也够多,能力也足,最重要的是它还特别努力。Isito在今年2700多个Commits,数量远远超过了Linkerd,可以说在产品上,Istio做的非常努力。而在人手上,整个Linkerd公司才不到20人,Istio的Working Groups的Leader就已经23位了,怎么玩?这就有一个很要命的问题:对方不仅强,还很努力。


接下来有一个关键的问题:到底怎么办?

现在Google带着Istio出来了,还叫上了一堆IBM,Lyft这样的助手,以及社区。对于Linkerd以及它的Service Mesh类的产品,就要面对一个问题:到底是想跪着生?还是站着死?

如果你有勇气和它对抗,那你站着,但若面对的是这样的竞争对手,胜算在哪里?如果没有勇气直面,接下来该怎么办?出路在哪里?这个问题困扰了我一段时间,因为我们数人云也在考虑要不要做一个Service Mesh的产品,这个问题细想起来,真的会很纠结。



Google

我们来看看Istio身后的Google。

Google是我个人是最崇拜的公司,没有之一,它做了很多让我感觉是真的在推动人类文明往前走的事情,比如它前段时间发表的论文。

我们回到容器、云的领域,Google非常的强,可以说是“剑在手 问天下谁是英雄”。

左边,Kuberentes,屠龙宝刀已成,现在是“号令天下 莫敢不从”,整个领域都没人敢说不。

右边,Istio,现在还在磨砺,虽然还未成功,但有勇气跟它竞争的人已经不多了。

这是目前我个人的判断,因为个人原因我比较关注这几个点。

GCP是Google云平台的缩写,下面是四个旗下的产品:

其中Kuberentes很熟悉了,它已经搞定整个容器,而且是Done的状态,基本上已经是事实标准了。

Isito按照我的理解是准备出来搞定下一代微服务的,仍在路上,但等成熟稳定后,基本上很难有强劲的竞争对手。

后面两个可能相对偏门一点,但对我比较特殊,我可能是国内第一批对gRPC进行研究的。如果大家对gRPC这个技术有所了解,可能会知道我的名字。这个东西基本上是搞定下一代的RPC通讯了,大家没有知觉的情况下,下一代的RPC基本上在它那里了。目前这个市场用的不是特别多,仍在培育当中,但也没有强劲的竞争对手。

而HTTP/2现在已经是W3C的标准,搞定了下一代HTTP:大家还停留在HTTP1.1上争夺的时候,Google已经偷偷摸摸的直接把HTTP/2搞定了。

这四个产品加在一起的有什么感觉?我的想法是GCP在下一盘很大的棋,若将它们串联在一起,接下来在容器、微服务、通信这个领域,都在Google的范围之内——它已经把路完全铺好了。

底层操作系统,中间的容器,可能有一部分的PaaS系统,类似GCP这种,都是从Kuberentes这边走,已经搞定。服务间各种通讯,通讯机制如HTTP/2以及gRPC,这两个已经是事实标准了,搞定。现在全力以赴做微服务,Istio,准备继续往上做。

大家注意这张图,Google现在是从底层一步步向上做,趋势非常明显。我们现在回头看这个布局。现在我不敢确定说Google是否真的在下这么一盘棋,但若真的有人在刻意下棋,只能说明这个棋手的能力太强了。现在要跟Google去争,如何去争?直接帮你将后面的东西全部铺好了。

当然,这里还有一个小小的悬念,如果一两年之内,Istio有能力将微服务这一块完全搞定,那么它的下一个目标会是什么?不出意外的话Google会继续往上走,继续往业务上走,但会是什么现在还想不明白。

这里留一个悬念,两年之后大家再来看这个图,就可以知道这个问好是什么。

OK,是不是有种阴谋论的感觉?

回到微服务,在Service Mesh这个领域,Google这一次没有直接自己单干,而是搞了一套Istio,然后这次找了IBM。这里面有一个象征意义的东西,Google其实是标准互联网典型代表,但IBM是传统企业,虽然也一直在往互联网上走,一直往这方面做,但企业形象还是偏重传统。他的目标用户也是偏向传统企业用户,它们的合作象征意义是非常大的。

上面我一直在推一个概念,我们现在这个世界,这个技术潮流,有一个很重要的趋势是:传统企业用户向互联网技术做转型,大家注意到这个趋势,会非常明显。如果你在互联网工作,是没什么感觉的。但是如果看传统企业用户,会发现他们现在的技术完全是往互联网这边走,往微服务、容器、敏捷走,现在基本上他们都开始陆陆续续放弃weblogic、EJB、ESB,这个趋势非常明显。

这样的一个合作很有意思。

Google在Istio之前是有一些项目的,当时做了一个Google Service Control,如果熟悉Envoy,会发现这个功能点和现在istio的功能点非常像。实际上当时的一个重要的事情是这样的,IBM的一个VP在Istio出来之后发表的一篇文章,意思是说Google和IBM各自在各自的领域做了一些事情,后来他们彼此间了解之后,发现相互之间是可以互补的,而且方向一致。所以做了很重要的一个决策:各自放弃吧,合起来一起做一个。刚好套上Service Mesh的概念,就这样一拍即合,搞定。

可以想象Google和IBM的影响力,一起合作是什么概念?我们可以看到Istio在社区里得到了非常积极的响应。这些东西是在0.1版本的时候就已经开始在响应了,0.1是在今年五月份。

这里面很重要的一个是Oracle。容器:K8S,这不出意外。微服务直接选Istio,这个有点出乎我意料。Serverless是直接收购了一个FN的项目。这里面很明确的是,他们的微服务就是Istio,这是它的战略决策。

Redhat就比较好理解,它一直跟Google和Kubernetes跟的很紧,所以它选择Istio完全可以理解。

反而是最后这一位,Pivotal,它的Cloud Foundry非常明确要支持Istio。但是这里面有点古怪的地方是,这家公司本身是好像有点跟Google对着干的感觉。

后面几家公司相对比较小一点,但是它们各自领域都是比较特殊的。但是这几家公司除了Ambassador时间不确认,剩下五家公司都是在0.1版本出来的,今年五月份出来,就明确要支持。

这也体现了Google在社区可怕的号召力:一个新的开源产品才发布0.1版本,别人就已经开始站队,这是什么概念。

左边这张图,大家应该看过了,前一段时间在网上非常火,因为这个代表今年KubeCon非常标志性的一个东西,就是Service Mesh在这次会议上非常火爆。2018年预测它会全面的爆发,至少这个技术会在大多数的领域会被人关注、使用、探索,不排除落地,如果它的release版本发布足够快。

Istio应该会在2018年发布,我还顺便问过0.3版本,按照它的说法,是已经接近了Production Ready。但是根据我们测试的结果,不行。这里面还有一些小障碍,可能0.4、0.5可能会,但是从目前看,差距不是特别远,但2018年这个产品肯定会发布的,具体是上半年还是下半年不好说。

 
IBM

再来看看IBM。

刚才说它有一个产品的,现在非常明确,这个产品已经停止演进。

现在的战略其实非常的明确,它自己的公有云改成基于Kubernetes,接下来会支持Istio,它的云服务商会推广。

而且听说已经在公有云上上线了,但是没有找到,不过很明显它接下来会直接在公有云上直接支持Istio。

这里面有一张图是Istio的Working Group,可以看到这个图上的leader,23位leader,基本上都是IBM和Google的人。而且这里面可以非常明确的看到一点,IBM在这个项目当中是属于深度参与的状态。它基本上和Google一对一了,基本上所有的团队都在,和Google平起平坐。目对于IBM来说也是投入非常大,也是非常重视的一个项目。

前面说到Istio有三位创始人,这里谈到两位,整个Working Group里只看到这两个公司,Lyft哪里去了?Lyft一直都没有出现。


Lyft


Lyft的贡献完全在Envoy代理,这张图是很经典的Istio架构的图,红色箭头对应的位置是Envoy,它是做底层的数据平面。Lyft所有的贡献都是集中在Envoy代理里面。其它的东西是Google和IBM在做,而这个地方是Lyft在做。

这里面有一些比较有意思的东西,有点阴谋论的感觉。

首先在Envoy这个角色上,它是扮演数据平面的角色。第二个是它的控制平面是通过API来跟数据平面交互,没有绑死,是一个明确的API。底层数据平面的具体实现和核心的控制平面是解耦的,是通过一个定义好的API来做这个约束。所以理论上有一个可能性,只要兼容这个API,Istio可以和任何一个数据平面集成。这是可以替换,当前默认集成是Envoy——这个地方有没有感觉到,似曾相识?

大家想一下K8S和Docker的关系,还有OCI规范,你会发现好像有这么回事。但是现在默认的是Envoy,但是这里面存在微妙的感觉,就是说它存在替换的可能性。有一些事情只要有可能,就有可能会发生,对不对?那会在什么情况下发生呢?

这个地方很有意思,Istio其实是给其他Service Mesh留了一条活路。Istio是来换代的,理论上它来了后,其他Service Mesh就死了,只有它能成,但是它还是留了一条活路。这个考虑,不太清楚,我个人的理解应该是“节约时间快速推出产品”,所以它刚刚出道的时候,选择了没有自己做数据平面而是集成。Istio出来时选择了集成Envoy,Envoy是c++。按照Google的习惯,做这种底层的东西,肯定是自己都做的。但是它选择集中精力去做控制平面,把数据平面给Envoy去做。所以这个地方,原配是Envoy,但是原配是原配,没有说一定要白头偕老。Linkerd就发现这个问题,只要努力就有机会,没有挖不动的墙角,只有不努力的小三。Linkerd就干了这个事情,他在1.2、1.3的版本当中,从半年前开始,他就开始做Istio的集成,努力的满足Google的API要求,往那边去走。这个兼容它一直在做,非常努力的在做,被我成为努力的小三。

有努力的小三,就意味着还有一个不努力的小三——nginmesh。今年大概九月份的时候,nginx突然宣布要搞出一个Service Mesh来。当时我个人很兴奋,当时它写了一篇文章,我就去翻译这些文档。文中说它要和Istio集成,当时以为有一场好戏看,两个小三开始打原配了。结果后来发现这个项目开源三个多月,它几乎没提交。非常的不努力,不知道发生了什么事情。

接下来,在看Istio的核心模块,控制面板上面有三个核心模块,上面这三个模块都是Google自己在做,唯独留了下面Sidecar。四个东西做三个,留一个,大家能想到什么成语吗?

围三阙一,又名叫“围师必阙”,这是孙子兵法里的一条,打仗的八个原则之一。它的意思是,如果你要全面合围敌人的话,有可能会让对方的指挥官定下拼死一搏的决心。反而你故意留一个缺口,对方就会在到底是逃跑还是死战之间摇摆不定,同时会使对方的军心和斗志涣散。

现在有没有这种感觉,四个东西故意留了一个,给其他Service Mesh一条活路。但是这有点阴谋论,我也不确定它们是不是真的这么玩。如果是真的,只能说Google的"心机"太可怕了。但是感觉上是这样的,因为对其它的Service Mesh而言,这个事情上就有选择。到底要不要跟Istio联手,到底要不要做这个小三。

这种事情因人而异,对不对?

对于Envoy和Lyft来说,好啊好啊,就像图中一样握手。女神说,你要不要来啊,来啊来啊,搞定。所有Envoy很开心,Lyft也很开心,Lyft直接把整个Envoy贡献出来了,整个团队干这个事。

但是有一个问题,对于右边这个图,对于Linkerd来说,这是荣幸吗?右边这个图是韩信当年的跨下之辱。同样是跟Istio联手,对于大家的选择是完全不一样的,为什么?你的屁股决定了你的脑袋。

这家公司是一家初创型的公司,现在才十几个人。它是一家技术型的创业公司,它不是Lyft。Lyft是做租车的,Envoy是它的一个开源项目,它不靠这个挣钱的,它把Envoy白送给Google,它有损失吗?它打车的市场会因为这个原因损失百分之一的份额吗?没有任何问题,所以它很开心,没问题。

但是对于Buoyant这家公司来说,这是命根子,它创业的根基就在这里,它能把自己的根基扔出去吗?所以说,彼之蜜糖,吾之砒霜。Lyft扔可以,Lyft可以扔掉Envoy,白送都行啊,我还贴个团队给你做,没问题。但是Linkerd能这么干吗?Linkerd如果只是跟Istio做集成,如果它的未来只是做集成,它还是以小三的身份,它都不是原配,那还有什么前途可言。

所以这个事情,后面一直困扰我,我看到它1.2版本做Istio集成之后,我就没想明白这个事。一直到后来……

这里有一个很有意思的典故,三国中曹操大军压境,赤壁大战之前,当时孙权犹豫到底是投降还是反抗。鲁肃当时劝孙权,说我们可以投降,没问题,我们投降还是可以继续荣华富贵,将军迎操,欲安所归?你孙权投降曹操,你想怎么样,你还能是头?

道理是一样的,现在是Istio大军压境,Linkerd考虑到底是战还是降。关键是你降了之后你能干什么?所以这个地方一直困扰我,因为我看到Linkerd一直在投降,死命的在兼容,死命的做努力的小三,对方还不理你。我看到Istio从来没有提过Linkerd,Linkerd那边死命的说我要跟Istio集成,标准的热脸贴冷屁股的感觉。

回到刚才那个问题,到底是想跪着生还是想站着死?因为站着真的会死,如果没有这个勇气,出路在哪里。很明显跟Istio做集成,这是一个非常温柔的陷阱,进去了,差不多就死在里面了,仅此而已。能做的空间很有限。它直接把天花板搁在那里了,剩下的东西它都做了,你只能做到这里而已,没有空间可言。

如果你看到这条死路,你就只能硬挺着跟它干一仗,但胜算在哪里?

如果没有想好这个问题,如果没有想好有什么机会,千万别跟Istio争了。

但是很明显,有个家伙想好了,这是非常令人惊讶的。至少对于我而言,当我第一次看到这个产品的时候,感觉突然兴奋了一把:真的有人搞出来了?

Conduit这个产品,是Buoyant的绝地大反击。在12月5号的时候,它突然发布了这个产品。先看看这个产品是什么?

首先它是从头开始的,除了还是这个公司之外,它跟Linkerd没有一毛钱关系。

然后它的目标是成为最快、最轻、最简单、最安全的Service Mesh。最简单不好说,因为大家都刚开始,最安全我也没有测过,但是最轻和最快这两个词是比较容易做体验的。

它为了达到这两个目标,它使用了Rust这个编程语言。这个语言是很偏门的语言。

(注:现场互动环节,听过Rust同学请举手。只有5个人)

这个语言是个非常偏门的语言,但是它最大的好处是性能超好,资源占用超级低,蛮梦幻的语言。除了有代码写的方式有点反人类之外,我之前说要学这个Rust的时候,他们说告诉我说你小心,反人类哦。这个语言好处是你真的把它吃透了,它应该是目前最适合拿来做proxy的一个语言,资源消耗非常低。

Conduit还有一个很重要的事情,就是它吸收了过去的经验。就是过去18个月,在Linkerd上沉淀了各种真实的经验。因为Linkerd是生产级的,而且Linkerd很多企业直接上生产,这一点非常重要。

可以看到这个Rust的过人之处。

后面三条数据不直白,但是第一条太明显了,Conduit代理用不到十兆实际内存,P99在分毫秒之内,这个可能不是太敏感,但是十兆应用太敏感了。proxy是跟每一个应用都直接对应启动起来,要启动N份,这个资源消耗其实是蛮大的。

这个时候的关键点就在于2018年,2018年Service Mesh这个市场几乎是蛮荒时代,除了Linkerd和Envoy有一小部分企业用户之外。大部分人都在等,等一个足够让大家放心的产品再用,市场基本上是空白的,但是要拿到这个市场有一个非常重要的事情:一定要用自己的实际表现说服大家,让大家觉得Service Mesh可以落地,可以做商用,可以上线。

这点很重要!

2018年最重要的事情就是:谁能第一个达到这个目标,让大家敢用,敢在生产上用。

大家如果有注意的话,会注意到,Istio在发自己的release note的时候,都写了一句话:不要用,不要用,不要用……很搞笑的,你能想象吗?他自己发的release note,特别注明不要用它。

在这里面Istio基本上就算一个贵族了,背景非常深厚,自己能力也很出众,盟友众多。基本上可以看到Istio只要它自己不犯错,它这个地位非常难撼动。现在的唯一的悬念就是说它的1.0或者是它的Production Ready版本什么时候发布,它如果今天马上发布的话,这个市场基本上没有什么悬念可言。它如果拖到明年、后年发布,那就没它什么事了。拖到年底,如果Conduit够快,也很难说。

所以这里面有非常大的悬念,谁先搞定第一个生产可用的版本。

Buoyant算是江湖草莽吧,一个小公司但是一身傲骨。之前看它俯低做小伺候Istio的时候感觉还很奇怪,但是突然之间把Conduit拿出来。前面那个行为现在感觉有点变质了,有点像当年勾践卧薪尝胆的感觉,卧薪尝胆,然后突然间憋出一个大招来了。

Conduit还是有一些优势的,首先这家公司因为Linkerd的原因,它一直是摸爬滚打在Service Mesh的第一线,它是少有的几个真正在线上跑过的Service Mesh,这一点是没人比的过的。它是最懂Service Mesh的,这是它最大的优势。人也不多,但是不多的几个人里面,有几个真的是高手,这也是一个优势。因为人不多,所以只能做简单一点,做的接地气一点,实用一点,基本上是可以预料的。但是现在打一个问号,我是预判的,实际是不是这样,还要看它产品真实表现。

最近也看到有人给了Conduit一个标签,叫做穷人的Service Mesh,因为它的资源消耗非常低,也比较简单,所以有这么一个标签。但是究竟是不是,接下来2018年,我们能看到。

右边写了一个问号,这么大的一个市场,会不会有新的竞争者进来,这个不好说,说不定哪天就有人蹦进来了。但是跟Istio集成的就不算,没有什么意思,如果进来只是为了做一个小三就没意思了。对于Service Mesh是一开局,开局就是红海,左边这两位已经在刀对刀的在拼杀了,所以如果是庸人,只能进来做个小三,打个酱油,基本上可以不用进来了。




Service Mesh 大浪潮下的应对


我们将整个Service Mesh的大潮,和市场,过了一遍。接下来我们看一下这个大潮下的应对。

首先这个东西是个革命,革命就是两个问题:

第一谁革命,大家都知道Service Mesh要革命。

第二个问题是革谁的命,这是比较有意思的。

Service Mesh号称下一代的微服务,下一代的微服务概念是什么,当前的微服务是谁?大家很清楚,当前主流微服务框架是左边Spring Cloud,基本上首选。现在刀架在脖子上,Pivotal这个公司会怎么样,是会顺应潮流,说那也好,我们也搞Service Mesh吧。搞个spring cloud on service mesh,或者干脆砍掉整个Spring Cloud,说觉得Spring Cloud没意思,直接spring on service mesh。

其实后者我挺喜欢的。Spring Boot是很清爽的东西,觉得它的设计,实现,包括资源消耗是很好的。如果Spring Boot能跑到Service Mesh上,真的是很清爽的搭配。但是,这个毕竟只是我的主意,也许他们不为所动,说不定他们就不玩Service Mesh。

为什么会有这个想法,因为去年曾经给它们提议,让他们支持RPC,被拒绝了。Spring Cloud说我喜欢rest。就是这么固执,不好说它最后做什么决策,2018年我们可以看,它也许有动作,也许没动作。

OK,这个地方革命的对象非常明确,就是以新一代微服务的身份,把整个微服务这条路走过去:走别人的路,让别人无路可走。只要它把微服务全部搞定了,自然就没有上一代啥事了。

Service Mesh实际上有一些天然的盟友,有一种类型的微服务框架它是比较容易向Service mesh靠拢的,即原来就是Sidecar模式,或者它有比较好的意愿可以快速转成Sidecar。

可以看到今年的全球架构师峰会上,华为在讲它的那个Mesh。它们原来有一个Golang sdk,最近好像是被我勾引了一把,他们快速堆出了一个Go版的Service Mesh出来,现在看还挺成功的。

还有Motan,这个我就不细说了,一会另外一位讲师周晶同学会做详细的分享。

多说一下,其实很多企业用户,有没有开源的产品。在某些企业里,也有一些典型的服务化框架,比如说唯品会的OSP框架,它就是一个很典型的。内部一个Sidecar模式在跑。对它而言,如果想向Service Mesh靠拢是非常简单的,因为本身和Service Mesh的方式非常相似。但是这里面有一个小悬念,它现在是基于Java的,那未来是不是还会基于Java还是把Java改掉,这就是一个悬念了。往后面看,看白衣到底是改不改。

现在来看谁会拥抱Service Mesh?咱们只谈国内,不谈国外。

在国内有一大批初创企业,典型的就是某某云,包括我们数人云。这些企业大部分是做容器、云、或者大数据。有一个共同点:单只做云这一块东西稍微有点薄,而且离最终的业务应用有点远。所以,向Google看齐,向上做,这是一条出路。其实很多公司都有这样的共识,只是多少的问题,有些人可能选,有些人可能不选。

但是如果选择向上做,那微服务基本上是一个很自然的选择。业界也是公认的:微服务和容器的搭配非常的合适。但是选微服务是不是选择Service Mesh,这是另外的事情。可以选择Spring Cloud,也可以选择Dubbo。

我们数人云算是率先走出第一步的。一方面会继续在Spring Cloud基础上提供稳定的服务,另外一个会积极的落地Service Mesh的方案,这是我们接下来会做的事情,我们走了第一步了。现在不知道2018年还会有谁跟进,我们预计肯定会有初创的公司跟我们一起走这条路的。现在的悬念就是说谁是第二个,第三个,会有多少个。

还有一些就是所谓的公有云的大鳄,它提供公有云的服务。Service Mesh对于公有云而言,这是一个神兵利器,这个暂时只有我说这个话,相信时间越久就会有更多的认可。因为一旦Service Mesh成熟,它会变成公有云的一个杀手锏的特性,到时候有没有Service Mesh的功能,会是公有云非常重要的标识。这一点在2018年或者是2019年会变成一个大概率的事件,大家可以等着来挖坟,万一到时候Service Mesh没成功,那就打我脸好了。暂时这是我的一个判断。

我们现在能看到的是,华为的公有云已经抢先出击了,提供了微服务的服务,它们是第一家。现有的公有云里华为现在动作最快,既提供传统架构的ServiceComb,也有基于Service Mesh的CSE mesher的。

华为第一家出来没问题,问题是后面还有没有跟进,阿里云会不会跟,腾讯会不会跟,这个应该是2018年小小悬念:他们会不会跟?

然后神仙打架,会殃及池鱼。

一旦Service Mesh成为主流,有一些领域会受到一些冲击,典型的像反向代理如Nginx、HAproxy,还有像API gateway。因为如果Service Mesh成主流之后,没必要用反向代理了,直接Service Mesh就好。也包括API gateway,有一部分功能其实Istio会往上面去做。这两个领域会有一些冲击。

我们看到Nginx曾经喊着说自己做Service Mesh,但是也没有下文。其它的像Zuul、Kong这些,之前了解到有一个朋友说Kong曾经也在想,要不要做Service Mesh。但是想了半天,最后没下决心,估计也卡在我刚才说的问题。大家还记得吧?如果要做的话,怎么干掉Google,如果没有信心干掉它的话,做它干什么?

但是这两个领域,如果有人站出来,也是个好事,可能会多一个选择。

我们今天的内容到此就结束了。

最后,“2018, The Year of Service Mesh”,我们期待这样一个时刻的到来。

今天的演讲到此结束,非常感谢大家。

深度解析Service Mesh中数据面板与控制面板

小数 发表了文章 • 0 个评论 • 655 次浏览 • 2017-12-19 18:12 • 来自相关话题

翻译:郑学滢(易宝支付研发工程师) (易宝支付研发工程师)(易宝支付研发工程师)

转自:容器时代(CaaSOne)



服务网格:数据面板 VS  控制面板

近两年来,服务网格(Service Mesh)的思想越来越受欢迎,随着学习该技术的人数激增,我发现所有技术社区里都产生了大量关于如何比较不同工具间差异的问题。

这种情况可以用我在7月份写的一系列推特来总结:
 
服务网格的困惑#1:linkerd ~=nginx ~= haproxy ~= envoy.它们都不等同于 istio,istio完全是个别的东西
 
前面提到的只是数据面板,仅通过它们无法工作,需要将它们配置到其他工具中

istio是实现一致性控制面板的一个实例,可以在该面板的不同层次上,用一 致的方式将一些东西连接在一起
 
在上面的这些推特上,我提到几个不同的项目(Linkerd,NGINX,HAProxy,Envoy,和 Istio),但重点介绍了服务网格数据面板和控制面板。在这篇文章中,我会回顾一下,并深入讨论我对数据面板和控制面板的看法,以及它们是如何与我之前在推特中提到的其他项目相关联的。


什么才是真正的服务网格?







上图在基础层面上说明了服务网格的含义。图中有4个服务集群(A-D),每一个服务实例用sidecar网络代理进行部署。所有网络间的通信(HTTP,REST,gRPC,Redis等)都通过自己的服务实例,这些实例通过本地sidecar代理找到响应的目标实例。因此,外部网络对于服务实例是不可见的,它只知道本地代理的存在。实际上,分布式系统网络已经被服务程序设计人员抽象出来。


数据面板

在服务网格中,sidecar代理执行如下任务:

服务发现:在所有的前后端服务实例中,哪些是可用的?

健康检查:服务发现的前端服务实例是健康并且可以接受网络通信的么?这
可能包括主动(例如外部ping一个到/healthcheck   endpoint的连接)和被动(比如使用3个连续的5xx作为一个不健康声明的指示)的健康检查。

路由:向本地服务实例发送一个rest风格的请求/foo,路由决定该请求应该向
哪个前端服务集群发送。

负载均衡:一旦路由选择了一个提供前端服务的集群,那么请求应该发送给
哪个服务实例?怎么配置超时?熔断怎么设置?如果请求失败了需要重试么?

认证与授权:对于访问的请求,访问者需要使用mTLS或者其他方法加密验
证么?如果验证通过,访问者可以访问请求的endpoint或者收到一个未认证通过的响应么?

可观测性:对于每一个请求,都会生成详细的统计数据,日志信息,和分布式操作记录数据,以便操作者可以理解分布式通信流并对他们发现的问题进行调试。

以上这些都是服务网格数据面板的职责。实际上,sidecar代理本身就是数据面板。换句话说,数据面板对条件转换,转发,和监控每一个由服务实例提供并在服务间传递的网络包负责。


控制面板

sidecar代理数据面板提供的网络抽象是非常奇妙的。然而,这些代理怎么知道将/foo路由到服务B?怎么处理查询到的服务发现数据?负载均衡,超时,熔断机制等是如何按指定配置的?使用蓝/绿或者逐步通信移动语义是如何完成部署的?谁配置全系统的认证和授权?

这些都是服务网格控制面板的职责。控制面板将一些独立无状态的代理构成集合,并把它们转换成一个分布式系统。

我认为许多技术人员觉得数据面板和控制面板划分概念难以理解,是因为多数人熟悉数据面板,而对控制面板是陌生的。我们接触物理网络路由器和交换机已经有很长时间了。我们理解包/请求需要由节点A发送到节点B,这可以用硬件或软件来现实。软件代理这一新类型只是我们以前长期使用的工具的升级版。






然而,我们使用控制面板也已经很长时间了,尽管大多数的网络操作者可能不太知道系统模块的技术成分。原因很简单—现在使用控制面板的人大多数是我们自己。

上图描述了我所说的“人类控制面板”。这种类型的部署工作依旧非常普遍,一个(可能烦躁的)操作人员手动完成静态配置,可能会借助一些脚本工具,然后使用一些特定的进程部署到代理中。然后这些代理会更新配置并继续用它来处理数据面板的任务。






上图描述了一个高级的服务网格控制面板。它由下面的部分构成:


人:仍然存在一个(希望没那么烦躁)人在这个循环中,并由他制定整个系统的决策。

控制面板的用户界面:这个人与某些类型的用户界面交互来控制系统,可能是一个网站入口,一个命令行界面,或者其他一些接口。通过UI,操作者可以获取全局系统配置设置,比如部署控制(蓝/绿和(或者)通信移动),认证和授权设置,路由表详情(比如服务A何时访问/foo,会发生什么),和负载均衡设置(例如超时,重试,熔断机制等)。

任务调度器:服务通过一些调度系统(比如Kubernetes或者Nomad)来运行在设备上。调度器负责将一个服务连同它的sidecar代理绑定在一起。

服务发现:当调度器启动或停止服务实例时,它将服务的生命状态报告给一个服务发现系统。

sidecar代理配置APIs:在需要操作员参与下,sidecar代理能够以最终一致地方式动态地从系统组件中获取声明。整个系统由所有正在运行的服务实例和sidecar代理聚合组成。envoy的通用数据面板API就是这样一个应用于实践的例子。

控制面板的根本目的是设置最终由数据面板发布的策略。许多优秀的控制面板将把系统的更多部分对操作者抽象,且需要更少的操作(假定他们是正常工作的状态)。


数据面板 VS 控制面板小结

服务网格数据面板:接收系统中每一个包或请求。提供服务发现,健康检查,路由,负载均衡,保证服务认证/授权,以及监控的功能。

服务网格控制面板:为正在网格中运行的数据面板提供策略和配置。不接受系统中的任何包或请求。控制面板将所有的数据面板转变为一个分布式系统。


当前项目概览

经过上面的解释,现在看一下服务网格的现状

数据面板:Linked,NGINX,HAProxy,Envoy,Traefik

控制面板:Istio,Nelson,SmartStack

这里简要的讨论造成现在许多生态系统问题的一些因素,就不对每个产品进行深入的分析了。

Linkerd是2016年初第一批出现的服务网格数据面板代理之一,它在提高人们对服务网格设计模式的意识和积极性方面做出了很大的贡献。Envoy则在6个月后发布(虽然在2015年末已经开发完成)。Linkerd和Envoy是人们讨论服务网格时最多提到的2个项目。

Istio在2017年5月宣布完成。它的主要原理与上图描述的优秀控制面板很相似。Istio的默认代理是Envoy。因此,Istio是控制面板,而Envoy是数据面板。很快,Istio获得了许多人的青睐,其他的数据面板开始集成Istio作为Envoy的替代物(Linkerd和NGINX都集成了Istio)。事实上,单一的控制面板使用不同的数据面板可能意味着控制面板和数据面板并不必须紧密的组合使用。一个像Envoy通用数据面板API的API可以在2个系统间建立一个桥梁。

Nelson和SmartStack有利于更进一步地说明控制面板和数据面板的区别。Nelson使用Envoy作为它的代理,并且在HashiCorp堆栈旁构建了一个健壮的服务网格控制面板(Nomad等)。SmartStack也许是服务网格的首批新浪潮。SmartStack组成了像HAProxy或者NGINX这样的控制面板,进一步说明了服务网格控制面板和数据面板解耦的可能性。

服务网格微服务通信体系现在获得许多的关注(就是现在!),任何时刻都有很多项目和供应商参与进来。在接下来的几年内,我们将会看到数据面板和控制面板的许多创新,并更好的集成了不同的组件。最终的结果应该是微服务通信体系对操作者(希望不那么烦躁)来说更加令人惊讶并简单易懂。

要点

一个服务网格有两个不同部分组成:数据面板和控制面板。二者是必须的。缺少任何一个,系统都无法工作。

每个人都熟悉控制面板,虽然控制面板可能是你。

所有的数据面板比较是通过各自的特点,性能,可配置性和可扩展性。

所有的控制面板比较是通过各自的特点,可配置性,可扩展性和可用性。

单一的控制面板可能包含合适的抽象和APIs,以便更多的数据面板可以使用。
  查看全部
翻译:郑学滢(易宝支付研发工程师) (易宝支付研发工程师)(易宝支付研发工程师)

转自:容器时代(CaaSOne)



服务网格:数据面板 VS  控制面板

近两年来,服务网格(Service Mesh)的思想越来越受欢迎,随着学习该技术的人数激增,我发现所有技术社区里都产生了大量关于如何比较不同工具间差异的问题。

这种情况可以用我在7月份写的一系列推特来总结:
 
服务网格的困惑#1:linkerd ~=nginx ~= haproxy ~= envoy.它们都不等同于 istio,istio完全是个别的东西
 
前面提到的只是数据面板,仅通过它们无法工作,需要将它们配置到其他工具中

istio是实现一致性控制面板的一个实例,可以在该面板的不同层次上,用一 致的方式将一些东西连接在一起
 
在上面的这些推特上,我提到几个不同的项目(Linkerd,NGINX,HAProxy,Envoy,和 Istio),但重点介绍了服务网格数据面板和控制面板。在这篇文章中,我会回顾一下,并深入讨论我对数据面板和控制面板的看法,以及它们是如何与我之前在推特中提到的其他项目相关联的。


什么才是真正的服务网格?

11.jpg



上图在基础层面上说明了服务网格的含义。图中有4个服务集群(A-D),每一个服务实例用sidecar网络代理进行部署。所有网络间的通信(HTTP,REST,gRPC,Redis等)都通过自己的服务实例,这些实例通过本地sidecar代理找到响应的目标实例。因此,外部网络对于服务实例是不可见的,它只知道本地代理的存在。实际上,分布式系统网络已经被服务程序设计人员抽象出来。


数据面板

在服务网格中,sidecar代理执行如下任务:

服务发现:在所有的前后端服务实例中,哪些是可用的?

健康检查:服务发现的前端服务实例是健康并且可以接受网络通信的么?这
可能包括主动(例如外部ping一个到/healthcheck   endpoint的连接)和被动(比如使用3个连续的5xx作为一个不健康声明的指示)的健康检查。

路由:向本地服务实例发送一个rest风格的请求/foo,路由决定该请求应该向
哪个前端服务集群发送。

负载均衡:一旦路由选择了一个提供前端服务的集群,那么请求应该发送给
哪个服务实例?怎么配置超时?熔断怎么设置?如果请求失败了需要重试么?

认证与授权:对于访问的请求,访问者需要使用mTLS或者其他方法加密验
证么?如果验证通过,访问者可以访问请求的endpoint或者收到一个未认证通过的响应么?

可观测性:对于每一个请求,都会生成详细的统计数据,日志信息,和分布式操作记录数据,以便操作者可以理解分布式通信流并对他们发现的问题进行调试。

以上这些都是服务网格数据面板的职责。实际上,sidecar代理本身就是数据面板。换句话说,数据面板对条件转换,转发,和监控每一个由服务实例提供并在服务间传递的网络包负责。


控制面板

sidecar代理数据面板提供的网络抽象是非常奇妙的。然而,这些代理怎么知道将/foo路由到服务B?怎么处理查询到的服务发现数据?负载均衡,超时,熔断机制等是如何按指定配置的?使用蓝/绿或者逐步通信移动语义是如何完成部署的?谁配置全系统的认证和授权?

这些都是服务网格控制面板的职责。控制面板将一些独立无状态的代理构成集合,并把它们转换成一个分布式系统。

我认为许多技术人员觉得数据面板和控制面板划分概念难以理解,是因为多数人熟悉数据面板,而对控制面板是陌生的。我们接触物理网络路由器和交换机已经有很长时间了。我们理解包/请求需要由节点A发送到节点B,这可以用硬件或软件来现实。软件代理这一新类型只是我们以前长期使用的工具的升级版。

22.jpg


然而,我们使用控制面板也已经很长时间了,尽管大多数的网络操作者可能不太知道系统模块的技术成分。原因很简单—现在使用控制面板的人大多数是我们自己。

上图描述了我所说的“人类控制面板”。这种类型的部署工作依旧非常普遍,一个(可能烦躁的)操作人员手动完成静态配置,可能会借助一些脚本工具,然后使用一些特定的进程部署到代理中。然后这些代理会更新配置并继续用它来处理数据面板的任务。

33.jpg


上图描述了一个高级的服务网格控制面板。它由下面的部分构成:


人:仍然存在一个(希望没那么烦躁)人在这个循环中,并由他制定整个系统的决策。

控制面板的用户界面:这个人与某些类型的用户界面交互来控制系统,可能是一个网站入口,一个命令行界面,或者其他一些接口。通过UI,操作者可以获取全局系统配置设置,比如部署控制(蓝/绿和(或者)通信移动),认证和授权设置,路由表详情(比如服务A何时访问/foo,会发生什么),和负载均衡设置(例如超时,重试,熔断机制等)。

任务调度器:服务通过一些调度系统(比如Kubernetes或者Nomad)来运行在设备上。调度器负责将一个服务连同它的sidecar代理绑定在一起。

服务发现:当调度器启动或停止服务实例时,它将服务的生命状态报告给一个服务发现系统。

sidecar代理配置APIs:在需要操作员参与下,sidecar代理能够以最终一致地方式动态地从系统组件中获取声明。整个系统由所有正在运行的服务实例和sidecar代理聚合组成。envoy的通用数据面板API就是这样一个应用于实践的例子。

控制面板的根本目的是设置最终由数据面板发布的策略。许多优秀的控制面板将把系统的更多部分对操作者抽象,且需要更少的操作(假定他们是正常工作的状态)。


数据面板 VS 控制面板小结

服务网格数据面板:接收系统中每一个包或请求。提供服务发现,健康检查,路由,负载均衡,保证服务认证/授权,以及监控的功能。

服务网格控制面板:为正在网格中运行的数据面板提供策略和配置。不接受系统中的任何包或请求。控制面板将所有的数据面板转变为一个分布式系统。


当前项目概览

经过上面的解释,现在看一下服务网格的现状

数据面板:Linked,NGINX,HAProxy,Envoy,Traefik

控制面板:Istio,Nelson,SmartStack

这里简要的讨论造成现在许多生态系统问题的一些因素,就不对每个产品进行深入的分析了。

Linkerd是2016年初第一批出现的服务网格数据面板代理之一,它在提高人们对服务网格设计模式的意识和积极性方面做出了很大的贡献。Envoy则在6个月后发布(虽然在2015年末已经开发完成)。Linkerd和Envoy是人们讨论服务网格时最多提到的2个项目。

Istio在2017年5月宣布完成。它的主要原理与上图描述的优秀控制面板很相似。Istio的默认代理是Envoy。因此,Istio是控制面板,而Envoy是数据面板。很快,Istio获得了许多人的青睐,其他的数据面板开始集成Istio作为Envoy的替代物(Linkerd和NGINX都集成了Istio)。事实上,单一的控制面板使用不同的数据面板可能意味着控制面板和数据面板并不必须紧密的组合使用。一个像Envoy通用数据面板API的API可以在2个系统间建立一个桥梁。

Nelson和SmartStack有利于更进一步地说明控制面板和数据面板的区别。Nelson使用Envoy作为它的代理,并且在HashiCorp堆栈旁构建了一个健壮的服务网格控制面板(Nomad等)。SmartStack也许是服务网格的首批新浪潮。SmartStack组成了像HAProxy或者NGINX这样的控制面板,进一步说明了服务网格控制面板和数据面板解耦的可能性。

服务网格微服务通信体系现在获得许多的关注(就是现在!),任何时刻都有很多项目和供应商参与进来。在接下来的几年内,我们将会看到数据面板和控制面板的许多创新,并更好的集成了不同的组件。最终的结果应该是微服务通信体系对操作者(希望不那么烦躁)来说更加令人惊讶并简单易懂。

要点

一个服务网格有两个不同部分组成:数据面板和控制面板。二者是必须的。缺少任何一个,系统都无法工作。

每个人都熟悉控制面板,虽然控制面板可能是你。

所有的数据面板比较是通过各自的特点,性能,可配置性和可扩展性。

所有的控制面板比较是通过各自的特点,可配置性,可扩展性和可用性。

单一的控制面板可能包含合适的抽象和APIs,以便更多的数据面板可以使用。
 

原理解析Service Mesh与ESB、API管理与消息代理的关系

小数 发表了文章 • 0 个评论 • 619 次浏览 • 2017-12-14 10:05 • 来自相关话题

译者:海松 

原题:Application Network Functions With ESBs, API Management, and Now.. Service Mesh?

转自:公众号EAworld

最近我谈到了微服务模式的发展①,以及像service proxies like Envoy from Lyft②的文章,阐述服务代理如何将弹性、服务发现、路由、指标收集等职责推到应用程序下层。否则,我们只能寄希望于各种应用程序自己能正确实施这些关键功能,或依赖某个特定语言的库来实现这点。有趣的是,这种service mesh的思路与我们的企业领域客户熟悉的其他概念有关。我收到了很多关于这种关系的问题。具体来说,service mesh与ESB、消息代理和API Management的关系是什么?这些概念肯定有重叠,所以让我们来深挖一下。关注Twitter @christianposta了解更多信息!


一、四个假设


服务通过网络进行通信

第一点:我们谈的服务是通过异步、包交换(packet-switched)网络进行通信和交互的服务。这意味着它们在自己的进程中运行,并且在自己的“时间边界”内(time boundaries,此处即异步的概念)中运行,且通过在网络中发送包进行通信。不幸的是,没有任何东西可以保证异步网络交互③:我们最终可能会遇到交互失败、交互停滞/延迟等等,而且这些情况不好区分。







如果仔细观察,这些交互并非微不足道

第二点:这些服务如何互相交互并非微不足道。我们必须处理以下事情,比如故障/部分成功、重试、重复检测、序列化/反序列化、语义/格式转换、多语言协议、路由到正确的服务来处理消息、处理消息洪泛(floods of messages)、服务编排、安全性影响等等。而其中许多事情可能而且必定会出错。


了解网络非常重要

第三点:了解应用程序如何通信、消息如何交换以及如何控制流量非常重要。这点非常类似于我们如何看待第3/4层网络。了解以下内容是有价值的,如:哪些TCP段和IP数据包正穿过网络、控制路由它们和允许它们的规则等等。







最终责任在应用程序

最后:正如通过端到端的论证④证我们所知道的,应用程序本身应当负责其业务逻辑的安全性,保证正确的语义实现。无论底层基础设施(即使会遇到重试、交易、重复检测等等)的可靠性如何,我们的应用程序必须防范用户做出糊涂的行为(如同一命令重复提交)。提供实现或优化的细节能有助于帮助实现。但不幸的是,没有办法解决这个问题。


二、应用程序网络功能

我认为,无论你更倾向于哪个服务架构(微服务、SOA、对象请求代理、客户端/服务器等),以上要点都是有效的。然而,过去我们对于哪些优化属于哪里十分模糊。在我看来,不仅横向的应用程序网络功能可以从应用程序中被优化掉(然后被投入到基础设施中 - 就像我们在较低级别堆栈上所做的事情那样),而且还有其他应用程序网络功能与我们的业务逻辑更密切相关,但却不应该被轻易地“优化”(optimized)掉。


三、网络

让我们迅速回顾下应用程序之下的网络是什么样的,它可是地位超凡哦:)。当我们从一个服务发“消息”到另一个服务时,我们将其传递到了操作系统的网络堆栈,操作系统会尝试将这条消息放入网络中。根据网络所处级别,网络会处理传输单元(帧、数据报、数据包)等。这些传输单元通常包括一个由“数据头”和“有效负载”组成的结构,“数据头”包含关于传输单元的元数据。通过元数据,我们可以做很多基础的事情,例如路由、确认跟踪/去重等。






这些传输单元通过网络中的不同点进行发送,这些点决定了是否允许单元通过,是否将其路由到不同的网络,或将其传送到预期的接收者处。在路径上的任意一点,这些传输单元可能被丢弃、复制、重新排序或推迟。更高级的“可靠性”功能,如操作系统内网络堆栈中的TCP,则可以跟踪重复、确认、超时、排序、丢失的单元等东西,并可以进行故障重试、数据包重新排序等。







这类功能由基础设施提供,不与业务逻辑混合 – 而且其规模相当可观,达到了互联网规模! 我刚看到的Phil Calcado精彩的博客很好地解释了这点⑤。


四、应用程序

在应用程序级别上,我们在做类似的事情。我们将与协作者服务的对话拆分成包含“消息”(请求、事件等)的传输单元。当我们通过网络进行调用时,我们必须能为应用程序消息执行超时、重试、确认、应用背压(apply backpressure)等操作。这些都是应用程序级别普遍的问题,并且在构建服务架构时总会出现。我们需要解决它们。我们需要一种实现应用网络功能的方法。







例如:过去我们尝试用邮件代理解决它们。有一组集中的面向消息的中间件(甚至可以通过多协议支持,使我们可以转换消息的有效负载,“集成”多个客户端),它们负责在客户端之间传递消息。我看到的很多例子使用的模式基本上是通过消息系统进行请求或回复(RPC)。






这间接帮助解决了应用程序网络功能中的一些问题。负载均衡、服务发现、背压、重试等工作都被委托给了消息代理。由于所有流量都要经过这些代理,所以我们有了一个中心点,从这个中心点可以观察和控制网络流量。但是,正如@tef_ebooks在Twitter⑥上指出的那样,这种做法用力过度,有些矫枉过正了。它往往会成为架构的瓶颈,用它来进行流量控制、路由、策略执行等并不像我们想象那么容易。

所以我们也做过同样的尝试。我们觉得“好吧,就把路由、转换、策略控制”加到现有的集中式消息总线里吧。实际上这是个非常自然的演变。我们可以使用消息主干网(messaging backbone)来提供集中化、控制和应用程序网络功能,如服务发现、负载均衡、重试等等,但还要加入更多内容,比如协议调解、消息转换、消息路由、编排等功能,因为我们觉得如果可以将这些看似同一层面的内容加入到基础设施中,应用程序或许会更轻量、更精简、更敏捷等等。这些需求绝对是真实的,ESB演变并满足了这些需要。






正如我的同事Wolfram Richter⑦指出,“关于ESB概念,IBM关于SOA架构的2005年白皮书(http://signallake.com/innovation/soaNov05.pdf第2.3.1章)提供了如下的定义:

在SOA逻辑架构中,企业服务总线(ESB)是名安静的伙伴。它在体系结构中的存在对于SOA应用程序的服务来说几乎是透明的。然而,ESB的存在是简化服务调用的基础,使我们能随时随地调用服务,而无需定位服务或是上传服务请求这些细节。

这似乎是行得通的!甚至像我们正在尝试的新技术一样。知道吗?我们的确是在尝试新技术!!!之前的问题并未奇迹般地消失,只是背景和环境发生了变化。我们希望从过去未达成的目标中吸取经验。

例如,在大型供应商展望的SOA时代(通过委员会等方式编写无穷尽的规范、重命名EAI等),我们发现三件事导致了“ESB”的承诺未能实现:

• 组织结构(让我们不停地建造一个个竖井(silo)!) 

• 技术复杂(SOAP/WS- *、JBI、规范XML、专有格式等) 

• 需要业务逻辑来实现路由、转换、中介、编排等

而最后一点导致了过度操作。我们希望敏捷化,但我们将重要的业务逻辑从服务中分离出来,并转移到另一个团队拥有的集成层。现在,当我们想要更改服务时(出于敏捷的需要),我们做不到;我们不得不暂停并和ESB团队产生大量同步(这会带来风险)。随着这个团队和这个架构成为应用程序的中心,我们就可以理解ESB团队为什么会被请求所淹没(同样是因为敏捷的需要),无法跟上节奏了(即风险的体现)。所以尽管意图很好,但是我们发现把核心的应用程序联网功能与业务逻辑有关的功能混到一起不是个好主意。我们最终会遭遇瓶颈。






接下来出现的是REST革命和API优先的思潮。这一运动部分是出于对SOAP/ESB/SOA复杂性的抵制,部分是考虑通过API转换数据,引发新的商业模式,扩展现有模式。我们还向架构引入了新的基础设施:API管理网关。该网关让我们能集中地控制针对业务API的外部访问,它是通过安全ACL、访问配额和API使用计划、指标收集、计费、文档等实现的。然而,就像我们在前面的消息代理例子中看到的那样,当采用集中治理时,我们会有一次处理过多事情的风险。例如,我们会想,当API调用通过我们的网关时,为何不添加路由、转换和编排呢?然而,这样做的后果是我们开始妄想打造一个能够将基础设施级网络问题与业务逻辑相结合的ESB。这是一条死胡同。






但是,即使在REST/非SOAP时代,我们仍需要解决上述各项服务之间的问题,(不仅仅是所谓的“南北”流量(编者注:“North-South” traffic。网络传输的流量方向,南北一般指代纵向的不同层级间的传输流量,比如内外网,东西一般指代同一级别的传输流量,比如虚拟机之间),还包括“东西方”流量交互的问题)。更具挑战性的是,我们需要找出一种使用商用基础设施环境(又名云)的方法,而这种方法往往会加剧上述问题。传统信息代理、ESB等不适合这种模式。相反,我们最终会在业务逻辑中编写应用程序网络功能。……我们开始看到诸如Netflix OSS堆栈⑧、Twitter Finagle⑨这样的事物,甚至还有我们自己的Fuse Fabric,它们的确可以解决其中的一些问题。它们通常是库或框架,旨在解决上述一些问题,但它们是特定语言编写的,并且混合在业务逻辑中(或在整个基础设施中分散的业务逻辑中)。因此,这个模式也有问题。这种方法需要在每种语言/框架/运行环境上进行大量投资。我们基本上必须在跨语言/框架上加倍努力,并期望它们能够有效、正确和一致地工作。






经历了上述这些困难,在有能力控制/配置/监控应用级请求的前提下,我们能用最低的成本,高度分散(high decentralization)地将应用网络功能加入到基础设施中,从而解决上述的一些问题。我们称之为“service mesh”。基于Envoy Proxy⑩的istio.io⑪就是个很好的例子。它使我们将应用程序网络功能的问题与业务逻辑区分的问题分离开来:






正如Phil Calcado说的那样⑫,这与TCP/IP网络层的工作非常相似;网络功能被推入到操作系统中,但它们并不是应用程序的一部分。


五、与此相关的概念

通过service mesh,我们明确地将应用程序网络功能与应用程序代码、业务逻辑分离开来,我们正在将其推向另一个层次(推向基础设施,这与我们在网络堆栈、TCP等方面所做的工作类似 )。






所涉及的网络功能包括:

• 简单的、基于元数据的路由 

• 自适应/客户端侧负载均衡 

• 服务发现 

• 熔断 

• 超时/重试/预算 

• 速率限制 

• 度量/记录/追踪 

• 故障注入 

• A/B测试/流量整形/请求镜像


明确不含以下项目(这些项目可能更适合于业务层级的逻辑、应用程序和服务,而不是某些集中式基础设施。):

• 消息转换 

• 消息路由(基于内容的路由) 

• 服务编排


那么service mesh与以下事物的不同点在于

ESB

• 在某些网络功能上有重叠 

• 控制点分散 

• 策略针对特定应用程序 

• 不处理业务逻辑问题(如映射、转换、基于内容的路由等)


消息代理

• 在服务发现、负载均衡、重试、背压等方面有重叠(大概差着30,000英尺) 

• 控制点分散 

• 策略针对特定应用程序 

• 不承担发消息的职责


API管理

• 在策略控制、速率限制、ACL,配额安全等方面有重叠 

• 不处理API的业务方面(定价、文档、用户到计划的映射等) 

• 类似点在于它不实现业务逻辑


至于API管理,似乎有一些重叠,但我更倾向于把这些重叠看作是高度互补。API管理提供有关API的更高级语义(如文档、用户注册/访问、生命周期管理、开发人员API计划、计费和退款等)。调用API时,较低级别的应用程序网络,如熔断器、超时、重试等都是至关重要的,但它们很适合service mesh层。重叠点如ACL、速率限制、配额和策略执行等可以由API管理层定义,但实际上由service mesh层实施。通过这种方式,我们可以拥有完整的端到端策略和访问控制,并强化南/北流量和东/西流量的弹性。如@ZackButcher⑬(来自Istio团队)在twitter中⑭指出那样,“随着规模越来越大,从生产和管理服务的角度来看,东西流量开始变得更像南北流量。”







六、把它们都整合起来






我们需要采用API优先的方法来处理我们的系统架构。我们也要解决弹性等问题。我们也发现了在集成上的挑战。在许多方面,将基于异步事件传递和事件处理的架构作为您的API和微服务交互的底层可以帮助提高可用性、弹性和降低脆性。过去,解决这些问题是一项挑战,因为竞争产品和解决方案的关注存在重叠和混淆。随着我们转向云架构,这种情况变得越来越明显,我们需要梳理这些问题,并将它们放在我们的架构中的适当位置,否则我们就会重蹈覆辙。


从上图可以看出: 

• API管理用于进入的南/北流量 

• service mesh(控制+数据层)用于服务之间的应用网络功能 

• service mesh执行东西流量的API管理策略 

• 集成(编排、转换、反损坏(anti-corruption)层)作为应用程序的一部分 

• 事件驱动的消息底层(back plane),用于真正的异步/事件驱动的交互


如果我们回顾前面提到的四个假设,那么下面是我们如何解决它们的方法: 


• 第一:服务通过网络进行交互 –我们使用service mesh数据层/服务代理 

• 第二:交互并非微不足道的 –在业务本身实现业务集成 

• 第三:控制和可观察性 –使用API管理加service mesh控制层 

• 第四:您具体的业务逻辑;使用service mesh/消息传递等进行优化


七、业务逻辑真的可以被分离出来吗?

我想是可以的,但会存在不清晰的边界。在service mesh中,我们说应用程序应该能意识到应用程序网络功能,但是不应该在应用程序代码中被实现。如何使应用程序更清楚地意识到应用程序网络功能或service mesh层正在做什么事情,有待进一步说明。我认为在这种情况下,很多库或框架会被创建出来。例如,如果Istio service mesh触发熔断,重试一些请求,或者由于特定原因而失败,那么应用程序需要对这些场景有更多的上下文信息以供理解。我们需要一种方法来捕获这些情况或背景并将其反馈给服务。另一个例子是在服务之间传播跟踪背景(即分布式跟踪,如OpenTracing),并且透明地完成传播。我们或许会看到,这些轻型的应用程序/特定语言的库可以使应用程序/服务更智能,并允许它们追溯特定的错误。


八、我们该何去何从

今天这一架构的所有部分具有不同的成熟度。即使如此,对我们的服务架构采取原则化的方法是关键。业务逻辑与应用程序网络应该分开。使用service mesh实现应用程序网络,使用API管理层来处理高级别的以API为中心的问题,将让特定业务的集成放在服务层中。这样一来,我们就可以通过事件驱动的底层(backplane)构建数据密集型或数据可用系统。我认为当我们前进时,我们将不断地看到这些原则在具体的技术实现中被采用。在Red Hat(我工作的地方),我们看到诸如3Scale⑮、Istio.io on Kubernetes⑯、Apache Camel⑰和诸如ActiveMQ Artemis⑱/Apache Qpid Dispatch Router⑲(包括非Red Hat技术,如Apache KafkaIMHO⑳)的讯息技术正被作为强大的构建块来构建遵循以上原则的服务架构。



原文链接:

http://blog.christianposta.com ... mesh/

参考地址:

① http://blog.christianposta.com ... ices/

② http://blog.christianposta.com ... ries/

③ https://www.somethingsimilar.c ... oods/

④ http://web.mit.edu/Saltzer/www ... d.pdf

⑤ http://philcalcado.com/2017/08 ... .html

⑥ https://twitter.com/tef_ebooks ... 22048

⑦ https://twitter.com/_wolfram

⑧ https://netflix.github.io/

⑨ https://twitter.github.io/finagle/

⑩ https://www.envoyproxy.io/

⑪ https://istio.io/

⑫ http://philcalcado.com/2017/08 ... .html

⑬ https://twitter.com/ZackButcher

⑭ https://twitter.com/ZackButche ... 70309

⑮ https://www.3scale.net/

⑯ https://istio.io/

⑰ https://camel.apache.org/

⑱ https://activemq.apache.org/artemis/

⑲ http://qpid.apache.org/compone ... .html

⑳ http://kafka.apache.org/ 查看全部
译者:海松 

原题:Application Network Functions With ESBs, API Management, and Now.. Service Mesh?

转自:公众号EAworld

最近我谈到了微服务模式的发展①,以及像service proxies like Envoy from Lyft②的文章,阐述服务代理如何将弹性、服务发现、路由、指标收集等职责推到应用程序下层。否则,我们只能寄希望于各种应用程序自己能正确实施这些关键功能,或依赖某个特定语言的库来实现这点。有趣的是,这种service mesh的思路与我们的企业领域客户熟悉的其他概念有关。我收到了很多关于这种关系的问题。具体来说,service mesh与ESB、消息代理和API Management的关系是什么?这些概念肯定有重叠,所以让我们来深挖一下。关注Twitter @christianposta了解更多信息!


一、四个假设


服务通过网络进行通信

第一点:我们谈的服务是通过异步、包交换(packet-switched)网络进行通信和交互的服务。这意味着它们在自己的进程中运行,并且在自己的“时间边界”内(time boundaries,此处即异步的概念)中运行,且通过在网络中发送包进行通信。不幸的是,没有任何东西可以保证异步网络交互③:我们最终可能会遇到交互失败、交互停滞/延迟等等,而且这些情况不好区分。

1.jpg



如果仔细观察,这些交互并非微不足道

第二点:这些服务如何互相交互并非微不足道。我们必须处理以下事情,比如故障/部分成功、重试、重复检测、序列化/反序列化、语义/格式转换、多语言协议、路由到正确的服务来处理消息、处理消息洪泛(floods of messages)、服务编排、安全性影响等等。而其中许多事情可能而且必定会出错。


了解网络非常重要

第三点:了解应用程序如何通信、消息如何交换以及如何控制流量非常重要。这点非常类似于我们如何看待第3/4层网络。了解以下内容是有价值的,如:哪些TCP段和IP数据包正穿过网络、控制路由它们和允许它们的规则等等。

2.jpg



最终责任在应用程序

最后:正如通过端到端的论证④证我们所知道的,应用程序本身应当负责其业务逻辑的安全性,保证正确的语义实现。无论底层基础设施(即使会遇到重试、交易、重复检测等等)的可靠性如何,我们的应用程序必须防范用户做出糊涂的行为(如同一命令重复提交)。提供实现或优化的细节能有助于帮助实现。但不幸的是,没有办法解决这个问题。


二、应用程序网络功能

我认为,无论你更倾向于哪个服务架构(微服务、SOA、对象请求代理、客户端/服务器等),以上要点都是有效的。然而,过去我们对于哪些优化属于哪里十分模糊。在我看来,不仅横向的应用程序网络功能可以从应用程序中被优化掉(然后被投入到基础设施中 - 就像我们在较低级别堆栈上所做的事情那样),而且还有其他应用程序网络功能与我们的业务逻辑更密切相关,但却不应该被轻易地“优化”(optimized)掉。


三、网络

让我们迅速回顾下应用程序之下的网络是什么样的,它可是地位超凡哦:)。当我们从一个服务发“消息”到另一个服务时,我们将其传递到了操作系统的网络堆栈,操作系统会尝试将这条消息放入网络中。根据网络所处级别,网络会处理传输单元(帧、数据报、数据包)等。这些传输单元通常包括一个由“数据头”和“有效负载”组成的结构,“数据头”包含关于传输单元的元数据。通过元数据,我们可以做很多基础的事情,例如路由、确认跟踪/去重等。

3.jpg


这些传输单元通过网络中的不同点进行发送,这些点决定了是否允许单元通过,是否将其路由到不同的网络,或将其传送到预期的接收者处。在路径上的任意一点,这些传输单元可能被丢弃、复制、重新排序或推迟。更高级的“可靠性”功能,如操作系统内网络堆栈中的TCP,则可以跟踪重复、确认、超时、排序、丢失的单元等东西,并可以进行故障重试、数据包重新排序等。

4.jpg



这类功能由基础设施提供,不与业务逻辑混合 – 而且其规模相当可观,达到了互联网规模! 我刚看到的Phil Calcado精彩的博客很好地解释了这点⑤。


四、应用程序

在应用程序级别上,我们在做类似的事情。我们将与协作者服务的对话拆分成包含“消息”(请求、事件等)的传输单元。当我们通过网络进行调用时,我们必须能为应用程序消息执行超时、重试、确认、应用背压(apply backpressure)等操作。这些都是应用程序级别普遍的问题,并且在构建服务架构时总会出现。我们需要解决它们。我们需要一种实现应用网络功能的方法。

5.jpg



例如:过去我们尝试用邮件代理解决它们。有一组集中的面向消息的中间件(甚至可以通过多协议支持,使我们可以转换消息的有效负载,“集成”多个客户端),它们负责在客户端之间传递消息。我看到的很多例子使用的模式基本上是通过消息系统进行请求或回复(RPC)。

6.jpg


这间接帮助解决了应用程序网络功能中的一些问题。负载均衡、服务发现、背压、重试等工作都被委托给了消息代理。由于所有流量都要经过这些代理,所以我们有了一个中心点,从这个中心点可以观察和控制网络流量。但是,正如@tef_ebooks在Twitter⑥上指出的那样,这种做法用力过度,有些矫枉过正了。它往往会成为架构的瓶颈,用它来进行流量控制、路由、策略执行等并不像我们想象那么容易。

所以我们也做过同样的尝试。我们觉得“好吧,就把路由、转换、策略控制”加到现有的集中式消息总线里吧。实际上这是个非常自然的演变。我们可以使用消息主干网(messaging backbone)来提供集中化、控制和应用程序网络功能,如服务发现、负载均衡、重试等等,但还要加入更多内容,比如协议调解、消息转换、消息路由、编排等功能,因为我们觉得如果可以将这些看似同一层面的内容加入到基础设施中,应用程序或许会更轻量、更精简、更敏捷等等。这些需求绝对是真实的,ESB演变并满足了这些需要。

7.jpg


正如我的同事Wolfram Richter⑦指出,“关于ESB概念,IBM关于SOA架构的2005年白皮书(http://signallake.com/innovation/soaNov05.pdf第2.3.1章)提供了如下的定义:

在SOA逻辑架构中,企业服务总线(ESB)是名安静的伙伴。它在体系结构中的存在对于SOA应用程序的服务来说几乎是透明的。然而,ESB的存在是简化服务调用的基础,使我们能随时随地调用服务,而无需定位服务或是上传服务请求这些细节。

这似乎是行得通的!甚至像我们正在尝试的新技术一样。知道吗?我们的确是在尝试新技术!!!之前的问题并未奇迹般地消失,只是背景和环境发生了变化。我们希望从过去未达成的目标中吸取经验。

例如,在大型供应商展望的SOA时代(通过委员会等方式编写无穷尽的规范、重命名EAI等),我们发现三件事导致了“ESB”的承诺未能实现:

• 组织结构(让我们不停地建造一个个竖井(silo)!) 

• 技术复杂(SOAP/WS- *、JBI、规范XML、专有格式等) 

• 需要业务逻辑来实现路由、转换、中介、编排等

而最后一点导致了过度操作。我们希望敏捷化,但我们将重要的业务逻辑从服务中分离出来,并转移到另一个团队拥有的集成层。现在,当我们想要更改服务时(出于敏捷的需要),我们做不到;我们不得不暂停并和ESB团队产生大量同步(这会带来风险)。随着这个团队和这个架构成为应用程序的中心,我们就可以理解ESB团队为什么会被请求所淹没(同样是因为敏捷的需要),无法跟上节奏了(即风险的体现)。所以尽管意图很好,但是我们发现把核心的应用程序联网功能与业务逻辑有关的功能混到一起不是个好主意。我们最终会遭遇瓶颈。

8.jpg


接下来出现的是REST革命和API优先的思潮。这一运动部分是出于对SOAP/ESB/SOA复杂性的抵制,部分是考虑通过API转换数据,引发新的商业模式,扩展现有模式。我们还向架构引入了新的基础设施:API管理网关。该网关让我们能集中地控制针对业务API的外部访问,它是通过安全ACL、访问配额和API使用计划、指标收集、计费、文档等实现的。然而,就像我们在前面的消息代理例子中看到的那样,当采用集中治理时,我们会有一次处理过多事情的风险。例如,我们会想,当API调用通过我们的网关时,为何不添加路由、转换和编排呢?然而,这样做的后果是我们开始妄想打造一个能够将基础设施级网络问题与业务逻辑相结合的ESB。这是一条死胡同。

9.jpg


但是,即使在REST/非SOAP时代,我们仍需要解决上述各项服务之间的问题,(不仅仅是所谓的“南北”流量(编者注:“North-South” traffic。网络传输的流量方向,南北一般指代纵向的不同层级间的传输流量,比如内外网,东西一般指代同一级别的传输流量,比如虚拟机之间),还包括“东西方”流量交互的问题)。更具挑战性的是,我们需要找出一种使用商用基础设施环境(又名云)的方法,而这种方法往往会加剧上述问题。传统信息代理、ESB等不适合这种模式。相反,我们最终会在业务逻辑中编写应用程序网络功能。……我们开始看到诸如Netflix OSS堆栈⑧、Twitter Finagle⑨这样的事物,甚至还有我们自己的Fuse Fabric,它们的确可以解决其中的一些问题。它们通常是库或框架,旨在解决上述一些问题,但它们是特定语言编写的,并且混合在业务逻辑中(或在整个基础设施中分散的业务逻辑中)。因此,这个模式也有问题。这种方法需要在每种语言/框架/运行环境上进行大量投资。我们基本上必须在跨语言/框架上加倍努力,并期望它们能够有效、正确和一致地工作。

11.jpg


经历了上述这些困难,在有能力控制/配置/监控应用级请求的前提下,我们能用最低的成本,高度分散(high decentralization)地将应用网络功能加入到基础设施中,从而解决上述的一些问题。我们称之为“service mesh”。基于Envoy Proxy⑩的istio.io⑪就是个很好的例子。它使我们将应用程序网络功能的问题与业务逻辑区分的问题分离开来:

11.jpg


正如Phil Calcado说的那样⑫,这与TCP/IP网络层的工作非常相似;网络功能被推入到操作系统中,但它们并不是应用程序的一部分。


五、与此相关的概念

通过service mesh,我们明确地将应用程序网络功能与应用程序代码、业务逻辑分离开来,我们正在将其推向另一个层次(推向基础设施,这与我们在网络堆栈、TCP等方面所做的工作类似 )。

12.jpg


所涉及的网络功能包括:

• 简单的、基于元数据的路由 

• 自适应/客户端侧负载均衡 

• 服务发现 

• 熔断 

• 超时/重试/预算 

• 速率限制 

• 度量/记录/追踪 

• 故障注入 

• A/B测试/流量整形/请求镜像


明确不含以下项目(这些项目可能更适合于业务层级的逻辑、应用程序和服务,而不是某些集中式基础设施。):

• 消息转换 

• 消息路由(基于内容的路由) 

• 服务编排


那么service mesh与以下事物的不同点在于

ESB

• 在某些网络功能上有重叠 

• 控制点分散 

• 策略针对特定应用程序 

• 不处理业务逻辑问题(如映射、转换、基于内容的路由等)


消息代理

• 在服务发现、负载均衡、重试、背压等方面有重叠(大概差着30,000英尺) 

• 控制点分散 

• 策略针对特定应用程序 

• 不承担发消息的职责


API管理

• 在策略控制、速率限制、ACL,配额安全等方面有重叠 

• 不处理API的业务方面(定价、文档、用户到计划的映射等) 

• 类似点在于它不实现业务逻辑


至于API管理,似乎有一些重叠,但我更倾向于把这些重叠看作是高度互补。API管理提供有关API的更高级语义(如文档、用户注册/访问、生命周期管理、开发人员API计划、计费和退款等)。调用API时,较低级别的应用程序网络,如熔断器、超时、重试等都是至关重要的,但它们很适合service mesh层。重叠点如ACL、速率限制、配额和策略执行等可以由API管理层定义,但实际上由service mesh层实施。通过这种方式,我们可以拥有完整的端到端策略和访问控制,并强化南/北流量和东/西流量的弹性。如@ZackButcher⑬(来自Istio团队)在twitter中⑭指出那样,“随着规模越来越大,从生产和管理服务的角度来看,东西流量开始变得更像南北流量。”

13.jpg



六、把它们都整合起来

14.jpg


我们需要采用API优先的方法来处理我们的系统架构。我们也要解决弹性等问题。我们也发现了在集成上的挑战。在许多方面,将基于异步事件传递和事件处理的架构作为您的API和微服务交互的底层可以帮助提高可用性、弹性和降低脆性。过去,解决这些问题是一项挑战,因为竞争产品和解决方案的关注存在重叠和混淆。随着我们转向云架构,这种情况变得越来越明显,我们需要梳理这些问题,并将它们放在我们的架构中的适当位置,否则我们就会重蹈覆辙。


从上图可以看出: 

• API管理用于进入的南/北流量 

• service mesh(控制+数据层)用于服务之间的应用网络功能 

• service mesh执行东西流量的API管理策略 

• 集成(编排、转换、反损坏(anti-corruption)层)作为应用程序的一部分 

• 事件驱动的消息底层(back plane),用于真正的异步/事件驱动的交互


如果我们回顾前面提到的四个假设,那么下面是我们如何解决它们的方法: 


• 第一:服务通过网络进行交互 –我们使用service mesh数据层/服务代理 

• 第二:交互并非微不足道的 –在业务本身实现业务集成 

• 第三:控制和可观察性 –使用API管理加service mesh控制层 

• 第四:您具体的业务逻辑;使用service mesh/消息传递等进行优化


七、业务逻辑真的可以被分离出来吗?

我想是可以的,但会存在不清晰的边界。在service mesh中,我们说应用程序应该能意识到应用程序网络功能,但是不应该在应用程序代码中被实现。如何使应用程序更清楚地意识到应用程序网络功能或service mesh层正在做什么事情,有待进一步说明。我认为在这种情况下,很多库或框架会被创建出来。例如,如果Istio service mesh触发熔断,重试一些请求,或者由于特定原因而失败,那么应用程序需要对这些场景有更多的上下文信息以供理解。我们需要一种方法来捕获这些情况或背景并将其反馈给服务。另一个例子是在服务之间传播跟踪背景(即分布式跟踪,如OpenTracing),并且透明地完成传播。我们或许会看到,这些轻型的应用程序/特定语言的库可以使应用程序/服务更智能,并允许它们追溯特定的错误。


八、我们该何去何从

今天这一架构的所有部分具有不同的成熟度。即使如此,对我们的服务架构采取原则化的方法是关键。业务逻辑与应用程序网络应该分开。使用service mesh实现应用程序网络,使用API管理层来处理高级别的以API为中心的问题,将让特定业务的集成放在服务层中。这样一来,我们就可以通过事件驱动的底层(backplane)构建数据密集型或数据可用系统。我认为当我们前进时,我们将不断地看到这些原则在具体的技术实现中被采用。在Red Hat(我工作的地方),我们看到诸如3Scale⑮、Istio.io on Kubernetes⑯、Apache Camel⑰和诸如ActiveMQ Artemis⑱/Apache Qpid Dispatch Router⑲(包括非Red Hat技术,如Apache KafkaIMHO⑳)的讯息技术正被作为强大的构建块来构建遵循以上原则的服务架构。



原文链接:

http://blog.christianposta.com ... mesh/

参考地址:

① http://blog.christianposta.com ... ices/

② http://blog.christianposta.com ... ries/

③ https://www.somethingsimilar.c ... oods/

④ http://web.mit.edu/Saltzer/www ... d.pdf

⑤ http://philcalcado.com/2017/08 ... .html

⑥ https://twitter.com/tef_ebooks ... 22048

⑦ https://twitter.com/_wolfram

⑧ https://netflix.github.io/

⑨ https://twitter.github.io/finagle/

⑩ https://www.envoyproxy.io/

⑪ https://istio.io/

⑫ http://philcalcado.com/2017/08 ... .html

⑬ https://twitter.com/ZackButcher

⑭ https://twitter.com/ZackButche ... 70309

⑮ https://www.3scale.net/

⑯ https://istio.io/

⑰ https://camel.apache.org/

⑱ https://activemq.apache.org/artemis/

⑲ http://qpid.apache.org/compone ... .html

⑳ http://kafka.apache.org/

《Service Mesh 的诞生》:从分布式到微服务

小数 发表了文章 • 0 个评论 • 1258 次浏览 • 2017-12-12 10:15 • 来自相关话题

作者:Phil Calçado,

翻译:雁惊寒

转自:CSDN云计算

摘要:本文由易到难地介绍了分布式系统到服务网格的演化过程,从而让读者对Service Mesh有了更加深刻的认识,以下是译文。


自从几十年前第一次引入分布式系统这个概念以来,出现了很多原来根本想象不到的分布式系统使用案例,但同时也引入了各种各样的新问题。

当这些系统还是比较少比较简单的时候,工程师可以通过减少远程交互的次数来解决复杂性问题。处理分布式问题最安全的方法是尽可能避免远程交互,虽然这可能意味着要在多个系统上存放重复的逻辑和数据。

行业上的需求推动着我们前进的步伐,分布式系统的组成从几个大型的中央电脑发展成为数以千计的小型服务。在这个新的世界里,我们必须走出困境,应对新的挑战和开放性问题。首先,具体问题具体分析,针对某个问题给出有针对性的解决办法,然后再提供更先进更复杂的解决方案。随着我们对问题领域越来越熟悉、提出的解决办法越来越好,我们开始将一些最常见的需求总结归纳为模式、库,以及最终的平台。

当电脑第一次联网


由于人们首先想到的是让两台或多台电脑相互通讯,因此,他们构思出了这样的东西:






互相之间可以通讯的两个服务可以满足最终用户的一些需求。但这个示意图显然过于简单了,缺少了包括通过代码操作的字节转换和在线路上收发的电信号转换在内的多个层。虽然,一定程度上的抽象对于我们的讨论是必需的,但还是让我们来添加网络协议栈组件以增加一点细节内容吧:






上述这个修改过的模型自20世纪50年代以来一直使用至今。一开始,计算机很稀少,也很昂贵,所以两个节点之间的每个环节都被精心制作和维护。随着计算机变得越来越便宜,连接的数量和数据量大幅增加。随着人们越来越依赖网络系统,工程师们需要保证他们构建的软件能够达到用户所要求的服务质量。

当然,还有许多问题急需解决以达到用户要求的服务质量水平。人们需要找到解决方案让机器互相发现、通过同一条线路同时处理多个连接、允许机器在非直连的情况下互相通信、通过网络对数据包进行路由、加密流量等等。

在这其中,有一种叫做流量控制的东西,下面我们以此为例。流量控制是一种防止一台服务器发送的数据包超过下游服务器可以承受上限的机制。这是必要的,因为在一个联网的系统中,你至少有两个不同的、独立的计算机,彼此之间互不了解。 计算机A以给定的速率向计算机B发送字节,但不能保证B可以连续地以足够快的速度来处理接收到的字节。例如,B可能正在忙于并行运行其他任务,或者数据包可能无序到达,并且B可能被阻塞以等待本应该第一个到达的数据包。这意味着A不仅不知道B的预期性能,而且还可能让事情变得更糟,因为这可能会让B过载,B现在必须对所有这些传入的数据包进行排队处理。

一段时间以来,大家寄希望于建立网络服务和应用程序的开发者能够通过编写代码来解决上面提出的挑战。在我们的这个流程控制示例中,应用程序本身必须包含某种逻辑来确保服务不会因为数据包而过载。这种重联网的逻辑与业务逻辑一样重要。在我们的抽象示意图中,它是这样的:






幸运的是,技术的发展日新月异,随着像TCP/IP这样的标准的横空出世,流量控制和许多其他问题的解决方案被融入进了网络协议栈本身。这意味着这些流量控制代码仍然存在,但已经从应用程序转移到了操作系统提供的底层网络层中:






这个模型相当地成功。几乎任何一个组织都能够使用商业操作系统附带的TCP/IP协议栈来驱动他们的业务,即使有高性能和高可靠性的要求。

当第一次使用微服务


多年以来,计算机变得越来越便宜,并且到处可见,而上面提到的网络协议栈已被证明是用于可靠连接系统的事实上的工具集。随着节点和稳定连接的数量越来越多,行业中出现了各种各样的网络系统,从细粒度的分布式代理和对象到由较大但重分布式组件组成的面向服务的架构。

这样的分布式系统给我们带来了很多有趣的更高级别的案例和好处,但也出现了几个难题。其中一些是全新的,但其他的只是我们在讨论原始网络时遇到难题的更高版本而已。

在90年代,Peter Deutsch和他在Sun公司的同事工程师们撰写了“分布式计算的八大错误”一文,其中列出了人们在使用分布式系统时通常会做出的一些假设。Peter认为,这些假设在更原始的网络架构或理论模型中可能是真实的,但在现代世界中是不成立的:

1.网络是可靠的

2.延迟为零

3.带宽是无限的

4.网络是安全的

5.拓扑是不变的

6.有一个管理员

7.传输成本为零

8.网络是同构的


大家把上面这个列表斥为“谬论”,因此,工程师们不能忽视这些问题,必须明确地处理这些问题。

为了处理更复杂的问题,需要转向更加分散的系统(我们通常所说的微服务架构),这在可操作性方面提出了新的要求。 之前我们已经详细讨论了一些内容,但下面则列出了一个必须要处理的东西:

1.计算资源的快速提供

2.基本的监控

3.快速部署

4.易于扩展的存储

5.可轻松访问边缘

6.认证与授权

7.标准化的RPC


因此,尽管数十年前开发的TCP/IP协议栈和通用网络模型仍然是计算机之间相互通讯的有力工具,但更复杂的架构引入了另一个层面的要求,这再次需要由在这方面工作的工程师来实现。

例如,对于服务发现和断路器,这两种技术已用于解决上面列出的几个弹性和分布式问题。

历史往往会重演,第一批基于微服务构建的系统遵循了与前几代联网计算机类似的策略。这意味着落实上述需求的责任落在了编写服务的工程师身上。






服务发现是在满足给定查询条件的情况下自动查找服务实例的过程,例如,一个名叫Teams的服务需要找到一个名为Players的服务实例,其中该实例的environment属性设置为production。你将调用一些服务发现进程,它们会返回一个满足条件的服务列表。对于更集中的架构而言,这是一个非常简单的任务,可以通常使用DNS、负载均衡器和一些端口号的约定(例如,所有服务将HTTP服务器绑定到8080端口)来实现。而在更分散的环境中,任务开始变得越来越复杂,以前可以通过盲目信任DNS来查找依赖关系的服务现在必须要处理诸如客户端负载均衡、多种不同环境、地理位置上分散的服务器等问题。如果之前只需要一行代码来解析主机名,那么现在你的服务则需要很多行代码来处理由分布式引入的各种问题。

断路器是由Michael Nygard在其编写的“Release It”一书中引入的模式。我非常喜欢Martin Fowler对该模式的一些总结:

断路器背后的基本思路非常简单。将一个受保护的函数调用包含在用于监视故障的断路器对象中。一旦故障达到一定阈值,则断路器跳闸,并且对断路器的所有后续调用都将返回错误,并完全不接受对受保护函数的调用。通常,如果断路器发生跳闸,你还需要某种监控警报。

这些都是非常简单的设备,它们能为服务之间的交互提供更多的可靠性。然而,跟其他的东西一样,随着分布式水平的提高,它们也会变得越来越复杂。系统发生错误的概率随着分布式水平的提高呈指数级增长,因此即使简单的事情,如“如果断路器跳闸,则监控警报”,也就不那么简单了。一个组件中的一个故障可能会在许多客户端和客户端的客户端上产生连锁反应,从而触发数千个电路同时跳闸。而且,以前可能只需几行代码就能处理某个问题,而现在需要编写大量的代码才能处理这些只存在于这个新世界的问题。

事实上,上面举的两个例子可能很难正确实现,这也是大型复杂库,如Twitter的Finagle和Facebook的Proxygen,深受欢迎的原因,它们能避免在每个服务中重写相同的逻辑。






大多数采用微服务架构的组织都遵循了上面提到的那个模型,如Netflix、Twitter和SoundCloud。随着系统中服务数量的增加,他们发现了这种方法存在着各种弊端。

即使是使用像Finagle这样的库,项目团队仍然需要投入大量的时间来将这个库与系统的其他部分结合起来,这是一个代价非常高的难题。根据我在SoundCloud和DigitalOcean的经验,我估计在100-250人规模的工程师组织中,需要有1/10的人员来构建模型。有时,这种代价很容易看到,因为工程师被分配到了专门构建工具的团队中,但是更多的时候,这种代价是看不见的,因为它表现为在产品研发上需要花费更多的时间。

第二个问题是,上面的设置限制了可用于微服务的工具、运行时和语言。用于微服务的库通常是为特定平台编写的,无论是编程语言还是像JVM这样的运行时。如果开发团队使用了库不支持的平台,那么通常需要将代码移植到新的平台。这浪费了本来就很短的工程时间。工程师没办法再把重点放在核心业务和产品上,而是不得不花时间来构建工具和基础架构。那就是为什么一些像SoundCloud和DigitalOcean这样的中型企业认为其内部服务只需支持一个平台,分别是Scala或者Go。

这个模型最后一个值得讨论的问题是管理方面的问题。库模型可能对解决微服务架构需求所需功能的实现进行抽象,但它本身仍然是需要维护的组件。必须要确保数千个服务实例所使用的库的版本是相同的或至少是兼容的,并且每次更新都意味着要集成、测试和重新部署所有服务,即使服务本身没有任何改变。

下一个逻辑


类似于我们在网络协议栈中看到的那样,大规模分布式服务所需的功能应该放到底层的平台中。

人们使用高级协议(如HTTP)编写非常复杂的应用程序和服务,甚至无需考虑TCP是如何控制网络上的数据包的。这种情况就是微服务所需要的,那些从事服务开发工作的工程师可以专注于业务逻辑的开发,从而避免浪费时间去编写自己的服务基础设施代码或管理整个系统的库和框架。

将这个想法结合到我们的图表中,我们可以得到如下所示的内容:






不幸的是,通过改变网络协议栈来添加这个层并不是一个可行的任务。许多人的解决方案是通过一组代理来实现。这个的想法是,服务不会直接连接到它的下游,而是让所有的流量都将通过一个小小的软件来透明地添加所需功能。

在这个领域第一个有记载的进步使用了边三轮(sidecars)这个概念。“边三轮”是一个辅助进程,它与主应用程序一起运行,并为其提供额外的功能。在2013年,Airbnb写了一篇有关Synapse和Nerve的文章,这是“边三轮”的一个开源实现。一年后,Netflix推出了Prana,专门用于让非JVM应用程序从他们的NetflixOSS生态系统中受益。在SoundCloud,我们构建了可以让遗留的Ruby程序使用我们为JVM微服务构建的基础设施的“边三轮”。






虽然有这么几个开源的代理实现,但它们往往被设计为需要与特定的基础架构组件配合使用。例如,在服务发现方面,Airbnb的Nerve和Synapse假设了服务是在Zookeeper中注册,而对于Prana,则应该使用Netflix自己的Eureka服务注册表 。

随着微服务架构的日益普及,我们最近看到了一波新的代理浪潮,它们足以灵活地适应不同的基础设施组件和偏好。 这个领域中第一个广为人知的系统是Linkerd,它由Buoyant创建出来,源于他们的工程师先前在Twitter微服务平台上的工作。很快,Lyft的工程团队宣布了Envoy的发布,它遵循了类似的原则。

Service Mesh


在这种模式中,每个服务都配备了一个代理“边三轮”。由于这些服务只能通过代理“边三轮”进行通信,我们最终会得到类似于下图的部署方案:






Buoyant的首席执行官威廉·摩根表示,代理之间的互连形成了服务网格。 2017年初,威廉写下了这个平台的定义,并称它为服务网格:

服务网格是用于处理服务到服务通信的专用基础设施层。它负责通过复杂的服务拓扑来可靠地传递请求。实际上,服务网格通常被实现为与应用程序代码一起部署的轻量级网络代理矩阵,并且它不会被应用程序所感知。

这个定义最强大的地方可能就在于它不再把代理看作是孤立的组件,并承认它们本身就是一个有价值的网络。








随着微服务部署被迁移到更为复杂的运行时中去,如Kubernetes和Mesos,人们开始使用一些平台上的工具来实现网格网络这一想法。他们实现的网络正从互相之间隔离的独立代理,转移到一个合适的并且有点集中的控制面上来。






来看看这个鸟瞰图,实际的服务流量仍然直接从代理流向代理,但是控制面知道每个代理实例。控制面使得代理能够实现诸如访问控制和度量收集这样的功能,但这需要它们之间进行合作:





 

最近公布的Istio项目是这类系统中最著名的例子。

完全理解服务网格在更大规模系统中的影响还为时尚早,但这种架构已经凸显出两大优势。首先,不必编写针对微服务架构的定制化软件,即可让许多小公司拥有以前只有大型企业才能拥有的功能,从而创建出各种有趣的案例。第二,这种架构可以让我们最终实现使用最佳工具或语言进行工作的梦想,并且不必担心每个平台的库和模式的可用性。 查看全部
作者:Phil Calçado,

翻译:雁惊寒

转自:CSDN云计算

摘要:本文由易到难地介绍了分布式系统到服务网格的演化过程,从而让读者对Service Mesh有了更加深刻的认识,以下是译文。


自从几十年前第一次引入分布式系统这个概念以来,出现了很多原来根本想象不到的分布式系统使用案例,但同时也引入了各种各样的新问题。

当这些系统还是比较少比较简单的时候,工程师可以通过减少远程交互的次数来解决复杂性问题。处理分布式问题最安全的方法是尽可能避免远程交互,虽然这可能意味着要在多个系统上存放重复的逻辑和数据。

行业上的需求推动着我们前进的步伐,分布式系统的组成从几个大型的中央电脑发展成为数以千计的小型服务。在这个新的世界里,我们必须走出困境,应对新的挑战和开放性问题。首先,具体问题具体分析,针对某个问题给出有针对性的解决办法,然后再提供更先进更复杂的解决方案。随着我们对问题领域越来越熟悉、提出的解决办法越来越好,我们开始将一些最常见的需求总结归纳为模式、库,以及最终的平台。

当电脑第一次联网


由于人们首先想到的是让两台或多台电脑相互通讯,因此,他们构思出了这样的东西:

1.jpg


互相之间可以通讯的两个服务可以满足最终用户的一些需求。但这个示意图显然过于简单了,缺少了包括通过代码操作的字节转换和在线路上收发的电信号转换在内的多个层。虽然,一定程度上的抽象对于我们的讨论是必需的,但还是让我们来添加网络协议栈组件以增加一点细节内容吧:

2.jpg


上述这个修改过的模型自20世纪50年代以来一直使用至今。一开始,计算机很稀少,也很昂贵,所以两个节点之间的每个环节都被精心制作和维护。随着计算机变得越来越便宜,连接的数量和数据量大幅增加。随着人们越来越依赖网络系统,工程师们需要保证他们构建的软件能够达到用户所要求的服务质量。

当然,还有许多问题急需解决以达到用户要求的服务质量水平。人们需要找到解决方案让机器互相发现、通过同一条线路同时处理多个连接、允许机器在非直连的情况下互相通信、通过网络对数据包进行路由、加密流量等等。

在这其中,有一种叫做流量控制的东西,下面我们以此为例。流量控制是一种防止一台服务器发送的数据包超过下游服务器可以承受上限的机制。这是必要的,因为在一个联网的系统中,你至少有两个不同的、独立的计算机,彼此之间互不了解。 计算机A以给定的速率向计算机B发送字节,但不能保证B可以连续地以足够快的速度来处理接收到的字节。例如,B可能正在忙于并行运行其他任务,或者数据包可能无序到达,并且B可能被阻塞以等待本应该第一个到达的数据包。这意味着A不仅不知道B的预期性能,而且还可能让事情变得更糟,因为这可能会让B过载,B现在必须对所有这些传入的数据包进行排队处理。

一段时间以来,大家寄希望于建立网络服务和应用程序的开发者能够通过编写代码来解决上面提出的挑战。在我们的这个流程控制示例中,应用程序本身必须包含某种逻辑来确保服务不会因为数据包而过载。这种重联网的逻辑与业务逻辑一样重要。在我们的抽象示意图中,它是这样的:

3.jpg


幸运的是,技术的发展日新月异,随着像TCP/IP这样的标准的横空出世,流量控制和许多其他问题的解决方案被融入进了网络协议栈本身。这意味着这些流量控制代码仍然存在,但已经从应用程序转移到了操作系统提供的底层网络层中:

4.jpg


这个模型相当地成功。几乎任何一个组织都能够使用商业操作系统附带的TCP/IP协议栈来驱动他们的业务,即使有高性能和高可靠性的要求。

当第一次使用微服务


多年以来,计算机变得越来越便宜,并且到处可见,而上面提到的网络协议栈已被证明是用于可靠连接系统的事实上的工具集。随着节点和稳定连接的数量越来越多,行业中出现了各种各样的网络系统,从细粒度的分布式代理和对象到由较大但重分布式组件组成的面向服务的架构。

这样的分布式系统给我们带来了很多有趣的更高级别的案例和好处,但也出现了几个难题。其中一些是全新的,但其他的只是我们在讨论原始网络时遇到难题的更高版本而已。

在90年代,Peter Deutsch和他在Sun公司的同事工程师们撰写了“分布式计算的八大错误”一文,其中列出了人们在使用分布式系统时通常会做出的一些假设。Peter认为,这些假设在更原始的网络架构或理论模型中可能是真实的,但在现代世界中是不成立的:

1.网络是可靠的

2.延迟为零

3.带宽是无限的

4.网络是安全的

5.拓扑是不变的

6.有一个管理员

7.传输成本为零

8.网络是同构的


大家把上面这个列表斥为“谬论”,因此,工程师们不能忽视这些问题,必须明确地处理这些问题。

为了处理更复杂的问题,需要转向更加分散的系统(我们通常所说的微服务架构),这在可操作性方面提出了新的要求。 之前我们已经详细讨论了一些内容,但下面则列出了一个必须要处理的东西:

1.计算资源的快速提供

2.基本的监控

3.快速部署

4.易于扩展的存储

5.可轻松访问边缘

6.认证与授权

7.标准化的RPC


因此,尽管数十年前开发的TCP/IP协议栈和通用网络模型仍然是计算机之间相互通讯的有力工具,但更复杂的架构引入了另一个层面的要求,这再次需要由在这方面工作的工程师来实现。

例如,对于服务发现和断路器,这两种技术已用于解决上面列出的几个弹性和分布式问题。

历史往往会重演,第一批基于微服务构建的系统遵循了与前几代联网计算机类似的策略。这意味着落实上述需求的责任落在了编写服务的工程师身上。

5.jpg


服务发现是在满足给定查询条件的情况下自动查找服务实例的过程,例如,一个名叫Teams的服务需要找到一个名为Players的服务实例,其中该实例的environment属性设置为production。你将调用一些服务发现进程,它们会返回一个满足条件的服务列表。对于更集中的架构而言,这是一个非常简单的任务,可以通常使用DNS、负载均衡器和一些端口号的约定(例如,所有服务将HTTP服务器绑定到8080端口)来实现。而在更分散的环境中,任务开始变得越来越复杂,以前可以通过盲目信任DNS来查找依赖关系的服务现在必须要处理诸如客户端负载均衡、多种不同环境、地理位置上分散的服务器等问题。如果之前只需要一行代码来解析主机名,那么现在你的服务则需要很多行代码来处理由分布式引入的各种问题。

断路器是由Michael Nygard在其编写的“Release It”一书中引入的模式。我非常喜欢Martin Fowler对该模式的一些总结:

断路器背后的基本思路非常简单。将一个受保护的函数调用包含在用于监视故障的断路器对象中。一旦故障达到一定阈值,则断路器跳闸,并且对断路器的所有后续调用都将返回错误,并完全不接受对受保护函数的调用。通常,如果断路器发生跳闸,你还需要某种监控警报。

这些都是非常简单的设备,它们能为服务之间的交互提供更多的可靠性。然而,跟其他的东西一样,随着分布式水平的提高,它们也会变得越来越复杂。系统发生错误的概率随着分布式水平的提高呈指数级增长,因此即使简单的事情,如“如果断路器跳闸,则监控警报”,也就不那么简单了。一个组件中的一个故障可能会在许多客户端和客户端的客户端上产生连锁反应,从而触发数千个电路同时跳闸。而且,以前可能只需几行代码就能处理某个问题,而现在需要编写大量的代码才能处理这些只存在于这个新世界的问题。

事实上,上面举的两个例子可能很难正确实现,这也是大型复杂库,如Twitter的Finagle和Facebook的Proxygen,深受欢迎的原因,它们能避免在每个服务中重写相同的逻辑。

微信图片_20171212100841.jpg


大多数采用微服务架构的组织都遵循了上面提到的那个模型,如Netflix、Twitter和SoundCloud。随着系统中服务数量的增加,他们发现了这种方法存在着各种弊端。

即使是使用像Finagle这样的库,项目团队仍然需要投入大量的时间来将这个库与系统的其他部分结合起来,这是一个代价非常高的难题。根据我在SoundCloud和DigitalOcean的经验,我估计在100-250人规模的工程师组织中,需要有1/10的人员来构建模型。有时,这种代价很容易看到,因为工程师被分配到了专门构建工具的团队中,但是更多的时候,这种代价是看不见的,因为它表现为在产品研发上需要花费更多的时间。

第二个问题是,上面的设置限制了可用于微服务的工具、运行时和语言。用于微服务的库通常是为特定平台编写的,无论是编程语言还是像JVM这样的运行时。如果开发团队使用了库不支持的平台,那么通常需要将代码移植到新的平台。这浪费了本来就很短的工程时间。工程师没办法再把重点放在核心业务和产品上,而是不得不花时间来构建工具和基础架构。那就是为什么一些像SoundCloud和DigitalOcean这样的中型企业认为其内部服务只需支持一个平台,分别是Scala或者Go。

这个模型最后一个值得讨论的问题是管理方面的问题。库模型可能对解决微服务架构需求所需功能的实现进行抽象,但它本身仍然是需要维护的组件。必须要确保数千个服务实例所使用的库的版本是相同的或至少是兼容的,并且每次更新都意味着要集成、测试和重新部署所有服务,即使服务本身没有任何改变。

下一个逻辑


类似于我们在网络协议栈中看到的那样,大规模分布式服务所需的功能应该放到底层的平台中。

人们使用高级协议(如HTTP)编写非常复杂的应用程序和服务,甚至无需考虑TCP是如何控制网络上的数据包的。这种情况就是微服务所需要的,那些从事服务开发工作的工程师可以专注于业务逻辑的开发,从而避免浪费时间去编写自己的服务基础设施代码或管理整个系统的库和框架。

将这个想法结合到我们的图表中,我们可以得到如下所示的内容:

7.jpg


不幸的是,通过改变网络协议栈来添加这个层并不是一个可行的任务。许多人的解决方案是通过一组代理来实现。这个的想法是,服务不会直接连接到它的下游,而是让所有的流量都将通过一个小小的软件来透明地添加所需功能。

在这个领域第一个有记载的进步使用了边三轮(sidecars)这个概念。“边三轮”是一个辅助进程,它与主应用程序一起运行,并为其提供额外的功能。在2013年,Airbnb写了一篇有关Synapse和Nerve的文章,这是“边三轮”的一个开源实现。一年后,Netflix推出了Prana,专门用于让非JVM应用程序从他们的NetflixOSS生态系统中受益。在SoundCloud,我们构建了可以让遗留的Ruby程序使用我们为JVM微服务构建的基础设施的“边三轮”。

8.jpg


虽然有这么几个开源的代理实现,但它们往往被设计为需要与特定的基础架构组件配合使用。例如,在服务发现方面,Airbnb的Nerve和Synapse假设了服务是在Zookeeper中注册,而对于Prana,则应该使用Netflix自己的Eureka服务注册表 。

随着微服务架构的日益普及,我们最近看到了一波新的代理浪潮,它们足以灵活地适应不同的基础设施组件和偏好。 这个领域中第一个广为人知的系统是Linkerd,它由Buoyant创建出来,源于他们的工程师先前在Twitter微服务平台上的工作。很快,Lyft的工程团队宣布了Envoy的发布,它遵循了类似的原则。

Service Mesh


在这种模式中,每个服务都配备了一个代理“边三轮”。由于这些服务只能通过代理“边三轮”进行通信,我们最终会得到类似于下图的部署方案:

9.jpg


Buoyant的首席执行官威廉·摩根表示,代理之间的互连形成了服务网格。 2017年初,威廉写下了这个平台的定义,并称它为服务网格:

服务网格是用于处理服务到服务通信的专用基础设施层。它负责通过复杂的服务拓扑来可靠地传递请求。实际上,服务网格通常被实现为与应用程序代码一起部署的轻量级网络代理矩阵,并且它不会被应用程序所感知。

这个定义最强大的地方可能就在于它不再把代理看作是孤立的组件,并承认它们本身就是一个有价值的网络。


10.jpg



随着微服务部署被迁移到更为复杂的运行时中去,如Kubernetes和Mesos,人们开始使用一些平台上的工具来实现网格网络这一想法。他们实现的网络正从互相之间隔离的独立代理,转移到一个合适的并且有点集中的控制面上来。

11.jpg


来看看这个鸟瞰图,实际的服务流量仍然直接从代理流向代理,但是控制面知道每个代理实例。控制面使得代理能够实现诸如访问控制和度量收集这样的功能,但这需要它们之间进行合作:

12.jpg

 

最近公布的Istio项目是这类系统中最著名的例子。

完全理解服务网格在更大规模系统中的影响还为时尚早,但这种架构已经凸显出两大优势。首先,不必编写针对微服务架构的定制化软件,即可让许多小公司拥有以前只有大型企业才能拥有的功能,从而创建出各种有趣的案例。第二,这种架构可以让我们最终实现使用最佳工具或语言进行工作的梦想,并且不必担心每个平台的库和模式的可用性。

Service Mesh:下一代微服务(PDF版本下载)

小数 发表了文章 • 4 个评论 • 877 次浏览 • 2017-11-07 15:58 • 来自相关话题

这是敖小剑老师在2017年10月的Qcon上海上做的演讲,附件为PDF格式,推荐给想了解service mesh技术的同学,有需求可以下载。
 
此次活动的演讲实录也可以在这里查看,点击链接即可 查看全部
这是敖小剑老师在2017年10月的Qcon上海上做的演讲,附件为PDF格式,推荐给想了解service mesh技术的同学,有需求可以下载。
 
此次活动的演讲实录也可以在这里查看,点击链接即可

PPT分享:8 Steps to Becoming Awesome with Kubernetes

敖小剑 发表了文章 • 2 个评论 • 763 次浏览 • 2017-11-06 15:33 • 来自相关话题

 
最近刚刚放出来的Slides,需要科学上网,也可以直接下载附件。

8 Steps to Becoming Awesome with Kubernetes





 
https://docs.google.com/presentation/d/1ij64THksTygvifW5BD-n0ipc6MDF4cGBRQcV3BRYaoM/edit#slide=id.g12c8aac1e6_0_0
 
终于看到国外也有人喊出下一代微服务的口号了!





 
另外宋总第一时间将图片做了汇总,更加明显了,我盗个图:





  查看全部
 
最近刚刚放出来的Slides,需要科学上网,也可以直接下载附件。

8 Steps to Becoming Awesome with Kubernetes

webwxgetmsgimg_(1).jpg

 
https://docs.google.com/presentation/d/1ij64THksTygvifW5BD-n0ipc6MDF4cGBRQcV3BRYaoM/edit#slide=id.g12c8aac1e6_0_0
 
终于看到国外也有人喊出下一代微服务的口号了!

webwxgetmsgimg.jpg

 
另外宋总第一时间将图片做了汇总,更加明显了,我盗个图:

webwxgetmsgimg_(2).jpg

 

Awesome Service Mesh资料清单

敖小剑 发表了文章 • 7 个评论 • 556 次浏览 • 2017-11-01 16:56 • 来自相关话题

Service Mesh是一个新兴的技术,资料相对比较少,为了便于收集整理Service Mesh相关的博客/文章/演讲/视频等资料,Service Mesh中文网决定创建并维护这份Awesome Service Mesh资料清单。

资料内容来自国内国内公开媒体,转载时我们会指明出处,标注原作者和原译者,如果是原创或者原创翻译也会标明作者或者译者身份。

首页为所有内容的列表和访问链接,后续内容是我们认为非常有阅读价值的中文内容,以方便大家集中浏览或者下载后阅读:
 
https://servicemesh.gitbooks.i ... mesh/

​备注: 目前采用的是gitbook提供的托管,服务器在国外,速度比较慢,偶尔被墙。后续会换成 国内服务器以提高访问速度。 
 
也可以下载后阅读:
下载pdf格式下载mobi格式下载epub格式
 
项目托管在github,欢迎大家star并提交资料线索,可以开 issue 也可以提交PR。
 
https://github.com/ServicemeshCN/awesome-servicemesh
  查看全部
Service Mesh是一个新兴的技术,资料相对比较少,为了便于收集整理Service Mesh相关的博客/文章/演讲/视频等资料,Service Mesh中文网决定创建并维护这份Awesome Service Mesh资料清单。

资料内容来自国内国内公开媒体,转载时我们会指明出处,标注原作者和原译者,如果是原创或者原创翻译也会标明作者或者译者身份。

首页为所有内容的列表和访问链接,后续内容是我们认为非常有阅读价值的中文内容,以方便大家集中浏览或者下载后阅读:
 
https://servicemesh.gitbooks.i ... mesh/

​备注: 目前采用的是gitbook提供的托管,服务器在国外,速度比较慢,偶尔被墙。后续会换成 国内服务器以提高访问速度。 
 
也可以下载后阅读:

 
项目托管在github,欢迎大家star并提交资料线索,可以开 issue 也可以提交PR。
 
https://github.com/ServicemeshCN/awesome-servicemesh