“服务器重启后,网站挂了”?手把手教你搞定腾讯云服务器开机自启
你有没有遇到过这种情况?大半夜正睡得香,突然接到报警电话,说公司网站打不开了,你揉着惺忪的睡眼,登录腾讯云后台一看,发现服务器不知道什么时候自动重启了——可能是系统补丁更新,也可能是云平台底层维护触发的硬件迁移,服务器是起来了,但你精心部署的Java应用、Nginx、数据库进程,却一个都没跟着起来。
这时候你会被同事的灵魂拷问砸得晕头转向:“上次不是让你配了开机启动吗?”而你盯着黑乎乎的SSH终端,脑子一片空白,心里只有一个想法:那个该死的“开机自启”,到底应该怎么配?
别慌,这种窘境,几乎每个运维人都经历过,今天我们就来彻底聊透“腾讯服务器怎么开机启动”这个话题,这不是一篇干巴巴的官方文档翻译,而是从实战踩坑中总结出来的、能让你的服务在服务器重启后像“老兵”一样自动归位的完整指南。
第一步:搞清楚“开机启动”的层次,别在错误的地方使劲
很多新手犯的第一个错误,就是把“云服务器控制台”里的操作,和“服务器操作系统内部”的操作混为一谈。
你可能会想:我在腾讯云控制台里,给这个云服务器设一个“开机启动”的按钮,不就行了?
错,云平台层面的“开机启动”,通常指的是云服务器实例本身的开机和关机行为(比如你设置了定时开关机,或者关联了弹性伸缩组),但操作系统内具体哪个服务、哪个进程、哪个脚本跟着系统一起起来,那是操作系统本身的工作,云平台管不了那么细。
我们要讨论的“腾讯服务器怎么开机启动”,核心是在你云服务器操作系统内部,如何去配置各种应用程序的自启。
第二步:分清“你”的身份——是原生应用,还是Docker容器?
在动手之前,先问自己一个问题:我的服务是怎么部署的?
场景A传统部署。 直接在服务器上安装了JDK,然后通过java -jar xxx.jar启动应用;或者手工编译安装了Nginx,这是最经典的“裸机运维”。
场景BDocker化部署。 使用了Docker Compose或者Kubernetes,你的服务跑在容器里。
对于这两种场景,配置方式截然不同,我们逐个击破。
场景A详解:传统部署下的开机自启(以CentOS/Ubuntu为例)
这是最常遇到的场景,也是坑最多的场景,很多人喜欢把启动命令直接塞进/etc/rc.local,或者简单地在/etc/rc.d/rc.local里加一行,这招在CentOS 6时代还行,但在CentOS 7/8以及Ubuntu 16.04之后,强烈不建议这么干。
原因有二:1.rc.local服务默认是关闭的,你得先手动开;2. 服务之间的依赖关系(比如你的Java应用需要先等数据库起来)完全没法控制,启动顺序一团糟。
正统的做法:使用systemd。
如今的主流Linux发行版都用systemd作为init系统,它稳定、功能强大,而且腾讯云官方镜像默认就是基于systemd,我们就用systemd来搞定。
案例:为一个Spring Boot的Jar包配置开机自启
假设你有个Jar包放在/opt/myapp/app.jar。
1、编写service文件。
在/etc/systemd/system/目录下创建一个文件,比如叫做myapp.service。
[Unit]
Description=My Awesome Java App
After=network.target remote-fs.target nss-lookup.target
# 如果你的应用依赖数据库,可以加上:
# After=mysqld.service postgresql.service
[Service]
Type=simple
User=www-data # 建议用非root用户运行,更安全
Group=www-data
WorkingDirectory=/opt/myapp
# 启动命令的关键!指定JDK路径和Jar包
ExecStart=/usr/bin/java -Xms512m -Xmx1024m -jar /opt/myapp/app.jar
# 重启策略:遇错自动重启,很有用
Restart=on-failure
RestartSec=10
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=multi-user.target2、重新加载systemd配置并启用服务。
sudo systemctl daemon-reload
sudo systemctl enable myapp.service # 这就是“开机自启”的开关!3、启动服务并检查状态。
sudo systemctl start myapp.service
sudo systemctl status myapp.service这时候,哪怕你重启整个云服务器,只要服务器操作系统内核起来了,systemd就会自动拉起这个myapp服务。 你再也不用半夜爬起来手动输一堆命令了。
案例:为Nginx或Tomcat配置自启
如果你是通过源码安装的Nginx,通常没有自动生成systemd服务文件,同样,仿照上面的模板,写一个Nginx的service文件即可,关键在于ExecStart和ExecStop要写对路径。
[Service] Type=forking PIDFile=/var/run/nginx.pid ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s quit
如果你用apt install nginx或者yum install nginx安装的,包管理器已经帮你写好了systemd文件,你只需要执行sudo systemctl enable nginx就行了。
场景B详解:Docker容器如何开机自启?
用Docker的话,事情就简单多了,但也容易踩一个很常见的坑。
错误示范:
你在命令行里docker run -d --name mynode mynode:v1跑了一个Node.js服务,服务器重启后,这个容器不会自动起来,因为Docker默认的策略是no,即容器退出或被守护进程重启(对应机器重启)后,不做任何操作。
正确做法:加上--restart参数。
当你运行容器时,一定要加上重启策略:
docker run -d \ --name mynode \ --restart unless-stopped \ mynode:v1
| 重启策略 | 说明 |
no | 默认值,不自动重启 |
always | 容器总是会重启,无论退出码是什么,甚至包括手动stop后,Docker服务重启也会拉起来。注意:你手动docker stop它,下次Docker重启它还是会活过来,有时候会吓你一跳 |
on-failure | 只在容器以非0退出码退出时重启(比如程序崩溃) |
unless-stopped | 与always类似,但如果你手动docker stop了它,Docker守护进程重启后,它不会被再次拉起来。这是最推荐的生产策略。 |
对于使用Docker Compose的场景,同样在docker-compose.yml里配置restart: unless-stopped即可。
进阶问题:你的服务依赖另一个容器(比如用了腾讯云数据库,但还是想先启Redis)?
Docker本身不保证容器的启动顺序,管理依赖关系,建议用Docker Compose的depends_on,虽然它只能保证依赖的容器在目标容器之前启动,但不能保证依赖的容器内服务已经完全就绪,更可靠的做法是在应用代码里加入等待逻辑(比如等待端口或心跳检测),或者使用类似dockerize、wait-for-it.sh这样的脚本。
第三步:专治“不服”——腾讯云服务器的特殊场景
刚才讲的是通用操作,但如果你用的是腾讯云服务器,有几个和社区云平台不一样的地方值得注意:
1、关于密钥和初始化脚本(user-data)。
腾讯云CVM支持在创建实例时,通过“提交自定义数据”的方式,传入一个初始化脚本(User Data),这个脚本会在第一次启动时自动执行一次。注意,只有第一次启动! 此功能适合做新机器的初始化配置(比如装软件、设环境变量),但不适合做常规的开机自启任务,如果你需要在每次重启后都执行的脚本,还是得用systemd。
2、强制关机”和“硬重启”。
如果你在腾讯云后台用了“强制关机”或者“重装系统”,有时会导致systemd记录的服务状态出现异常,比如有时明明enable了,重启后服务却没起来,这时候可以尝试systemctl reset-failed myapp.service,或者检查一下/etc/systemd/system下的文件是否有语法错误。
3、挂载路径的问题。
很多腾讯云服务器会挂载云硬盘(比如/data分区),如果你的应用启动时需要读写这块硬盘,而云硬盘的挂载操作(/etc/fstab)是在服务器启动比较靠后的环节,如果你的systemd服务文件里没有写好After=local-fs.target,极有可能你的服务启动时,/data目录还是空的,导致应用崩溃。
解决方案: 在service文件的[Unit]段,明确加上RequiresMountsFor=/data,或者After=local-fs.target,确保文件系统挂载完毕后再启动你的服务。
一次配置,高枕无忧
说了这么多,其实核心就两句话:
1、传统方式死磕systemd,别再用/etc/rc.local了,那只是你偷懒的遮羞布,写好service文件,enable一下,最稳。
2、容器方式死磕--restart unless-stopped,简单明了,如果有复杂依赖,用好depends_on加上应用层的就绪检查。
把你手头所有重要的服务都按这个标准配置一遍,然后你就可以做那个“别人半夜被报警吵醒,你却可以安心睡觉”的运维大神。
下次如果有人再问你“腾讯服务器怎么开机启动”,你就把这篇文章甩给他,然后淡淡地说:“自己看,写得很清楚。” 前提是你自己也照着做了一遍。
文章摘自:https://idc.huochengrm.cn/fwq/25175.html
评论