본문 바로가기

서버운영 (TA, ADMIN)/미들웨어

[Nginx] Building an API Gateway with Lua and Nginx

Nginx_with_lua https://yos.io/2016/01/28/building-an-api-gateway-with-lua-and-nginx/


API_Gateway_Pattern https://microservices.io/patterns/apigateway.html


lua-nginx-module https://github.com/openresty/lua-nginx-module


Lua 5.1 Reference http://www.lua.org/manual/5.1/manual.html




The various *_by_lua, *_by_lua_block and *_by_lua_file configuration directives serve as gateways to the Lua API within the nginx.conf file. The Nginx Lua API described below can only be called within the user Lua code run in the context of these configuration directives.


The API is exposed to Lua in the form of two standard packages ngx and ndk. These packages are in the default global scope within ngx_lua and are always available within ngx_lua directives.


The packages can be introduced into external Lua modules like this:


local say  = ngx.say

local _M = {}


function _M.foo(a)

say(a)

end


return _M



Use of the package.seeall flag is strongly discouraged due to its various bad side-effects.


It is also possible to directly require the packages in external Lua modules;


local ngx = require "ngx"

local ndk = require "ndk"


The ability to require these packages was introduced in the v0.2.1rc19 release.


Network I/O operations in user code should only be done through the Nginx Lua API calls as the Nginx event loop may be blocked and performance drop off dramatically otherwise. Disk operations with relatively small amount of data can be done using the standard Lua io library but huge file reading and writing should be avoided wherever possible as the may black the Nginx process significantly. Delegating all network and disk I/O operations to Nginx's subrequests (via ngx.location.capture method and similar) is strongly recommended for maximum performance.



ngx.arg


syntax: val = ngx.arg[index]

context: set_by_lua*, body_filter_by_lua*


when this is used in the context of the set_by_lua* directives, this table is read-only and holds the input arguments to the config directives:


value = ngx.arg[n]


location /foo {

set $a 32;

set $b 56;


set_by_lua $sum

'return tonumber(ngx.arg[1]) + tonumber(ngx.arg[2])'

$a $b;


echo $sum;

}


that writes out 88, the sum of 32 and 56.


When this table is used in the context of body_filter_by_lua*, the first element holds the input data chunk to the output filter code and the second element holds the boolean flag for the "eof" flag indicating the end of the whole output data stream.


The data chunk and "eof" flag passed to the downstream Nginx output filters can also be overridden by assigning values directly to the corresponding table elements. When setting nil or an empty Lua string value to ngx.arg[1], no data chunk will be passed to the downstream Nginx output filters at all.




ngx.crc32_long


syntax: intval = ngx.crc32_short(str)

context: set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certification_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*


Calculates the CRC-32(Cyclic Redundancy Code) digest for the str argument.


This method performs better on relatively long str inputs(i.e., longer than 30~60 bytes), as compared to ngx.crc32_long. The result is exactly the same as ngx.crc32_long.


Behind the scene, it is just a thin wrapper around the ngx_crc32short function defined in the Nginx core.