姜 伟,潘邵芹
(北京工业大学 信息学部,北京 100124)
随着业务需求的多元化以及系统规模的不断扩大,单体架构的服务架构可扩展性越来越差,系统变得难以维护,而微服务通过服务功能拆分、模块功能聚合,使单体架构的服务拆分成多个微服务,提高了扩展性和可维护性[1-3],因此微服务架构在分布式服务领域有着越来越重要的位置。微服务架构目前的负载均衡策略主要在调用方控制,依赖于随机调用或Round Robin方式,没有考虑网络负载以及调用链路情况[3-4]。
SDN是目前广受关注的新型网络架构[5-6],通过将控制平面和数据平面进行分离,提高了对网络流量的控制能力,使SDN控制器能够实施细粒度的路径规划和控制能力[7-8],是未来网络的发展方向。
文中研究基于SDN的微服务负载均衡方案,通过将微服务部署于SDN网络,可以借助SDN控制平面的精细化管控能力提供更细粒度的负载均衡能力,实现针对微服务特点的负载均衡的优化。
负载均衡一般会维护一个服务端清单,利用心跳检测等手段进行清单维护,保证清单中都是可以正常访问的服务节点。当用户发送请求时,会先到达负载均衡器,负载均衡器根据负载均衡算法(轮询、随机、加权轮询)从可用的服务端列表中取出一台服务端的地址,根据负载情况进行转发,降低系统的压力[9-12]。
文献[13]设计并实现了一种链路负载均衡方案,在利用SDN获取了全局网络拓扑视图的基础上,实现了一种最优K条路径算法,选择出最优的K条冗余链路,制定评价模型对于每条候选链路进行评估,得到最有利于当前全局网络负载均衡的链路,最终将对应的转发策略部署到OpenFlow交换机的流表上。
文献[14]提出一种基于SDN的分布式服务器负载均衡方法,SDN控制器管理通过SDN网络访问服务器集群的进出流量,并能综合网络设备、服务器负载与用户特定需求,部署动态可扩展的负载均衡策略。
文献[9]确定了在OpenFlow网络中进行负载均衡需要解决的三个关键问题:服务器状态的度量、网络状态的度量和路径选择,提出了一种基于Open Flow的负载均衡算法。该算法对网络建立起全局的视图,综合考虑网络资源与计算资源的使用状态,通过统一的决策,合理地进行流量分配,以达成负载均衡的目标。
文中主要工作是研究将SDN技术应用于微服务架构,利用SDN对网络的精细化管控能力使微服务架构达到更优的负载均衡策略。重点研究并解决了下列问题:
研究负载均衡由客户端上移到控制平面:为了使负载均衡能够在得知全网流量视图的基础上计算策略,而不是仅仅依靠round robin这种比较随机的方式,需要将微服务调用的负载均衡策略选择从客户端上移到控制平面。
基于调用链分析的微服务负载均衡:负载均衡决策上移到控制平面后,可以针对全局网络视图进行路径决策,还可以根据微服务的特点,进行调用链路分析,不局限在两个主机之间的网络通信,而是综合考虑整个调用链路的网络负载情况,提升负载均衡决策的效果。
服务限流:当服务调用量过多或服务容量不够时,只靠负载均衡仍然可能不足以支撑微服务集群的正常工作,为避免过多的流量造成网络或服务不可用,需要进行限流。
基于SDN的微服务网络组成如图1所示。微服务的应用服务器部署于SDN网络之中,微服务之间通过应用名进行服务调用,应用名与ip的绑定与映射由服务注册与发现机制完成,通过将服务注册与发现组件嵌入到控制平面也就是SDN控制器,实现将微服务调用过程的负载均衡完全上移到控制平面,服务调用方不需要感知负载均衡策略,而控制平面则能够实现更精细化的负载均衡策略,可以综合考量服务提供方主机的负载情况、网络路径的带宽情况,进而引入调用链路分析,根据微服务的特点进行调用链路的负载均衡决策,而不仅仅限于两台主机之间的网络通信。
图1 基于SDN的微服务网络组成
使用SDN进行负载均衡设计,首先需要解决如何将微服务调用过程对目的节点的选择上移到SDN控制器。为此,文中定义虚IP。虚IP与特定的服务进行绑定,调用该服务时使用虚IP,这样调用方不需要知道被调用服务有几台机器,也不需要知道这些机器的IP,负载均衡策略完全对调用方透明。此外,当被调用服务节点下线、上线新机器时,调用方不需要感知。服务提供方服务节点的选取、网络路径的计算都由SDN的微服务链路计算与负载均衡模块进行处理。当SDN控制器计算好网络路径后,目的服务节点也就确定下来,这时候会有IP改写的过程,将虚IP改写成实际服务节点的IP。
当微服务A的某台节点调用微服务B的服务时,主要会有以下步骤:
(1)需要发起服务调用的机器向服务发现模块进行服务发现请求,请求微服务B的IP;
(2)服务发现模块返回微服务B对应的虚IP:ipB;
(3)微服务A向ipB发起服务请求;
(4)SDN控制器进行路径计算,选择微服务B的某个主机的IP,如ip2;
(5)SDN控制器向SDN交换机下发流表进行转发的同时对IP进行改写(目的IP由IPB改为ip2)。
微服务架构中,服务调用通常伴随着下游依赖的调用,导致一个服务调用的链路可能会比较长,在负载均衡决策中,就不能只考虑服务调用的两个节点之间,而应该考虑整个调用链路上的负载均衡。
图2展示了典型微服务调用的调用链路。应用A调用应用B时,伴随着应用B调用应用C,应用C调用应用D和E,只对应用A到应用B之间的链路做负载均衡存在弊端。图3展示了微服务的分布式节点网络联通图。节点{Xi|X∈(A,B,C,D…),i∈(1,2,3,4…)}分别代表微服务X的服务器节点,连接线表示某台服务器可以通过网络(可以经过若干交换机,图里省略了交换机)与另一台服务器通信,在应用A调用应用B的服务时,存在多条链路可以选择,如果只考虑A→B的链路,链路负载可能不是最佳的选择,还可能选择的链路无法完成后续调用导致调用失败(C1→D1之间网络故障无法调用成功)。
图2 微服务调用(A→B)引起的服务调用链路
图3 微服务调用的分布式节点示意(省略交换机)
微服务调用有以下特点:
(1)服务以分布式部署,服务调用没有明确的调用目的主机,网络路径选择是对服务之间,而不是主机之间;
(2)局部最优不一定表示整个调用链路最优;
(3)某个网络链路中断如C1→D1中断导致A→B1→C1是调不通的路径,如果不进行调用链路分析,对A调用B服务进行路径选择时可能会选择A→B1的路径,导致B服务的后续调用失败。
基于调用链路分析的负载均衡算法综合考虑整个服务调用链路涉及到的网络负载状况,进行综合的路径选择考量。SDN控制器在处理流表请求时分析应用之间的依赖关系,逐渐维护出微服务之间的调用链路,在进行微服务负载均衡路径计算时,综合考虑整个调用链路涉及到的所有网络节点的负载情况,计算出更合适的路径。
以图3为例,基于调用链路分析的微服务负载均衡路径计算主要步骤可通过图4简要描述:
(1)节点标注:计算路径时不再抽象成无差别的网络节点,明确网络节点的身份:交换机、服务A、服务B……
(2)链路剪枝:剪掉不符合调用逻辑的节点如A→F(服务A没有调用服务B)、B2→E1(服务B没有调用服务C);
(3)以服务为基准进行费用计算。从最后一个服务开始,标注调用该服务的某台机器需要的费用;
(4)依次沿着调用链路逆向计算费用,直到调用源头。
图4 基于调用链路分析的微服务负载均衡
当网络请求到达SDN网络时,需要路由到限流服务器决定是否通过,SDN控制器通过对SDN交换机安装流表,将网络流量转发到限流服务器,由限流服务器决定是否允许网络流量通过。
如果网络流没有触发限流,被允许通过,限流服务器需要把数据包发送回网络,并按照合适的路径传输给目的主机。但前文提到,需要把新进入网络的数据包转发到限流服务器,当限流服务器把数据包传回网络时,需要网络能够正确处理网络数据包,不再转发给限流服务器,而是按照正常的路径规划转发到目标节点。
为了能够区分到达限流服务器之前的数据包和从限流服务器传回的数据包,文中通过VLAN标记对两种数据包进行标识。当限流服务器将数据包传回SDN网络时,需要对数据包添加VALN标记,SDN交换机和SDN控制器通过VLAN标记对两种数据包进行区分。此技术消耗一个VLAN id即可,文中定义为VLAN 10。
在SDN交换机的流表项匹配时,使用流表优先级确定对网络数据包的转发决定。为此需要预先安装另一条流表1:VLAN 10,转发至SDN控制器,优先级A。前文提到的默认转发到限流服务器的流表2优先级定义为B。优先级A>B,当网络数据包到达SDN网络时,SDN交换机有两个流表,流表1优先级高,但此时数据包没有VLAN 10的标记,所以不匹配流表1,但匹配流表2,从而按照流表2的转发决定转发到限流服务器。当限流服务器把数据包传回SDN网络时,由于添加了VLAN 10标记,从而匹配到了流表1,按照流表1的转发决定把数据包转发到SDN控制器,SDN控制器为其进行路径选择,然后安装相应流表(定义为流表3,优先级C)到SDN交换机。此时流表优先级C>A>B。所以数据包此后会按照流表3的转发决定,被转发到目的服务节点。
图5为网络流被允许通过时网络流的走向。其中,步骤3将网络流转发到限流服务器,限流服务器决定允许该网络流正常转发,对数据包添加VLAN 10标记,然后传回到SDN网路中,到达SDN交换机后,由于匹配到了流表1,且流表1的优先级大于流表2,所以会向SDN控制器发出请求流表。步骤7控制器为交换机安装正常转发的流表3,该流表的优先级最高,后续的转发行为将按照此流表正常转发到服务节点。
图5 微服务通信时的网络数据流向
Mininet是一款广泛使用的SDN网络测试平台,文中基于Mininet搭建网络拓扑,并基于ONOS(一款分布式SDN控制器)编写算法,微服务使用thrift框架编写,运行于docker容器中,docker容器内运行ubuntu操作系统。整个实验的网络拓扑如图6所示,共10台SDN交换机,由Mininet拓扑脚本建立,13台运行微服务的主机,部署在13台docker容器中,微服务之间的调用关系与图5保持一致。docker容器与SDN交换机进行桥接,以进行网络连通。实验中交换机端口带宽配置为50 M,延迟10 ms。
图6 实验拓扑
首先将D1与S6的连接断开,主机A1发起服务调用,使用随机模式的负载均衡与文中提出的基于调用链路分析的负载均衡算法分别进行1 000次调用,重复10次试验,结果表明文中算法的调用全部成功,随机模式的实验结果如图7所示。大体上有三分之一的调用失败,其原因为A应用调用B应用有3个候选机器,每个机器同等概率被调用,但主机B1的调用后续链路是不通的。
图7 实验1随机负载均衡算法失败次数
然后将D1与S6的连接恢复,延迟时间增加到100 ms,使用iperf工具进行随机的背景流量发送,然后进行100次服务调用,对比平均调用时延,结果如图8所示。可见文中提出的算法能够有效降低调用时延,其原因主要是随机负载均衡算法无法感知某个调用链路具体的优劣,无法进行更优化的路径选择。
最后进行服务限流实验,开启20 M/s的随机背景流量,随后不断加大调用频率,出现大量超时后,统计100次调用成功的平均时延,共统计10次,随后开启限流,丢弃1/4的流量,重复实验,结果如图9所示。实验表明限流功能能够有效减少网络拥堵。
图8 随着流量增多服务调用延迟趋势
图9 限流实验结果
对基于SDN的微服务场景下的负载均衡与限流进行了研究,通过虚IP与IP改写技术,将微服务调用的负载均衡上移到控制平面,进而提出了基于调用链路分析的负载均衡算法。同时通过VLAN标记和流表优先级机制实现服务限流,在服务过载时保护服务的正常服务,避免服务不可用。实验结果表明,提出的算法、策略能够降低微服务的调用时延,提升微服务的性能。