项目作者: ZigzagAK

项目描述 :
NGINX Dynamic API Gateway
高级语言: C
项目地址: git://github.com/ZigzagAK/ngx_api_gateway.git
创建时间: 2019-04-01T21:03:51Z
项目社区:https://github.com/ZigzagAK/ngx_api_gateway

开源协议:BSD 2-Clause "Simplified" License

下载


Nginx Api Gateway module

ngx_api_gateway is a dynamically configurable solution for routing requests.

Key features

  • Dynamically add and remove upstreams.
  • Dynamically modify routes between URLs and backends.
  • Synchronization with external registry.
  • Templating.
  • Environment may be used in configuration inventory.
  • Internal configuration persistent storage.

Build status

Build Status

Dependencies

Modules

Other

SQLite for persistance.

Status

Development.

Overview

Upstreams

You may dynamically add and remove upstreams to nginx in runtime without reloads.

This feature is very important because reloads of nginx needs to close all active connections and create another ones. Websockets and tcp streams may prevent fast reloads.

Routes

As you know, locations in nginx is a configuration time feature and routing can’t be changed in runtime dynamically.

With dynamic routes you may add and remove routes based on prefix tree and regular expression patterns.

You may associate URLs to upstream in runtime without chaning nginx cnfiguration with REST without reloads.

Configurations is stored to internal sqlite database and on reload is loaded to nginx configuration.

Synchronization with external registry

Routes and upstreams configuration may be fetched from external http server and applied. Some of changes may needs to reload nginx.

Templating

For detailed templating possibilities you may look ngx_template_module.

Synopsis

env.template:

  1. env {{name}};

env.yml:

  1. ---
  2. env:
  3. - name: LISTEN_PORT

dynamic.template:

  1. server {
  2. listen {{listen}} reuseport;
  3. default_type text/plain;
  4. location / {
  5. auth_request {{auth.request}};
  6. api_gateway_router_dynamic {{dynamic_var}}:5m;
  7. proxy_connect_timeout {{proxy.connect_timeout}};
  8. proxy_read_timeout {{proxy.read_timeout}};
  9. if ({{dynamic_var}} = '') {
  10. return 404 'No route';
  11. }
  12. proxy_pass {{proxy.protocol}}://{{dynamic_var}};
  13. }
  14. location = /auth_stub {
  15. internal;
  16. return 200;
  17. }
  18. }

dynamic.yml:

  1. ---
  2. dynamic:
  3. - name: dynamic_entrypoint1
  4. listen: "{{env(LISTEN_PORT1)|default(9000)}}"
  5. dynamic_var: $dynamic1
  6. auth:
  7. request: /auth_stub
  8. proxy:
  9. connect_timeout: 10s
  10. read_timeout: 60s
  11. protocol: http
  12. - name: dynamic_entrypoint2
  13. listen: "{{env(LISTEN_PORT2)|default(9001)}}"
  14. dynamic_var: $dynamic2
  15. auth:
  16. request: /auth_stub
  17. proxy:
  18. connect_timeout: 10s
  19. read_timeout: 60s
  20. protocol: http

check.temlate:

  1. healthcheck passive type=http rise={{rise}} fall={{fall}} timeout={{timeout}} interval={{interval}};
  2. healthcheck_request_uri {{request.method}} {{request.uri}};
  3. healthcheck_response_codes {{response.codes}};
  4. healthcheck_response_body {{response.match}};

check.yml:

  1. ---
  2. check:
  3. - name: http
  4. rise: 1
  5. fall: 2
  6. timeout: 10000
  7. interval: 10
  8. request:
  9. method: GET
  10. uri: /healthz
  11. response:
  12. codes: 200 204
  13. match: .*

nginx.conf:

  1. template keyfile=env.yml template=env.template;
  2. http {
  3. upstream_conf_zone 8m;
  4. template keyfile=check.yml template=check.template;
  5. api_gateway_template keyfile=dynamic.yml template=dynamic.template;
  6. server {
  7. listen 8888;
  8. location = /healthcheck/get {
  9. healthcheck_get;
  10. }
  11. location = /healthcheck/status {
  12. healthcheck_status;
  13. }
  14. location = /route {
  15. api_gateway_route;
  16. }
  17. location = /dynamic {
  18. dynamic_upstream;
  19. }
  20. location = /upstream {
  21. upstream_conf;
  22. }
  23. }
  24. }

For more examples look into example folder.

Dynamic upstreams

upstream_conf_zone

Syntax upstream_conf_zone
Default 8m
Context http

upstream_conf

Syntax upstream_conf
Default -
Context location

Add upstream

Method: POST

Arguments:

  • method - roundrobin, leastconn, ip_hash.
  • stream - add stream upstream.
  • keepalive - number of keepalived connections.
  • keepalive_requests - number of keepalived requests.
  • keepalive_timeout - timeout for keepalived connection.
  • dns_update - background synchronization hosts addresses by DNS in seconds. Looking for details in ngx_dynamic_upstream.

Example: curl -X POST 'localhost:6000/upstream?name=test&keepalive=600&keepalive_requests=10'.

Delete upstream

Method: DELETE

Example: curl -X DELETE 'localhost:6000/upstream?name=test'.

Get information about upstreams

Method: GET

Example: curl localhost:6000/upstream.

Output:

  1. [
  2. {
  3. "keepalive": 600,
  4. "keepalive_requests": 10,
  5. "method": "roundrobin",
  6. "name": "test1",
  7. "type": "http"
  8. },
  9. {
  10. "keepalive": 600,
  11. "keepalive_requests": 10,
  12. "method": "roundrobin",
  13. "name": "test2",
  14. "type": "http"
  15. }
  16. ]

Dynamic routes

Dynamic routes is implemented via api_gateway_router_dynamic directive.

Declare dynamic router

Syntax api_gateway_router_dynamic <variable>:<mem>
Default -
Context http,location

Example:

  1. location / {
  2. api_gateway_router_dynamic $backend:5m;
  3. proxy_pass http://$backend;

Routes associated with nginx variable, declared with api_gateway_router_dynamic directive.

route_conf

Syntax route_conf
Default -
Context location

Register location handler for setup new route, delete existing.

Add new route

Method: POST

Arguments:

  • backend - upstream name.
  • api - route. May be uri mask (/a/b/*/c/d) or regular expression.
  • var - variable name.

Example: curl -X POST localhost:8888/route?backend=app1&api=/a/b/*/c&var=$backend.

Delete route

Method: DELETE

Arguments:

  • api - route. May be uri mask (/a/b/*/c/d) or regular expression.
  • var - variable name.

Example: curl -X DELETE localhost:8888/route?api=/a/b/*/c&var=$backend.

Static routes

Static routes is implemented via api_gateway_router directive.

It injects backend’s configuration into server or location.

Declare static router

Syntax api_gateway_router <variable>:<mem> <backends>
Default -
Context server,location

Example:

check.yml:

  1. ---
  2. check:
  3. - name: http
  4. rise: 1
  5. fall: 2
  6. timeout: 10000
  7. interval: 10
  8. request:
  9. method: GET
  10. uri: /healthz
  11. response:
  12. codes: 200 204
  13. match: .*

backend.template:

  1. upstream {{__group}}@{{name}} {
  2. zone shm_{{name}} 256k;
  3. dns_update {{dns.update}};
  4. dns_add_down on;
  5. {{servers}}
  6. check passive type=http rise={{check@http.rise}} fall={{check@http.fall}} timeout={{check@http.timeout}} interval={{check@http.interval}};
  7. check_request_uri {{check@http.request.method}} {{check@http.request.uri}};
  8. check_response_codes {{check@http.response.codes}};
  9. check_response_body {{check.response.match}};
  10. }

backends.yml:

  1. ---
  2. backends:
  3. - name: backend1
  4. api:
  5. - /app1/fun1
  6. - ~ ^/app3/fun2
  7. - /app1/fun3
  8. - /app1/*/hello/*
  9. - /app1/0000000
  10. dns:
  11. update: 60s
  12. server:
  13. max_conns: 10
  14. max_fails: 2
  15. fail_timeout: 30s
  16. upsync:
  17. interval: 60s
  18. timeout: 10s
  19. check:
  20. response:
  21. match: pong
  22. servers:
  23. - server 127.0.0.1:3333 max_conns={{server.max_conns}} max_fails={{server.max_fails}} fail_timeout={{server.fail_timeout}};
  24. - server 127.0.0.1:4444 max_conns={{server.max_conns}} max_fails={{server.max_fails}} fail_timeout={{server.fail_timeout}};
  25. - name: backend2
  26. api:
  27. - /app2/fun1
  28. - ~ ^/app2/fun2
  29. - /app2/fun3
  30. - /app2/*/hello/*
  31. - /app2/0000000
  32. dns:
  33. update: 60s
  34. server:
  35. max_conns: 10
  36. max_fails: 2
  37. fail_timeout: 30s
  38. upsync:
  39. interval: 60s
  40. timeout: 10s
  41. check:
  42. response:
  43. match: pong
  44. servers:
  45. - server 127.0.0.1:5555 max_conns={{server.max_conns}} max_fails={{server.max_fails}} fail_timeout={{server.fail_timeout}};
  46. - server 127.0.0.1:6666 max_conns={{server.max_conns}} max_fails={{server.max_fails}} fail_timeout={{server.fail_timeout}};

entrypoint.template:

  1. server {
  2. listen {{listen}} reuseport;
  3. default_type text/plain;
  4. {{server.directives|default()}}
  5. {{server.locations|default()}}
  6. location / {
  7. auth_request {{auth.request}};
  8. {{location.directives|default()}}
  9. api_gateway_router $backend:1m {{backends}};
  10. proxy_connect_timeout {{proxy.connect_timeout}};
  11. proxy_read_timeout {{proxy.read_timeout}};
  12. proxy_pass {{proxy.protocol}}://$backend;
  13. }
  14. location = /auth_stub {
  15. internal;
  16. return 200;
  17. }
  18. }

entrypoints.yml:

  1. ---
  2. entrypoints:
  3. - name: app
  4. listen: 11111
  5. server:
  6. directives:
  7. - set $variable1 1;
  8. - set $variable2 2;
  9. locations:
  10. - location ~* ^/app1/.+\.(jpg|gif|png)$ { proxy_pass http://backends@backend1; }
  11. - location ~* ^/app2/.+\.(jpg|gif|png)$ { proxy_pass http://backends@backend2; }
  12. location:
  13. directives:
  14. - set $variable3 3;
  15. - set $variable4 4;
  16. auth:
  17. request: /auth_stub
  18. proxy:
  19. connect_timeout: 100s
  20. read_timeout: 600s
  21. protocol: http
  22. backends:
  23. - backends@backend1
  24. - backends@backend2

nginx:

  1. http {
  2. template keyfile=check.yml;
  3. api_gateway_template keyfile=backends.yml template=backend.template;
  4. api_gateway_template keyfile=entrypoints.yml template=entrypoint.template;
  5. }

Synchronization with external registry

api_gateway_template

Syntax api_gateway_template keyfile=keys.yml template=template_file url=host:port/url
Context http

Synchronization inventory with external registry.

Example: api_gateway_template keyfile=backends.yml template=backend.template url=127.0.0.1:7777/registry/backends;

See example for details.

Update timeout

Syntax api_gateway_timeout <timeout>
Context http

Update interval

Syntax api_gateway_interval <interval>
Context http