Nginx as a load balancer for Magento

Nginx as a load balancer for Magento

Introduction

During seasonal peaks or as traffic grows, there will be a need to add multiple app servers to your Magento store. A load balancer for Magento becomes essential. We have found that using nginx as a load balancer gives acceptable performance. We have not found many instances where we would recommend a hardware load balancer. Recent tests by nginx confirms this.

We would recommend a different load balancer only for additional features such as autoscaling.

Nginx as a load balancer offers many advantages including

  • uneven upsream servers as nginx can assign weights to each load balancer
  • self healing – takes a upstream server out of a cluster if it stops responding
  • path based load balancing
  • combination of path based and weight based load balancing
  • php upstream servers
  • SSL/TLS termination

This article assumes the process of adding a new app server to a Magento cluster is well understood. Here the focus is on the nginx configuration.

Load Balancer for Magento : Basic architecture


loadbalancer

Salient points

  • All traffic hits the nginx load balancer
  • Nginx is only installed on the load balancer server – the app servers run php-fpm
  • Nginx serves static content
  • https is terminated at the ngnix load balancer

Load Balancer for Magento : nginx configuration

Any app server serves all traffic

This is what is typically done – all traffic is distributed across the app servers using a automated strategy.

upstream magento_apps {
  server 192.168.251.3:9000 weight=3;
  server 192.168.251.4:9000 weight=1;
}
…
location ~ \.php$ {
  if (!-e $request_filename) { rewrite / /index.php last; }
  expires off;
  include /etc/nginx/fastcgi_params;
  fastcgi_pass magento_apps;
  fastcgi_index index.php;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

A section ‘upstream’ is used to tell nginx that a list of servers that need to be used to balance across. The upstream section is referred by the fastcgi_pass directive, instead of the typical

  fastcgi_pass   127.0.0.1:9000;

Also note that the server directive is specifying the php-fpm port of 9000 – the load balancing is not on http but on fastcgi. Nginx has a inbuilt support for fastcgi load balancing.
The weight parameter is used to balance against varying server sizes – in this case the 192.168.251.3 server is 3x the capacity of the 192.168.251.4.

The default load balancing algorithm is round robin. Instead a least connected or a ip-hash method could be selected. Refer here for more configuration details.

Distribute load by URL

It is possible to distribute the load across servers by URLs. For example, a server may be designated as a report or admin or perhaps a checkout server. A checkout server is typically used with the thought that the checkout flow should be the fastest response as the cost of a drop off at this stage leads to an abandoned cart. With a separate server to handle checkouts, this traffic does not compete for CPU resources with landing page traffic which can surge based on ads.
URLs in nginx are identified with the location directive. Each URL group can have one or more servers.

upstream magento_checkout {
  server 192.168.251.3:9000;
  server 192.168.251.4:9000;
}

location @checkouthandler {
  expires off;
  include        /etc/nginx/fastcgi_params;
  fastcgi_pass   magento_checkout;
  fastcgi_index  index.php;
  fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
}

location /onestepcheckout{
  index index.html index.php;
  try_files $uri $uri/ @checkouthandler;
}

Load balancing inside a server

With fastcgi and php-fpm it is possible to distribute the resources of a single server into groups. For example in a 12 core CPU server, it is possible to assign a set of 4 php processes to handle landing page traffic another set of 4 to handle browsing traffic and another set of 4 to handle checkout traffic. If there is no inline communication with the internet – such as a curl call when processing an order – and a well tuned database, the ratio of CPU cores to the total number of php processes can be as low as 1:1.

Sizing the load balancer

The size of the load balancer for Magento will be determined by the number of hits. If response sizes are large sufficient memory has to be available to nginx to hold intermediate buffers. The internal network has to be good enough to handle the sum of all responses without holding back the server.

Nginx has studied response at the upper end in comparison with a F5 hardware load balancer.

Logging additional variables

Changing the log file to record information of which upstream server is serving. The following additional useful variables are available :

  $upstream_addr is available to record which upstream server was used.
  $upstream_response_time has the time in ms that the upstream server took to respond

Conclusion

Increasingly hardware is being replaced by software. The load balancer for Magento need not be specialized hardware for load balancing of a Magento site can be replaced by a general purpose server running nginx with no reduction in performance but significant cost savings.

Share this post