Tag Archives: Monkeyd

GSoC 2014 Update : Caching plugin for Monkey server – Week 4

After a busy first half of the fourth week (I had exam and assignment submissions) I started testing the code that I have written for memory  leaks and other discrepancies that may have cropped in while I wrote it. I used valgrind a memory leak detecting tool to correct a few errors and also manually tried to find if there exists any errors. Testing is a continuous process and am still continuously doing it.
I also made sure that the files get unmapped after their usage is over. Since the hash table is not going to be persisted, the files in the cache should also be deleted, once the hash table gets deleted and hence the need of unmapping of the mapped files.
Roadmap for the next week :
  1. To include a configuration file for the cache plugin.
  2. To start integrating cache with the server.

Git hub repo : https://github.com/tssavita/cache-plugin-implementation

Selected for Google Summer of Code 2014.

Recently, my proposal for Google Summer of Code 2014 in Monkey HTTP Server got selected. I have posted my GSoC proposal here.

Advanced Caching plugin for Monkey server

Organization: Monkey Project

Short description: This proposal provides a brief description of the implementation of a caching plugin for Monkey server. This plugin will be of great benefit to the server since it will reduce the server load and increase the performance of the server by enabling to handle requests from more clients. More has been described in the proposal.

Table of Contents:

  1. Short Description
  2. Deliverables
  3. Workflow
  4. Implementation details
  5. Cache Algorithm
  6. Benefits to the project
  7. Timeline
  8. About myself

1. Short Description:

In conditions of high traffic, where the servers are loaded with a large number of requests, it sometimes happens that a server is requested for the same information repeatedly by clients, that too, often within a very short span of time. This clearly wastes the performance of the server since it could be tending to the requests of many other clients.

As a solution to this problem, the idea proposes a caching plugin for Monkey server. A cache is a collection of locally stored data that are often requested by the client or user. Since a cache is physically more close to the requester, information from the cache can be accessed more quickly than from the server itself. With the help of the cache, information that was recently requested is stored in the cache. The performance of the server, to satisfy the requests of multiple clients can be improved.

2. Deliverables:

 By the completion of this internship, the following will have been delivered to Monkey project.  

  1. A cache plugin for Monkey server.

  2. A GUI for the plugin, for the admin to keep track of how the performance of the server by keeping track of the number of successful attempts in fetching information from the cache and number of failed attempts.

3. Workflow:

  1. As the server starts running, it loads all the plugins that have been enabled by the user. The cache plugin will be an optional plugin – the user has the option to enable or disable it while configuring the server, as is the case with other plugins.
  2. As the requests arrive, they are redirected to threads that are least loaded (that have the least number of active connections) by means of asynchronous sockets that are used by the server.
  3. At this point, the caching plugin intercepts if it is a GET request and with the name of the resource, it looks up at cache, instead of fetching data from the server. This step could have the following two alternatives:
    1. On looking up, if it finds the entry of the resource, it gets the cache memory location of the resource.
      1. The plugin then caches and retrieves the contents of the file from the cache memory.
    2. If it does not find the entry, then it fetches the resource from the disk.
      1. While returning it to the client, it checks the configuration file for the cache.
      2. If the file satisfies all the rules that have been mentioned in the configuration file, for the cache, then it stores a copy of the file in the cache, along with the time of storage. It then returns the resource to the client.
Here is a diagram of how the cache works fits in the entire system : 

4. Implementation Details

4. 1. The two main tasks involved in this project are the following:

  1. The cache plugin: In order to find out if the resource is present in the cache or not, a hash table is maintained, that stores the name of the resource and the memory reference where it is located in the cache. A hash table has been chosen because, a lookup operation in a hash tables takes only O (1) time as opposed to greater time by other data structures. However, this decision is subject to changes and in case a more appealing solution turns up, it may be adopted. But this does not create any major changes in the implementation. Only the memory location of the resource needs to be returned.
    1. Handle only get requests – URL parsing – using functions in src/mk_http.c. The various functions that have been defined in src/mk_http.c help in finding out if the method is GET or not.
    2. After that instead of calling mk_http_init () in src/mk_http.c a checking function is encountered that checks if the plugin has been enabled or not.
    3. If the plugin has been enabled, lookup (key) the function for hash table lookup is called, passing as parameters to it, the name of the resource.
    4. In the table if the resource is found, the function returns the memory location where the resource is located in cache.
      1. Next, the retrieve (memory_location), another function of the plugin, will retrieve the file from the cache, with the help of the memory location reference that is passed to it.
      2. The contents of the file is then written to through the socket connection that is open with the client.
    5. In the hash table if the function is not found, then the mk_http_init () function is called, that normally retrieves the content of the file requested, from the disk of the server.
      1. After it checks the validity of the file, (for example, if the file exists, and if it is accessible, etc. ) it is retrieved from the server accordingly.
      2. The configuration file is checked for rules which are to be obeyed, while storing the file in the cache. If the file satisfies all rules, it is stored in the cache.
  2. A front end with Twitter bootstrap and Angular JS: For the convenience of the admin, the plugin will also have a simple graphical user interface. The plugin will have a front end developed with the help of Twitter bootstrap and Angular JS. Since HTTP callbacks are used, the output obtained could be specified to be in JSON format. It will help the admin keep track of the following: 
      1. Number of hits and misses.
      2. How much area of the cache has been occupied.
      3. Option to clear the cache.
      4. Live displays statistics of hits and misses so far.
4. 2. Files included are :
  1. Hash table: This file would contain the following functions among others:
    1. Insert (resource_name) – This function helps insert values into the hash table.
    2. Lookup (key) – This function is for searching if a particular key exists in a hash table. The key here, is the resource and path of the resource combined together.
    3. Remove () – This function checks the duration of time that each file has been in the cache for and removes any such file that has exceeded the time limit mentioned in the configuration file.
  2. Configuration file : This file contains the rules for files that can be stored in the cache. It can be customized according to the needs to the user. Examples for some of the rules are: 
    1. Limit of size of files that can be stored in the cache.
    2. Types of files that should be stored in the cache.
  3. Cache Plugin: This would contain the following functions among others:
    1. Retrieve (memory_location) – This function caches into memory and locating the file. Note that each time a file is retrieved successfully from the memory, the number of hits is incremented.
    2. Write (buffer) – Writing the contents of the file on the socket connected with the client.
    3. Store_in_cache (file) – This function checks the rules in the configuration file, and if the file satisfies the conditions, then it is stored in the cache and the memory location where it was stored, is returned.
4. 3. Issues to be handled during implementation:
No race condition while accessing the cache by different threads. Therefore, it should be made sure that no other thread accesses the cache while it is being written by another thread.

 5. Cache Algorithm

 Solution 1 : Implementation using min heap.

 The first solution is to use a min heap to store the files and in a cache. The nodes of the heap is used to store files. Each node a.k.a. file is inserted into the min heap using the access count which indicates how many times the file has been accessed. Each time a file is looked up for, using the hash table, the access count is incremented by 1. The heap is then balanced accordingly. The node at the top of the min heap will have the minimum access count. When the cache becomes full, the node at the top (the root node) is deleted, the new resource could be inserted, and the heap is again balanced accordingly.

Run time calculation:
The time complexity for operations of a min heap is as follows :

Insertion : O (log n)
Deletion : O (log n)
Lookup : O (log n)

Time complexity for operations of a hash table = O (1)
Total run time of that LFU cache : Time complexity of lookup in hash table + Time complexity of operations in min heap.

Since the run time for hash table operations is constant, the run time of the cache entirely depends on the time complexity of operations of the min heap, which is, O (log n).

Solution 2 : Implementation using two doubly linked lists.

For the implementation I would like to propose the idea of using doubly linked lists so that the run time of the cache could be optimized to O (1). The doubly linked list called a frequency list, will have nodes that represent different frequencies. Each node in the list is a head to another doubly linked list that contains all files that have the same access number.
So essentially when the first request comes, the hash table is empty and so is the cache. Thus it is retrieved from the server and before returning to the client, it stores a copy of this in the cache. This file is inserted in the linked list of frequencies, inside the linked list of frequency 1. If another file is requested for by the client, it is inserted in the cache after retrieving from the server. In the cache, it is inserted inside the linked list for frequency 1 files. Thus the insertion time is O(1). If suppose the file that was first inserted, was requested for again by the client, the memory location would be present in the hash table. Its access number is incremented to 2. It checks if there is a node for frequency 2. If no, it creates a node for frequency 2 immediately after 1 and then inserts the file in linked list for frequency 2. Thus the time complexity for accessing a file is O(1). If the cache becomes full, the element that has the least access number is to be removed from the linked list. This would any file in the linked list for frequency 1. So the deletion time is also O(1).
The following diagram will give you clear picture of the implementation proposal.
Run time complexity calculation:
The time complexity for the operations of a doubly linked lists:
Insertion : O (1)
Deletion : O (1)
Lookup : O (1)Time complexity for operations of a hash table = O (1)
Total run time of the LRU cache : Time complexity of hash table + Time complexity of the doubly linked list.Since the hash table operations take only constant time, it should not affect the run time of the cache. Thus the runtime would be entirely dependent on the runtime of the linked lists, which would be O(1).

6. Benefits:

The main goal of Monkey server is to provide a high performance with low usage of resource. By cutting down on the requests for same resource, that the server has to deal with, it makes way for better performance as the server can accommodate other requests. The following would be the benefits that the plugin will provide to the server:
  1. Client’s benefit : Faster access to data and reduced time lag between requesting for information and receiving it.
  2. Reduced load for the server: Fetching same data multiple times can be avoided thereby saving the energy of the server.
  3. Increased performance of the server: It can satisfy the requests come from many clients.

7. Timeline:

Now – April 21st

  • Study about the internal structure of Monkey server.
  • Submit quality patches so that I understand the structure better.

April 21st – May 19th

  • Continue studying about the structure of the server.
  • Investigate more into how to handle plugin data and come up with a solution.
  • Community Bonding Period: During this period, I would like to take some solid work like documenting some specific part of the server, so that it strengthens my knowledge about the internals of the server.

May 19th – May 25th

  • Discuss with the mentor about weekly plans.
  • Analyze, compare and contrast the advantages of using various data structures for lookup purpose.
  • Decide on whether or not to change the decision on using a hash table for lookup.
  • Decide on whether to use a min heap or doubly linked lists for the purpose of implementation of an LRU cache.
  • Discuss with the mentor about how to improve the performance of the plugin.

May 26th – June 1st

  • Finish writing the configuration file that contains functions that check if a file is eligible to be stored in a cache.

June 2nd – June 8th

  • Read documentation for implementation of the decided lookup structure (as of now, hash table).
  • Implementation of the data structure lookup, along with insert, lookup and delete functions.
  • Simultaneously test if it works alone as a standalone structure.

June 9th – June 15th

  • Implement the cache with the solution that has been decided upon during the initial phase.
  • Write the cache plugin with functions to retrieve the file from cache, store the file that is retrieved from the server, in the cache, etc..

June 16th – June 22nd

  • Complete the implementation of functions for the cache. 
  • Implement handling of data that is requested by plugins from various servers.
  • Test integration with hash table.

June 23rd – June 29th

  • Continue integration with Monkey server: Testing and trying for various incoming requests, if the cache works fine.
  • Constantly try to optimize the performance of the plugin.
  • Get code written till date, ready for midterm evaluation.

Deliverable at the end of this period: The cache plugin would be ready by the end of midterm evaluation period.

June 30th – July 6th

  • Buffer period for completing any incomplete work in the functioning of the plugin.
  • This is also the buffer time for changing anything that was found inappropriate previously, or anything that was found to bring down the performance of the server.

July 7th – July 17th

  • Read the documentation for developing user interface with twitter bootstrap.
  • Implement a basic GUI using bootstrap.

July 18th – July 28th

  • Improvise by taking comments from the mentor and others in the organization.
  • Integrate with the data that has been stored – number of hits and misses.
  • Integrate with statistics and create live displays, as mentioned in the second part of the implementation details section.

July 29th – August 3rd

  • Testing phase: Do a thorough testing of the graphical user interface and see if the data displayed is correct.
  • Check the working of the entire plugin.

August 4 – August 10th

  • This is the period for cleaning up any code cleaning up.

August 11th – August 17th

  • Complete the remaining documentation and get the code ready for submission.

Epoll feature and its use in Monkey HTTP server

There is a reason that I mentioned in my earlier post on Introduction to Monkey server runs only on Linux operating systems. It is because, the server depends on a set of non-portable Linux system calls for its performance. One among the most important of system calls is the epoll feature.

What is epoll ?

Epoll is a feature provided by Linux kernel to manage file descriptors. It monitors the file descriptors that have been added to an epoll instance to see if I/O event is possible on any one of them. They may be used either as edge-triggered or level-triggered.

Some of the functions used in this regard are :

  1. epoll_create1 – This creates an epoll instance. Each epoll instance has a file descriptor. epoll_create1 () returns the efd (epoll file descriptor) of the epoll instance created.
  2. epoll_ctl – This is used to perform specified operations on them. It may be adding a particular fd to the epoll instance.
  3. epoll_wait – This waits on the file descriptors to see if an I/O event is possible. If this is not possible on any of the file descriptors monitored by an epoll instance of efd, it blocks the calling thread.

Some of the data types used in this regards are :

  1. struct epoll_data – void *ptr, int fd, uint32_t u32, uint64_t u64.
  2. struct epoll_events – uint32_t events, epoll_data_t data.

Some of the actions whose occurrence the epoll instance looks for in a file descriptor are as follows :

  1. EPOLLIN – for a read operation
  2. EPOLLOUT – for a write operation
  3. EPOLLERR – indicates an error that happened on the file descriptor
  4. EPOLLHUP – indicates that a hangup occured on the fd
  5. EPOLLRDHUP – indicates that the connection was set down by a socket peer
  6. EPOLLET – sets Edge triggered behaviour for the file descriptor

Epoll component in Monkey server

The monkey server also makes use of the epoll feature provided by the Linux kernel to handle the innumerable file descriptors.

Implementation Details :

The epoll states of all the file descriptors that are being handled by a thread are stored in a red black tree in addition to being stored in an epoll queue. Besides this, each thread also has two lists – one for available and the other for busy slots. Further for each file descriptor, a set of data is to be maintained about the behaviour, events to be monitored, current mode, etc.The structures that are used to represent the various the epoll states for a file descriptor and for a thread are as follows :

  1. struct epoll_state_index – for each thread.
    1. size – number of requests that a thread can handle.
    2. red black tree for all the epoll state nodes in the thread.
    3. available list of those epoll state nodes that are free.
    4. busy list of those epoll state nodes being currently used.
  2. struct epoll_state – for each file descriptor.
    1. file descriptor – one whose epoll state this struct represents
    2. mode – current mode of the file descriptor (this is an element of events list)
    3. events – the list of events that should be monitored
    4. behaviour – denoting whether the events should be monitored on the basis of edge triggering or level triggering.
    5. A red black node so that it can be added to the red black tree that stores the epoll states for file descriptors for a particular thread.
    6. A list node so that it can be added to either the busy queue or available queue that is maintained for each thread.
  3. struct mk_epoll_handlers – this will be explained in another post.
    1. int (*read) (int);
    2. int (*write) (int);
    3. int (*close) (int);
Functions in src/mk_epoll.c :

In the source code for Monkey server, there are separate functions written for this very important component. The following is a brief description of the functions and what each function does :

  1. mk_epoll_create () – This creates an epoll instance for a thread, with the help of the system call epoll_create1, and returns the epoll file descriptor for the epoll instance of the thread. If due to some reason, the epoll instance was not created (that is, epoll_create1 returned -1), it prints an error.
  2. mk_epoll_init (int efd, int max_events) – This is the function where the epoll instance waits infinitely for on the events that occur on the file descriptors. It is done with the help of epoll_wait function. Depending on which event is occurring on the file descriptor, the corresponding method is called. It does this for all the file descriptors are present on the epoll instance.
  3. mk_epoll_state_get (int fd) – This function gets called  from two places – from function mk_epoll_add and mk_epoll_chage_mode. Given the file descriptor, this function gets the epoll state of the file descriptor from the red black tree that contains the epoll states of all file descriptors for the thread. If the epoll state of a file descriptor has not been found, it prints a message saying so and returns NULL.
  4. mk_epoll_state_set (int fd, uint8_t mode, unsigned int behaviour, uint32_t events) – Given the parameters, it searches the red black tree for this particular epoll state node with file descriptor = fd. If the node is already present, it just sets the mode, and if the mode is not SLEEP, the events and behaviour of the fd, with the values that have been passed to this function. This case will happen when it called from inside change_mode function (explained in the end). If the node is not present in the red black tree (which means that it is a new one), it is assigned the values that have been passed to this function, such as mode, behaviour, events, etc.. This node is then removed from the available queue and added to the busy queue. It is also inserted into the red black tree for the thread.
  5. mk_epoll_state_init () – This function initializes values for members of struct epoll_state_index.
  6. mk_epoll_add (int efd, int fd, int init_mode, unsigned int behaviour) – With the given parameters, it adds the initial mode to the events list of the file descriptor fd. It then calls epoll_ctl with operation EPOLL_CTL_ADD on fd, to add it to the epoll instance for the thread. At the end it calls state_set function to add it to the red black tree and the one of the lists of the thread.
  7. mk_epoll_del (int efd, int fd) – This removes the epoll state of fd from the epoll instance efd, with the help of EPOLL_CTL_DEL operation in epoll_ctl function. It then calls mk_epoll_del_state function to remove it from other places.
  8. mk_epoll_state_del (int fd) – This function removes it from the red black tree where the epoll states are stored, and deletes it from the list where it is present, adds the epoll state node to the available queue.
  9. mk_epoll_change_mode (int efd, int fd, int mode, unsigned int behaviour) – This function is used to change the mode of a particular file descriptor. Using a switch case, it checks the mode against possible modes. On finding the matching case, it appends that particular mode to the events list. If the mode is SLEEP, it disables all events in the event list for the file descriptor. If the mode is WAKEUP, it gets the node from red black tree, and (if the file descriptor is present ) reassigns events and behaviour for the node (which had been previously disabled when its mode was changed to SLEEP). After the changes made to the mode of the file descriptor, it calls epoll_ctl (efd, EPOLL_CTL_MOD, fd, events_list) for the descriptor in the epoll instance of the thread, with operation to modify the epoll event for fd. It then calls the state_get function again to reset the mode, events list and behaviour.
Workflow :

The workflow of where and when the epoll is used in the Monkey server has been explained, trying maximum to keep out other components of the server :

  1. When a thread is created that will be listening for incoming requests, an epoll instance is created using epoll_create.
  2. Now that an epoll instance has been created for the thread, this epoll instance is initialized with values for various fields of the instance.
  3. As soon as an incoming connection arrives, it is assigned the least loaded thread and soon after this, the file descriptor for this connection is added to the epoll instance of the thread.
  4. The epoll instance monitors the events that occur in each file descriptor that has been added to it.
  5. Depending on whether the event on a file descriptor is read or write or any of the events mentioned in the previous section, the corresponding method is called.
  6. After all the requests on a particular socket have been completed, it is removed from the epoll instance.

References :

  1. man pages for epoll
  2. http://swpd.github.io/blog/2013/05/18/monkey-http-daemon-internals/
  3. http://edsiper.linuxchile.cl/blog/category/monkey/

Reverse Proxy and its support by Monkey HTTP server

Reverse proxy is the process of routing client requests to backend servers. It sits in between the client and backend servers. It takes a request from the client and assigns it to one of the servers. It fetches the requested resource from the server and returns it to the client. Some of the advantages of using a reverse proxy are :

  1. Helps clients access servers that are configured beyond a firewall. Only the IP address of the proxy is publicized the outer world.
  2. Helps balance loads among different backend servers. It helps choose which server should take the load of the incoming request from the client.
  3. If one of the servers fails to deliver the content of the client request, the request can be assigned to another server.
  4. It is also possible to cache information that is requested frequently by clients. This reduces the load of having to fetch the resource from the server each time.

The following diagram gives a picture of the entire system.


Monkey plugin for reverse proxy :

The monkey server provides support for reverse proxy through the plugin proxy_reverse. You can read more about it here.

Workflow :

This is a brief workflow and where the reverse proxy plugin fits in :

  1. Incoming requests from clients
  2. The request URI is processed to check if it satisfies the regex rules
  3. Checked if a match is found on the basis of the previous search
  4. A balancing algorithm and a list of slave servers are decided on this basis
  5. The list of servers is passed to a balancing function.
  6. A balancing function determines which server should be used.
  7. A new socket is created to connect to the slave server
  8. The socket is set to non-blocking mode
  9. If a connection cannot be established, another slave server is selected and tried to connect
  10. If all servers return an error and cannot be connected to, then an error is returned.
Algorithms for balancing :

Some of balancing algorithms used for this purpose are as follows :

  1. Naive – first alive server from server
  2. First alive – first alive server from 0
  3. Round Robin
    1. with locking – uses mutexes
    2. without locking – does not use mutexes
  4. Least Connections
Some developments in future : Providing cache for reverse proxy plugin

Thanks to Sonny Karlsson, a developer of Monkey httpd server for the idea. He proposed the idea of developing a cache for reverse proxy plugin in the monkey server.

Exception case:
When Monkey server becomes one of the slave servers for reverse proxy plugin there is the possibility of a recursion happening. The following diagrams would show a normal case and the exceptional case. For this reason, it has to be identified if a request is coming from a client or a reverse proxy plugin. If it is found that the resource is not present in the cache, and the slave server to which the request is going to be redirected is Monkey server itself, this would be like an ordinary incoming request to the server, which would be processed and looked up the cache, to see if the resource is present. This will happen indefinitely. Thus, if the resource requested by a request from the proxy reverse plugin is not present in the cache and the slave server to which the request is going to be directed to is found to be Monkey, immediately the next slave server in the list is chosen and the request is sent to this server. The following diagram will show you a workflow of entire system.

Caching the reverse proxy plugin requests
Caching the reverse proxy plugin requests
References :
  1. Picture courtesy : http://www.excitingip.com/1783/what-is-a-reverse-proxy-server/
  2. http://nikolanikov.wordpress.com/2013/08/14/monkey-proxy-reverse-plugin-preview/

Virtual Hosting and its support by Monkey HTTP server

Virtual hosting is allowing one server to represent different machines. This basically for supporting multiple host names on one server. For example, there may be two websites – example.com and example.org that may be having the same IP address. For the two websites, even though their information is hosted on the same server, it is maintained in different directories.

There are two types of virtual hosting at the moment:
1. Name-based virtual hosting
2. IP based virtual hosting


What is its advantage ?

The advantage of virtual hosting is that a server shares its resources with multiple websites have the site content on the same server. It shares its resources like processor cycles and memory, etc. with different servers. In a server, virtual hosting is seen as a method to share the server content between different domains.

How to configure Monkey server with two virtual host ?

The following are the steps to be followed while configuring support for virtual hosts in Monkey server.

1. You need to change the /etc/hosts file to add multiple hosts to the same IP address. For example, monkey1 monkey2

So now we have two virtual hosts assigned to the same IP address.

2. Now both of these servers will have different directories under which their resources are shared, in monkey/htdocs/ directory. (monkey/htdocs/monkey1 and monkey/htdocs/monkey2)

3. Each will also need configuration file that states the Document root folder where its resources have been located and its ServerName. The example of a configuration file for one of these servers is as follows:

    Documentroot /home/savita/monkey/htdocs/monkey1
    ServerName monkey1

4. Now on typing the URL: https://monkey1:2001/monkey1/amma1.jpg this particular image which was stored in monkey1 folder is displayed on the browser. For virtual host monkey2, this resource will be present in monkey2/ directory. So if you were to type in the URL space, https://monkey2:2001/monkey2/amma2.jpg, the image that was placed in that location is obtained and displayed on the browser.

The process of having different virtual hosts. In each HTTP request, the host name and the resource URI are mentioned. Now, it checks if the particular virtual host exists and within the virtual host, a particular resource exists or not. If not, then an error is returned.

Sharing file descriptors among different requests :

Monkey follows a special method of sharing file descriptors among different requests that come to the same virtual host so that it avoids opening numerable file descriptors at the same time. This is called File Descriptor Table (FDT).

For each worker or thread, a hash table is maintained with 64 entries and each of these maintains a subarray of 8 chains. So when a request arrives at one of the virtual hosts, it hashes the name of the resource being requested (which can be obtained from the HTTP header) and looks up if the file descriptor for this resource is already present in the hash table for that particular worker. If present, instead of opening another file descriptor for the same file, the already open file descriptor is used. The number of users using that particular file descriptor is incremented. If a particular request stops using a particular file, it checks if the number of users of the file descriptor is greater than zero or not. If it is greater than 0, then a message is just returned that states that the file descriptor is still being used. Else, if the number of users of the file descriptor is zero, then the file descriptor is closed. <using close (2) system call>.

This improves the performance of the monkey server.

Under normal conditions, different virtual hosts do not share data with each other. The main reason that the sharing of file descriptors takes place between different requests within the same virtual host and not among different virtual hosts is to enable or disable such an option for various virtual hosts.

Reference :

  1. Picture Courtesy : http://www.thegeekstuff.com/2011/07/apache-virtual-host/
  2. https://github.com/monkey/monkey/commit/4efbc11bafeb56fbe2b4f0f6925671630ce84125

Monkey HTTP server

Monkey server is a lightweight Http server for Linux, written completely in C. It places immense importance on performance and consumes very less memory and for this reason, it is also favourable for embedded devices. It focuses strongly on Linux, the reason for this being that the server depends on the Linux kernel to perform operations that improve the performance of the server. It is HTTP/1.1 compliant. Some of the important features of the server are:

  1. Multi threaded architecture to handle incoming requests from clients: Each thread has the capability to handle 1000 client requests.
  2. Monkey server uses an event driven model to handle requests coming to a thread at the same time.
  3. It supports virtual hosting.
  4. Provides support for IPv4 and IPv6.

The major components of the monkey server are scheduler, threads, plugins. The monkey server has a variety of plugins that serve various functionalities.

  1. Auth – for basic HTTP authentication for users of different virtual hosts of the server.
  2. CGI – helps in enabling CGI support for monkey server.
  3. Cheetah – command line for the server.
  4. Dirlisting – showing the contents of the directory when a client requests a directory.
  5. FastCGI – for FastCGI proxy support. It acts as a proxy for Fastcgi application servers.
  6. Liana – provides the network layer support to the server.
  7. Logger – the log writer plugin that allows the server to keep track of frequently occurring issues and keep statistics.
  8. Mandril – security plugin that allows to filter incoming requests on the basis of URI or IP addresses.
  9. Polarssl – provides HTTPS support for the server
  10. Proxy reverse – provides support to the server for reverse proxying and routing back requests to backend servers.

Setting up and installation :

Follow the below steps to install and monkey from source code.

git clone https://github.com/monkey/monkey.git 
cd monkey

Take localhost:2001 in your browser and lo ! You have successfully installed and run monkey server.


References :

You could read more about this server here :

  1. http://monkey-project.com/gsoc2014/getting_started
  2. http://edsiper.linuxchile.cl/blog/category/monkey/
  3. Image found here