Es fiel mir schwer, eine residente Java-Anwendung (und eine Sprache, die auf einer JVM wie Scala ausgeführt wird) als Daemon unter AWS EC2 auszuführen (obwohl nicht speziell auf EC2 beschränkt), daher lasse ich sie hier.
Abgesehen von "EC2 ??" ...
Erstellen Sie ein RC-Skript, um eine Java-Anwendung als Linux-Dienst zu starten.
Es gibt verschiedene Arten von RC-Skripten, aber ich denke, dass dies zumindest in Ordnung ist. (Init.d und Startskripte für Scala / Java Server-Apps Ich habe es ein wenig angepasst, basierend auf den eingeführten Inhalten.
/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"
#Die Prozess-ID-Datei lautet/var/Unter Ausführen erstellen
PID_FILE=/var/run/$DAEMON_NAME.pid
#Datei sperren/var/lock/Erstellen Sie unter subsys
#Wenn Sie keine Sperrdatei erstellen, wird der Dienst beim Herunterfahren des Computers nicht gestoppt.
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() {
# $!Speichern Sie die Prozess-ID des in gestarteten Prozesses (Schreiben Sie sie später in die Prozess-ID-Datei).
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
#Wenn der Dienst normal gestartet werden kann, erstellen Sie eine Prozess-ID-Datei und eine Sperrdatei.
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`
#Beim Stoppen des Prozesses-Töte nicht um 9
#Wenn Sie die Beendigung erzwingen, wird der Shutdown-Hook nicht ausgeführt und die ausgeführte Verarbeitung endet in der Mitte.
kill -HUP $PID
echoGreen "Stopped [$PID]"
#Wenn der Dienst normal gestoppt werden kann, löschen Sie die Prozess-ID-Datei und die Sperrdatei.
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
Stellen Sie das implementierte Anwendungsmodul und das RC-Skript auf der EC2-Instanz bereit.
Hier ist ein Beispiel für eine Vorlage zum Erstellen von EC2 mit Cloud Formation.
EC2AutoScalingConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Metadata:
# CloudFormation:Einstellungen für Init, um Ressourcen von S3 abzurufen
AWS::CloudFormation::Authentication:
S3AccessCreds:
type: S3
roleName:
Ref: EC2Role
buckets:
-S3-Bucket-Name, in dem Module usw. gespeichert sind
#Initialisierungsprozess der EC2-Instanz. Holen Sie sich das Modul aus S3 und stellen Sie es bereit.
AWS::CloudFormation::Init:
configSets:
Setup:
- PreDeploy
- DeployExampleServer
- PostDeploy
- StartApplication
#Vorverarbeitung. Installation der erforderlichen Pakete usw. Es ist besser, es in AMI zu behalten.
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
#Anwendung bereitstellen
DeployExampleServer:
files:
#Holen Sie sich das Modul von S3
/home/ec2-user/example/example-server.jar:
source:
Fn::Sub: https://s3-${AWS::Region}.amazonaws.com/S3-Bucket-Name, in dem Module usw. gespeichert sind/example-server-1.0.0.jar
owner: ec2-user
group: ec2-user
#Holen Sie sich das RC-Skript von S3
/home/ec2-user/example/example:
source:
Fn::Sub: https://s3-${AWS::Region}.amazonaws.com/S3-Bucket-Name, in dem Module usw. gespeichert sind/example
owner: ec2-user
group: ec2-user
mode: "000755"
#Übertragen Sie die von der Anwendung ausgegebenen Protokolle mit awslogs an CloudWatch
/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
#Cron plant einen automatischen Neustart, wenn der JVM-Prozess der Anwendung ausfällt
/home/ec2-user/example/conf/cron.conf:
content: |+
*/5 * * * * /sbin/service example start > /dev/null 2>&1
owner: ec2-user
group: ec2-user
#Beachten Sie, dass wenn Sie mehrere Befehle in Befehle schreiben, diese in alphabetischer Reihenfolge ausgeführt werden.
commands:
#Platzieren Sie das RC-Skript (/etc/init.d Unter dem symbolischen Link)
A_RegisterService:
command: ln -s /home/ec2-user/example /etc/init.d/example
#Fügen Sie mit chkconfig hinzu und stellen Sie die Anwendung so ein, dass sie automatisch startet / stoppt, wenn die EC2-Instanz gestartet / gestoppt wird
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
#Geben Sie der gestarteten EC2-Instanz einen beschreibenden Namen
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
das ist alles.
Recommended Posts