HTTP Load Balancer Example: Mongoose
This article looks at an HTTP load balancer in Mongoose. This is a fairly advanced example that will showcase Mongoose usage as both a server and a client.
Join the DZone community and get the full member experience.
Join For FreeWelcome back to our Mongoose Embedded Web Server examples blog post series! In this edition, we will look at an HTTP load balancer. This is a fairly advanced example that will showcase Mongoose's usage as both a server and a client.
As always, you can download Mongoose Embedded Web Server and work through the example yourself.
An HTTP load balancer is a piece of serving infrastructure; an additional stage between a user’s browser and a server that is introduced when there are multiple servers to choose from. Which one should be used to handle the client’s request? The load balancer takes the user’s request, makes the decision, and forwards it to one of the servers. These are commonly called backends. More advanced load balancers will keep track of the load of the backends and pick the least loaded, but our example load balancer is very basic: it will just alternate between the configured backends. We have two backends configured, the first request will go to backend 1, the second will go to backend 2, the third will go to backend 1 again, and so forth.
Example Run-Through
So let’s test it first and then take a look under the hood. For our example, we will need the balancer itself and backends. We will use a restful_server as the backend. We’ll need at least two to see balancing going on, so let’s compile and start two on different ports:
mongoose/examples/restful_server$ make
cc restful_server.c ../../mongoose.c -o restful_server -g -W -Wall -I../.. -Wno-unused-function -DMG_ENABLE_THREADS -DMG_DISABLE_HTTP_WEBSOCKET -lpthread
mongoose/examples/restful_server$ ./restful_server -p 8910
Starting RESTful server on port 8910, serving .
In another terminal window - run simultaneously:
mongoose/examples/restful_server$ ./restful_server -p 8911
Starting RESTful server on port 8910, serving .
Use your browser to verify that both backends are working: http://127.0.0.1:8910 and http://127.0.0.1:8911 should display the “RESTful API demo” index page.
Now compile and run the load_balancer example:
mongoose/examples/load_balancer master$ make
cc load_balancer.c ../../mongoose.c -o load_balancer -W -Wall -pthread
rojer@nbt:~/go/src/cesanta.com/mongoose/examples/load_balancer master$ ./load_balancer -p 8000 -l - -b / 127.0.0.1:8910 -b / 127.0.0.1:8911
Adding backend for / : 127.0.0.1:8910 [redirect=0,prefix_replacement=/]
Adding backend for / : 127.0.0.1:8911 [redirect=0,prefix_replacement=/]
Starting LB on port 8000
Arguments are documented in the README file, but briefly: -p 8000
tells it to listen for incoming connection on port 8000, -l
- sets the log file to “-
”, which is a special value for stdout
and the two -b
options add our backends.
With that done, you should see the same index page when you point your browser to http://127.0.0.1:8000/. But, each time you reload, the page will be served by a different instance of the backend, and you will see records in the balancer log:
1465822060 GET / backend=127.0.0.1:8910
1465822061 GET / backend=127.0.0.1:8911
1465822062 GET / backend=127.0.0.1:8910
Under the Hood
Now, let’s check out how it works internally. There are a few hundred lines of code in the main file, but as usual, most of the action happens in the event handler (ev_handler). When the client’s request arrives (ev == MG_EV_HTTP_REQUEST
), it picks a backend to use, connects to it, and forwards the client’s request. When the server responds (ev == MG_EV_HTTP_REPLY
), the response is forwarded to the client’s connection. The rest of the code is error handling, dealing with HTTP keep-alive and idle backends.
That’s it for now. We hope this helps you get an idea of how to combine serving and making HTTP requests in the same program.
Published at DZone with permission of Deomid Ryabkov, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments