Hello,
I'm trying to write a simple function with OpenResty, Redis and RabbitMQ. The use case is the following, we receive requests on /data?ip=x.x.x.x, and the parameter ip needs to be lookep up in a Redis database. If we find a value, we return it, otherwise, we send the ip to a RabbitMQ exchange to be analyzed and saved in Redis by another app.
I have one performance constraint, this endpoint needs to reply within 8 to 10ms with thousands of calls every second.
I've written a first version which complies with the business requirements, but not yet with the performance.
It seems that the RabbitMQ publishing part is bringing the performance down by a 10x factor.
If I only keep the Redis read, I get an average response time of 1-2ms, with the RabbitMQ publish, I'm up to 15ms and huge standard deviation.
What should I try in order to improve this ?
worker_processes auto;
error_log error.log;
events {
worker_connections 1024;
}
http {
server {
listen 8080;
location /data {
default_type text/html;
content_by_lua_block {
local redis = require "resty.redis"
local red = redis:new()
local strlen = string.len
local cjson = require "cjson"
local rabbitmq = require "resty.rabbitmqstomp"
-- connect via ip address directly
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local ip = ngx.var.arg_ip
local res, err = red:get(ip)
if not res then
ngx.say("failed to get ip: ", err)
return
end
local ok, err = red:set_keepalive(10000, 100)
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end
if res == ngx.null then
ngx.say("\n")
local opts = { username = "guest",
password = "guest",
vhost = "/" }
local mq, err = rabbitmq:new(opts)
if not mq then
return
end
local ok, err = mq:connect("127.0.0.1",61613)
if not ok then
return
end
local msg = {ip=ngx.var.arg_ip}
local headers = {}
headers["destination"] = "/exchange/xandr"
headers["persistent"] = "true"
headers["content-type"] = "text/plain"
local ok, err = mq:send(ngx.var.arg_ip, headers)
if not ok then
return
end
local ok, err = mq:set_keepalive(10000, 100)
if not ok then
return
end
return
end
ngx.say(res)
}
}
}
}