Jahnavi latha
Jahnavi latha

Reputation: 1

Nginx - How to get the count of requests handled by each upstream IP in the upstream block?

upstream test {
    server ip1:port1;
    server ip1:port2;
    server ip1:port3;
    server ip1:port4;
}
location / {
    set $dst  test;
    proxy_pass http://$dst;
}

Approach -
Initially in the database, I stored the request count of each upstream IP in the upstream block with zero. When a request is made to Nginx, I get the upstream IP used by proxy_pass, Then perform an ngx.location.capture subrequest to the database to increment the count of an upstream IP.

But How can I perform ngx.location.capture after proxy_pass?

Is there any other approach to achieve this?

Can anyone help me with this?

Upvotes: 0

Views: 637

Answers (1)

boppy
boppy

Reputation: 1908

I assume that after proxy_pass means that you don't want your DB to slow down the response to the client.

In the official reference under Directives you can see that the "Log Phase" is the last phase that is entered after the content phase that sends data. As the reference also tells, the code executed in the log phase has no chance to alter the content (because it's sent already).

The second limit is that there is no ngx.location.capture available. So your DB basically has to be updated by the lua code, not by running a subrequest.

Basic idea using LuaSQLite3:

upstream test {
    server ip1:port1;
    server ip1:port2;
    server ip1:port3;
    server ip1:port4;
}
location / {
    set $dst  test;
    proxy_pass http://$dst;

    log_by_lua_block {
        local sqlite3 = require("lsqlite3")
        local db = sqlite3.open('access_list.sqlite3')
        db:exec([[
          CREATE TABLE logs (
            backend     VARCHAR NOT NULL PRIMARY KEY,
            access      INTEGER NOT NULL DEFAULT 1
          );
        ]])

        local prep = db:prepare('INSERT INTO logs(backend) VALUES (:backend) ON CONFLICT(backend) DO UPDATE SET access=access+1')
        prep:bind_names({ backend = ngx.var.dst })
        prep:step()
        prep:reset()
        db:close()
    }
}

You can further optimize here if you start the db connection in the init phase of openresty.

Upvotes: 0

Related Questions