[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] Beginners' question: multi-threaded HTTP service



On 2012-11-19 16:47, Mark Ellzey wrote:
> On Mon, Nov 19, 2012 at 03:31:17PM +0200, Nir Soffer wrote:
>>
>> I don't think this is a good example for using libevent (maybe I do not
>> understand what it does correctly).
>>
>> That server creates one event loop for accepting connections, and then one
>> event loop for each connection. Since the event loops are run from worker
>> threads, your server is actually a standard threaded server, and you don't
>> get the benefits of event based servers. For example, you can serve only
>> limited amount of connections in the same time.
>>
>> One event loop for doing all IO will probably be fine for your minimal and
>> fast http server. Add worker threads for cpu bound tasks or working with
>> blocking apis, and use queues to pass jobs to the workers and back to the
>> io thread.
>>
>> If one IO thread is not enough, you can use one event loop for each
>> core. This is how ngix works:
>> http://www.aosabook.org/en/nginx.html
> 
> This is actually how libevhtp's threading model works; each thread in
> the pool maintains its own event base, a connection is passed to a
> thread with the least amount of utilization before accept() is called.
> In short, the main thread only deals with the socket that triggered an
> event, the threads actually accept() and handle the connection.
> 
> The trick to having the least amount of lock contention is to use the
> event base that the thread is tied to for other events. This way you
> don't even have to enable threading in libevent.
> 
> Creating a threaded webserver in libevhtp is trivial:
> 
> #include <evhtp.h>
> 
> #define NUM_THREADS 4
> 
> int main(int argc, char ** argv) {
> 	struct event_base * evbase = event_base_new();
> 	evhtp_t           * htp    = evhtp_new(evbase, NULL); 
> 
> 	evhtp_set_gencb(htp, mycallback, NULL);
> 	evhtp_use_threads(htp, NULL, NUM_THREADS, NULL);
> 	evhtp_bind_socket(htp, "127.0.0.1", 8080, 1024);
> 	event_base_loop(evbase, 0);
> 
> 	return 0;
> }
> 
> The second argument of evhtp_use_threads is a callback function that is 
> executed for each new thread that spawns. The first argument in the
> callback is your evthr_t structure that contains the thread-specific
> event_base. You can use this to add events in a threadsafe manner.

Thanks. I was already studying the files test*.c and they start to make
sense. Two more questions I hope you won't mind.

I am using MonoDB as a backend via the C library libmongo-client. Only
no CMake module exists for it, please see
  http://public.kitware.com/Bug/view.php?id=13704
How can I easily add this to your CMake structure? If you want I can
request CMake to support your module called FindLibEvent.cmake in their
next release.

Second question is regarding buffer_in in request. I can't seem to find
a proper example with helpers to retrieve the POST parameters. All I
found that was working is (from
http://www.wangafu.net/~nickm/libevent-book/Ref6_bufferevent.html )

void readcb(struct bufferevent *bev, void *ptr)
{
    char buf[1024];
    int n;
    struct evbuffer *input = bufferevent_get_input(bev);
    while ((n = evbuffer_remove(input, buf, sizeof(buf))) > 0) {
        fwrite(buf, 1, n, stdout);
    }
}

> Some people have told me the method it uses is "not optimal", but it is
> able to handle over 10,000 connections and service 70-90,000 requests/s,
> so I have yet to see a better solution that avoids libevent locking. I
> actually like the idea that each event_base is sandboxed in their own
> thread.

I will give it some thorough testing when my service is finished. :)

Thanks,

Pander

> ***********************************************************************
> To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
> unsubscribe libevent-users    in the body.
> 

***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.