Mule Start / Stop Service Customization with lots of Flexibility.
Below concept can be used in on-prem or hybrid Mule setup.
Typically when we need to start or stop mule we can go in the “bin” directory of mule and do ./start mule or ./stop mule.
Now if say we had some environment variable like our env=”dev, qa, uat, prd ” etc. we can go to our wrapper.conf file and add those entries which is one good way.
Tomorrow for some reason we have to disregard entire Mule Server or Cluster of Servers probably its corrupt (rare case, but it has happened in the company I was working), or say we are upgrading the version (essentially means new runtime).
While setting up this kinds of things, we will have to recollect everything that was done in wrapper.conf file of our Mule Runtime Installation, as all the values are very critical. How about doing this dynamically ?
More importantly our Mule Runtime is in AWS EC2 instance, and we need to allocate sufficient Memory to our Mule RT Servers, again we can go to wrapper.conf and do the changes there, but say we have an environment where we are still in evolving phase or say new heavy applications are getting added, we might have to increase the Server Memory, or say in Dev Environment we have not done any optimization and our box size is small comparted to QA/UAT and Prd, we can set the Memory value individually in wrapper.conf file of respective Mule RT Servers.
It would be better idea if we are dynamically setting the Memory size based on the machine’s Memory, or more over what is the free memory that is available in the box ? I guess if we can do this we are reducing a lot of manual effort DevOps would be very happy and at the same time as an Architect our life would be good J
Use of systemctl Command to achieve this.
NOTE : Use this with caution, as it is very powerful read more about this how systemctl uses systemd System and all the Services, also you got to have sudo access to do this.
So what we are going to do here is create a Mule Service which can be identified via systemctl.
- Location of the system directory : /etc/systemd/system
- Create a file service (this file name is what we will be using in systemctl command to do our required operations, please note we can either user either full name “mule.service” or shorter form “mule” .service is required in creating file but not in systemctl command).
- Below is the code, I have just created a separate file “sh” to keep “mule.service” file short for better understanding.
[Unit]
Description=Mule Runtime Service // Meaningful Description which can be used by Systemctl commands if we ever list all the services running on our System or something else.
After=network-online.target // Would be executed only after the network is started
[Service]
Type=forking
User=mule // which user will have access and who can start / stop Mule Runtime Servers
Group=mule // All the required users should belong to this Group
ExecStart=/var/lib/mule/mule.sh start // this is the file where we have written all the customization before we start the mule, which you can go ahead and customize it as per your need
ExecStop=/var/lib/mule/mule.sh stop // same as above for stop command any customization needed
StandardOutput=syslog // standard output location
StandardError=syslog // standard error location
SyslogIdentifier=mule
[Install]
WantedBy=multi-user.target // will be needed by multiple user to access this service
- Now for mule.sh file, we need to learn and understand atleast basics of shell programming, and below is snippet of the code.
#!/bin/bash
# RHEL Mule Init Script
echo “Mule init script run as $(whoami)”
# Set JDK related environment
JAVA_HOME=/usr/lib/jvm/jre-openjdk
PATH=$PATH:$JAVA_HOME/bin
# Set Mule related environment
mule_home=”/var/lib/mule/mule-enterprise-standalone-3.9.0″
mule_wrapper=$mule_home/conf/wrapper.conf
MULE_ENV=production
# Export environment variables
export JAVA_HOME MULE_HOME MULE_LIB PATH MULE_ENV RUN_AS_USER
memsize=$(free -m | grep Mem | awk ‘{print $2}’)
memsize_KB=$(cat /proc/meminfo | grep MemTotal | awk ‘{print $2}’)
memsize_GB=$((memsize_KB/1000000 + 1))
action=$1
cd $mule_home/bin
if [[ $memsize_GB -ge 32 ]]; then
heapsize_MB=$((memsize_GB*1000/2))
elif [[ $memsize_GB -ge 24 ]]; then
heapsize_MB=16000
elif [[ $memsize_GB -ge 16 ]]; then
heapsize_MB=12000
elif [[ $memsize_GB -ge 12 ]]; then
heapsize_MB=8000
elif [[ $memsize_GB -ge 8 ]]; then
heapsize_MB=4000
else
heapsize_MB=1024
fi
case “$action” in
start|restart)
echo “setting Mule heapsize to $heapsize_MB MB”
sed -i s/^wrapper.java.initmemory=.*/wrapper.java.initmemory=$heapsize_MB/ $mule_wrapper
sed -i s/^wrapper.java.maxmemory=.*/wrapper.java.initmemory=$heapsize_MB/ $mule_wrapper
;;
*)
;;
esac
case “$action” in
start)
echo “Start service mule”
$mule_home/bin/mule start
;;
stop)
echo “Stop service mule”
$mule_home/bin/mule stop
;;
restart)
echo “Restart service mule”
$mule_home/bin/mule restart
;;
status)
echo “Mule status”
$mule_home/bin/mule status
;;
*)
echo “Usage: $0 {start|stop|restart}”
exit 1
;;
esac
- Finally add our mule.service file to /etc/systemd/system/multi-user.target.wants directory giving full access.
- Finally try doing
systemctl status mule or systemctl start mule, where command is
systemctl “action” “service”
action = status or stop or start
service = mule