京东网络接入体系解密之高性能四层网关DLVS

综合技术 2018-02-07 阅读原文

DLVS诞生之初

在SLB这块,京东用户接入系统提供四层负载均衡服务和应用层负载均衡服务,对于公网流量接入部分,和很多公司一样采用的是四层和应用层负载相结合的架构,利用四层负载来实现应用层的水平扩展。四层负载在JFE 1.0版本中使用开源的LVS实现,考虑单机性能的问题,使用了DR模式和集群部署方式,并将LVS和应用层负载按照服务单元进行部署。这种模式在中等规模的业务场景运行良好,随着业务的不断增长,单业务QPS超过200万,以及全站HTTPS改造要求SSL在SLB上完成卸载,应用层负载集群规模将不断扩大,同时受限机房机架资源等因素,需要实现四,应用层负载解耦。为此我们对四层负载进行了重新的设计和自主研发,加入了在线上服务保障过程中的业务诉求,在性能、可用性、运维管理以及安全防护上提升。

业务增长对性能的需求

在过去的10年,京东的流量峰值从几十万到现在的千万级QPS,给流量分发的四层负载均衡服务带来了巨大的挑战。Linux内核实现版本受限于网卡的中断收包模式以及二三层锁的开销,系统经过调优后的转发能力单台QPS在十万级别。为了满足业务流量的陡增,只能是通过增加集群规模和通过多集群的方式进行扩容,随着集群数量和规模的不断增加,给服务保障带来了具大的挑战,容量管理以及容灾方案设计都变得非常的复杂。

服务质量的精细化

由于支撑的业务场景越来越丰富,既有长连接(IM)应用场景又有视频业务需求,同时业务对服务稳定性的要求越来越高,接入平台作为基础设施服务,可用性要求越来越高,要求在不同层面保障服务的稳定性,避免单机故障和机房故障对线上服务的影响。

目前常用的集群方案是采用路由来实现,在京东内部我们使用的BGP协议(后面会介绍部署方式),最终要依赖交换机的ECMP来实现,ECMP的缺陷是如果一台服务器宕机,同一条流的数据包可能就会被转发到集群其它机器上,如果没有会话同步,那么该连接数据包就会丢弃,最终业务层超时。这对于一些长连接在线的业务影响会更加明显,比如在线的IM业务以及推送业务等服务。

运维管理的自动化

随着业务流量的陡增,集群规模越来越大和多集群的出现,同时对于线上大量应用的业务配置变更,对运维也是很大的挑战。自动化程度,成为衡量公司技术能力的一项重要指标。

对于接入平台,承载了公司众多的业务,实现快速的业务变更同时做到每次变更对业务无损,从平台角度看这是必须要去解决的问题。

安全防护能力

接入流量作为服务入口,在面对网络攻击时,需要具备安全防护的能力,保障平台服务的稳定性,同时做到对业务透明和精准防护,减少对业务的影响。传统方案通常采用单独的检测和清洗集群来实现,从技术层面看完全可以把异常流量清洗功能移到四层负载上,并以集群的方式部署,节省资源的同时减少旁路部署带来的复杂网络拓扑。同时四层负载更加接近业务,更方便用户根据特定业务定制一些安全规则,真正起到分层防护的能力,保证业务的安全稳定。

方案选择与功能定义

数据包收发方案选择

对于高性能的数据包处理方案来说,目前主流方案包括了硬件化方案和软件化方案。

对于硬件化方案,性能上虽然会优于软件化方案,但它昂贵的价格、有限的容量、灵活性和扩展性都不太适合处于中间转发位置的四层负载。而且随着多核服务器的普及,软件方案也可以达到网卡限速的性能,从价格、容量和灵活性上都远高于硬件方案,最终我们放弃了硬件方案。

在众多的软件化方案中,pfring依然轮询RX Queue,而不能同时访问所有的RX Queue。导致单核占用率比较高,不能充分利用多核性能。pfring和netmap对于大叶内存和numa等也没有库来支持,在实际的应用中(多路处理器和网卡),必然会影响性能。

综合来看,dpdk能充分发挥多核处理的的优势,来提供更好的转发性能外。同时dpdk提供了便于快速开发的库(内存池、网卡信息获取、无锁队列、hash等)。最重要的是dpdk由Intel发起并支撑,加之社区活跃程度高,我们最终选择了dpdk作为数据包收发方案。

功能定义

  • 支持集群部署
  • 支持配置集中管理
  • 支持会话保持
  • 支持tcp、udp的四层负载均衡
  • 支持DR和FULLNAT模式
  • 支持rr、wrr、源ip hash等负载均衡算法
  • 支持主动健康检查
  • 支持透传客户机IP
  • 支持会话同步
  • 支持syn flood, ack flood等四层攻击防护
  • 支持畸形报文过滤、黑白名单

系统实现

DLVS核心架构

结合各个功能的实现方式,下图是四层负载的DLVS的核心架构(后续章节会展开讲解)。

DLVS包括数据平面和控制平面,控制平面主要负责配置、监控和日志的管理。数据平面主要是基于dpdk实现的数据包处理和转发。控制平面和数据平面的通信主要通过kni接口和unix 域套接字接口。

控制平面的quagga用于和交换机建立BGP连接,发布路由和DLVS保活监控;keepalived用于vip、real server等业务的配置和real server的健康检查;管理agent用于提供对外配置接口和日志上报接口。

数据平面虽然是单进程,但我们在内部采用了多线程机制,并将管理和业务流量分离,以避免大的业务流量对管理流量产生影响。即把线程分为管理线程和业务线程,它们之间通过队列进行通信。管理线程负责处理经过内核的报文、进程间通信的报文等,同时将配置下发给各个业务线程,既每个业务线程都拥有一份配置。业务线程有多个线程,包括负载均衡业务的处理、安全防护和会话管理等。

接下来我们从业务角度、性能角度、高可靠性角度和安全防护角度来说明四层负载DLVS的具体实现。

负载均衡业务的实现

结合京东商城和京东云的业务需求,对于四层负载我们支持了TCP和UDP两种协议,支持fullnat和dr两种模式,并支持了rr、wrr和源ip哈希选择real server等基本功能,具体的实现我们不再详细解读,大家参考kernel版lvs的实现即可,原理方法基本一致。在这里我们只结合真实业务场景中遇到的问题来提醒大家在实现过程中特别需要注意的几点。

rr算法选取real server

在实际使用过程中,每台DLVS选取real server都是从头开始轮询的。在实际应用场景中,我们发现集群新增DLVS时,real server的流量严重不平衡,都集中在了配置的比较靠前的几台real server上。我们通过随机哈希real server的位置,再进行rr选取,从而解决了这个问题。wrr的选取解决方案类似。

业务配置的加载

开源的lvs是kernel的module,在dpdk上来实现lvs的功能会导致原有的keepalived和ipvsadm无法进行配置和监控的管理。我们利用域套接字实现的接口来替换keepalived和ipvsadm的消息下发接口,从而实现了dpdk版lvs与keepalived和ipvsadm的无缝对接。

业务的接口我们使用统一的库DLVS wrapper来实现,交互流程如下图所示:

Client真实IP获取

由于业务的需要,有些服务需要获取到client的真实IP和端口号。开源的lvs采用的toa(将真实源IP和端口加在tcp option中的方式),需要real server安装相应的内核补丁,这对于在线业务迁移带来具大的成本。

我们采用proxy protocol将client的真实IP和端口号进行封装,然后传递给后端的应用,由于采用了应用层的方式,应用层支持proxy protocol即可,无需要修改内核代码,并且升级修改对业务无损。

proxy protocol交互过程和协议格式如下图所示:

proxy protocol format
PROXY_STRING
+ single space + INET_PROTOCOL
+ single space + CLIENT_IP
+ single space + PROXY_IP
+ single space + CLIENT_PORT
+ single space + PROXY_PORT
+ “rn”

Example
:PROXY TCP4 198.51.100.22 203.0.113.7 35646 80rn

在收到客户端发过来的第一个ACK数据包时,插入一个TCP数据包,负载是上述proxy protocol内容。

高可靠性的实现

管理流量与业务流量分离

如果管理流量和业务流量夹杂在一起,在高业务流量的情况下,对管理流量可能会产生影响,如:bgp引流出错、配置的丢失、健康检查报文的丢失等。所以我们需要将业务流量和管理流量进行分离。我们结合dpdk的fdir技术和对rss hash配置的源码修改来实现。

由于控制平面基于Linux的进程,所以我们使用了kni口作为管理数据流接口,首先我们通过fdir接口,将kni的IP地址下发给网卡,并绑定到网卡的0号队列。然后对dpdk的rss hash进行了修改,保证业务报文(非kni ip)在rss hash队列时,从1~N中选择。逻辑流程如下图所示:

会话同步

为了保障一些服务的长链接在部分四层负载服务节点出现异常后,同集群其他节点能够处理已建立的TCP连接,需要对会话进行跨机器存储,来保证四层负载设备出现异常时,流量被牵引到其他四层负载节点上,数据包能够继续正确转发。

对于京东一个在线业务来说,在线活跃连接在大促期间会非常大,为此,DLVS会话同步方案设计出发点是需要支持亿级用户在线,并可以根据业务增长在单集群内水平扩展。对于会话保持的实施方案,我们先对现有方案进行了调研,然后结合现有方案的不足进行重新设计。

现有方案:

方案一,每台四层负载都采用主备的方式。具体逻辑架构如图所示:

从逻辑架构图上,可以明确看到这种方案的优缺点。优点是实现简单、扩展性好。缺点是正常工作时,一半的服务器闲置,造成资源浪费。

方案二,对四层负载进行分组,组内成员通过组播进行会话同步,逻辑架构如图所示:

与方案一相比,该方案可以充分利用四层负载服务器,不会造成资源的浪费。但是,它的缺点也很明显,由于四层负载集群被分组。分组内的四层负载通过组播的方式相互同步会话。这就会导致组的大小受限于单台四层负载的容量和带宽,集群组无法灵活地扩展。

DLVS会话同步方案:

为了尽量减少资源浪费的问题,我们对四层负载进行了分类,master DLVS和backup DLVS。master DLVS用于承载正常业务流量,backup DLVS用于承载出现异常的master DLVS的流量。考虑到业务整体突发异常性的概率, backup DLVS数量远小于master DLVS的数量,而且对backup DLVS的容量和带宽进行了扩容。

为了解决横向扩展的问题,我们首先采取了外部cache存储全局会话,其次将分组对业务(vip)透明,通过虚拟的分组来进行cache和backup DLVS的划分,从而使得横向扩展不会受限于单台四层负载的容量和带宽。使得四层负载在支持会话同步的情况下,实现对亿级在线用户流量的负载服务稳定。

结合解决资源浪费和扩展性的问题,给出整体的系统架构图:

为了更加方便大家了解会话同步相关的数据流程,我们结合几个场景讲解数据流的走向。

1. 分组对业务透明

通过将backup DLVS和cache进行分组,实现了业务master DLVS的分组的透明。使得DLVS的集群可以横向扩展,用于支撑亿级在线用户业务。

2. 正常DLVS的数据流

3. 宕机DLVS的数据流

4. 重启DLVS的数据流

重启过程中的数据流和宕机的数据流基本一致,参考宕机数据流。

重启后的数据流,首先恢复的master DLVS依据device id与cache进行会话批量同步,同步完后发送恢复通告给backup DLVS,然后master DLVS进行业务流量的转发。

5. 新增DLVS的数据流

新增master DLVS时,首先根据device id与cache进行会话同步,然后发送设备新增通告,最后转发业务流量。由于一致性hash的原因,会有一部分原有会话流量发送到新增DLVS上,DLVS将流量转发给backup DLVS,backup进行会话查询,根据device id进行二层转发给原DLVS,保证会话的一致性。

安全防护的实现

作为流量的入口,需要提供基础的流量防护功能。传统的方式是在流量出入口部署流量检测和清洗设备。检测是被一般是旁路部署,通过引流的方式将异常流量引流到清洗设备进行清洗,然后进行流量回注。采用旁路部署的方式,主要是为了防止因为清洗异常流量的性能消耗(清洗设备对报文进行了深度的分析)而影响到正常流量。但旁路部署同样带来了一些问题,比如:清洗设备对报文进行了深度的解析分析(七层报文解析分析),使其自己成为流量的瓶颈;流量的多次转发造成一定的延迟;未被牵引的流量不能进行安全防护;对实际业务用户无感知等

四层负载作为流量的入口,由于我们采用的高性能实现方案,大大提升了四层负载的性能,所以我们希望四层负载能够替代传统的流量检测和清洗设备功能。来减少延迟、对全部业务进行四层防护,并结合业务进行定制化防护等。同时不需要在部署流量监测和清洗设备,节省大量的资源。

流量清洗设备防护内容一般包括畸形报文防护、黑白名单支持、dns防护、四层ddos防护、cc防护等。考虑到报文解析和深度分析带来的性能消耗,结合四层负载所承载的功能,我们已经将报文解析到了传输层(TCP、UDP等),将cc的防护放到了四层负载后端的七层负载上来进行。把畸形报文防护、黑白名单、dns防护和四层ddos防护放到DLVS上来实现(这也符合网络分层防护的思想)。最终流量接入的防护架构如下。

在通过四七层负载来提供分层防护替换流量检测和清洗设备后,使得整个流量接入的网络拓扑变得简单易操作。

结合具体的实现我们来详细解读四层防护在DLVS上的实现

一键开启关闭

对于安全防护,我们采取了一键开启或关闭。在安全防护能力比较健全的用户环境中,可以直接关闭安全防护功能,以便进一步提升四层负载的性能。

同时,我们也支持了基于vip的安全防护开关,可以根据特殊的业务,开启安全防护功能,使得安全防护更加灵活。

多样性防护

开源lvs在安全防护上,只支持了synproxy(用于对tcp syn flood的伪造源IP进行校验)。我们在支持synproxy的基础上,增加了多种防护机制。

畸形报文防护:对于数据报文解析过程中,对非法的报文(IP分片攻击、TCP标志位攻击、smurf攻击和land攻击等)格式进行过滤。

黑白名单:结合大数据学习分析和威胁情报的信息,直接对五元组报文进行过滤或放行。对于临时的业务封禁非常便捷。

DNS防护:对于DNS的flood攻击、DNS缓存投毒攻击、DNS异常报文攻击等的防护。

四层DDOS防护:对udp flood、icmp flood、tcp flags flood等进行防护。

结合一键开关和多样性防护,我们安全防护内部的数据包流程逻辑如下图所示:

增加了安全防护后,必然会对四层负载的性能造成一定的影响,不过我们经过优化处理后,单机的TCP新建也达到了1M、并发达到了8M+,足以满足线上业务需求。

常用防护手段

结合业务使用场景的实现。我们对主要的TCP攻击防护、UDP攻击防护和DNS攻击防护进行概要的介绍。

  • TCP防护的常用手段:synproxy、首包丢弃、tcp flags检查、sequence检查、基于阈值的分析、限速等
  • UDP防护的常用手段:基于阈值的分析、UDP报文随机指针内容统计、负荷指纹学习和识别、限速等。
  • DNS防护的常用手段:基于阈值的分析、首包丢弃、构造request回验、校验query id和域名等

高性能的实现

dpdk的使用

底层的框架我们采用的是Intel提供的dpdk技术。dpdk的特性(用户态驱动、网卡驱动采取poll mode、支持burst收发、支持大页内存、numa、无锁队列、CPU亲和性、内存池等)我们这里不再重复,详情参考官网 www.dpdk.org
。我们采用了run-to-completion的方式,主要是考虑到减少线程之间通过队列传递报文造成的性能损耗。dpdk主要模块分解(摘自网络)如下图所示:

配置无锁实现

四层负载配置的管理不同于通用网络设备,由于后端的real server可能会经常的变化。所以四层负载下发配置的频率也会比较高。传统的实现方式,对于配置的下发,都是要进行加锁处理的。这势必会影响其它流量的性能。

为了避免这种影响,我们通过配置per core化即master core利用core间队列,为每个业务core都下发一份配置,各个业务core顺序执行读取配置和处理业务,实现了配置下发的无锁。

会话无锁实现

四层负载的新建和并发能力,直接和会话的创建和查找是否加锁有直接关系。如果一个会话只有一个core来处理,即可实现无锁,但是多核处理器下如何保证上下行流量都能落到同一个core呢?

我们再下发配置时,将local ip进行了per core绑定,即下行流量通过rss hash到达某个core绑定的队列时,在选择local ip时,也就只会选择已经绑定该core的local ip。同时我们利用fdir技术,将该local ip与该core 绑定的网卡队列绑定。这样便实现了上下行流量都落在同一个业务处理core。逻辑流程如下所示:

性能数据

数据基于X86服务器并配置Intel X520网卡,分别以大小数据包为例,对转发过程中的bps、cps及cpu使用率进行了统计。

CPU型号

资源大小

bps

CPS(每秒TCP新建连接数)

CPU(%)

Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.10GHz

2

8.5G

120万+

90

Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.10GHz

2K

9.2G

40万+

40

线上应用

京东商城SLB应用场景

DLVS是京东商城用户接入系统一部分,为全站业务提供四层负载均衡服务,目前接入业务除了有短连接服务,还有像IM,消息推送等长连接业务场景。 DLVS作为底层服务,承载全站业务流量,除了在实现上要保障高可用,同时在线上部署架构层面,我们要规避依赖的基础设施故障(比如机房,机架) 层面对服务的影响,为此我们和网络团队一起协作,设计了一套全新部署架构,实现了部署在多机房里的DLVS集群互备,依赖京东商城内网传输网络,通过动态路由(IBGP)将流量导入到DLVS集群,依赖BGP的强大流量调度功能,可以快速地将不同VIP的流量在集群间调度,在依赖底层的基础设施出现故障时,系统自动将流量切换到其它机房备份集群,整个过程对服务几乎无影响,示意图如下:

DLVS和交换机建立BGP连接,集群的机器发布同样的路由,不同集群之间通过BGP的community选项进行区分,通过匹配不同的community字段在把路由重分布时设置不同的cost,来控制路由。在所有集群的BGP失效时,所有流量落到其中一个默认的集群

京东云IP高防应用场景

京东云高防产品针对网站类业务提供网站高防服务,非网站类业务提供IP高防服务。

在高防业务场景中,流量首先到我们的DLVS,经过清洗模块完成流量清洗后,通过FULLNAT模式将流量导入到用户源站或者我们的WAF集群。在高防IP中部署逻辑图如下:

总结

基于Intel dpdk实现的高性能四层负载DLVS,无论是京东商城接入体系和京东云高防产品中作为所有业务流量的入口,在平台可用性和支撑业务发展都发挥了重要的作用。与开源实现相比,支持会话同步以及层网络防护等特性,为业务提供了更精细化的服务质量保障,成为同类产品中的佼佼者。现已整合为企业接入系统解决方案的核心部件,对外提供解决方案支持,帮助公司快速建立一套领先的流量接入体系,并可在此基础上进行二次开发,根据公司业务特点进行定制化,为业务保驾护航。

InfoQ

责编内容by:InfoQ阅读原文】。感谢您的支持!

您可能感兴趣的

MultiVAC(Mtv)基于可信分片计算的高性能弹性公链... MultiVAC 是为大规模去中心化应用设计的下一代高性能公链,通过可信分片技术为区块链系统赋予了可持续 无限扩展的能力。MultiVAC 首次提出了基于可...
每日一博 | Spring Cloud 之负载均衡框架 Ribbon 介绍... 6 负载均衡框架Ribbon介绍 本文节选自《疯狂Spring Cloud微服务架构实战》,本书将于2017年11月出版。 本书代码共享地址: htt...
Lighttpd 1.4.41 发布,高性能 Web 服务器 Lighttpd 1.4.41 发布了Lighttpd 是一个德国人领导的开源Web服务器软件,其根本的目的是提供一个专门针对高性能网站,安全、快速、兼...
深入理解负载均衡 负载均衡是 高可用 架构的一个关键组件,主要用来提高性能和可用性,通过负载均衡将流量分发到多个服务器,同时多服务器能够消除这部分的 单点故障 。 当然...
扫描应用程序以查找并修复 2017 年“OWASP Top 10”漏洞... 编者注:本文已经过更新,反映了 2017 年 OWASP Top 10 应用程序安全风险清单 的内容。 简介 Web 应用程序处于云计算革命的最...