All Projects → Justinmad → phi

Justinmad / phi

Licence: other
an api-gateway based on openresty

Programming Languages

lua
6591 projects
CSS
56736 projects
HTML
75241 projects
javascript
184084 projects - #8 most used programming language
shell
77523 projects
perl
6916 projects

Projects that are alternatives of or similar to phi

Apioak
Full Lifecycle Management API Gateway.
Stars: ✭ 335 (+1356.52%)
Mutual labels:  api-gateway, luajit, openresty
Api Umbrella
Open source API management platform
Stars: ✭ 1,735 (+7443.48%)
Mutual labels:  api-gateway, luajit, openresty
Annon.api
Configurable API gateway that acts as a reverse proxy with a plugin system.
Stars: ✭ 306 (+1230.43%)
Mutual labels:  api-gateway, rate-limiting
Apisix
The Cloud-Native API Gateway
Stars: ✭ 7,920 (+34334.78%)
Mutual labels:  api-gateway, luajit
Kong
🦍 The Cloud-Native API Gateway
Stars: ✭ 30,838 (+133978.26%)
Mutual labels:  api-gateway, luajit
Lua Resty Jit Uuid
Fast and dependency-free UUID library for LuaJIT/ngx_lua
Stars: ✭ 169 (+634.78%)
Mutual labels:  luajit, openresty
Lua Resty Redis Connector
Connection utilities for lua-resty-redis
Stars: ✭ 186 (+708.7%)
Mutual labels:  luajit, openresty
Kong Docs Cn
微服务 Api 网关 Kong 最新文档中文版
Stars: ✭ 371 (+1513.04%)
Mutual labels:  api-gateway, openresty
Istio Workshop
In this workshop, you'll learn how to install and configure Istio, an open source framework for connecting, securing, and managing microservices, on Google Kubernetes Engine, Google’s hosted Kubernetes product. You will also deploy an Istio-enabled multi-service application
Stars: ✭ 120 (+421.74%)
Mutual labels:  api-gateway, rate-limiting
Enroute
EnRoute Universal Gateway: Cloud Native API gateway with OpenAPI support and free L7 rate-limiting built on Envoy proxy
Stars: ✭ 126 (+447.83%)
Mutual labels:  api-gateway, rate-limiting
Lua Resty Repl
Interactive console (REPL) for Openresty and luajit code
Stars: ✭ 165 (+617.39%)
Mutual labels:  luajit, openresty
nginx-lua
Nginx 1.19+ with LUA support based on Alpine Linux, Amazon Linux, Debian, Fedora and Ubuntu.
Stars: ✭ 112 (+386.96%)
Mutual labels:  luajit, openresty
Motan Openresty
A cross-language RPC framework for rapid development of high performance distributed services based on OpenResty.
Stars: ✭ 117 (+408.7%)
Mutual labels:  luajit, openresty
kong-scalable-rate-limiter
Kong plugin for Rate Limiting at high throughputs.
Stars: ✭ 19 (-17.39%)
Mutual labels:  api-gateway, rate-limiting
Lua Resty Http
Lua HTTP client cosocket driver for OpenResty / ngx_lua.
Stars: ✭ 1,647 (+7060.87%)
Mutual labels:  luajit, openresty
Lua Cassandra
Pure Lua driver for Apache Cassandra
Stars: ✭ 95 (+313.04%)
Mutual labels:  luajit, openresty
Vanilla
An OpenResty Lua MVC Web Framework
Stars: ✭ 1,018 (+4326.09%)
Mutual labels:  luajit, openresty
Lua Resty Route
URL Routing Library for OpenResty Supporting Pluggable Matching Engines
Stars: ✭ 88 (+282.61%)
Mutual labels:  luajit, openresty
Ngr
A high-performance & enterprise-class edge gateway middleware
Stars: ✭ 89 (+286.96%)
Mutual labels:  api-gateway, openresty
Apicast
3scale API Gateway
Stars: ✭ 225 (+878.26%)
Mutual labels:  api-gateway, openresty

项目简介

基于openresty+nginx的api网关,实现了基本的动态路由、动态upstream、负载均衡、限流、降级的功能,同时提供了类似于nginx plus的统计功能

系统简图

Phi

目录

安装

  • 方式一
    • 项目运行依赖[OpenResty],安装了OpenResty的情况下可以跳过此安装步骤
  • 方式二
  • 方式三
    • 执行install目录下的install.sh来完成一键安装。项目默认将被安装在/home/phi-0.0.1目录下
        ./install.sh ${path_to_nginx_src}
    • 请将/home/phi-0.0.1/sbin加入环境变量
  • 方式四
    • 根据项目根目录下的Dockerfile制作docker镜像,并启动
    • 项目默认安装在/home/phi目录下,默认暴露80,9090,12345端口
    • 你需要在配置文件中指定redis的主机和端口
    • 你应该将conf目录映射到外部路径中

启动和配置

  • 确保nginx命令可执行,可以使用command -v nginx查看
  • 使用bin目录下的phi:
    • 用法: phi start|stop|restart|reload|test
    • 可选参数 :
      • -D: 启动远程debug模式,默认占用端口8172,使用参考:[ZeroBrane Studio],[EmmyLua]
      • -H: 远程debug 主机名,默认localhost
      • -P: 远程debug 端口,默认8172
      • -p: nginx启动目录,同nginx -p参数
      • -c: nginx启动配置文件名称,同nginx -c参数
      • -d: 以非守护进程方式启动,同-g 'daemon off'
  • 你也可以使用nginx启动命令来启动项目
  • 你也可以自行指定nginx配置文件,但需要在你已存在的nginx配置中添加如下内容
    • Nginx 配置
      • 在nginx配置中添加如下内容
          # 需要安装luajit/lua,xxx表示项目根路径,需要在nginx/tengine编译时添加如下模块lua_nginx_module(0.10.11)和lua_upstream_nginx_module(0.07),安装方式参考install/install.sh
          lua_package_path '../openresty/?.lua;../phi/?.lua;../lib/?.lua;;';
          lua_package_cpath '../openresty/?.so;../lib/?.so;;';
          # 如果使用了openresty,那么只需引入下面的包
          #lua_package_path '../phi/?.lua;../lib/?.lua;;';
          #lua_package_cpath '../lib/?.so;;';
          #生产环境务必开启
          lua_code_cache on;
          # 共享内存的大小按需调整
          lua_shared_dict phi                     5m;
          lua_shared_dict phi_events              5m;
          lua_shared_dict phi_lock                5m;
          lua_shared_dict phi_router              10m;
          lua_shared_dict phi_upstream            10m;
          lua_shared_dict phi_limiter             10m;
          lua_shared_dict phi_degrader            10m;
          lua_shared_dict phi_limit_req           128m;
          lua_shared_dict phi_limit_conn          128m;
          lua_shared_dict phi_limit_count         128m;
          # 开启mio统计面板的情况下需添加如下dict
          lua_shared_dict status  8m;
          lua_shared_dict summary 128m;
          lua_shared_dict recording_summary 128m;
          #lua入口文件
          init_by_lua_file ../entry_lua_file/init_by_lua.lua;
          init_worker_by_lua_file ../entry_lua_file/init_worker_by_lua.lua;
          server {
                  set $upstream_connection '';
                  listen 80;
                  server_name phi_entry;
                  location = /favicon.ico {
                      log_not_found off;
                      access_log off;
                  }
                  location / {
                      set $backend '';
                      rewrite_by_lua_file ../entry_lua_file/rewrite_by_lua.lua;
                      proxy_http_version 1.1;
                      proxy_set_header Connection $upstream_connection;
                      proxy_set_header Upgrade $http_upgrade;
                      proxy_set_header Host $host;
                      proxy_set_header X-Real-IP $remote_addr;
                      proxy_pass http://$backend;
                  }
                  log_by_lua_file ../entry_lua_file/log_by_lua.lua;
          }
          upstream phi_upstream {
              server 0.0.0.1;
              balancer_by_lua_file ../entry_lua_file/balancer_by_lua.lua;
              # 请按需调整
              keepalive 2000;
          }
  • Phi 配置
    • 项目启动默认会读取bin目录和conf目录下的phi.ini,你可以创建此文件用来覆盖项目的默认配置
    • phi/config/default_config.lua中定义了默认的配置项
        return {
            debug = true,                 -- 是否开启远程debug
            debug_host = "127.0.0.1",     -- debug的host
            debug_port = 8172,            -- 远程debug占用端口
            enabled_admin = true,         -- 是否启动管理控制台
            enabled_mio = true,           -- 是否启动统计面板
            enabled_policies = { "UNIQUE", "RANGE", "PREFIX", "SUFFIX", "COMPOSITE", "MODULO", "REGEX" }, -- 启用的policy规则
            enabled_mappers = { "HEADER", "URI_ARGS", "IP", "URI" }, -- 启用的mapper类型
            default_paths = {             -- 默认的配置文件加载路径 conf/phi.ini 或者./phi.ini
                current_path .. "phi.ini", conf_path .. "phi.ini"
            },
            application_context_conf = {  -- 默认的application容器配置路径 conf/application.ini 或者./application.ini
                current_path .. "application.ini", conf_path .. "application.ini"
            }
        }
    • 配置项读取优先级
      • 环境变量中对应的值,环境变量取值会在所有的key前面加PHI_,例如debug对应环境变量中的PHI_DEBUG的值
      • default_paths中指定的ini文件中配置的值
      • default_config.lua中指定的默认值

启动管理控制台

  • 如果你使用phi中的nginx配置,管理控制台默认是启用的,通过12345端口即可访问
  • 当你使用自定义的nginx配置,你需要确保phi配置中enabled_admin=true,并在nginx配置中添加如下server
server {
    listen 12345;
    location / {
        default_type application/json;
        content_by_lua_file ../entry_lua_file/admin_content_by_lua.lua;
        log_by_lua_file ../entry_lua_file/log_by_lua.lua;
    }
}
  • 管理面板截图 admin

启动统计面板

  • 目前的统计功能因为涉及很多对Shared_Dict的操作,以及对ngx.var的使用在性能上会有一定损失,单核心下差距明显(50%),多核心下差距会缩小
  • 在执行Nginx的编译前的配置中请添加 --with-http_stub_status_module,[OpenResty]默认开启,使用install中的安装脚本默认会添加此模块到nginx
  • 数据统计默认是关闭的
  • 在bin/或comf/下添加phi.ini设置enabled_admin=true开启,并在nginx配置中添加如下server(如果没有),通过12345端口可访问
    server {
            listen       9090;
            access_log logs/api_access.log main;
            error_log logs/api_error.log info;
            set  $template_root "";
            location = /favicon.ico {
                log_not_found off;
                access_log off;
            }
            # 静态文件
            location ~* /static/(.*) {
                alias ../static/$1;
            }
            location /robots.txt {
                return 200 'User-agent: *\nDisallow: /';
            }
            location = / {
                try_files '' ../static/index.html;
            }
            location / {
                content_by_lua_file ../lib/mio/api/main.lua;
            }
        }
  • 统计面板截图 dashborad
  • 更多可参考[MIO],对源代码做了一些修改

快速开始

  • 参考默认配置
    • 使用80端口作为api网关入口
    • 使用9090端口作为统计面板入口
    • 使用12345端口作为管理控制台api入口
    • 将conf/vhost.conf引入nginx配置中,用来模拟后端服务器,分别占用5555、6666、7777、8888端口
  • 添加一个api-server,使用主机名sample.com
    curl -H 'content-type:application/json' -X POST --data \
        '{"hostkey": "sample.com","data": {"default": "127.0.0.1:5555"}}' \
        http://localhost:12345/router/add
    
    • 访问刚才添加的api server
    curl -H 'content-type:application/json' -H 'Host:sample.com' http://localhost
    
    返回内容
        this is the fake backend peer... listen port 5555
    
  • 添加一组命名为dynamic_ups的api server,负载均衡策略使用轮询,其它参考[Load Balance]
    curl -H 'content-type:application/json' -X POST --data \
        '{"upstreamName":"dynamic_ups","strategy":"roundrobin","mapper":"ip","servers":[{"name":"127.0.0.1:5555","info":{"weight":10}},{"name":"127.0.0.1:6666","info":{"weight":10}}]}' \
        http://localhost:12345/upstream/addOrUpdateUps
    
  • 将主机名sample.com指向的api server修改为dynamic_ups,其它api参考[Dynamic Upstream]
    curl -H 'content-type:application/json' -X POST --data \
        '{"hostkey": "sample.com","data": {"default": "dynamic_ups"}}' \
        http://localhost:12345/router/add
    
    • 访问刚才添加的api server
    curl -H 'content-type:application/json' -H 'Host:sample.com' http://localhost
    
    • 请求返回内容
        this is the fake backend peer... listen port 5555
    
    • 再次请求返回内容
        this is the fake backend peer... listen port 6666
    
  • 对主机名sample.com添加一条路由规则,取请求头中X-UID的值,值尾数为8的请求转发到8888端口,值尾数为7的请求转发到7777端口,其它请求转发到default中的dynamic_ups中进行负载均衡,其它路由规则参考[Router]
    curl -H 'content-type:application/json' -X POST --data \
        '{"hostkey":"sample.com","data":{"default":"dynamic_ups","policies":[{"order":2,"policy":"modulo","mapper":{"type":"header","tag":"X-UID"},"routerTable":[{"result":"127.0.0.1:8888","expression":8},{"result":"127.0.0.1:7777","expression":7}]}]}}' \
        http://localhost:12345/router/add
    
    • 访问刚才添加的api server
    curl -H 'content-type:application/json' -H 'Host:sample.com' -H 'X-UID:123458' http://localhost
    
    • 返回内容,取不到X-UID时,请求将会在5555/6666的server之间进行轮询
        this is the fake backend peer... listen port 8888
    
  • 对主机名sample.com添加一条限流规则,取用户IP值作为限流key,限制每10秒钟内只能成功访问1次,其它限流规则参考[Rate Limiting]
    curl -H 'content-type:application/json' -X POST --data \
        '{"hostkey":"sample.com","data":{"time_window":10,"rate":1,"type":"count","mapper":"ip"}}' \
        http://localhost:12345/rate/add
    
    • 访问刚才添加的api server
    curl -H 'content-type:application/json' -H 'Host:sample.com' -H 'X-UID:123458' http://localhost
    
    • 返回内容
        this is the fake backend peer... listen port 8888
    
    • 被限流后返回
    {
      "status": {
        "message": "Limited access,Service Temporarily Unavailable,please try again later :-)",
        "success": false
      },
      "code": 503
    }
  • 对域名sample.com添加一条降级规则,并启动降级,所有的降级规则都是基于host+uri来进行的,当访问/test时返回执行降级策略,限流规则是优先于降级执行的,其它降级规则参考[Service Degradation]
    curl -H 'content-type:application/json' -X POST --data \
        '{"hostkey":"sample.com","infos":[{"uri":"/test","info":{"type":"fake","enabled":true,"target":"This is a degraded fake data"}}]}' \
        http://localhost:12345/degrade/add
    
    • 访问刚才添加的api server
    curl -H 'content-type:application/json' -H 'Host:sample.com' -H 'X-UID:123458' http://localhost/test
    
    • 返回内容
        {"message":"This is a degraded fake data"}
    
    • 再次访问将会进入上面添加的限流规则中

管理控制台API

  • 枚举值

    • mapper

      mapper是一组映射函数,会将请求映射到一个具体的值,以便将这个值交给policy进行运算, 请求参数中如果有mapper字段只需要传递相应的枚举值即可,如"mapper":"ip" 有一些mapper需要指定tag,此时mapper字段应传递一个json对象,如:{"type":"uri_args","tag":"uid"},会取出请求参数中的uid的值

      value Description
      header 取请求头中指定字段,配合tag字段使用,tag值表示请求头的名称
      host 取请求头/请求行中的host,无需指定tag
      ip 取请求头中的用户ip,无需指定tag
      uri_args 取请求中的uri参数,配合tag字段使用,tag值表示参数名称
      uri 取请求行中的uri
      cookie 取请求头中的cookie,配合tag字段使用,tag值表示cookie名称
    • policy

      policy是一组计算函数,string calculate(arg, hashTable),此函数接收一个具体值和一个规则对象, 该对象中的数据结构应符合{"result":"xxx","expression":"xxxxxxxx"}的规则(组合规则除外), calculate函数会根据expression字段的表达式计算出一个boolean值,如果为true就立即返回result的值,否则就继续执行

      value Description 哈希表结构示例
      modulo 对10取模运算 [{"result":"upstream1","expression":1},{"result":"upstream2","expression":2},{"result":"upstream3","expression":3}]
      range 范围运算 [{"result":"hehehehe","expression":[1001,2000]},{"result":"upstream1","expression":[min,"NONE"]},{"result":"upstream2","expression":[min,max]},{"result":"upstream3","expression":["NONE",max]}]
      prefix 取前缀匹配 [{"result":"upstream1","expression":"/api"},{"result":"upstream2","expression":"/openApi"}]
      suffix 取后缀匹配 [{"result":"upstream1","expression":".js"},{"result":"upstream2","expression":".css"}]
      regex lua正则匹配 [{"result":"upstream1","expression":"regex1"},{"result":"upstream2","expression":"regex2"}]
      composite 组合规则 {"primary":{"order":2,mapper":"ip","policy":"range_policy","routerTable":[{"result":"secondary","expression":[1,100]},{"result":"upstream","expression":["NONE",1000]}]},"secondary":{"order":2,"mapper":"ip","policy":"range_policy","routerTable":[{"result":"secondary","expression":[1,100]}]}}
      unique 返回唯一结果 {"result":"upstream1"}
  • Router

    • 动态路由,实现分流/灰度功能
    • 添加路由规则
      • 请求路径:/router/add
      • 请求方式:POST
      • 返回数据格式:JSON
      • 请求字段说明:
        • order:数字,多个规则排序,数值越大优先级越高
        • policy:枚举值,路由规则计算方式,对应枚举policy
        • routerTable:对象路由规则表,对应枚举policy中哈希表结构示例
        • mapper:枚举值,请求映射函数,对应枚举mapper
        • tag:字符串,参考mapper中对tag的说明
      • 请求数据示例:
        • 以下示例表示:从uri参数中提取uid的值,根据值的范围进行匹配,小于2000的将会被路由到upstream1, 2001到3000之间的将被路由到upstream2,大于3000的将被路由到upstream3
        {
          "hostkey": "www.sample.com",
          "data": {
            "default": "an upstream name",
            "policies": [{
              "order": 3,
              "policy": "range",
              "mapper": {"type":"uri_args","tag":"uid"},
              "routerTable": {
                "upstream1": [
                  2000,
                  "NONE"
                ],
                "upstream2": [
                  2001,
                  3000
                ],
                "upstream3": [
                  "NONE",
                  3000
                ]
              }
            }]
          }
        }
    • 查询路由规则
      • 请求路径:/router/get
      • 请求方式:GET
      • 请求数据格式:uri参数
      • 请求数据示例:
        hostkey=xxx
        
      • 返回数据格式:JSON
      • 返回数据示例:
        {
          "status": {
            "message": "ok",
            "success": true
          },
          "code": 200,
          "data": {
            "policies": [
              {
                "order": 3,
                "policy": "range",
                "mapper": {"type":"uri_args","tag":"uid"},
                "routerTable": {
                  "upstream4": [
                    1001,
                    2000
                  ]
                }
              },
              {
                "order": 2,
                "policy": "range",
                "mapper": "ip",
                "routerTable": {
                  "upstream1": [
                    1001,
                    100
                  ]
                }
              }
            ],
            "default": "phi_upstream"
          }
        }
    • 查询所有路由规则
      • 请求路径:/router/getAll
      • 请求方式:GET
      • 请求数据格式:uri参数
      • 请求数据示例:
        hostkey=xxx
        
      • 返回数据格式:JSON
    • 删除路由规则
      • 请求路径:/router/del
      • 请求方式:GET
      • 请求数据格式: uri参数
      • 请求数据示例:
        hostkey=xxx
        
  • DynamicUpstream

    • 动态的upstream列表,简单的负载均衡功能
    • 查询所有运行中的upstream信息
      • 请求路径:/upstream/getAllRuntimeInfo
      • 请求方式:GET
      • 返回数据格式:JSON
      • 返回数据示例:
        {
            "status": {
              "message": "ok",
              "success": true
            },
            "code": 200,
            "data": {
              "stable_ups": {
                "primary": [
                  {
                    "weight": 1,
                    "id": 0,
                    "conns": 0,
                    "fails": 0,
                    "current_weight": 0,
                    "fail_timeout": 10,
                    "effective_weight": 1,
                    "name": "127.0.0.1:8888",
                    "max_fails": 1
                  }
                ],
                "backup": {}
              },
              "dynamic_ups": {
                 "mapper": "ip",
                 "servers": [{
                     "weight": 10,
                     "name": "127.0.0.1:5555",
                     "down": false
                 },{
                     "weight": 10,
                     "name": "127.0.0.1:6666",
                     "down": true
                 }],
                 "strategy": "roundrobin"
             }
            }
        }
    • 查询所有upstream信息
      • 请求路径:/upstream/getAllUpsInfo
      • 请求方式:GET
      • 返回数据格式:JSON
      • 返回数据示例:
        {
            "status": {
              "message": "ok",
              "success": true
            },
            "code": 200,
            "data": {
              "stable_ups": {
                "primary": [
                  {
                    "weight": 1,
                    "id": 0,
                    "conns": 0,
                    "fails": 0,
                    "current_weight": 0,
                    "fail_timeout": 10,
                    "effective_weight": 1,
                    "name": "127.0.0.1:8888",
                    "max_fails": 1
                  }
                ],
                "backup": {}
              },
              "dynamic_ups": {
                "mapper": "ip",
                "servers": [
                  {
                    "name": "127.0.0.1:8989",
                    "weight": 10
                  }
                ],
                "strategy": "resty_chash"
              }
            }
        }
    • 查询指定upstream的server列表
      • 请求路径:/upstream/getUpstreamServers
      • 请求方式:GET/POST
      • 请求数据格式:uri参数/表单参数
      • 请求数据示例:
            upstreamName=xxxx
        
      • 返回数据格式:JSON
      • 返回数据示例:
        {
            "status": {
              "message": "ok",
              "success": true
            },
            "code": 200,
            "data": {
              "127.0.0.1:12346": {
                "weight": 100
              },
              "127.0.0.1:7777": {
                "weight": 10
              },
              "127.0.0.1:8888": {
                "weight": 10
              },
              "strategy": "resty_chash",
              "mapper": "ip"
            }
        }
    • 从server列表中摘除/启动指定server,暂时不参与/重新参与负载均衡
      • 请求路径:/upstream/setPeerDown
      • 请求方式:GET/POST
      • 请求数据格式:uri参数/表单参数
      • 请求数据示例:
        upstreamName=xxxx&serverName=xxx&down=true
        
    • 添加或者更新指定upstream
      • 请求路径:/upstream/addOrUpdateUps
      • 请求方式:POST
      • 请求数据格式:JSON
      • 字段说明:
        • mapper:请求映射函数,对应枚举mapper

        • tag:参考mapper中对tag的说明

        • strategy

          LoadBalance

          枚举值,根据权重值分配负载均衡调用比例

          value Description
          resty_chash 简单hash算法
          roundrobin 轮询算法
        • severs:数组,表示一组server,每一条记录有两个字段

          • name:表示server地址,ip:port
          • info:对象,目前支持2个字段
            • weight:数字,表示该服务器的权重
            • down:布尔型,表示是否参与负载均衡
      • 请求数据示例:
        {
          "upstreamName": "a new upstream",
          "strategy": "resty_chash",
          "mapper": "ip",
          "servers": [
            {
              "name": "127.0.0.1:8989",
              "info": {
                "weight": 10
              }
            },
            {
              "name": "127.0.0.1:8989",
              "info": {
                "weight": 10
              }
            }
          ]
        }
    • 删除指定upstream
      • 请求路径:/upstream/delUps
      • 请求方式:GET
      • 请求数据格式:uri参数
      • 请求数据示例:
            upstreamName=xxxx
        
    • 从指定upstream中删除servers
      • 请求路径:/upstream/delUpstreamServers
      • 请求方式:POST
      • 请求数据格式:JSON
      • 请求数据示例:
        {
          "upstreamName": "a new upstream",
          "servers": [
            "127.0.0.1:8989"
          ]
        }
    • 向指定upstream中添加server,upstreamName不存在时会返回错误
      • 请求路径:/upstream/addUpstreamServers
      • 请求方式:POST
      • 请求数据格式:JSON
      • 请求数据示例:
        {
            "upstreamName":"an exists upstream name",
            "servers":[{
              "name":"127.0.0.1:8989",
              "info":{
                  "weight":100
              }
            }]
        }
  • RateLimiting

    • 动态路由,实现分流/灰度功能
    • 添加路由规则
      • 请求路径:/rate/add
      • 请求方式:POST
      • 返回数据格式:JSON
      • 请求字段说明
        • type:枚举值,多个规则排序,数值越大优先级越高

          value Description
          req 限制请求速率,type=req时,需传递rate(速率),burst(允许突发值)两个参数
          例如:rate=200,burst=100,表示允许200req/sec,流量突发时最多允许达到300req/sec,其中超过200req的请求将被delay
          conn 限制并发连接数,type=conn时,需传递conn(连接数),burst(允许突发连接数),delay(延迟时间)三个参数
          例如conn=100,burst=100,delay=0.05,表示正常允许100并发连接,突发流量下最大允许200并发连接,其中超出的部分,将被deplay
          count 限制单位时间窗口内的调用次数,type=count时,需传递rate(速率),time_window(单位时间窗口)两个参数
          例如rate=1000,time_window=60,表示60秒内最多允许调用1000次,超出的请求会被拒绝
          traffic 组合限流,启动组合限流时,组合限流需在请求数据中添加policies字段,数组类型[{"time_window": 10,"rate": 1,"}],每一条数据为一条限流规则,如需对多个规则进行排序,请在每一条中添加order字段,数字越大优先级越高
        • mapper:可选值,未传递此参数的情况下,所有限流粒度都是以host作为限流key,请求映射函数,对应枚举mapper

        • tag:参考mapper中对tag的说明

        • rejected:拒绝策略,rejected:直接拒绝访问,degrade:查询降级策略

      • 请求数据示例:
        {
          "hostkey": "www.sample.com",
          "data": {
            "time_window": 10,
            "rejected": "xxx",
            "rate": 1,
            "order": 1,
            "type": "count",
            "mapper":"ip"
          }
        }
    • 查询路由规则
      • 请求路径:/rate/get
      • 请求方式:GET
      • 请求数据格式:uri参数
      • 请求数据示例:
        hostkey=xxx
        
      • 返回数据格式:JSON
    • 查询所有路由规则
      • 请求路径:/rate/getAll
      • 请求方式:GET
      • 请求数据格式:uri参数
      • 请求数据示例:
        hostkey=xxx
        
      • 返回数据格式:JSON
    • 删除路由规则
      • 请求路径:/rate/del
      • 请求方式:GET
      • 请求数据格式: uri参数
      • 请求数据示例:
        hostkey=xxx
        
  • ServiceDegradation

    • 接入层的简易降级开关,所有的降级都是以host+uri为依据
    • 添加降级数据
      • 请求路径:/degrade/add
      • 请求方式:POST
      • 返回数据格式:JSON
      • 请求字段说明
        • type:枚举值

          value Description
          fake 返回target中指定的数据
          redirect 重定向到target指定的路径
        • "enabled": true/false,针对此uri的降级开关

      • 请求数据示例:
        {
          "hostkey": "auto.deploy.com",
          "infos": [
            {
              "uri": "/uri",
              "info": {
                "type": "redirect",
                "enabled": true,
                "target": "http://sample.com"
              }
            }
          ]
        }
    • 查询路由规则
      • 请求路径:/degrade/enabled
      • 请求方式:GET
      • 请求数据格式:uri参数
      • 请求数据示例:
        hostkey=xxx&uri=/xxxx
        
      • 返回数据格式:JSON
    • 查询路由规则
      • 请求路径:/degrade/get
      • 请求方式:GET
      • 请求数据格式:uri参数
      • 请求数据示例:
        hostkey=xxx
        
      • 返回数据格式:JSON
    • 查询所有路由规则
      • 请求路径:/degrade/getAll
      • 请求方式:GET
      • 请求数据格式:uri参数
      • 返回数据格式:JSON
    • 删除路由规则
      • 请求路径:/degrade/del
      • 请求方式:GET
      • 请求数据格式: uri参数
      • 请求数据示例:
        hostkey=xxx&uri=/xxxx
        

性能测试

我在自己的笔记本上使用ab进行了简单的负载测试:

  • 测试准备
    • nginx配置:开启一个worker进程,并且最多占用一个cpu核心
      worker_processes 1;
      worker_cpu_affinity auto;
    • 关闭了访问日志,错误日志级别为error
    • 开启另外一台nginx,作为一个静态文件服务器,目标文件大小为1Kb
  • 多测试场景
    • Local环境,所有相关应用都部署在同一机器,相当于忽略网络开销
      • 测试机器配置
        • 笔记本 I7-6700HQ + 16GB
      • 使用AB进行压力测试,20个并发,发起1000000次请求,使worker进程cpu达到100%,启用-k
        • 原生的nginx反向代理:50K T/S
        • 开启router功能后测试结果:32K T/S
        • 开启dynamic ups和balancer之后: 25K T/S
        • 此测试应该可以反映,服务器在满负荷下的吞吐量极限值(完全没有网络开销),两者会有40%的差距,在开启统计功能的情况下差距会继续扩大(10%)
        • 在开启多核情况下性能会有明显提升
    • 内网环境测试
      • 测试机器配置
        • 三台 KVM CPU:2C RAM:2G 千兆网卡
        • 一台部署PHI应用,一台部署NGINX静态文件服务,一台压测
      • 使用AB进行压力测试,100个并发,发起100000次请求,使worker进程cpu达到100%,启用-k,测试结果和上面是相似的
        • 原生的nginx反向代理:21K T/S
        • 开启router功能后测试结果:15K T/S
        • 开启dynamic ups和balancer之后: 11K T/S
      • 测试在保持大量并发连接数下的系统稳定性:
        • TODO
  • 测试结果
    • 在只考虑CPU负载的情况下,相较于nginx的原生代理,系统容量(TPS)会有接近50%的差距,而RT两者基本没有什么差别
    • 在多核心的机器下,网络带宽应该会优先于cpu而达到瓶颈
  • 性能测试是一项很复杂的工作,以任何一个单一指标来定性系统性能瓶颈都是不严谨的,我们在生产中也应按照应用特征、机器配置、网络状况进行综合分析。

使用的第三方lua库或工具

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].