Nginx Module Concurrency Query

Hello,

I have been trying to get a simple nginx_module working. I referred
Emiller’s Guide to Nginx Module Development – Evan Miller and found it very
useful.

The module takes “http://10.90.50.31:1257/hello?w=lelj&ljd=22112” and
sleeps for few sec and simply prints the URI.

Here is the code :-

#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#include <unistd.h>

static char *ngx_http_hello_world(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);

static ngx_command_t ngx_http_hello_world_commands[] = {

{ ngx_string(“hello_world”),
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
ngx_http_hello_world,
0,
0,
NULL },

ngx_null_command

};

//static u_char ngx_hello_world[] = “elcome world”;

static ngx_http_module_t ngx_http_hello_world_module_ctx = {
NULL, /* preconfiguration /
NULL, /
postconfiguration */

NULL, /* create main configuration /
NULL, /
init main configuration */

NULL, /* create server configuration /
NULL, /
merge server configuration */

NULL, /* create location configuration /
NULL /
merge location configuration */
};

ngx_module_t ngx_http_hello_world_module = {
NGX_MODULE_V1,
&ngx_http_hello_world_module_ctx, /* module context /
ngx_http_hello_world_commands, /
module directives /
NGX_HTTP_MODULE, /
module type /
NULL, /
init master /
NULL, /
init module /
NULL, /
init process /
NULL, /
init thread /
NULL, /
exit thread /
NULL, /
exit process /
NULL, /
exit master */
NGX_MODULE_V1_PADDING
};

int sum(int a, int b)
{
return a+b;
}

static ngx_int_t ngx_http_hello_world_handler(ngx_http_request_t *r)
{
ngx_buf_t *b;
ngx_chain_t out;

r->headers_out.content_type.len = sizeof(“text/html”) - 1;
r->headers_out.content_type.data = (u_char *) “text/html”;

b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));

out.buf = b;
out.next = NULL;

b->pos = (r->args).data;
b->last = (r->args).data + (r->args).len;
b->memory = 1;
b->last_buf = 1;

usleep(1500000);

r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = (r->args).len;
ngx_http_send_header(r);

return ngx_http_output_filter(r, &out);
}

static char *ngx_http_hello_world(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
{
ngx_http_core_loc_conf_t *clcf;

clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_http_hello_world_handler;

return NGX_CONF_OK;
}

nginx.conf
###########
worker_processes 4;
events {
worker_connections 1024;
}
… # … #

            location = /hello {
                    hello_world ;
            }

#########

But I guess, I am missing something here.

I tried ab (Apache benchmarking) on it, and I found that response time
degrades on increasing concurrency.

ab -c 10 -n 100 “http://10.90.50.31:1257/hello?w=lelj&ljd=22112


Time per request: 3804.810 [ms] (mean)

ab -c 20 -n 100 “http://10.90.50.31:1257/hello?w=lelj&ljd=22112


Time per request: 7587.228 [ms] (mean)

ab -c 30 -n 100 “http://10.90.50.31:1257/hello?w=lelj&ljd=22112


Time per request: 11376.207 [ms] (mean)

The response time was 11376ms, 7587ms, 3804ms for 30, 20, 10 concurrency
respectively.
I am not sure what I am missing.

Can someone please guide me on how do I make this module scale?

  • Danny

Posted at Nginx Forum:

Hello!

On Fri, Jul 01, 2011 at 09:40:20AM -0400, Danny Glover wrote:

I have been trying to get a simple nginx_module working. I referred
Emiller’s Guide to Nginx Module Development – Evan Miller and found it very
useful.

The module takes “http://10.90.50.31:1257/hello?w=lelj&ljd=22112” and
sleeps for few sec and simply prints the URI.

Here is the code :-

[…]

usleep(1500000);

[…]

The response time was 11376ms, 7587ms, 3804ms for 30, 20, 10 concurrency
respectively.
I am not sure what I am missing.

Can someone please guide me on how do I make this module scale?

The behaviour you see is expected: you can’t sleep as it will
block all requests in a worker process. Welcome to event-based
programming. :slight_smile:

You have to arm timer and return back to event loop, then continue
processing once event fires. You may take a look how to do this
in standard limit_req module, though it will require some adaption
for handler module. In particular, you’ll have to return NGX_DONE
and then finalize request yourself, much like it’s done when
reading request body.

Maxim D.

Hi Maxim,

Thank you for the details.
I will read through.

  • Danny

Posted at Nginx Forum: