2017-02-20 35 views
2

Мы пытаемся создать платформу для проверки входящего запроса с использованием HAProxy + Lua. Наш прецедент предназначен для создания сценариев LUA, которые по существу делают вызов сокета API проверки и на основе ответа из API проверки. Мы хотим перенаправить запрос на API-интерфейс бэкэнд, и если проверка не сработает, мы хочу вернуть запрос прямо из сценария LUA. Например, для ответа 200 мы хотели бы перенаправить запрос на backend 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 скрипта . Однако, что проблематично, мы должны отправить ответ из сценария 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 

Любая помощь очень ценится в достижении этой функциональности. Кроме того, я понимаю, что вызов SOCKET из сценария Lua является блокирующим вызовом, который противоречит поведению HAProxy по умолчанию для поддержания активности. Не стесняйтесь предлагать любую другую утилиту для достижения этой функциональности, если вы ее уже использовали.

ответ

7

Хорошо, я выяснил ответ на этот вопрос: Я создал 2 backend для успеха и отказа запросов, и на основе ответа я возвращаю 2 разных строки. В «fail_backend» я вызвал другую службу, которая по сути является core.register_service и может вернуть ответ. Я вставив код как для конфигурационного файла и Lua скрипт

HAProxy файл конф:

#--------------------------------------------------------------------- 
# 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] 

Lua скрипт:

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/Lua? Я попытался установить, но получить 'module 'socket.http' not found'. Использование HA 1.7.7 –

+0

Насколько я помню, я использовал LuaRocks для установки модуля socket.http – Geek

 Смежные вопросы

  • Нет связанных вопросов^_^