乐趣区

关于负载均衡:BFE和Nginx有什么差异-转发模型的对比

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_a
upstream cluster_a {
    server 192.168.1.1:8080;
    server 192.168.1.2:8080;
}

# 定义转发指标集群 cluster_b
upstream 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.com
3、在后的,如 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 开源我的项目”公众号,取得本我的项目的更多更新。谢谢!

退出移动版