描述:首先微服务本身就是一个鲜明的分布式环境,eureka就是注册中心,其它服务要做的就是被eureka管理起来。
需求:将微服务部署到Ubuntu系统(服务器)上,以便用户使用,如果断电了,让其自动启动。!!!
!!!!前者两个月前就OK了,后面这个自动启动足足折磨了我两天半!!!!
能从百度解决问题的都是带了一丝幸运与上帝的关照。而我这个问题百度的方法过了一遍,然而没有什么用!!!
唉!!!不说了,一言难尽,奉献给你们解决办法,希望少走弯路,再一个也是让自己记住这个两天半。。。。。
将你的微服务各个服务打成jar包,直接丢到服务器某个目录下,最好建一个目录,例如我的:/jar
截图如下:
写一个shell脚本,我linux基本不行,也没有刻意研究过,只能百度找个模板,自己改改能运行成功就OK了!
脚本如下:
#!/bin/bash
#chkconfig: 2345 80 90
#description:demo
#程序代码数组
APPS=(eureka zuul auth resource dispatching rsdata)
#程序名称数组
NAMES=(注册中心 网关 auth服务 resource服务 dispathing服务 rsdata服务)
#jar包数组
JARS=(eurekasvr-0.0.1-SNAPSHOT.jar zuulsvr-0.0.1-SNAPSHOT.jar auth-server-0.0.1-SNAPSHOT.jar resources-service-0.0.1-SNAPSHOT.jar dispatching-service-0.0.1-SNAPSHOT.jar rsdata-0.0.1-SNAPSHOT.jar)
#jar包路径数组
PATHS=(/jar/ /jar/ /jar/ /jar/ /jar/ /jar/)
start(){
local APPNAME=
local NAME=
local CLASSNAME=
local PROJECTDIR=
local command="sh demo.sh start"
local cmd2="$1"
local cmd2ok=0
local cnt=0
local okcnt=0
#local C_PID="0"
#for i in `seq 0 22`
echo "---------------------------开始启动服务..."
for(( i=0;i<${#APPS[@]};i++))
do
APPNAME=${APPS[$i]}
NAME=${NAMES[$i]}
CLASSNAME=${JARS[$i]}
PROJECTDIR=${PATHS[$i]}
if [ "$cmd2" == "all" ] || [ "$cmd2" == "$APPNAME" ]; then
cmd2ok=1
C_PID="0"
cnt=0
#ps -ef | grep "$CLASSNAME" | awk '{print $2}' | while read pid
PID=`ps -ef |grep $(echo $CLASSNAME |awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
#do
#C_PID=$(ps --no-heading $pid | wc -l)
#if [ "$C_PID" == "1" ]; then
if [ -n "$PID" ]
then
echo "$APPNAME---$NAME:己经运行,PID=$PID"
#okcnt=$(($okcnt+1))
else
cd $PROJECTDIR
rm -f $PROJECTDIR/nohup.out
command="nohup /usr/bin/java -jar $CLASSNAME"
exec $command >> $PROJECTDIR/nohup.out &
#ps -ef | grep "$CLASSNAME" | awk '{print $2}' | while read pid
#do
# C_PID=$(ps --no-heading $pid | wc -l)
#done
PID=`ps -ef |grep $(echo $CLASSNAME |awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
cnt=0
#while (("$C_PID" == "0"))
while [ -z "$PID" ]
do
if (($cnt==30))
then
echo "$APPNAME---$NAME:$cnt秒内未启动,请检查!"
break
fi
cnt=$(($cnt+1))
sleep 1s
#ps -ef | grep "$CLASSNAME" | awk '{print $2}' | while read pid
#do
# C_PID=$(ps --no-heading $pid | wc -l)
#done
PID=`ps -ef |grep $(echo $CLASSNAME |awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
done
okcnt=$(($okcnt+1))
echo "$APPNAME---$NAME:己经成功启动,PID=$PID"
#出借模块和总装模块启动较慢
if [ "$APPNAME" == "deal" ] ;
then
echo "$APPNAME---$NAME:启动中..."
sleep 30s
fi
if [ "$APPNAME" == "dispatch" ] ;
then
echo "$APPNAME---$NAME:启动中..."
sleep 10s
fi
fi
#done
fi
done
if (($cmd2ok==0))
then
echo "command2: all|eureka|remove|get"
else
echo "---------------------------本次启动:$okcnt个服务"
fi
}
stop(){
local APPNAME=
local CLASSNAME=
local PROJECTDIR=
local command="sh demo.sh stop"
local cmd2="$1"
local cmd2ok=0
#local C_PID="0"
local okcnt=0
echo "---------------------------开始停止服务..."
for(( i=0;i<${#APPS[@]};i++))
do
APPNAME=${APPS[$i]}
NAME=${NAMES[$i]}
CLASSNAME=${JARS[$i]}
PROJECTDIR=${PATHS[$i]}
if [ "$cmd2" == "all" ] || [ "$cmd2" == "$APPNAME" ]; then
cmd2ok=1
#ps -ef | grep "$CLASSNAME" | awk '{print $2}' | while read PID
PID=`ps -ef |grep $(echo $CLASSNAME |awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
#do
#C_PID=$(ps --no-heading $PID | wc -l)
#if [ "$C_PID" == "1" ]; then
if [ -n "$PID" ]
then
echo "$NAME:PID=$PID准备结束"
kill $PID
#C_PID=$(ps --no-heading $PID | wc -l)
#while (("$C_PID" == "1"))
PID=`ps -ef |grep $(echo $CLASSNAME |awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
while [ -n "$PID" ]
do
sleep 1s
#C_PID=$(ps --no-heading $PID | wc -l)
PID=`ps -ef |grep $(echo $CLASSNAME |awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
done
echo "$NAME:成功结束"
okcnt=$(($okcnt+1))
else
echo "$NAME:未运行"
fi
#done
fi
done
if (($cmd2ok==0))
then
echo "command2: all|eureka|remove|get"
else
echo "---------------------------本次共停止:$okcnt个服务"
fi
}
case "$1" in
start)
start "$2"
exit 1
;;
stop)
stop "$2"
;;
restart)
stop "$2"
start "$2"
;;
*)
echo "command1: start|stop|restart"
exit 1
;;
esac
既然脚本创建好了,你必须先把脚本这一关过了,执行一下看看是否运行成功,如果不成功,就先把这个问题解决了,否则后面没办法进行下去。
执行脚本命令如下:
//注意:该方法适应于我这个脚本---
sh /jar/demo.sh start all
bash /jar/demo.sh start all
//如果出现其它没有权限什么的错误,就赋值给脚本执行权限
sudo chmod 777 /jar/demo.sh
//至于其它错误,可自行解决!!!
将脚本设置开机自动启动
我的系统是Ubuntu 16.0.4,
该环境 /etc 目录下有一个 rc.local 这个是系统开机启动时自动执行里面的命令的
大多数人也就犯了一个通病,说:既然是执行命令的,那么我直接运行这个脚本不就行了嘛?
一丶它虽然可以允许脚本,但是它不知道你的脚本依赖关系到底是如何,因为你的eureka启动之后,后续的其它服务与eureka是有依赖关系的,它不知道你后面的服务是否有eureka有关系,换而言之就是不知道它该注册到哪里去,由此就会出错,在你查看进程的时候你可以看一下,只有一个eureka进程,其它的就没有进程!!!
二丶这个/etc/rc.local 我理解的就是它在系统开机时最后执行的!其它的我也不了解,这里先说解决办法。
解决办法如下:
进入/etc/init.d目录下
创建文件: 例如我的 shjardemo
赋给它权限为777
该文件内容如下
#!/bin/bash
# MyApp
#
# description: bla bla
case $1 in
start)
#这里 /bin/bash 就是linux的一个什么软连接啥的,我也不晓得什么意思
#后面的 就是启动脚本 然后日志输出在 /jar目录下 (该日志文件会自动生成)
#后面的停止和重启 是一样的理解
/bin/bash /jar/demo.sh start all >/jar/initdemo.output 2>&1
;;
stop)
/bin/bash /jar/demo.sh stop all >/jar/initdemo.output 2>&1
;;
restart)
/bin/bash /jar/demo.sh stop all >/jar/initdemo.output 2>&1
/bin/bash /jar/demo.sh start all >/jar/initdemo.output 2>&1
;;
esac
exit 0
然后执行命令:该命令的意思就是将这个文件添加到系统开机执行
sudo update-rc.d shjardemo defaults
如果出现这个信息,不用担心,这是init.d目录修改时自动出现的,没有关系,
然后重启系统
sudo reboot
之后等待 输入ip和端口 查看eureka是否访问成功就行了,我的效果如图所示:
注意:如果等了一会儿出不来,你的脚本没问题,那么试试这个能否解决
第一:
输入命令:
#shjardemo 代表的是你启动脚本的那个文件夹
sudo service shjardemo start
#如果启动之后报错,出现一大串字母还有红色的提升信息
那么执行这个命令
systemctl daemon-reload
#然后再次重启 试一下!!!