Web Server Load-Balancing with HAProxy on Ubuntu 14.04

What is HAProxy?

HAProxy(High Availability Proxy) is an open-source load-balancer which can load balance any TCP service. HAProxy is a free, very fast and reliable solution that offers load-balancing, high-availability, and proxying for TCP and HTTP-based applications. It is particularly well suited for very high traffic web sites and powers many of the world’s most visited ones.

Since it’s existence, it has become the de-facto standard open-source load-balancer. Although it does not advertise itself, but is used widely. Below is a basic diagram of how the setup looks like:

Installing HAProxy

I am using Ubuntu 14.04 and install it by:

apt-get install haproxy

You can check the version by:

haproxy -v

We need to enable HAProxy to be started by the init script /etc/default/haproxy. Set ENABLED option to 1 as:

ENABLED=1

To verify if this change is done properly, execute the init script of HAProxy without any parameters. You should see the following:

$ service haproxy <press_tab_key>
reload   restart  start    status   stop

HAProxy is now installed. Let us now create a setup in which we have 2(two) Apache Web Server instances and 1(one) HAProxy instance. Below is the setup information:

We will be using three systems, spawned virtually through VirtualBox:

Instance 1 – Load Balancer

Hostname: haproxy
OS: Ubuntu
Private IP: 192.168.205.15

Instance 2 – Web Server 1

Hostname: webser01
OS: Ubuntu with LAMP
Private IP: 192.168.205.16

Instance 2 – Web Server 2

Hostname: webserver02
OS: Ubuntu with LAMP
Private IP: 192.168.205.17

Here is the diagram of how the setup looks like:

Let us now configure HAProxy.

Configuring HAProxy

Backup the original file by renaming it:

mv /etc/haproxy/haproxy.cfg{,.original}

We’ll create our own haproxy.cfg file. Using your favorite text editor create the /etc/haproxy/haproxy.cfg file as:

global
        log /dev/log   local0
        log 127.0.0.1   local1 notice
        maxconn 4096
        user haproxy
        group haproxy
        daemon

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        option redispatch
        maxconn 2000
        contimeout     5000
        clitimeout     50000
        srvtimeout     50000

listen webfarm 0.0.0.0:80
    mode http
    stats enable
    stats uri /haproxy?stats
    balance roundrobin
    option httpclose
    option forwardfor
    server webserver01 192.168.205.16:80 check
    server webserver02 192.168.205.17:80 check

Explanation:

global
        log /dev/log   local0
        log 127.0.0.1   local1 notice
        maxconn 4096
        user haproxy
        group haproxy
        daemon

The log directive mentions a syslog server to which log messages will be sent.
The maxconn directive specifies the number of concurrent connections on the front-end. The default value is 2000 and should be tuned according to your system’s configuration.
The user and group directives changes the HAProxy process to the specified user/group. These shouldn’t be changed.

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        option redispatch
        maxconn 2000
        contimeout     5000
        clitimeout     50000
        srvtimeout     50000

The above section has the default values. The option redispatch enables session redistribution in case of connection failures. So session stickness is overriden if a web server instance goes down.
The retries directive sets the number of retries to perform on a web server instance after a connection failure.
The values to be modified are the various timeout directives. The contimeout option specifies the maximum time to wait for a connection attempt to a web server instance to succeed.
The clitimeout and srvtimeout apply when the client or server is expected to acknowledge or send data during the TCP process. HAProxy recommends setting the client and server timeouts to the same value.

listen webfarm 0.0.0.0:80
    mode http
    stats enable
    stats uri /haproxy?stats
    balance roundrobin
    option httpclose
    option forwardfor
    server webserver01 192.168.205.16:80 check
    server webserver02 192.168.205.17:80 check

Above block contains configuration for both the frontend and backend. We are configuring HAProxy to listen on port 80 for webfarmwhich is just a name for identifying an application.
The stats directives enable the connection statistics page. This page can viewed with the URL mentioned in stats uri so in this case, it is http://192.168.205.15/haproxy?stats a demo of this page can be viewed here.
The balance directive specifies the load balancing algorithm to use. Algorithm options available are:

  • Round Robin (roundrobin),
  • Static Round Robin (static-rr),
  • Least Connections (leastconn),
  • Source (source),
  • URI (uri) and
  • URL parameter (url_param).

Information about each algorithm can be obtained from the official documentation.

The server directive declares a backend server, the syntax is:

server <server_name> <server_address>[:port] [param*]

The name we mention here will appear in logs and alerts. There are some more parameters supported by this directive and we’ll be using the check parameter in this article. The check option enables health checks on the web server instance otherwise, the web server instance is ?always considered available.

Once you’re done configuring start the HAProxy service:

sudo service haproxy start

Testing Load-Balancing and Fail-over

We will append the server name in both the default index.html file located by default at /var/www/index.html

On the Instance 2 – Web Server 1 (webserver01 with IP- 192.168.205.16), append below line as:

sudo sh -c “echo \<h1\>Hostname: webserver01 \(192.168.205.16\)\<\/h1\> >> /var/www/index.html”

On the Instance 3 – Web Server 2 (webserver02 with IP- 192.168.205.17), append below line as:

sudo sh -c “echo \<h1\>Hostname: webserver02 \(192.168.205.17\)\<\/h1\> >> /var/www/index.html”

Now open up the web browser on local machine and browse through the haproxy IP i.e. http://192.168.205.15

Each time you refresh the tab, you’ll see the load is being distributed to each web server. Below is screenshot of my browser:

For the first time when I visit http://192.168.205.15 , I get:

And for the second time, i.e. when I refresh the page, I get:

You can also check the haproxy stats by visiting http://192.168.205.15/haproxy?stats

There’s more that you can do to this setup. Some ideas include:

  • take one or both web servers offline to test what happens when you access HAProxy
  • configure HAProxy to serve a custom maintenance page
  • configure the web interface so you can visually monitor HAProxy statistics
  • change the scheduler to something other than round-robin
  • configure prioritization/weights for particular servers

That’s all!

Advertisements

load balancer

Types of Load Balancing

Now that we have an understanding of the basic components that are used in load balancing, let’s get into the basic types of load balancing.

No Load Balancing

A simple web application environment with no load balancing might look like the following:

No Load Balancing

In this example, the user connects directly to your web server, at yourdomain.com and there is no load balancing. If your single web server goes down, the user will no longer be able to access your web server. Additionally, if many users are trying to access your server simultaneously and it is unable to handle the load, they may have a slow experience or they may not be able to connect at all.

Layer 4 Load Balancing

The simplest way to load balance network traffic to multiple servers is to use layer 4 (transport layer) load balancing. Load balancing this way will forward user traffic based on IP range and port (i.e. if a request comes in for http://yourdomain.com/anything, the traffic will be forwarded to the backend that handles all the requests for yourdomain.com on port 80). For more details on layer 4, check out the TCP subsection of our Introduction to Networking.

Here is a diagram of a simple example of layer 4 load balancing:

Layer 4 Load Balancing

The user accesses the load balancer, which forwards the user’s request to the web-backend group of backend servers. Whichever backend server is selected will respond directly to the user’s request. Generally, all of the servers in the web-backend should be serving identical content–otherwise the user might receive inconsistent content. Note that both web servers connect to the same database server.

Layer 7 Load Balancing

Another, more complex way to load balance network traffic is to use layer 7 (application layer) load balancing. Using layer 7 allows the load balancer to forward requests to different backend servers based on the content of the user’s request. This mode of load balancing allows you to run multiple web application servers under the same domain and port. For more details on layer 7, check out the HTTPsubsection of our Introduction to Networking.

Here is a diagram of a simple example of layer 7 load balancing:

Layer 7 Load Balancing

In this example, if a user requests yourdomain.com/blog, they are forwarded to the blog backend, which is a set of servers that run a blog application. Other requests are forwarded to web-backend, which might be running another application. Both backends use the same database server, in this example.

 

reference :

https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts

Caused by: org.hibernate.QueryException: Not all named parameters have been set:

Please check the order ,if you try to get result and count .you need to set the parameter of params. see the bellow order.

 

String countQ = “Select count (id) ” + hql;

Query countQuery = em.createQuery(countQ);
TypedQuery<IataRateMaster> query = em.createQuery(hql, IataRateMaster.class);

if (params != null) {

for (Entry<String, Object> e : params.entrySet()) {
countQuery.setParameter(e.getKey(), e.getValue());
}

for (Entry<String, Object> e : params.entrySet()) {
query.setParameter(e.getKey(), e.getValue());
}
}

Long countTotal = (Long) countQuery.getSingleResult();

query.setFirstResult(dto.getSelectedPageNumber() * dto.getRecordPerPage());

query.setMaxResults(dto.getRecordPerPage());

List<IataRateMaster> resultlist = query.getResultList();

angular js filter

<table class=”table table-inline”>
<thead>
<tr>
<th class=”inl_sno”>#</th>
<th class=”inl_l”>Airport of Discharge</th>
<th class=”inl_m text-right”>Min Amount</th>
<th class=”inl_s text-right”>Normal</th>
<th class=”inl_s text-right”>+45</th>
<th class=”inl_s text-right”>+100</th>
<th class=”inl_s text-right”>+300</th>
<th class=”inl_s text-right”>+500</th>
<th class=”inl_s text-right”>+1000</th>
</tr>
</thead>
<tbody class=”bor-0″>

<tr>
<td><span class=”icon-search”></span></td>
<td><input type=”text” class=”form-control” ng-model=”iataRateChargeSearch.pod.portName”></td>
<td><input type=”text” class=”form-control” ng-model=”iataRateChargeSearch.minAmount”></td>
<td><input type=”text” class=”form-control” ng-model=”iataRateChargeSearch.normal”></td>
<td><input type=”text” class=”form-control” ng-model=”iataRateChargeSearch.plus45″></td>
<td><input type=”text” class=”form-control” ng-model=”iataRateChargeSearch.plus100″></td>
<td><input type=”text” class=”form-control” ng-model=”iataRateChargeSearch.plus300″></td>
<td><input type=”text” class=”form-control” ng-model=”iataRateChargeSearch.plus500″></td>
<td><input type=”text” class=”form-control” ng-model=”iataRateChargeSearch.plus1000″></td>

</tr>
</tbody>

<tbody>
<tr
ng-repeat=”iataRateCharge in iataRateMaster.iataRateChargeList | filter:iataRateChargeSearch:startsWith track by $index”>
<td>{{$index + 1}}</td>
<td>{{iataRateCharge.pod.portCode}} –
{{iataRateCharge.pod.portName}}</td>
<td>{{iataRateCharge.minAmount}}</td>
<td>{{iataRateCharge.normal}}</td>
<td>{{iataRateCharge.plus45}}</td>
<td>{{iataRateCharge.plus100}}</td>
<td>{{iataRateCharge.plus300}}</td>
<td>{{iataRateCharge.plus500}}</td>
<td>{{iataRateCharge.plus1000}}</td>
</tr>
</tbody>
</table>

A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance

 

while calling update  method we need to make new object of child list.

example :  see in the else part

if (iataRateMaster.getIataRateChargeList() != null && iataRateMaster.getIataRateChargeList().size() > 0) {

for (IataRateCharge iataRateCharge : iataRateMaster.getIataRateChargeList()) {
iataRateMasterValidator.iataRateChargeValidate(iataRateCharge);
iataRateCharge.setIataRateMaster(iataRateMaster);
}

}

else {
iataRateMaster.setIataRateChargeList(new ArrayList<IataRateCharge>());
}