当前位置: 首页 > news >正文

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不停机部署

背景 最近做大疆项目时&#xff0c;后台更新部署时&#xff0c;机场和无人机就会掉线。设备自动重连注册时间比较长&#xff0c;应用长时间不可用。所以需要灰色发布服务。docker-compose的swarm模式可解决此问题。 服务构建脚本Dockerfile # 使用官方Java基础镜像&#xff…...

鸿蒙应用开发—数据持久化之SQLite

文章目录 SQLite简介创建数据库添加数据查询数据更新数据删除数据升级数据库使用事务参考 SQLite简介 SQLite是一个轻量级关系数据库&#xff0c;占用资源很少&#xff0c;只有几百KB的大小&#xff0c;无需服务器支撑&#xff0c;是一个零配置、事务性的SQL数据库引擎。 相对…...

JSON对象处理工具类

目录 1. 工具类的功能设计 2. 工具类的实现 依赖配置 工具类代码 3. 工具类的使用示例 示例1&#xff1a;美化JSON打印 示例2&#xff1a;从JSON中提取数据 示例3&#xff1a;修改JSON数据 示例4&#xff1a;合并JSON对象 4. 总结 在现代软件开发中&#xff0c;JSON&…...

通义万相 2.1 + 蓝耘算力,AI 视频生成的梦幻组合

在这个科技日新月异的时代&#xff0c;人工智能不断刷新着我们对世界的认知。一次偶然的机会&#xff0c;我借助北京蓝耘科技股份有限公司提供的算力支持&#xff0c;踏上了使用通义万相 2.1 进行 AI 视频生成的奇妙之旅。 目录 1.1初遇蓝耘科技&#xff1a; 1.2通义万相 2.1…...

汽车一键启动按钮更换注意事项

汽车一键启动开关更换教程 一键启动开关是现代汽车中常见的便捷配置&#xff0c;但随着时间的推移&#xff0c;这个部件可能会出现失灵的情况。当一键启动开关发生故障时&#xff0c;许多车主选择自行更换。以下是整理的一键启动开关更换教程&#xff1a; 更换前的准备 选择匹…...

AI系统架构

在AI系统架构中&#xff0c;通常可以分为基础设施层、模型层和应用层。它们分别对应不同的技术和应用场景&#xff0c;具体如下&#xff1a; 1. 基础设施层&#xff08;Infrastructure Layer&#xff09; 这是AI系统的底层支持&#xff0c;主要涉及计算资源、存储、网络等基础…...

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_01基础固定表头示例

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_01基础固定表头…...

spring boot3.4.3+MybatisPlus3.5.5+swagger-ui2.7.0

使用 MyBatis-Plus 操作 books 表。我们将实现以下功能&#xff1a; 创建实体类 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中 添加公共/通用 方法/函数

一&#xff0c;现在app 下面创建Common目录&#xff0c;然后在创建Common.php 文件 二&#xff0c;修改composer.json文件 添加这个到autoload 中 "files": ["app/Common/Common.php"]"autoload": {"psr-4": {"App\\": &quo…...

在vs中无法用QtDesigner打开ui文件的解决方法

解决方法 右键ui文件&#xff0c;选择打开方式&#xff0c;弹出如下界面。 点击添加&#xff0c;弹出如下界面 点击程序后边的三个点&#xff0c;去电脑查找designer.exe,我的位置为D:\Qt\Qt5.9.9\5.9.9\msvc2015_64\bin\designer.exe。 名称可以自己起一个名字&#xff0c…...

springboot 文件下载

在springboot中&#xff0c;执行如下代码实现文件下载 GetMapping("/file/download/test")public void Download(HttpServletResponse response){try {String path "XXXXXXXXXXXX";//文件路径File file new File(path);// 读到流中InputStream inputStre…...

Nest.js全栈开发终极实践:TypeORM+微服务+Docker构建高可用企业级应用

文章目录 **第一部分&#xff1a;认识Nest.js与基础环境搭建****1.1 什么是Nest.js&#xff1f;****1.2 环境准备****1.3 创建第一个项目****1.4 启动开发服务器****1.5 核心文件解读** **第二部分&#xff1a;基础控制器与路由****2.1 控制器的作用****2.2 创建自定义控制器**…...

Go语言集成DeepSeek API和GoFly框架文本编辑器实现流式输出和对话(GoFly快速开发框架)

说明 本文是GoFly快速开发框架集成Go语言调用 DeepSeek API 插件&#xff0c;实现流式输出和对话功能。为了方便实现更多业务功能我们在Go服务端调用AI即DeepSeek接口&#xff0c;处理好业务后再用Gin框架实现流失流式输出到前端&#xff0c;前端使用fetch请求接收到流式的mar…...

Hexo博客Icarus主题不蒜子 UV、PV 统计数据初始化配置

文章首发于 不蒜子 UV、PV 统计数据初始化配置 适用场景 如果你有个运行的网站域名&#xff0c;采用了不蒜子统计 UV、PV等访客和阅读数据&#xff0c;但是有一天&#xff0c;你觉得想要换一个新的域名。当你将网站绑定到新的域名后&#xff0c;突然发现&#xff0c;所有的文章…...

在资源有限中逆势突围:从抗战智谋到寒门高考的破局智慧

目录 引言 一、历史中的非对称作战&#xff1a;从李牧到八路军的智谋传承 李牧戍边&#xff1a;古代军事博弈中的资源重构 八路军的游击战&#xff1a;现代战争中的智慧延续 二、创业界的逆袭之道&#xff1a;小米与拼多多的资源重构 从MVP到杠杆解 社交裂变与资源错配 …...

SQLAlchemy系列教程:如何执行原生SQL

Python中的数据库交互提供了高级API。但是&#xff0c;有时您可能需要执行原始SQL以提高效率或利用数据库特定的特性。本指南介绍在SQLAlchemy框架内执行原始SQL。 在SQLAlchemy中执行原生SQL SQLAlchemy虽然以其对象-关系映射&#xff08;ORM&#xff09;功能而闻名&#xff…...

绪论数据结构基本概念(刷题笔记)

&#xff08;一&#xff09;单选题 1.与数据元素本身的形式、相对位置和个数无关的是&#xff08;B&#xff09;【广东工业大学2019年829数据结构】 A.数据存储结构 B.数据逻辑结构 C.算法 D.操作 2.在数据结构的讨论中把数据结构从逻辑上分为&#xff08;C&#xff09;【中国…...

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 状态码有哪些&#xff1f; HTTP 状态码用于指示服务器对客户端请求的响应结果&#xff0c;常见的 HTTP 状态码可以分为以下几类&#xff1a; 1. 信息类&#xff08;1xx&#xff09; 100 Continue&#xff1a;客户端应继续发送请求。101 Switching Protocols&…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...