Lua 가 Nginx 에서 의 응용
Nginx 표준 모듈 과 설정 이 시스템 요구 에 유연 하 게 적응 하지 못 할 경우 Lua 확장 과 맞 춤 형 Nginx 서 비 스 를 고려 할 수 있 습 니 다.OpenResty 는 대량의 우수한 Lua 라 이브 러 리, 제3자 모듈 을 통합 하여 초고 속 병행, 확장 성 이 높 은 웹 서 비 스 를 편리 하 게 구축 할 수 있 기 때문에 OpenResty 가 제공 하 는 lua - nginx - module 방안 을 선택 합 니 다.
Lua 환경 설치
lua - nginx - module 은 LuaJIT 와 ngx 에 의존 합 니 다.devel_kit。LuaJIT 설치 필요, ngxdevel_kit 는 원본 패키지 만 다운로드 하고 Nginx 컴 파일 시 ngx 를 지정 합 니 다.devel_kit 디 렉 터 리.
시스템 의존 라 이브 러 리
우선 시스템 에 다음 의존 라 이브 러 리 가 설치 되 어 있 는 지 확인 하 십시오.
$ yum install readline-devel pcre-devel openssl-devel gcc
LuaJIT 설치
우선, LuaJIT 환경 을 설치 하고 다음 과 같다.
$ wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz
$ tar zxvf LuaJIT-2.0.5.tar.gz
$ cd LuaJIT-2.0.5
$ make install
#
==== Successfully installed LuaJIT 2.0.5 to /usr/local ====
LuaJIT 와 관련 된 환경 변 수 를 설정 합 니 다.
$ export LUAJIT_LIB=/usr/local/lib
$ export LUAJIT_INC=/usr/local/include/luajit-2.0
$ echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
$ ldconfig
관련 모듈 다운로드
다운로드 ngxdevel_kit 소스 패키지, 다음 과 같 습 니 다:
$ wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz
$ tar zxvf v0.3.0.tar.gz
#
ngx_devel_kit-0.3.0
다음은 Lua 모듈 lua - nginx - module 소스 패 키 지 를 다운로드 하여 Nginx 컴 파일 을 준비 합 니 다.
$ wget https://github.com/openresty/lua-nginx-module/archive/v0.10.10.tar.gz
$ tar zxvf v0.10.10.tar.gz
#
lua-nginx-module-0.10.10
Lua 모듈 불 러 오기
Nginx 1.9 버 전 후 모듈 을 동적 으로 불 러 올 수 있 지만 버 전이 너무 낮 아서 Nginx 를 다시 컴 파일 할 수 밖 에 없습니다.Nginx 소스 패키지 다운로드 및 압축 풀기:
$ wget http://nginx.org/download/nginx-1.13.5.tar.gz
$ tar zxvf nginx-1.13.5.tar.gz
Nginx 를 컴 파일 하고 다시 설치 하기:
$ cd nginx-1.13.5
# --add-module=/usr/src/lua-nginx-module-0.10.10 --add-module=/usr/src/ngx_devel_kit-0.3.0
$ ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-http_stub_status_module --with-pcre --add-module=/usr/src/lua-nginx-module-0.10.10 --add-module=/usr/src/ngx_devel_kit-0.3.0
$ make
$ make install
#
$ nginx -v
Nginx 환경 설정
현재 Nginx 만 설정 하면 Lua 스 크 립 트 를 삽입 할 수 있 습 니 다.우선 http 부분 에 Lua 모듈 과 제3자 라 이브 러 리 경 로 를 설정 합 니 다.
# (cjson) luajit-2.0/lib
lua_package_path '/home/www/lua/?.lua;;';
lua_package_cpath '/usr/local/include/luajit-2.0/lib/?.so;;';
다음 에 Lua 스 크 립 트 서 비 스 를 설정 합 니 다.
# hello world
server {
location /lua_content {
# MIME
default_type 'text/plain';
content_by_lua_block {
ngx.say('Hello,world!')
}
}
}
설치 와 설정 이 정상 인지 테스트 하기:
$ service nginx test
$ service nginx reload
# /lua_content
Hello,world!
Lua 호출 Nginx
lua - nginx - module 모듈 에 서 는 Lua 에 풍부 한 Nginx 호출 API 를 제공 하 였 으 며, 각 API 는 각자 의 역할 환경 을 가지 고 있 으 며, 상세 한 설명 은 Nginx API for Lua 를 참조 하 시기 바 랍 니 다.여기 에는 기본 API 의 사용 만 열거 되 어 있다.
먼저 Lua 스 크 립 트 서 비 스 를 설정 합 니 다. 설정 파일 은 다음 과 같 습 니 다.
location ~ /lua_api {
# Nginx
set $name $host;
default_type "text/html";
# Lua
content_by_lua_file /home/www/nginx-api.lua;
}
요청 부분
ngx.var.var_name
형식 으로 Nginx 변수 값 을 가 져 오 거나 설정 할 수 있 습 니 다. 예 를 들 어 requesturi, host, request 등.-- ngx.say
ngx.say(ngx.var.request_uri)
ngx.var.name = 'www.fanhaobai.com'
이 방법 은 현재 요청 한 헤더 정 보 를 표 형식 으로 되 돌려 줍 니 다.요청 한 헤더 정보 보기:
ngx.say('Host : ', ngx.req.get_headers().host, '
')
for k,v in pairs(ngx.req.get_headers()) do
if type(v) == "table" then
ngx.say(k, " : ", table.concat(v, ","), '
')
else
ngx.say(k," : ", v, '
')
end
end
물론, ngx. req. set 를 통 해헤더 () 도 헤더 정 보 를 설정 할 수 있 습 니 다.
ngx.req.set_header("Content-Type", "text/html")
이 방법 은 현재 요청 한 모든 GET 인 자 를 표 형식 으로 되 돌려 줍 니 다.요청 query
?name=fhb
의 GET 인자 보기:ngx.say('name : ', ngx.req.get_uri_args().name, '
')
for k,v in pairs(ngx.req.get_uri_args()) do
if type(v) == "table" then
ngx.say(k, " : ", table.concat(v, ","), '
')
else
ngx.say(k," : ", v, '
')
end
end
마찬가지 로 ngx. req. set 를 통 해uri_args () 는 요청 한 모든 GET 인 자 를 설정 합 니 다.
ngx.req.set_uri_args({name='fhb'}) --{name='fhb'} query name=fhb
이 방법 은 현재 요청 한 모든 POST 인 자 를 표 형식 으로 되 돌려 줍 니 다. POST 데 이 터 는 application / x - ww - form - urlencoded 형식 이 어야 합 니 다.요청
curl --data 'name=fhb' localhost/lua_api
의 POST 인자 보기:-- body
ngx.req.read_body()
ngx.say('name : ', ngx.req.get_post_args().name, '
')
for k,v in pairs(ngx.req.get_post_args()) do
if type(v) == "table" then
ngx.say(k, " : ", table.concat(v, ","), '
')
else
ngx.say(k," : ", v, '
')
end
end
ngx. req. get 통과 하기body_data () 방법 은 해석 되 지 않 은 요청 body 내용 문자열 을 가 져 올 수 있 습 니 다.
요청 한 대문자 형식의 요청 방식 을 가 져 옵 니 다. ngx. req. setmethod () 는 요청 방식 을 설정 할 수 있 습 니 다.예 를 들 면:
ngx.say(ngx.req.get_method())
응답 부분
ngx.header.header_name
형식 으로 응답 헤드 정 보 를 얻 거나 설정 합 니 다.다음 과 같다.ngx.say(ngx.header.content_type)
ngx.header.content_type = 'text/plain'
ngx. print () 방법 은 응답 body 에 지정 한 내용 을 채 웁 니 다.다음 과 같다.
ngx.print(ngx.header.content_type)
위 에서 사용 한 바 와 같이, ngx. say () 방법 은 ngx. print () 방법 과 같 으 며, 나중에 줄 바 꿈 자 를 추가 할 뿐 입 니 다.
어떤 상태 코드 로 응답 내용 을 되 돌려 줍 니 다. 상태 코드 상수 대응 관 계 는 HTTP status constants 부분 을 볼 수 있 고 디지털 형식의 상태 코드 도 지원 합 니 다.
ngx.exit(403)
현재 요청 한 url 로 다시 설정 합 니 다. 응답 상태 코드 선택 가능 목록 은 301, 302 (기본 값), 303, 307 입 니 다.
ngx.redirect('http://www.fanhaobai.com')
기타
이 방법 은 정규 표현 식 일치 방법 을 제공 합 니 다.GET 인자 의 숫자 와 일치 하 는 요청
?name=fhb&age=24
:local m, err = ngx.re.match(ngx.req.set_uri_args, "[0-9]+")
if m then
ngx.say(m[0])
else
ngx.say("match not found")
end
이 방법 을 통 해 내용 을 Nginx 로그 파일 에 기록 할 수 있 습 니 다. 로그 파일 단 계 는 log 단계 와 일치 해 야 합 니 다.
그것들 은 모두 문자열 인 코딩 방식 이다.ngx. md5 () 는 문자열 을 md5 암호 화 처리 할 수 있 으 며, ngx. encodebase 64 () 는 문자열 base 64 인 코딩, ngx. decodebase 64 () 는 base 64 디 코딩 입 니 다.
Nginx 에 Lua 삽입
Lua 에서 Nginx 의 API 를 어떻게 호출 하여 Nginx 의 기능 을 확장 하거나 맞 추 는 지 설명 합 니 다. 그러면 작 성 된 Lua 스 크 립 트 는 Nginx 에서 어떻게 실 행 됩 니까?사실 Nginx 는 모듈 명령 형식 을 통 해 11 개의 처리 단계 에서 삽입 식 처 리 를 하고 명령 은 http, server, server if, location, location if 라 는 몇 가지 범 위 를 덮어 씁 니 다.
모듈 명령 어 목록
기본 적 인 Lua 모듈 명령 만 열거 하고 더 많은 정 보 는 Directives 부분 을 참고 합 니 다.
지령
소재 단계
사용 범위
설명 하 다.
init_by_luainit_by_lua_file
프로필 불 러 오기
http
전역 설정 초기 화 에 사용 할 수 있 습 니 다.
set_by_luaset_by_lua_file
rewrite
serverlocationlocation if
복잡 한 논리의 변수 할당, 주 의 는 차단 되 어 있 습 니 다.
rewrite_by_luarewrite_by_lua_file
rewrite
httpserverlocationlocation if
복잡 한 논리의 퍼 가기 나 재 정립 을 실현 하 다.
content_by_luacontent_by_lua_file
content
locationlocation if
요청 처리 및 출력 응답
header_filter_by_luaheader_filter_by_lua_file
응답 헤드 정보 필터
httpserverlocationlocation if
응답 헤더 정보 설정
body_filter_by_luabody_filter_by_lua_file
출력 필터
httpserverlocationlocation if
출력 을 필터 하거나 수정 합 니 다.
사용 명령
명령 마다
*_lua
와 *_lua_file
두 개의 명령 이 있 고 *_lua
명령 후 Lua 코드 블록 이 며 *_lua_file
명령 후 Lua 스 크 립 트 파일 경로 임 을 알 수 있 습 니 다.다음은 *_lua
명령 에 대해 서 만 설명 할 것 이다.이 명령 은 Nginx 의 Master 프로 세 스 가 설정 을 불 러 올 때 실 행 됩 니 다. 따라서 Lua 모듈 초기 화 작업 을 완료 할 수 있 습 니 다. Worker 프로 세 스 도 이 를 계승 합 니 다.
nginx.conf
프로필 의 http 부분 에 다음 코드 를 추가 합 니 다.-- worker
lua_shared_dict shared_data 1m;
init_by_lua_file /usr/example/lua/init.lua;
init.lua
스 크 립 트 초기 화:local cjson = require 'cjson'
local redis = require 'resty.redis'
local shared_data = ngx.shared.shared_data
우리 가 set 명령 을 직접 사용 하면 복잡 한 변수 할당 논 리 를 실현 하기 어렵 고 setby_lua 모듈 명령 으로 이 문 제 를 해결 할 수 있 습 니 다.
nginx.conf
프로필 location 부분 은 다음 과 같 습 니 다.location /lua {
set_by_lua_file $num /home/www/set.lua;
default_type 'text/html';
echo $num;
}
set.lua
스 크 립 트 내용 은:local uri_args = ngx.req.get_uri_args()
local i = uri_args.a or 0
local j = uri_args.b or 0
return i + j
상기 할당 논리, query
?a=10&b=2
를 요청 할 때 응답 내용 은 12 입 니 다.내부 URL 재 작성 이나 외부 재 설정 을 실현 할 수 있 습 니 다.
nginx.conf
설정 은 다음 과 같 습 니 다.location /lua {
default_type "text/html";
rewrite_by_lua_file /home/www/rewrite.lua;
}
rewrite.lua
스 크 립 트 내용:if ngx.req.get_uri_args()["type"] == "app" then
ngx.req.set_uri("/m_h5", false);
end
접근 권한 제어 에 사용 합 니 다.예 를 들 어 신분 표 지 를 가 진 사용자 만 접근 할 수 있 습 니 다.
nginx.conf
설정 은 다음 과 같 습 니 다.location /lua {
default_type "text/html";
access_by_lua_file /home/www/access.lua;
}
access.lua
스 크 립 트 내용 은:if ngx.req.get_uri_args()["token"] == "fanhb" then
return ngx.exit(403)
end
이 명령 은 Lua 에서 Nginx 부분 을 호출 하여 응답 내용 을 출력 하 는 데 사용 되 었 습 니 다.
케이스
접근 권한 제어
Lua 모듈 을 사용 하여 본 사이트 의 ES 서 비 스 를 수신 조작 으로 제어 합 니 다. 즉, 수신 IP 가 아 닌 조회 조작 만 할 수 있 습 니 다.
nginx.conf
설정 은 다음 과 같 습 니 다.location / {
set $allowed '115.171.226.212';
access_by_lua_block {
if ngx.re.match(ngx.req.get_method(), "PUT|POST|DELETE") and not ngx.re.match(ngx.var.request_uri, "_search") then
start, _ = string.find(ngx.var.allowed, ngx.var.remote_addr)
if not start then
ngx.exit(403)
end
end
}
proxy_pass http://127.0.0.1:9200$request_uri;
}
액세스 주파수 제어
Nginx 프로필 의 location 부분 에 Lua 스 크 립 트 기본 매개 변 수 를 설정 하고 Lua 모듈 명령 을 설정 합 니 다.
default_type "text/html";
set rate_per 300
access_by_lua_file /home/www/access.lua;
Lua 스 크 립 트 는 주파수 제어 논 리 를 실현 하고 Redis 를 사용 하여 단위 시간 내 접근 횟수 를 캐 시 합 니 다. key 는 uri 를 방문 하여 token 을 연결 한 후의 md5 값 입 니 다.구체 적 인 내용 은 다음 과 같다.
local redis = require "resty.redis"
local red = redis:new()
local limit = tonumber(ngx.var.rate_per) or 200
local expire_time = tonumber(ngx.var.rate_expire) or 1000
local key = "rate.limit:string:"
red:set_timeout(500)
local ok, err = red:connect("www.fanhaobai.com", 6379)
if not ok then
ngx.log(ngx.ERR, "failed to connect redis: " .. err)
return
end
key = key .. ngx.md5(ngx.var.request_uri .. (ngx.req.get_uri_args()['token'] or ngx.req.get_post_args()['token']))
local times, err = red:incr(key)
if not times then
ngx.log(ngx.ERR, "failed to exec incr: " .. err)
return
elseif times == 1 then
ok, err = red:expire(key, expire_time)
if not ok then
ngx.log(ngx.ERR, "failed to exec expire: " .. err)
return
end
end
if times > limit then
return ngx.exit(403)
end
return
관련 글 »
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Neovim을 위한 자동 완성NeoVim으로 생산성을 높일 수 있는 가장 멋진 기능 중 하나는 자동 완성이므로 성능에 따라 플러그인을 선택할 수 있습니다. YouCompleteMe Coc.nvim 이 플러그인은 사용하기 좋지만 Javascrip...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.