2017-02-20 6 views
2

HAProxy + Lua를 사용하여 들어오는 요청 확인 플랫폼을 구축하려고합니다. 유스 케이스는 본질적으로 유효성 검증 API에 대한 소켓 호출을 작성하는 LUA 스크립트를 작성하는 것입니다. 유효성 검증 API의 응답 을 기반으로 요청을 백엔드 API로 재 지정하려고합니다. 유효성 검증이 실패하면 LUA 스크립트에서 바로 요청을 반환하고 싶습니다. 예를 들어 200 응답의 경우 요청을 백엔드 API로 리디렉션하려는 경우 404에 대해 요청을 반환해야합니다. 이 문서에서 Lua-Haproxy 통합과 함께 을 사용할 수있는 다양한 기본 기능이 있다는 것을 알고 있습니다. 나는 목록 위의 모든 기능을 시도HAproxy + Lua : Lua 스크립트에서 유효성 검사가 실패한 경우 요청을 반환합니다.

core.register_action() --> I'm using this. Take TXN as input 
core.register_converters() --> Essentially used for string manipulations. 
core.register_fetches() --> Takes TXN as input and returns string; Mainly used for representing dynamic backend profiles in haproxy config 
core.register_init() --> Used for initialization 
core.register_service() --> You have to return the response mandatorily while using this function, which doesn't satisfy our requirements 
core.register_task() --> For using normal functions. No mandatory input class. TXN is required to fetch header details from request 

, 나는 core.register_service이 루아 스크립트에서 응답을 반환하기 위해 기본적으로 이해합니다. 그러나 문제가되는 것은 LUA 스크립트의 응답을 보내야하며 요청을 BACKEND로 리디렉션하지 않습니다. 현재 core.register_action을 사용하여 요청을 중단하고 있지만이 기능을 사용하여 요청을 반환 할 수 없습니다. 다음

local http_socket = require("socket.http") 
local pretty_print = require("pl.pretty") 

function add_http_request_header(txn, name, value) 
    local headerName = name 
    local headerValue = value 
    txn.http:req_add_header(headerName, headerValue) 
end 

function call_validation_api() 
    local request, code, header = http_socket.request { 
            method = "GET",     -- Validation API Method       
            url = "http://www.google.com/"  -- Validation API URL 
            } 

    -- Using core.log; Print in some cases is a blocking operation http://www.arpalert.org/haproxy-lua.html#h203 
    core.Info("Validation API Response Code: " .. code) 
    pretty_print.dump(header) 
    return code 
end 

function failure_response(txn) 
    local response = "Validation Failed" 
    core.Info(response) 
    txn.res:send(response) 
-- txn:close() 
end 

core.register_action("validation_action", { "http-req", "http-res" }, function(txn) 
    local validation_api_code = call_validation_api() 
    if validation_api_code == 200 then 
     core.Info("Validation Successful") 
     add_http_request_header(txn, "test-header", "abcdefg") 
     pretty_print.dump(txn.http:req_get_headers()) 
    else 
     failure_response(txn) --->>> **HERE I WANT TO RETURN THE RESPONSE** 
    end 
end) 

구성 파일 항목입니다 : 여기 처럼 내 코드가 어떻게 표시되는지를 보여줍니다

frontend http-in 
    bind :8000 
    mode http 
    http-request lua.validation_action 

    #Capturing header of the incoming request 
    capture request header test-header len 64 

    #use_backend %[lua.fetch_req_params] 
    default_backend app 

backend   app 
    balance  roundrobin 
    server  app1 127.0.0.1:9999 check 

어떤 도움이 많은이 기능을 달성 감사합니다. 또한 Lua 스크립트의 SOCKET 호출은 HAProxy의 keep-alive 연결 특성과 반대되는 블로킹 호출이라는 것을 알고 있습니다. 이미이 기능을 사용했다면이 유틸리티를 사용하기 위해 다른 유틸리티를 제안하십시오.

답변

7

Ok이 질문에 대한 대답을 알아 냈습니다. 요청 성공 및 실패에 대해 2 백엔드를 작성했으며 응답에 따라 2 개의 다른 문자열을 반환합니다. "failure_backend"에서 나는 본질적으로 core.register_service 인 다른 서비스를 호출했으며 응답을 반환 할 수 있습니다. 나는 구성 파일 및 루아 스크립트 모두에 코드를 붙여 해요

HAProxy의 conf 파일 :

#--------------------------------------------------------------------- 
# Global settings 
#--------------------------------------------------------------------- 
global 
    # to have these messages end up in /var/log/haproxy.log you will 
    # need to: 
    # 
    # 1) configure syslog to accept network log events. This is done 
    # by adding the '-r' option to the SYSLOGD_OPTIONS in 
    # /etc/sysconfig/syslog 
    # 
    # 2) configure local2 events to go to the /var/log/haproxy.log 
    # file. A line like the following can be added to 
    # /etc/sysconfig/syslog 
    # 
    # local2.*      /var/log/haproxy.log 
    # 
    log   127.0.0.1 local2 
    maxconn  4000 
    user  haproxy 
    group  haproxy 
    daemon 
    #lua file load 
    lua-load /home/aman/coding/haproxy/http_header.lua 

    # turn on stats unix socket 
    stats  socket  /var/lib/haproxy/stats 

#--------------------------------------------------------------------- 
# common defaults that all the 'listen' and 'backend' sections will 
# use if not designated in their block 
#--------------------------------------------------------------------- 
defaults 
    mode  http 
    log   global 
    option  httplog 
    option  dontlognull 
    retries  3 
    timeout  http-request 90s 
    timeout  queue   1m 
    timeout  connect   10s 
    timeout  client   1m 
    timeout  server   1m 
    timeout  http-keep-alive 10s 
    timeout  check   10s 
    maxconn  3000 

#--------------------------------------------------------------------- 
# main frontend which proxys to the backends 
#--------------------------------------------------------------------- 
frontend   http-in 
    bind   :8000 
    mode   http 
    use_backend  %[lua.validation_fetch] 
    default_backend failure_backend 

#--------------------------------------------------------------------- 
# round robin balancing between the various backends 
#--------------------------------------------------------------------- 
backend   success_backend 
    balance  roundrobin 
    server  app1 172.23.12.94:9999 check 

backend    failure_backend 
    http-request use-service  lua.failure_service 

# For displaying HAProxy statistics. 
frontend   stats 
    bind   :8888 
    default_backend stats 

backend  stats 
    stats enable 
    stats hide-version 
    stats realm Haproxy Statistics 
    stats uri /haproxy/stats 
    stats auth aman:[email protected] 

루아 스크립트

local http_socket = require("socket.http") 
local pretty_print = require("pl.pretty") 

function add_http_request_header(txn, name, value) 
    local headerName = name 
    local headerValue = value 
    txn.http:req_add_header(headerName, headerValue) 
end 

function call_validation_api() 
    local request, code, header = http_socket.request { 
            method = "GET",       -- Validation API Method       
            url = "http://www.google.com/"  -- Validation API URL 
            } 

    -- Using core.log; Print in some cases is a blocking operation http://www.arpalert.org/haproxy-lua.html#h203 
    core.Info("Validation API Response Code: " .. code) 
    pretty_print.dump(header) 
    return code 
end 

function failure_response(txn) 
    local response = "Validation Failed" 
    core.Info(response) 
    return "failure_backend" 
end 

-- Decides back-end based on Success and Failure received from validation API 
core.register_fetches("validation_fetch", function(txn) 
    local validation_api_code = call_validation_api() 
    if validation_api_code == 200 then 
     core.Info("Validation Successful") 
     add_http_request_header(txn, "test_header", "abcdefg") 
     pretty_print.dump(txn.http:req_get_headers()) 
     return "success_backend" 
    else 
     failure_response(txn) 
    end 
end) 

-- Failure service 
core.register_service("failure_service", "http", function(applet) 
     local response = "Validation Failed" 
     core.Info(response) 
     applet:set_status(400) 
     applet:add_header("content-length", string.len(response)) 
     applet:add_header("content-type", "text/plain") 
     applet:start_response() 
     applet:send(response) 
end) 
+0

당신이 할 수 socket.http HProxy 설치하려면 얼마나/루아? 설치를 시도했지만'module 'socket.http'not found '를 얻습니다. HA 1.7.7을 사용하여 –

+0

내가 아는 한, socket.http 모듈을 설치하기 위해 LuaRocks를 사용했다. – Geek