I've had a hard time running a resident Java (and a language running on a JVM such as Scala) application as a daemon on AWS EC2 (though not specifically limited to EC2), so I'll leave it here.
Aside from "EC2 ??" ...
Create an rc script to start your Java application as a Linux service.
There are various styles of rc scripts, but I think that at least this is fine. In (Init.d and Start Scripts for Scala / Java Server Apps I customized it a little based on the contents introduced)
, but it is safer to explicitly specify -Duser.timezone = UTC` as it can change unexpectedly.stop, do not force the JVM process to be killed. (If you force kill, the shutdown hook will not be executed)/etc/init.d/example
#!/bin/bash
### BEGIN INIT INFO
# Provides:          example
# chkconfig:         2345 99 99
# Required-Start:    $local_fs $network $named networking
# Required-Stop:     $local_fs $network $named networking
# Short-Description: example
# Description:       example
### END INIT INFO
DAEMON_NAME=example
DAEMON_DIR=/home/ec2-user/example
MODULE_NAME=example-server
START_SCRIPT="java -Duser.timezone=UTC -jar $DAEMON_DIR/$MODULE_NAME.jar"
#The process ID file is/var/Create under run
PID_FILE=/var/run/$DAEMON_NAME.pid
#Lock file/var/lock/Create under subsys
#If you do not create a lock file, the service will not be stopped when you shut down the machine.
LOCK_FILE=/var/lock/subsys/$DAEMON_NAME
# ***********************************************
# ***********************************************
ARGS="" # optional start script arguments
DAEMON=$START_SCRIPT
# colors
red='\e[0;31m'
green='\e[0;32m'
yellow='\e[0;33m'
reset='\e[0m'
echoRed() { echo -e "${red}$1${reset}"; }
echoGreen() { echo -e "${green}$1${reset}"; }
echoYellow() { echo -e "${yellow}$1${reset}"; }
start() {
  # $!Save the process ID of the process started in (Write it to the process ID file later)
  PID=`$DAEMON $ARGS > /dev/null 2>&1 & echo $!`
}
case "$1" in
start)
    if [ -f $PID_FILE ]; then
        PID=`cat $PID_FILE`
        echo $PID
        if [ -z "`ps axf | grep -w ${PID} | grep -v grep`" ]; then
            start
        else
            echoYellow "Already running [$PID]"
            exit 0
        fi
    else
        start
    fi
    if [ -z $PID ]; then
        echoRed "Failed starting"
        exit 3
    else
        #If the service can be started normally, create a process ID file and lock file.
        echo $PID > $PID_FILE
        touch $LOCK_FILE
        echoGreen "Started [$PID]"
        exit 0
    fi
;;
status)
    if [ -f $PID_FILE ]; then
        PID=`cat $PID_FILE`
        if [ -z "`ps axf | grep -w ${PID} | grep -v grep`" ]; then
            echoRed "Not running (process dead but pidfile exists)"
            exit 1
        else
            echoGreen "Running [$PID]"
            exit 0
        fi
    else
        echoRed "Not running"
        exit 3
    fi
;;
stop)
    if [ -f $PID_FILE ]; then
        PID=`cat $PID_FILE`
        if [ -z "`ps axf | grep -w ${PID} | grep -v grep`" ]; then
            echoRed "Not running (process dead but pidfile exists)"
            exit 1
        else
            PID=`cat $PID_FILE`
            #When stopping the process-Do not kill at 9
            #When forced to terminate, the shutdown hook is not executed and the processing being executed ends in the middle.
            kill -HUP $PID
            echoGreen "Stopped [$PID]"
            #If the service can be stopped normally, delete the process ID file and lock file.
            rm -f $PID_FILE
            rm -f $LOCK_FILE
            exit 0
        fi
    else
        echoRed "Not running (pid not found)"
        exit 3
    fi
;;
restart)
    $0 stop
    $0 start
;;
*)
    echo "Usage: $0 {status|start|stop|restart}"
    exit 1
esac
Deploy the implemented application module and rc script to the EC2 instance.
Here is an example of a template for building EC2 with Cloud Formation.
chkconfig, the application will be automatically started / stopped when the EC2 instance is started / stopped. (Reference: Run a shell on EC2 at startup or terminate
)EC2AutoScalingConfig:
  Type: AWS::AutoScaling::LaunchConfiguration
  Metadata:
    # CloudFormation:Settings to enable Init to get resources from S3
    AWS::CloudFormation::Authentication:
      S3AccessCreds:
        type: S3
        roleName:
          Ref: EC2Role
        buckets:
          -S3 bucket name where modules etc. are stored
    #EC2 instance initialization process. Get the module from S3 and deploy it.
    AWS::CloudFormation::Init:
      configSets:
        Setup:
          - PreDeploy
          - DeployExampleServer
          - PostDeploy
          - StartApplication
      #Preprocessing. Installation of required packages, etc. It is better to keep it in AMI.
      PreDeploy:
        packages:
          yum:
            java-1.8.0-openjdk-devel: []
            awslogs: []
        files:
          /home/ec2-user/awslogs-agent-setup.py:
            source: https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py
            mode: "000755"
          /home/ec2-user/awslogs.conf:
            content: |+
              [general]
              state_file = /var/lib/awslogs/agent-state
              [/var/log/messages]
              log_group_name = /example/ec2
              log_stream_name = {instance_id}-sysmsg
              file = /var/log/messages
              datetime_format = %b %d %H:%M:%S
              buffer_duration = 5000
              initial_position = start_of_file
        commands:
          SetDefaultJVM:
            command: alternatives --set java /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java
      #Deploy application
      DeployExampleServer:
        files:
          #Get module from S3
          /home/ec2-user/example/example-server.jar:
            source:
              Fn::Sub: https://s3-${AWS::Region}.amazonaws.com/S3 bucket name where modules etc. are stored/example-server-1.0.0.jar
            owner: ec2-user
            group: ec2-user
          #Get rc script from S3
          /home/ec2-user/example/example:
            source:
              Fn::Sub: https://s3-${AWS::Region}.amazonaws.com/S3 bucket name where modules etc. are stored/example
            owner: ec2-user
            group: ec2-user
            mode: "000755"
          #Transfer the log output by the application to CloudWatch with awslogs
          /home/ec2-user/example/conf/awslogs.conf:
            content: |+
              [example]
              log_group_name = /example/example-server
              log_stream_name = {instance_id}-{{name}}
              file = /root/logs/example.log
              encoding = utf_8
              datetime_format = %Y/%m/%d %H:%M:%S.%f
              time_zone = UTC
              buffer_duration = 5000
              initial_position = start_of_file
              multi_line_start_pattern =  {datetime_format}
            owner: ec2-user
            group: ec2-user
          #A cron schedule that automatically restarts the application's JVM process when it goes down
          /home/ec2-user/example/conf/cron.conf:
            content: |+
              */5 * * * * /sbin/service example start > /dev/null 2>&1
            owner: ec2-user
            group: ec2-user
        #Note that if you write multiple commands in commands, they will be executed in alphabetical order.
        commands:
          #Place the rc script (/etc/init.d Below symbolic link)
          A_RegisterService:
            command: ln -s /home/ec2-user/example /etc/init.d/example
          #Add with chkconfig and set the application to start / stop automatically when the EC2 instance starts / stops
          B_AddChkconfig:
            command: chkconfig --add example && chkconfig example on
          C_AppendAwsLogsConf:
            command: cat /home/ec2-user/example/conf/awslogs.conf >> /home/ec2-user/awslogs.conf
          D_AppendCrontab:
            command: cat /home/ec2-user/example/conf/cron.conf >> /home/ec2-user/cron.conf
      PostDeploy:
        commands:
          A_PipUpgrade:
            command:
              pip install --upgrade pip
          B_ConfigureAwsLogs:
            command:
              Fn::Sub: python /home/ec2-user/awslogs-agent-setup.py -n -r ${AWS::Region} -c /home/ec2-user/awslogs.conf
          C_ConfigureCron:
            command: crontab /home/ec2-user/cron.conf
        services:
          sysvinit:
            awslogs:
              enabled: true
              ensureRunning: true
            crond:
              enabled: true
              ensureRunning: true
      StartApplication:
        commands:
          A_ManagedContentsSynchronizer:
            command: service example start
  Properties:
    :
    UserData:
      Fn::Base64:
        Fn::Sub: |+
          #!/bin/bash
          #Give the launched EC2 instance a descriptive name
          INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`
          START_TIME=`date '+%Y%m%d%H%M'`
          aws ec2 create-tags --region ${AWS::Region} --resources ${!INSTANCE_ID} --tags Key=\"Name\",Value=example-${!START_TIME}
          # ---- Run cfn-init
          yum -y update
          yum update -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource EC2AutoScalingConfig --configsets Setup
that's all.
Recommended Posts