Nginx是一个被宽泛应用的反向代理(Reverse Proxy)开源软件。在“反向代理”这个方向上,BFE是被设计用来代替Nginx的。于是,一个被常常提出的问题呈现了:为什么要应用BFE?和Nginx相比,BFE到底有什么中央是不同的。
BFE和Nginx最大的不同是设计出发点和转发模型。BFE从一开始就是为转发场景设计的,可能很好的满足各种转发场景的需要;而Nginx原本是作为Web Server设计的,用来做转发是“科班出身”,在模型方面存在一些问题。
本文将重点阐明两者在“转发模型”上的差别。
1. 对Nginx的剖析
1.1 Nginx的转发配置
首先看看Nginx是怎么做的。
Nginx配置中的外围概念是server, location,upstream。
- server:代表一个web server,能够定义web server的监听端口和主机名
- location:代表一个web server之下的各门路/接口
- upstream:代表被转发的指标
一个典型的Nginx转发配置如下所示:
# 定义转发指标集群cluster_aupstream cluster_a { server 192.168.1.1:8080; server 192.168.1.2:8080;}# 定义转发指标集群cluster_bupstream cluster_b { server 192.168.1.3:8080; server 192.168.1.4:8080;}# 定义www.a.com的转发规定server { listen 80; server_name www.a.com; # host location / { # path, 设置为any proxy_pass http://cluster_a;# 转发给cluste_a }}# 定义www.b.com的转发规定server { listen 80; server_name www.b.com; # host location / { # path,设置为any proxy_pass http://cluster_b; # 转发给cluster_b }}
如果要在转发过程中做一些非凡的解决,则在以上的配置中插入相干的语句。例如,针对www.a.com的申请,能够减少如下rewrite规定:
server { listen 80; server_name www.a.com; location / { rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg)$' /data?file=$3.$4; proxy_pass http://cluster_a }}
1.2 Nginx转发模型的问题
尽管目前很多人将Nginx用于转发场景,然而不得不说,Nginx的转发机制有比较严重的问题。
(1) 转发配置的形容能力较弱
对于一个转发场景来说,配置规定的根本逻辑是:转发条件 => 转发指标
多条转发规定能够造成一张转发表。
转发条件 | 转发指标 |
---|---|
Host=www.a.com | cluster_a |
Host=www.b.com | cluster_b |
在Nginx中,并没有呈现明确的转发表概念,转发规定的形容受到配置中server-location构造的限度。server-location构造原本是设计用于web server的,用于转发就比拟轻便。例子中这种简略的转发逻辑须要比拟多的配置语句。
在Nginx开源版本中,location形容机制在表达能力方面的毛病具体表现在:
- 仅反对基于uri的条件,无奈间接反对基于申请Header或申请上下文的条件
- 针对常见的uri蕴含匹配、后缀匹配也不得不应用正则表达式
- 难以对多个条件灵便进行逻辑组合(与或非)
(2) 转发规定的优先级较简单
在存在多条转发规定的时候,优先级的管制就变得十分重要。
Nginx在匹配优先级上做了肯定的限度,必须首先匹配Host以确定server,而后在server内匹配location。这个限度在简略的场景下没有问题,然而在比较复杂的场景下可能会制约规定的编写。
在匹配server和匹配location时,都有比较复杂的规定(见下)。在比较复杂的场景下,最终失效的后果并不容易预测。
匹配server时,规定如下:
1、齐全匹配2、通配符在前的,如*.test.com3、在后的,如www.test.*4、正则匹配,如~^\.www\.test\.com$如果都不匹配1、优先选择listen配置项后有default或default_server的2、找到匹配listen端口的第一个server块
在匹配location时,规定如下:
1. 字符串最长匹配(非正则表达式) 和在配置文件中呈现的先后顺序无关2. 正则匹配 正则表达式依照配置文件中程序匹配,一旦匹配,不会持续匹配
(3) 大量应用正则表达式
在Nginx中,对于略微简单的场景,就须要在转发规定的形容中应用正则表达式。
在实践中,咱们发现正则表达式存在以下两个重大问题:
- 配置难以保护。正则表达式存在重大的可读性问题。用正则表达式编写的转发条件很难看懂,且容易存在二义性。
- 性能存在隐患。对于编写不当的正则表达式,可能在特定的流量特色下会呈现重大的性能进化。
(4) “根底转发”和“转发的附加解决”混淆在一起
在反向代理的转发模型中,须要包容以下两个基本功能:
- 根底转发配置。定义转发的条件和转发的指标。
- 转发的附加解决。定义在转发中须要做的操作,如rewrite, redirect等等。
在Nginx中,“根底转发”和“转发的附加解决”(如,rewrite, redirect等)只能混在一起写。在一些状况下,“转发的附加解决”和“根底转发”的匹配逻辑可能并不完全一致,在Nginx中配置保护比拟艰难。
(5) 不反对在多组实例间依照比例调度
在多数据中心或多容器云的场景下,可能有这样的需要:
- 多组实例都提供雷同的服务
- 在多组实例间,使用权重比例来调度流量
这个需要转换为Nginx的概念,就是须要反对对满足某种转发规定的申请,依照设定的权重转发给多个upstream。Nginx不反对这样的性能。
2. BFE和Nginx的差别
BFE的定位是“为企业级场景设计的古代七层负载平衡开源软件”。和Nginx相比,BFE有以下的变动:
(1) 面向转发场景设计
- 在BFE中明确引入了“转发表”的概念,能够清晰而简洁的设定转发条件和转发指标。
- 在BFE中,除了Host和Path外,也能够很容易的应用申请中更多的信息作为转发条件。
- 在BFE“转发表”的多条规定间,有较简略的优先级策略,更易于了解
(2) 尽量避免正则表达式的应用
针对正则表达式所存在的问题,BFE中设计了“条件表达式”(Condition Expression)机制,以进步转发规定的可维护性,并升高性能进化的隐患。
(3) 将“转发的附加解决”和“根底转发”的配置拆散
如rewrite、redirect这样的解决,各自有独立的配置。
(4) 提供了多组实例间依照比例调度的性能
这个性能对于多数据中心或多容器云场景的调度十分有用。
3. BFE转发中的基本概念
在BFE中,有以下基本概念:
(1) 租户(Tenant)。应用BFE转发的业务能够基于“租户”的单位来辨别。BFE引擎中的配置,比方转发策略、各扩大模块的配置等,都是以租户为单位来辨别的。
在BFE中,租户也被称为“产品线(Product)”。
(2) 后端集群(Cluster)。具备同类性能的后端被定义为一个集群。对于一个租户,能够定义多个集群。在某些场景中,集群也被称为服务(Service)。在一个租户内,能够应用租户的路由转发表将流量转发给适合的集群。
(3) 后端子集群(Sub Cluster)。在多数据中心场景下,集群能够划分为多个子集群。通常,能够将集群中处于同一数据中心的后端定义为一个子集群。在某些场景中,子集群也被称为实例组(Instance Group)。子集群概念的引入,次要是为了解决多数据中心场景下的流量调度。
(4) 后端实例(Instance)。每个子集群可蕴含多个后端服务实例(Instance),每个后端实例通过"IP地址 + 端口号"标识。
下图中用一个例子对以上概念之间的关系做出了阐明,其中蕴含2个租户。租户1配置了2个集群(集群A和集群B),这2个集群别离有2个子集群和1个子集群,各子集群有1~3个实例;租户2只配置了一个集群(集群C),集群C有2个子集群,2个子集群各有2个实例。
4. BFE的转发过程
上面应用一个例子来说BFE的转发流程。例子的场景如下图所示。客户端首先通过DNS解析,取得目标IP地址(步骤1-2)。之后申请首先被发送到四层负载平衡(步骤3),而后再转发给BFE(步骤4)。
在HTTP申请达到BFE后,BFE的解决步骤如下:
- 步骤 5:确定HTTP申请所属的租户。BFE能够依据HTTP申请头中的“Host”字段或HTTP申请的指标IP地址来确定租户。在本案例中,针对HTTP申请头中demo.example.com域名,BFE找到对应的租户为demo。
- 步骤 6:依据租户的分流规定,决定HTTP申请的目标集群。对于每个租户,能够配置一张独立的路由转发表。通过查找路由转发表,确定申请所属的目标集群。路由转发机制的详情将在前面的章节中介绍。在本案例中,通过查表确定对应的目标集群为demo-static。
- 步骤 7:依据集群的内网流量调度策略,抉择适合的子集群。对于每个BFE集群,能够针对每个集群的各子集群设置转发权重。BFE依据设置的转发权重来执行转发操作。内网流量调度机制的详情将在前面的章节中介绍。在本案例中,假如在IDC1的BFE集群上,demo-static的3个子集群对应的转发权重为(100, 0, 0),所以,确定转发的指标子集群为demo-static.idc1。
- 步骤 8:依据集群的子集群负载平衡策略,抉择适合的实例。对于每个集群,能够设置子集群的负载平衡策略,如WRR(Weighted Round Robin,加权轮询)、WLC(Weighted Least Connections,加权最小连接数)等。BFE依据子集群的负载平衡策略,在子集群中抉择适合服务实例来解决申请。在本案例中,最终抉择demo-static-01.idc1来解决申请。
5. BFE的转发表
在BFE内对每个租户保护一张独立的“转发表”。对于每个属于该租户的申请,通过查问转发表取得指标集群。
转发表由多条“转发规定”组成。在查问时,对多条转发规定以程序的形式查找;只有命中任何一条转发规定,就会完结退出,其中最初一条规定为“默认规定(Default)”。在所有转发规定都没有命中的时候,执行默认规定。
每条转发规定蕴含两局部:匹配条件和指标集群。其中匹配条件应用BFE自研的“条件表达式“来表述。
上面展现了一个转发表的例子。在这个例子中,蕴含以下3种服务集群。
(1) 动态集群(demo-static):服务动态流量。
(2) post集群(demo-post):服务post流量。
(3) main集群(demo-main):服务其余流量。
冀望的转发逻辑如下:
(1) 对于Path以"/static"为前缀的,都发往demo-static集群。
(2) 申请办法为"POST"且Path以"/setting"为前缀的,都发往demo-post集群。
(3) 其余申请,都发往demo-main集群。
6. 附加解决的独立配置
在BFE中,为各扩大解决模块建设了独立的配置文件,这样能够升高配置保护的复杂性,防止配置之间的耦合。
以redirect性能为例,在目录conf/mod_redirect/下,能够看到mod_redirect.conf和redirect.data这两个配置文件。
rewrite.data蕴含重定向规定,可动静加载。在安装包中,示例中的配置文件如下:
{ "Version": "1", "Config": { "example_product": [ { "Cond": "req_path_prefix_in(\"/redirect\", false)", "Actions": [ { "Cmd": "URL_SET", "Params": ["https://example.org"] } ], "Status": 301 } ] }}
7. 总结
本文从“转发模型”的角度对Nginx和BFE进行了比照。
Nginx从Web Server登程,被“借用“于反向代理场景,在转发模型方面存在多处问题。在简略的利用场景下,这些问题可能还不显著;然而在较简单和较大规模的场景下,这些问题会显现出来。
BFE 定位于“为企业级场景设计的古代七层负载平衡开源软件”,在设计中思考了简单业务场景的需要,能够反对简单的转发规定,反对多数据中心和多容器云调度场景。
因为篇幅所限,对于BFE转发模型的介绍比拟粗略。有趣味的读者可进一步查看《深刻了解BFE》中的阐明。此书已由电子工业出版社正式出版,书名为《万亿级流量转发 - BFE核心技术与实现》。
可通过扫描下方的二维码优惠购买。
欢送关注“BFE开源我的项目”公众号,取得本我的项目的更多更新。谢谢!