BFE原生路由转发功能分析

原创 吴就业 122 0 2021-10-13

本文为博主原创文章,未经博主允许不得转载。

本文链接:https://wujiuye.com/article/e1193c604c274ed1a64e2ef065ec6149

作者:吴就业
链接:https://wujiuye.com/article/e1193c604c274ed1a64e2ef065ec6149
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。

本篇文章写于2021年10月13日,从公众号|掘金|CSDN手工同步过来(博客搬家),本篇为原创文章。

为什么加上“原生”,因为我们基于BFE开发已经魔改了。

路由转发是BFE作为一个七层流量代理服务的核心功能,BFE设计了一套支持多租户、多机房的路由转发模型。

traffic-forward.png

图片来源:《深入理解BFE》

基本概念

在原生路由转发功能中,bfe对租户、集群、子集群、实例的概念解释如下:

相关配置文件

路由转发过程

与路由相关的流程:确定租户->确定集群->确定子集群->确定实例

与转发相关的流程:获取转发器->转发请求

bfe原生路由转发流程.png

说明:这些步骤中的从xx配置文件中查找/获取xx配置,只是为了便于理解才这样描述,实际上,BFE在启动时就已经加载所有配置文件缓存在内存中了。

案例分析

商城产品线(ShoppMall),域名为shoppmall.com,订单服务(OrderService)部署在中国机房(CN-idc0),部署三个实例。

相关配置如下:

host_rule:

{
    "Version": "1.0.0",
    "DefaultProduct": null,
    "Hosts": {
        // 对应HostTags下的配置
        "ShoppMallTag":[
            "shoppmall.com"
        ]
    },
    "HostTags": {
        "ShoppMall":[
            // 标签随便定
            "ShoppMallTag"
        ]
    }
}

route_rule:

{
    "Version": "1.0.0",
    "ProductRule": {
        "ShoppMall": [
            {
                // 以/order开头的请求路由到OrderService微服务
                "Cond": "req_path_prefix_in("/order")",
                "ClusterName": "OrderService"
            }
        ]
    }
}

cluster_rule:

{
    "Version": "init version",
    "Config": {
        // OrderService集群的基础配置
        "OrderService": {
            // 请求后端相关:连接超时等
            "BackendConf": {
                "TimeoutConnSrv": 2000,
                "TimeoutResponseHeader": 50000,
                "MaxIdleConnsPerHost": 0,
                "RetryLevel": 0
            },
            // 心跳检测配置
            "CheckConf": {
                "Schem": "http",
                "Uri": "/healthcheck",
                "Host": "example.org",
                "StatusCode": 200,
                "FailNum": 10,
                "CheckInterval": 1000
            },
            // 全局负载均衡策略配置
            "GslbBasic": {
                "CrossRetry": 0,
                "RetryMax": 2,
                "HashConf": {
                    "HashStrategy": 0,
                    "HashHeader": "Cookie:UID",
                    "SessionSticky": false
                }
            },
            // 客户端读写相关
            "ClusterBasic": {
                "TimeoutReadClient": 30000,
                "TimeoutWriteClient": 60000,
                "TimeoutReadClientAgain": 30000,
                "ReqWriteBufferSize": 512,
                "ReqFlushInterval": 0,
                "ResFlushInterval": -1,
                "CancelOnClientClose": false
            }
        }
    }
}

gslb:

{
    "Clusters": {
        // 订单集群的子集群配置
        "OrderService": {
            "GSLB_BLACKHOLE": 0,
            "CN-idc0": 100
        }
    },
    "Hostname": "",
    "Ts": "0"
}

cluster_table:

{
    "Version": "1.0.0",
    "Config": {
        // 集群
        "OrderService": {
            // 子集群
            "CN-idc0": [
                // 实例
                {
                    "Addr": "127.0.0.1",
                    "Name": "example_hostname",
                    "Port": 8180,
                    "Weight": 10
                },
                {
                    "Addr": "127.0.0.1",
                    "Name": "example_hostname",
                    "Port": 8181,
                    "Weight": 10
                },
                {
                    "Addr": "127.0.0.1",
                    "Name": "example_hostname",
                    "Port": 8182,
                    "Weight": 10
                }
            ]
        }
}

客户端发送POST http://shoppmall.com/order/createOrder请求路由过程如下:

总结

笔者个人觉得,BFE的路由配置文件太多了,而且不太直观,有点绕,不区分租户配置,将会导致一个文件一大堆的配置,不易于管理。

可能是开源的缘故,bfe不想依赖其它第三方如配置中心、数据库之类的服务,所以才改为使用配置文件配置,又或者原本设计就是使用文件配置。而这其实与使用nginx一样,需要经常修改配置文件。

#中间件

声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。

文章推荐

Quartz分布式调度原理

在同一时刻需要触发的Job只有少量的情况下,我们看不到Quartz的性能缺陷,在Job数量明显增加情况下,我们就会发现,调度延迟会有明显增加。尽管横向扩展节点,调度延迟也不会降低,且整体调度性能没有明显好转,反而更糟糕。

重构XXL-JOB,使用响应式编程实现异步RPC提升调度吞吐量

如果同一时刻需要下发几百个执行job的请求给执行器,使用这种阻塞的RPC,意味着需要开启几百个线程,使用几百个连接发送请求,而这几百个线程都需要阻塞等待响应,Job越多,需要的线程数就会越多,对调动中心的性能影响就越大。

重构支持多租户的XXL-JOB,如何实现多个逻辑集群的均衡选主

我们基于XXL-JOB的架构原理,重新架构设计了支持多租户横向扩展的分布式任务调度平台。本篇介绍如何实现多个逻辑集群(多个租户逻辑上是独立的集群)的均衡选主。

基于Kafka,延迟消息队列的设计

由于Kafka不支持延迟消息,而目前公司技术栈中消息中间件使用的是Kafka,业务方希望使用RocketMQ满足延迟消息场景,但如果仅仅只是需要延迟消息功能而引入多一套消息中间件,这会增加运维与维护成本。在此背景下,我们希望通过扩展Kafka客户端提供延迟消息的支持。