Linux定时任务重启jar、docker容器

本文介绍了如何创建和配置Linux脚本来监控和重启服务。详细步骤包括编写shell脚本,设置定时任务,安装及使用lsof命令检查端口占用,以及处理docker容器的重启。此外,还涉及到了日志管理和时区设置,以及排查定时任务不执行的问题。

原创:https://blog.youkuaiyun.com/Zhs_2000/article/details/109837996

脚本内容

#!/bin/sh
 
#切换到目录
cd /root
date=`date`
 
#查询端口占用
lsof -i:7001
 
# $? -ne 0 不存在 $? -eq 0存在 
if [ $? -ne 0 ]
then
	nohup java -Xms512m -Xmx512m -jar vehicle-7001.jar > /dev/null 2>&1 &
    echo $date  ":=============== restart ===============" >> restart.log
else
    echo $date  ":=============== is normal ==============" >> restart.log
fi

1、新建脚本并保存

vim /usr/local/monitor_restart.sh

2、新增定时任务

crontab -e
*/3 * * * * . /etc/profile;/bin/sh /usr/local/monitor_restart.sh

查看所有定时任务

crontab -l

重启crontab

service crond restart

查看日志:

tail -2 /var/log/cron

报错日志:

tail -2 /var/spool/mail/root

lsof: command not found,安装lsof

yum install lsof

定时运行命令(重启docker容器)

新增重启命令
切换到存放的路径

cd /app/myapp
vim live_restart.sh

命令内容

#!/bin/sh
 
date=`date`
 
docker restart live
echo $date  ": live restart " >> /app/myapp/live_restart.log

保存后授权

chmod 777 live_restart.sh 

测试执行一次

./live_restart.sh

查看日志,是否有执行时间的输出

cat live_restart.log

成功会显示类似:Wed Jul 14 09:41:00 CST 2021 : live restart

修改日志权限

chmod 777 live_restart.log

确保上述成功后,添加linux定时任务

crontab -e

每天凌晨2点、13点执行一次

0 2 * * * . /etc/profile;/bin/sh /app/myapp/live_restart.sh
0 13 * * * . /etc/profile;/bin/sh /app/myapp/live_restart.sh

查看所有定时任务

crontab -l

重启定时任务

service crond restart

定时任务不执行排查

1、脚本、日志是否修改了权限
2、相关路径是否是全路径
3、时区是否正确

查看定时任务状态,正常为:Active: active (running)

service crond status

查看定时任务日志

tail -100f /var/log/cron

Ubuntu系统定时任务命令为cron不是crond

service cron restart

查看当前时间

date

查看时间状态

timedatectl status

将时区设置为上海

timedatectl set-timezone "Asia/Shanghai"
<think>我们面对的问题是如何在已经启动的Docker容器中运行一个Java程序。根据之前的引用和我们的知识,我们可以通过以下几种方法来实现: 方法1:将Java程序复制到正在运行的容器中,然后在容器内执行 步骤: 1. 将本地的Java程序(例如HelloWorld.java)复制到容器内 2. 进入容器(或者不进入,使用docker exec执行命令) 3. 在容器内编译并运行Java程序 但是,注意:容器内可能没有Java环境(即没有安装JDK)。所以,我们需要确保容器内已经安装了Java运行环境。如果没有,我们需要先安装。 方法2:如果容器内没有Java环境,我们可以考虑重新构建镜像,在镜像中安装Java环境,然后重新创建容器。但用户要求的是在已经启动的容器中运行,所以我们优先考虑在现有容器中操作。 具体步骤: 1. 检查容器内是否有Java环境: ```bash docker exec <容器名或ID> java -version ``` 如果显示版本信息,则说明已安装;否则需要安装。 2. 如果没有Java环境,我们需要在容器内安装JDK(以基于Debian的容器为例,使用apt): ```bash docker exec -it <容器名或ID> apt update docker exec -it <容器名或ID> apt install -y openjdk-11-jdk ``` 注意:不同的容器基础系统安装命令可能不同(如Alpine使用apk,CentOS使用yum)。 3. 将Java程序从宿主机复制到容器内: ```bash docker cp /宿主机/路径/HelloWorld.java <容器名或ID>:/容器内路径/ ``` 4. 进入容器(可选,也可以不进入直接执行命令): ```bash docker exec -it <容器名或ID> /bin/bash ``` 然后在容器内编译和运行: ```bash javac HelloWorld.java java HelloWorld ``` 或者不进入容器,直接执行: ```bash docker exec <容器名或ID> sh -c "cd /容器内路径 && javac HelloWorld.java && java HelloWorld" ``` 方法3:如果容器内没有安装JDK,而且我们不想在容器内安装(比如容器是精简版,安装困难),我们可以将Java程序编译成可执行的jar包,然后在容器内运行这个jar包(这样只需要JRE,但最好还是用JDK,因为JRE可能没有包含在基础镜像中,而且我们还需要运行javac来编译)。或者,我们可以在宿主机上编译好,然后将.class文件或jar包复制到容器内,然后运行。 步骤: 1. 在宿主机编译Java程序(需要宿主机有JDK): ```bash javac HelloWorld.java ``` 2. 将编译好的.class文件复制到容器内: ```bash docker cp HelloWorld.class <容器名或ID>:/容器内路径/ ``` 3. 在容器内运行: ```bash docker exec <容器名或ID> java -cp /容器内路径 HelloWorld ``` 方法4:如果容器内没有Java环境,而且我们无法安装(比如权限问题,或者容器是只读文件系统),我们可以考虑将容器提交为新的镜像,然后在新镜像中安装Java环境,再运行。但这样会改变容器状态,而且需要重新启动容器。 步骤: 1. 将当前容器提交为新的镜像: ```bash docker commit <容器名或ID> 新镜像名:标签 ``` 2. 编写Dockerfile,基于新镜像安装JDK: ```Dockerfile FROM 新镜像名:标签 RUN apt update && apt install -y openjdk-11-jdk ``` 3. 构建新镜像: ```bash docker build -t 带jdk的镜像名 . ``` 4. 用新镜像启动容器(注意保留原容器的配置,如端口映射、卷挂载等): ```bash docker run ... 带jdk的镜像名 ``` 5. 然后按照方法1或2运行Java程序。 但是,用户要求的是在已经启动的容器中运行,所以方法4需要重新创建容器,可能不符合要求。 总结:推荐使用方法2或3,具体取决于容器内是否有Java环境以及我们是否有权限安装。 注意事项: - 容器内如果没有Java环境,安装JDK可能会增加容器的大小,且可能不符合容器轻量化的原则。 - 如果只是临时运行,可以安装;如果是长期使用,建议重新构建包含Java环境的镜像。 - 在容器内运行Java程序时,注意工作目录和类路径。 另外,根据引用[3]的内容,我们也可以考虑使用Dockerfile来构建一个包含Java程序的镜像,但是用户要求的是在已启动的容器中运行,所以这种方法不直接适用,但可以作为长期解决方案。 因此,我们给出在已启动容器中运行Java程序的步骤(假设容器内没有Java环境,我们选择安装): 步骤1:安装JDK(以Debian/Ubuntu容器为例) ```bash docker exec -it <容器名或ID> apt update docker exec -it <容器名或ID> apt install -y openjdk-11-jdk ``` 步骤2:复制Java源文件到容器 ```bash docker cp /宿主机/路径/HelloWorld.java <容器名或ID>:/容器内路径/ ``` 步骤3:编译并运行 ```bash docker exec <容器名或ID> javac /容器内路径/HelloWorld.java docker exec <容器名或ID> java -cp /容器内路径 HelloWorld ``` 或者合并为一条命令: ```bash docker exec <容器名或ID> sh -c "javac /容器内路径/HelloWorld.java && java -cp /容器内路径 HelloWorld" ``` 注意:如果容器内没有/bin/sh,请使用/bin/bash。 如果容器是Alpine Linux,安装JDK的命令为: ```bash docker exec -it <容器名或ID> apk add openjdk11 ``` 如果容器是CentOS,安装JDK的命令为: ```bash docker exec -it <容器名或ID> yum install -y java-11-openjdk-devel ``` 另外,如果容器是只读文件系统(例如在Kubernetes中设置的安全策略),则无法安装软件,此时只能使用方法3(在宿主机编译,然后复制.class文件)或者使用方法4重新构建镜像。 最后,如果容器中已经运行了其他服务,我们在容器内运行Java程序可能会影响现有服务,因此需要谨慎。如果只是临时测试,可以这样操作;如果是长期运行,建议将Java程序作为服务运行,并考虑使用Dockerfile构建新的镜像。 相关问题: 1. 如何查看Docker容器内的文件? 2. 如何进入正在运行的Docker容器? 3. 如何将Docker容器内的文件复制到宿主机? 4. 如何在不进入容器的情况下在容器内执行命令? 5. 如何构建包含Java环境的Docker镜像?</think>### 在已启动的Docker容器中运行Java程序的完整指南 以下是几种可靠的方法,根据您的具体场景选择最适合的方案: --- #### 方法1:通过`docker cp`复制并运行(推荐) ```bash # 1. 将Java程序复制到容器docker cp /宿主机路径/YourProgram.java 容器名或ID:/容器内路径/ # 2. 进入容器shell docker exec -it 容器名或ID sh # 3. 在容器内编译运行 cd /容器内路径 javac YourProgram.java java YourProgram ``` > **适用场景**:临时调试或单次执行,不需要修改容器配置[^2] --- #### 方法2:直接执行Java命令(需容器有JDK环境) ```bash # 单行命令直接运行(需指定完整类路径) docker exec 容器名或ID java -cp /容器内路径 YourProgram # 示例:运行位于/app目录的Main类 docker exec mycontainer java -cp /app Main ``` > **前提条件**:容器内已安装JDK(可通过`docker exec 容器名 java -version`验证) --- #### 方法3:通过SSH运行(需容器启用SSH) ```bash # 1. 获取容器IP docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 容器名 # 2. SSH连接并执行 ssh root@容器IP "cd /app && java YourProgram" ``` > **配置要求**:需在Dockerfile中添加SSH支持: > ```Dockerfile > RUN apt-get update && apt-get install -y openssh-server > RUN echo 'root:password' | chpasswd > CMD ["/usr/sbin/sshd", "-D"] > ``` --- #### 方法4:后台运行Java程序(守护进程) ```bash # 使用nohup保持程序运行 docker exec -d 容器名 sh -c "nohup java -jar /app/your.jar > /var/log/java.log 2>&1 &" # 验证进程 docker exec 容器名 ps aux | grep java ``` --- #### 方法5:通过Dockerfile重建容器(持久化方案) ```Dockerfile # 基于现有容器创建新镜像 FROM 现有镜像名:标签 # 添加Java程序 COPY YourProgram.java /app/ # 编译并设置启动命令 RUN javac /app/YourProgram.java CMD ["java", "-cp", "/app", "YourProgram"] ``` ```bash # 构建并运行新容器 docker build -t java-app . docker run -d --name java-container java-app ``` > **优势**:程序成为容器固有部分,重启后自动运行[^3] --- ### 关键注意事项 1. **JDK依赖**: - 若容器无JDK,需先安装: ```bash # Ubuntu docker exec 容器名 apt-get update && apt-get install -y openjdk-17-jdk # Alpine docker exec 容器名 apk add openjdk17 ``` 2. **文件权限**: ```bash docker exec 容器名 chmod +x /app/YourProgram.class ``` 3. **程序输出**: - 查看日志:`docker logs 容器名` - 实时监控:`docker attach 容器名` 4. **资源限制**: ```bash docker run -d --cpus="1.5" --memory="512m" java-app ``` --- ### 方案选择建议 | 场景 | 推荐方法 | 原因 | |--------------------------|----------|-------------------------------| | 临时调试/单次执行 | 方法1 | 无需重建容器,快速验证 | | 容器已有JDK的定时任务 | 方法2 | 单命令完成,适合cronjob | | 需要远程管理的生产环境 | 方法3 | 提供完整的SSH管理能力 | | 长期运行的服务 | 方法5 | 保证服务持久性和可维护性 | | 需要脱离终端持续运行 | 方法4 | nohup保证进程不随终端退出关闭 | > **生产环境最佳实践**:使用方法5将Java程序构建进镜像,确保环境一致性[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值