Persist/Share tomcat session state between multiple instances



In this article, I am going to explain how can you persist/share tomcat session state between multiple instances, and improve your site performance.

Persisting your session state outside of the tomcat servers is a very common and recommended configuration for large scale websites. This is usually done in pursuit of an architecture style called Shared Nothing.

In my post configuring multiple tomcat application servers with Apache HTTP server I’ve explained how to load balance multiple tomcat with apache web server. There is a common problem user found while load balancing with multiple tomcat servers, of sticky and non-sticky sessions on tomcat. So what is these sticky and non-sticky session actually?

lets have an example, suppose we have three tomcat servers to serve the request for our website behind a single apache server. And all the web request will come to apache server and the load balancer will decide which actual tomcat server will serve the request.
Now suppose we have three request request_A, request_B, and request_C, now what the load balancer should do to serve these requests? Should these requests served by different tomcat server because we also have three tomcat servers, or should these all go to same server? Here comes the role of sticky and non-sticky sessions.

think about if the request_A is for login and request_B is for user_dashboard page, and request_C is some other user’s page request, and what happened if request_A(login) served from server-1 and request_B(dashboard) served from server-2? is the dashboard will be served to the user or server-2 will send user a login page because of no active logged-in session on the server.

Sticky Session

Sticky session refers to a common feature of many load balancing solutions for handling session based web requests.
In case of sticky session, load balancer manage and route all the requests for a particular session to the same tomcat server that executed the first request for that session.

Sticky session: same session request will be served from same tomcat

Non-sticky Session

In case of non-sticky session all requests can be served from different tomcat servers, and each server will create a new session object for the request to serve. These three sessions are purely independent and doesn’t know about each other, and there is no direct way of knowing what is there in the session object of the other tomcat server.

This post is about, how to synchronize between these server sessions, and how to write/read the session data into a layer which is common to all.

non-sticky session are concurrent by nature, and when you are using parallel requests they will be executed by different tomcat servers and session will be used concurrently due to non-stickyness. But if you are having concurrent parallel requests that might change the session, you need to implement/use some kind of synchronization or session locking mechanism.

Non-sticky session: all requests served from different tomcats

Persist/share tomcat session state

There are many solutions exists to persist/share tomcat session state between multiple instances. Some most common and widely used solutions are: database, memcache, cassandra, redis, mongo, etc.

Personally I didn’t support for database to store session state, as persisting sessions in the database limits your scalability. If you still want to store session in a database and scalability is not that important for you, I prefer to use a combination of database + any caching platform.

Persist/share tomcat session state between multiple instances

I’ve written separate posts for some commonly used solutions, because writing in a single post will make this post very large, so follow the corresponding post link for more details.

  • Manage tomcat session replication using memcached (coming soon)
  • Manage tomcat session replication using cassandra (coming soon)
  • Manage tomcat session replication using redis (coming soon)
  • Manage tomcat session replication using mongo (coming soon)

They all works good, and this is up to you which one suits you the best.

References:

Shared Nothing Architecture

Load Balancing

Replication aware JDBC connection in java and MySQL



Hi,

recently I was reviewing the code a project which was having some database issues, while the review I found that the project environment was setup with the MySQL with one master node and two slave node, and I was surprised that in the code they have used the default JDBC driver for database connectivity which actually uses on single node for all read/write operations.

When asked to developer about the reason of using the default driver for database connectivity, he actually don’t knows that the default JDBC connector does not support replication aware connection. So I’ve realised that many of the developers actually don’t know about the replication aware JDBC connection driver, and I’ve decided to write this post.

There are very little difference between default JDBC connector which support single node mysql connection and ReplicationAware JDBC Connector which is used to create Replication aware JDBC connection using multi node mysql setup.

1) The DriverClass

As you all know that for different type of connection we need to load different driver class. The default JDBC Connector class uses com.mysql.jdbc.Driver driver class and ReplicationAware driver uses com.mysql.jdbc.ReplicationDriver driver class for connection.

2) The connection string

As in default JDBC connection we have only single node and in replication environment we can have n number of nodes, so our connection string will also be different for both connections.

while using default jdbc connector we use connection string as

jdbc:mysql://[database host][:port]/[database_name][?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]

and for replication aware jdbc connector we have to provide all server’s ip including master and slaves

jdbc:mysql:replication://[master host][:port],[slave host 1][:port][,[slave host 2][:port]]...[/[database_name]][?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]

thats it 🙂

you have done it. its the only difference between default JDBC connector and ReplicationAware JDBC connector.

See MySQL documentation here for list of configuration properties that can be appended to the JDBC URL.

One more thing that how to ensure that your operations redirecting to master and slave correctly:

1) Standalone Application:

if you are using standalone application then just call connection.setReadOnly(false) before any transaction and your all read/write operations will execute on master node and set readOnly flag to true if you want to execute queries from slave. ReplicationDriver will take care of your transactions and pick a slave from the list to execute query on a slave node. (Read configuring load balancing with connector/J)

2) Spring transactions:

If you are working with Spring, just add @Transactional annotation to the method with readOnly flag.

For read/write operations on master node, use @Transactional(readOnly = false) and all the database operations will go to the master only.
For read only operations with slave node, use @Transactional(readOnly = true) and all the database operations will go to the slave.

 

References:

MySQL Replication with Connector/J

MySQL Configuration Properties for Connector/J

 

Helpful bash aliases for any Unix/Linux user



Aliases can be very helpful for any linux user, and after writing my last post “How to create custom command in Unix/Linux” I want to share these helpful bash aliases for any unix/linux user.

List in long format

alias ll=’ls -l’

Clear the screen

alias c=’clear’

Clear the history and screen

alias hcl=’history -c; clear’

use Bye to exit

alias bye=’exit’

Some change directory options

alias ..=’cd ..’

alias …=’cd ../..’

alias ….=’cd ../../..’

alias …..=’cd ../../../..’

Display path info

alias path=’echo -e ${PATH//:/\n}’

Display current Date/Time or Both

alias now=’date’

alias nowtime=’date +”%T”‘

alias nowdate=’date +”%d-%m-%Y”‘

Open last modified file in VIM

alias Vim=”vim ‘ls -t | head -1′”

Show all running java processes

alias psjava=’ps -ef | grep java’

If you are a regular windows user, create windows version of linux commands

alias cls=’clear’

alias dir=’ls -l’

alias chdir=’cd’

alias md=’mkdir’

alias copy=’cp’

alias rename=’mv’

alias move=’mv’

alias del=’rm -i’

alias rd=’rmdir’

alias deltree=’rm -r’

I think these alias can be helpful for you. There are many more but I’ve shared those I think are very useful for any Unix/Linux user.

References:

Alias Command

 

How to create custom commands in Unix/Linux



Few days ago one of my friend told me that the work on linux is so difficult, because he didn’t remember the complex commands of linux and every time when he want to do some debugging on their linux server he always need to google some commands first, so I’ve decided to write this post “How to create custom commands in Unix/Linux”.

There are many ways to do this, I’ve explained some of the easiest way to create custom commands.

  • using a bash/shell script
  • using alias command

Using a bash/shell script

A bash/shell script is a linux program that can be run by a UNIX shell. You can learn more about shell script on wikipedia. we are not here to learn about shell script. I assume you already have a basic knowledge of writing shell scripts.

So, we can learn creating custom command using a simple example.

Suppose you want to create a custom command for printing system’s date and time.

create a file called dt.sh anywhere on your machine using any text editor, i.e. /home/girishgaurav/dt.sh or just name the script what you want to type in to the terminal.


give it the execute permission using

chmod 777 /home/girishgaurav/dt.sh

you done half way, and its really that easy 🙂

now you have two choices to configure this script to be used as a command:

  1. move this script to /usr/bin directory and you just done everything and your custom command named dt is ready to use. just type dt on the shell and see the output.

$ dt

Fri Dec 5 22:49:05 IST 2014

  1. for advance user who don’t want to mix system’s command with your own, you can create a separate directory for your custom commands:
    create a directory called commands in your home directory, i.e. /home/girishgaurav/commands/ or whatever you like and update your path variable to include this commands directory.

now just move the dt.sh to the above created directory and your custom command is ready 🙂

 

Using alias command

The alias command is very useful to create your custom commands. The format is alias name=’command’

Now if you want to do our previous datetime example using alisas, it is more simple than writing a bash script.


and you are done, your custom command is created, is that so easy 🙂

No! it’s not that easy. You’ve created your custom command for the current shell lifetime, and whenever you exit from the shell your command will no longer available for the next time.

So, for permanent, you need to do some more…

create a file called .bash_aliases in your home directory using any text editor or using touch command, i.e. touch ~/.bash_aliases

Now you all done with your custom commands and you can create any command that you want.

Here are some useful aliases that can be helpful for any linux user.

References:

Bash/Shell Script

Alias Command

How to enable garbage collection logging (GC logs) in Apache tomcat



In this article I’ll provide information about how to enable garbage collection logging (GC logs) in Apache tomcat.

GC logs are very important when you are debugging an application. GC logs helps to analyse how your program uses the memory.

GC logs also helps to find how often garbage collector cleans the memory for unused objects.

So, you can enable garbage collection logging in few simple steps, that are as follows:

for this you need a file named setenv.sh in the $TOMCAT_HOME/bin directory. Create one if it doesn’t exists.

setenv.sh is executed when Apache Tomcat is started and sets the JVM options needed to enable garbage collection logging.

 

Restart Apache Tomcat to enable the changes.

look into tomcat’s logs directory you will find gc.log file, and you can analyse your GC logs 🙂

 References:

http://tomcat.apache.org

Java VM Options

 

Send error logs through email using log4j SMTP appender



recently I was reading about Apache log4j appenders. and found log4j SMTPAppender which sends an e-mail when a specific logging event occurs, typically on errors or fatal errors. That time I got idea to write this post to send error logs through email using log4j SMTP appender.

for a developer error logs are very important. and it is very helpful for any developer to deliver error logs directly in their inbox.

So, you can add a simple SMTP appender entry in log4j configuration file and get error logs directly in your inbox.

 

References:

Log4j SMTPAppender

Official log4j Homepage

 

[Maven – Build Error] Unsupported WTP Version



Hi,

recently I was working on a project and I found a build error while I tried to execute mvn -eclipse:eclipse command to build eclipse project settings for my maven project.

the solution for the above error message is specify maven-eclipse-plugin setting in your project’s pom file.

<plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-eclipse-plugin</artifactId>
      <version>2.5</version>
      <configuration>
         <wtpversion>${supported-wtp-version}</wtpversion>
      </configuration>
</plugin>

its all done 🙂 now you will be able to create eclipse project from your maven project.

 

How to use vimdiff as SVN DIFF tool



Hi,

in this post I am going to explain how to configure your svn-client to use vimdiff as default SVN diff tool.

when I work on my Linux machine, and I try to view changes done on a file before committing to SVN, I use SVN DIFF command to compare my changes.

it works cool for files having few changes, but whenever I make N number of changes to a large file, and I try to compare it using SVN DIFF its vary painful and time consuming task, but same will be easy if SVN show these changes graphically like VIMDIFF do. I always used vimdiff for comparing two files on my Linux machine.

that time I got the idea that, can we use VIMDIFF as SVN DIFF tool?

Answer is YES….

and here’s the solution:

create a file called svndiff.sh any where on your machine i.e. /home/girishgaurav/svndiff.sh

 

 

give it the execute permission using

chmod 777 /home/girishgaurav/svndiff.sh

now you done half way 🙂

now open svn-client’s config file i.e. /etc/subversion/config

 

now you all done 🙂

now your SVN DIFF command will use vimdiff as default diff-viewer.

 

Loading library/model classes from your views in CodeIgniter



Hi,

When I was new to CodeIgniter, I need some data manipulation using a library function in my view classes, I simply loaded the library and called the library function, as I always do….

$this->load->library(‘some_library’);

$this->some_library->some_library_function(some_parameters);

but when run this code, I surprised by the error:

Before this I had used library functions many times in the code, and it always works fine, and after checking the code thoroughly I didn’t find any mistake in the code.

So, what happened with that code?

then I realize that I always use the library functions in the Controllers, this is the first time I’m using it in the views.

then I found the problem! You can do almost everything in the view, even when you shouldn’t, but loading library, models etc. has to be done in the controller. After searching and reading many articles on the net I found a solution to use library functions anywhere in the application with the help of get_instance() method.

get_instance() method returns the CodeIgniter super object. this is used to access CodeIgniter native resources from within your custom classes. Normally, to call the codeigniter’s member function we use $this object i.e. $this->load->library(‘some_library_name’); or $this->load->helper(‘some_helper_name’);

but if you want to use your these functions from views, or any other custom class you have to use &get_instance() method to get the codeigniter’s object.

$ci_obj = & get_instance();
$ci_obj->load->library('some_library');
$ci->some_library->some_library_function();

or you can use the given helper function to load library from anywhere in the code:

function load_library($library_name) {

$ci = & get_instance();
$ci->load->library($library_name);
return $ci->$library_name;

}

it will return the library object and you can call any library function using that object in anywhere in the views or any other custom class.

 

Download/Attach source-code/java-docs with maven dependencies



I am using Maven in my projects from last couple of years, and the automatically downloading the Jars from repository feature of maven is really helpful for developers. But If you are using Eclipse and want to read/analyse Source Code or Java Doc of API then you need the jar file that contains the Source code and java doc of the API, but unfortunately maven does not download and attach the source code and java doc of the APIs automatically.

Maven provides some different ways to download and attach that source code and Java Doc:

  • Using maven eclipse plugin
  • Using maven dependency plugin

Note: The sources and javadocs of the libraries must exist in the repository so that the plugin can download it and attach it.

1. Maven eclipse plugin:

Maven dependencies that are deployed with the source and javadocs can be downloaded and attached to the Eclipse library by using maven-eclipse-plugin. It can be done by:

  • passing command-line argument to the maven-eclipse-plugin, or
  • by declaring in the pom.xml

1.1 passing command-line argument to maven-eclipse-plugin:

This example shows that how to do this by passing command line argument to the maven-eclipse-plugin:

mvn eclipse:eclipse -DdownloadSources=true -DdownloadJavadocs=true

1.2 declaring in the pom.xml

This sample pom shows that how to declare downloadSources and downloadJavadocs configuration in pom.xml

<project>

<build>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-eclipse-plugin</artifactId>

<configuration>

<downloadSources>true</downloadSources>

<downloadJavadocs>true</downloadJavadocs>

</configuration>

</plugin>

</plgins>

</build>

</project>

2. Maven dependency plugin:

maven-dependency-plugin provides a goal named sources that resolves the project source dependencies from the repository.

usage:

mvn dependency:sources

This is useful when you want the source attachments downloaded to your local repository and you don’t want to use the eclipse plugin to do this since the eclipse plugin creates/overwrites the eclipse files.

Load more

%d bloggers like this: