仅配置服务降级网关的应用

121 阅读3分钟

场景

我们的程序有时候必须调用第三方接口,有些接口调用频繁,执行速度也很快,几十毫秒就能返回,但每天总有那么几次返回的非常慢,甚至触发了30秒timeout。我们希望这种异常超时发生时,该接口能立即停止执行,返回一个预定义数据,以防止我们自己的客户端卡住或者白屏。

有的第三方接口本身执行比较慢,要500毫秒以上,甚至好几秒,我们希望这种接口能改为异步,执行完毕后再回调通知我们,以防我方的请求变慢。

然而,不幸的是,第三方服务往往不受控,驱动对方修改太过困难。因此也就有了本文的工具:基于Openresty的仅配置服务降级网关。

该网关解决两个问题:

  1. 接口超时服务降级
  2. 同步接口转异步

原理

网络结构

服务降级 - 网络结构.jpg

工作流程

服务降级 - 工作原理.jpg

三种模式

  1. 透传模式:接口未在toml配置文件中定义时,透传请求给第三方服务接口
  2. 超时降级:接口在toml中配置为timeout类型时,一旦超出配置的timeout_ms,停止执行,立即返回toml中定义的response
  3. 同步转异步:接口在toml中配置为callback类型时,网关接收到请求后立即返回toml中定义的response,同时异步向第三方服务接口发送请求,收到第三方服务响应后,回调我方服务

用法

安装网关

yum install -y yum-utils

# CentOS版本 < 9
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
# CentOS版本 >= 9
yum-config-manager --add-repo https://openresty.org/package/centos/openresty2.repo

yum install -y openresty
yum install -y openresty-opm openresty-resty

# opm package,实现超时服务降级和同步转异步
opm get sssxyd/lua-resty-downgrade

systemctl enable openresty

配置Server

vim /usr/local/openresty/nginx/conf/nginx.conf


server {
    listen 8280;
    server_name _;
    root /usr/local/openresty/nginx/html;
    
    charset utf-8;
    index index.php index.html index.htm;

    access_log /var/log/nginx/access.downgrade.log  main;
    error_log /var/log/nginx/error.downgrade.log;

    autoindex off;

    # 静态文件和其他路径请求
    location / {
        try_files $uri $uri/ /index.html?$query_string;
        proxy_pass  http://127.0.0.1:8080; 
    }

    # 超时降级/同步转异步
    location /thirdpart/ {
        access_by_lua_block {
            local downgrade = require "resty.downgrade"
            downgrade.load_rules("/path/to/your_route_rules.toml")
            downgrade.proxy_pass(ngx.var.uri)
        }
        # 未适配的接口透传
        proxy_pass  http://127.0.0.1:8080; 
    }
}

编写规则

vim /path/to/your_route_rules.toml

["/thirdpart/user/getPageData"]
# 当前路由的请求,适配超时服务降级模式
type = "timeout"
# 上游服务地址,支持https
backend_url = "http://127.0.0.1:8080"
# 超时时间,单位毫秒
timeout_ms = 250
# 超时服务降级触发后,返回的HTTP状态码,默认200
#status_code = 200
# 超时服务降级触发后,返回的ContentType,默认JSON
#content_type = "application/json; charset=utf-8"
# 超时服务降级触发后,返回的Body内容
resp_body = '''
{
    "code": 100,
    "msg": "timeout downgrade",
    "result": {
        "total": 0,
        "data": []
    }
}
'''

["/thirdpart/traffic/getTrafficNo"]
# 当前路由的请求,适配同步转异步模式
type = "callback"
# 上游服务地址,支持https
backend_url = "http://127.0.0.1:8080"
# 回调地址,向该接口 Post JSON格式的数据
callback_url = "http://127.0.0.1:8281/handle_callback"
# 当前请求中存储回调凭证的header名称,默认:X-Callback-Credentials,该header可以为空
#callback_credentials_header = "X-Callback-Credentials"
# 同步转异步触发后,立即返回的HTTP状态码,默认200
#status_code = 200
# 同步转异步触发后,立即返回的ContentType,默认JSON
#content_type = "application/json; charset=utf-8"
# 同步转异步触发后,立即返回的Body内容
resp_body = '''
{
    "code": 101,
    "msg": "callback downgrade",
    "result": {
        "trafficNo" : ""
    }
}
'''

管理服务

# 启动
systemctl start openresty

# 停止
systemctl stop openresty

# 重启
systemctl restart openresty

# 编辑toml后重新加载
openresty -s reload

附录

详情参见: 项目GitHub主页