In this post we shall provide you the second bash script file which is called "tomcat-copy-files-to-secondary.sh".
Let me suggest you the directory structure which we are using at hudku.com for these script files.
scripts
setup
tomcat
Create a directory for scripts and under that create two directories "setup" and "tomcat". The first script file goes into the "setup" folder and as you know already that setup script needs to be run only once. The current script and the next two scripts should be copied into "tomcat" folder. The scripts in this "tomcat" directory are repeatedly used whenever we want to start or stop the secondary instance of tomcat.
As already explained in my previous post these scripts need following environment variables.
export TOMCAT_PRIMARY_INSTANCE_NAME="tomcat7"
export TOMCAT_SECONDARY_INSTANCE_NAME="my-app-secondary"
After the above directory setup then please set one more environment variable providing the path to the "scripts" folder mentioned above.
export ELASTICBEANSTALK_APP_SCRIPT_DIR="path-to-scripts"
As our website hudku.com is an Amazon Elastic Beanstalk application we had chosen that name but these scripts are in no way tightly coupled to Beanstalk environment.
The current script copies the required files from existing primary instance directory to the secondary instance directory.
Why this script can't be automatically run whenever we want to start the secondary instance?
The main purpose behind having this script is "You Choose" whether the files have to be copied. Suppose if the newly deployed application version in the primary instance has a serious bug or problem then you do not want to copy that version and make the secondary also to contain that flaw. So you should run this copy script only if the current application in primary instance is stable and you want it to be copied. That is the main reason for the existence of this script file.
In other words, you do not have to copy the application from primary instance to secondary every time you want to start the secondary tomcat instance.
The main directories to be copied from primary tomcat instance are "bin", "conf" and "webapps". We should be overwriting if those directories already exist in the secondary tomcat instance directory. After copying from the primary instance we also need to take care to set proper permissions for the files and directories.
Then finally the port numbers used in the copied server.xml file in the conf directory should be changed. As mentioned in my earlier post "Zero Downtime with Amazon Elastic Beanstalk" the Tomcat instance by default uses three ports open viz., HTTP Connector listening port 8080, AJP Connector listening to port 8009 and a redirect port 8443. For the secondary instance we just bump them up by 100 and change 8080 ==> 8180, 8009 ==> 8109 and 8443 ==> 8543 using "sed" command.
At hudku.com we actually do not use HTTP port 8080, but instead use the AJP port 8009. Hence 8080 is commented out in the server.xml of our primary instance. I do not know how much we save by commenting it out but in general if we do not need anything, we comment it and do not allow it to be active. In our application the Apache server always talks to Tomcat using AJP port 8009.
But when we run the secondary instance we open the HTTP port also so that we can retrieve the HTML content using Linux "curl" command to test whether the instance has come up and functioning properly. That's the reason the script contains a line to remove the beginning and ending xml comment tag so that HTTP Connector is not commented out in the secondary instance sever.xml configuration file.
In server.xml file of our primary instance the HTTP Connector section looks as below.
<!-- HTTP 8080 Comment Begin
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000" maxThreads="400" compression="on" compressableMimeType="text/html,text/xml,text/plain,text/css,application/javascript,application/json"
redirectPort="8443" />
HTTP 8080 Comment End -->
We use the signature "HTTP 8080 Comment" in both the beginning and ending comment lines. The same signature is used in the script to delete those two lines so that HTTP Connector becomes active for the secondary instance. In your server.xml, this signature would be missing and the line in the script to remove them would do nothing.
Here is the source code of the script "tomcat-copy-files-to-secondary.sh" to copy the files from primary tomcat instance to secondary tomcat instance. Nothing complicated here.
#!/bin/bash # Execute "export DEBUG=1" to debug this script. # Set value to 2 to debug this script and the scripts called within this script. # Set value to 3,4,5 and so on to increase the nesting level of the scripts to be debugged. [[ $DEBUG -gt 0 ]] && set -x; export DEBUG=$(($DEBUG - 1)) # # Copies application files from primary instance to secondary instance directory # tomcatPrimaryInstanceName="$TOMCAT_PRIMARY_INSTANCE_NAME" tomcatSecondaryInstanceName="$TOMCAT_SECONDARY_INSTANCE_NAME" tomcatPrimaryInstanceDir="/usr/share/$tomcatPrimaryInstanceName" tomcatSecondaryInstanceDir="/usr/share/$tomcatSecondaryInstanceName" http8080Comment="HTTP 8080 Comment" rm -rf $tomcatSecondaryInstanceDir/bin rm -rf $tomcatSecondaryInstanceDir/conf rm -rf $tomcatSecondaryInstanceDir/webapps cp -pLR $tomcatPrimaryInstanceDir/bin $tomcatSecondaryInstanceDir/ cp -pLR $tomcatPrimaryInstanceDir/conf $tomcatSecondaryInstanceDir/ cp -pLR $tomcatPrimaryInstanceDir/webapps $tomcatSecondaryInstanceDir/ # Set the directory and file permissions chmod -R 777 $tomcatSecondaryInstanceDir/* chown -R tomcat:tomcat $tomcatSecondaryInstanceDir/* # For secondary instance remove the comments around HTTP 8080 connector sed -i -e "/.*$http8080Comment.*/d" /$tomcatSecondaryInstanceDir/conf/server.xml # Substitute the port numbers in server.xml sed -i -e "s/8005/8105/g" -e "s/8080/8180/g" -e "s/8009/8109/g" -e "s/8443/8543/g" /$tomcatSecondaryInstanceDir/conf/server.xml echo "Successfully copied the files to secondary tomcat instance $tomcatSecondaryInstanceName"