docker不停机部署
背景
最近做大疆项目时,后台更新部署时,机场和无人机就会掉线。设备自动重连注册时间比较长,应用长时间不可用。所以需要灰色发布服务。docker-compose的swarm模式可解决此问题。
服务构建脚本Dockerfile
# 使用官方Java基础镜像(推荐选择Alpine轻量版)
FROM openjdk:17-jdk-alpine
# 更新时区
RUN apk add --no-cache tzdata
ENV TZ=Asia/Shanghai
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \&& echo "Asia/Shanghai" > /etc/timezone \
# 设置工作目录
WORKDIR /app# 将JAR文件复制到容器中(注意替换为你的JAR文件名)
COPY ./*.jar /app/
COPY ./lib/*.jar /app/lib/ARG JAVA_OPTS="-server -Xmx512m -Xms512m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256M -Xss256k -XX:+DisableExplicitGC -XX:+UseG1GC -XX:LargePageSizeInBytes=128m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dumps/oom_dump.hprof -Djava.security.egd=file:/dev/./urandom"RUN mkdir -p /app/dumps
RUN mkdir -p /app/logs
# 启动命令
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app/${project.build.finalName}.jar > /app/logs/${project.build.finalName}.log 2>&1"]
容器编排配置docker-compose.yml
下面的内容没有一行是多余的,修改时要慎重考虑
version: '3.8'
networks:${project.artifactId}-stack-proxy-tier: # 自定义的网络名称(可任意定义,但是需要提前创建)external: trueservices:${project.artifactId}: #docker应用服务名称,不能包含非法字符比如点image: ${project.build.finalName}:${project.version}deploy:replicas: 2 # 至少保持2个副本update_config:parallelism: 1 # 每次更新1个实例delay: 10s # 新实例启动间隔order: start-first # 先启动新实例,再停止旧实例restart_policy:condition: anyhealthcheck:test: ["CMD-SHELL", "wget -q --spider http://localhost:23111/actuator/health || exit 1"]interval: 10stimeout: 5sretries: 3start_period: 20svolumes:- ./${project.build.finalName}.jar:/app/${project.build.finalName}.jar- ./lib:/app/libenvironment:- VIRTUAL_HOST=192.168.1.4 # ip或者域名- VIRTUAL_PORT=23111 # 应用启动的端口networks:- ${project.artifactId}-stack-proxy-tier# 配置Nginx反向代理nginx:image: jwilder/nginx-proxy #专应用docker负载均衡、服务发现额镜像,功能非常强大environment:- TZ=Asia/Shanghai- HTTP_CHECK=/"actuator/health"ports:- "22011:80"volumes:- /var/run/docker.sock:/tmp/docker.sock:ronetworks:- ${project.artifactId}-stack-proxy-tierdepends_on:- ${project.artifactId}
启动脚本restart
linux
#!/bin/bash# 设置脚本在遇到错误时立即退出
set -einit(){docker swarm init# 检查Overlay网络是否存在:ml-citation{ref="3,4" data="citationList"}if [[ -z $(docker network ls --filter name=^${project.artifactId}-stack-proxy-tier$ --format '{{.Name}}') ]]; thenecho "Creating overlay network..."docker network create --driver overlay --attachable ${project.artifactId}-stack-proxy-tierelseecho "Network ${project.artifactId}-stack-proxy-tier already exists, skipping creation."fideploy
}restart(){deploy
}deploy() {# 构建Docker镜像docker build -t ${project.build.finalName}:${project.version} .# 部署Docker堆栈docker stack deploy --detach=false -c docker-compose.yml ${project.artifactId}-stack
}remove() {#删除堆栈docker stack rm ${project.artifactId}-stack#删除网络docker network rm ${project.artifactId}-stack-proxy-tier
}case $1 ininit) init;;restart) restart;;remove) status;;*) echo "require init|restart|remove";;
esac
windows
@echo off
setlocal enabledelayedexpansionif "%1"=="init" goto init
if "%1"=="restart" goto restart
if "%1"=="remove" goto remove
echo require init^|restart^|remove
exit /b 1:init
docker swarm init
for /f "tokens=*" %%i in ('docker network ls --filter name^^=^${project.artifactId}-stack-proxy-tier$ --format "{{.Name}}"') do set network=%%i
if "!network!"=="" (echo Creating overlay network...docker network create --driver overlay --attachable ${project.artifactId}-stack-proxy-tier
) else (echo Network ${project.artifactId}-stack-proxy-tier already exists, skipping creation.
)
goto deploy:restart
goto deploy:deploy
docker build -t ${project.build.finalName}:${project.version} .
docker stack deploy --detach=false -c docker-compose.yml ${project.artifactId}-stack
exit /b 0:remove
docker stack rm ${project.artifactId}-stack
docker network rm ${project.artifactId}-stack-proxy-tier
exit /b 0
整合maven
上面脚本配置中的类似${project.build.finalName}变量是需要maven在构建时替换的。
resources进行替换,打包工具我用的maven-assembly-plugin,根据项目自行替换
<build><resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource><resource><directory>src/assembly/docker</directory><includes><include>docker-compose.yml</include><include>Dockerfile</include><include>restart.sh</include><include>restart.bat</include><include>nginx.conf</include></includes><filtering>true</filtering></resource></resources><plugin><!-- 配置打包文件 --><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>3.6.0</version><configuration><descriptors><descriptor>src/assembly/distribution.xml</descriptor></descriptors><finalName>${project.artifactId}-${project.version}</finalName></configuration><executions><execution><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin><plugin><!-- 配置启动入口 --><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.2.2</version><configuration><archive><manifest><mainClass>com.dji.sample.CloudApiSampleApplication</mainClass><addClasspath>true</addClasspath><classpathPrefix>lib</classpathPrefix></manifest></archive></configuration></plugin></plugins></build>
我所有的脚本以及配置文件是放在src/assembly/docker下的

maven构建配置distribution.xml
<?xml version="1.0" encoding="UTF-8"?>
<assemblyxmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"><id>package</id><formats><format>zip</format></formats><includeBaseDirectory>false</includeBaseDirectory><fileSets><fileSet><directory>target</directory><outputDirectory>./</outputDirectory><includes><include>*.jar</include></includes></fileSet><fileSet><directory>target/classes</directory><outputDirectory>./</outputDirectory><includes><include>docker-compose.yml</include><include>Dockerfile</include><include>restart.sh</include><include>restart.bat</include><include>nginx.conf</include></includes></fileSet></fileSets><dependencySets><dependencySet><outputDirectory>lib</outputDirectory></dependencySet></dependencySets>
</assembly>
docker容器启动
首次部署命令
restart.bat init
重启命令
restart.bat restart
删除命令(仅限调试)
restart.bat remove
修改镜像版本
每次更新时需要修改项目的版本号${revision}

相关文章:
docker不停机部署
背景 最近做大疆项目时,后台更新部署时,机场和无人机就会掉线。设备自动重连注册时间比较长,应用长时间不可用。所以需要灰色发布服务。docker-compose的swarm模式可解决此问题。 服务构建脚本Dockerfile # 使用官方Java基础镜像ÿ…...
鸿蒙应用开发—数据持久化之SQLite
文章目录 SQLite简介创建数据库添加数据查询数据更新数据删除数据升级数据库使用事务参考 SQLite简介 SQLite是一个轻量级关系数据库,占用资源很少,只有几百KB的大小,无需服务器支撑,是一个零配置、事务性的SQL数据库引擎。 相对…...
JSON对象处理工具类
目录 1. 工具类的功能设计 2. 工具类的实现 依赖配置 工具类代码 3. 工具类的使用示例 示例1:美化JSON打印 示例2:从JSON中提取数据 示例3:修改JSON数据 示例4:合并JSON对象 4. 总结 在现代软件开发中,JSON&…...
通义万相 2.1 + 蓝耘算力,AI 视频生成的梦幻组合
在这个科技日新月异的时代,人工智能不断刷新着我们对世界的认知。一次偶然的机会,我借助北京蓝耘科技股份有限公司提供的算力支持,踏上了使用通义万相 2.1 进行 AI 视频生成的奇妙之旅。 目录 1.1初遇蓝耘科技: 1.2通义万相 2.1…...
汽车一键启动按钮更换注意事项
汽车一键启动开关更换教程 一键启动开关是现代汽车中常见的便捷配置,但随着时间的推移,这个部件可能会出现失灵的情况。当一键启动开关发生故障时,许多车主选择自行更换。以下是整理的一键启动开关更换教程: 更换前的准备 选择匹…...
AI系统架构
在AI系统架构中,通常可以分为基础设施层、模型层和应用层。它们分别对应不同的技术和应用场景,具体如下: 1. 基础设施层(Infrastructure Layer) 这是AI系统的底层支持,主要涉及计算资源、存储、网络等基础…...
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_01基础固定表头示例
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_01基础固定表头…...
spring boot3.4.3+MybatisPlus3.5.5+swagger-ui2.7.0
使用 MyBatis-Plus 操作 books 表。我们将实现以下功能: 创建实体类 Book。 创建 Mapper 接口 BookMapper。 创建 Service 层 BookService 和 BookServiceImpl。 创建 Controller 层 BookController。 配置 MyBatis-Plus 和数据库连接。 1. 项目结构 src ├─…...
解决CentOS 8.5被恶意扫描的问题
CentOS 8 官方仓库已停止维护(EOL),导致一些常用依赖包如fail2ban 无法正常安装。 完整解决方案: 一、问题根源 CentOS 8 官方仓库已停更:2021 年底 CentOS 8 停止维护,默认仓库的包可能无法满足依赖关系。EPEL 仓库兼容性:EPEL 仓库可能未适配 CentOS 8.5 的旧版本依赖…...
laravel中 添加公共/通用 方法/函数
一,现在app 下面创建Common目录,然后在创建Common.php 文件 二,修改composer.json文件 添加这个到autoload 中 "files": ["app/Common/Common.php"]"autoload": {"psr-4": {"App\\": &quo…...
在vs中无法用QtDesigner打开ui文件的解决方法
解决方法 右键ui文件,选择打开方式,弹出如下界面。 点击添加,弹出如下界面 点击程序后边的三个点,去电脑查找designer.exe,我的位置为D:\Qt\Qt5.9.9\5.9.9\msvc2015_64\bin\designer.exe。 名称可以自己起一个名字,…...
springboot 文件下载
在springboot中,执行如下代码实现文件下载 GetMapping("/file/download/test")public void Download(HttpServletResponse response){try {String path "XXXXXXXXXXXX";//文件路径File file new File(path);// 读到流中InputStream inputStre…...
Nest.js全栈开发终极实践:TypeORM+微服务+Docker构建高可用企业级应用
文章目录 **第一部分:认识Nest.js与基础环境搭建****1.1 什么是Nest.js?****1.2 环境准备****1.3 创建第一个项目****1.4 启动开发服务器****1.5 核心文件解读** **第二部分:基础控制器与路由****2.1 控制器的作用****2.2 创建自定义控制器**…...
Go语言集成DeepSeek API和GoFly框架文本编辑器实现流式输出和对话(GoFly快速开发框架)
说明 本文是GoFly快速开发框架集成Go语言调用 DeepSeek API 插件,实现流式输出和对话功能。为了方便实现更多业务功能我们在Go服务端调用AI即DeepSeek接口,处理好业务后再用Gin框架实现流失流式输出到前端,前端使用fetch请求接收到流式的mar…...
Hexo博客Icarus主题不蒜子 UV、PV 统计数据初始化配置
文章首发于 不蒜子 UV、PV 统计数据初始化配置 适用场景 如果你有个运行的网站域名,采用了不蒜子统计 UV、PV等访客和阅读数据,但是有一天,你觉得想要换一个新的域名。当你将网站绑定到新的域名后,突然发现,所有的文章…...
在资源有限中逆势突围:从抗战智谋到寒门高考的破局智慧
目录 引言 一、历史中的非对称作战:从李牧到八路军的智谋传承 李牧戍边:古代军事博弈中的资源重构 八路军的游击战:现代战争中的智慧延续 二、创业界的逆袭之道:小米与拼多多的资源重构 从MVP到杠杆解 社交裂变与资源错配 …...
SQLAlchemy系列教程:如何执行原生SQL
Python中的数据库交互提供了高级API。但是,有时您可能需要执行原始SQL以提高效率或利用数据库特定的特性。本指南介绍在SQLAlchemy框架内执行原始SQL。 在SQLAlchemy中执行原生SQL SQLAlchemy虽然以其对象-关系映射(ORM)功能而闻名ÿ…...
绪论数据结构基本概念(刷题笔记)
(一)单选题 1.与数据元素本身的形式、相对位置和个数无关的是(B)【广东工业大学2019年829数据结构】 A.数据存储结构 B.数据逻辑结构 C.算法 D.操作 2.在数据结构的讨论中把数据结构从逻辑上分为(C)【中国…...
delphi 正则提取html中的内容
function ExtractTextFromHTML(const HTML: string): string; var RegEx: TRegEx; begin Result := HTML; // 移除<script>标签及其内容 Result := TRegEx.Replace(Result, <script.*?>.*?</script>, , [roIgnoreCase, roSingleLine]); // 移除<s…...
18天 - 常见的 HTTP 状态码有哪些?HTTP 请求包含哪些内容,请求头和请求体有哪些类型?HTTP 中 GET 和 POST 的区别是什么?
常见的 HTTP 状态码有哪些? HTTP 状态码用于指示服务器对客户端请求的响应结果,常见的 HTTP 状态码可以分为以下几类: 1. 信息类(1xx) 100 Continue:客户端应继续发送请求。101 Switching Protocols&…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
