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: true

services:
  ${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: any
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider http://localhost:23111/actuator/health || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 20s
    volumes:
        - ./${project.build.finalName}.jar:/app/${project.build.finalName}.jar
        - ./lib:/app/lib
    environment:
      - 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:ro
    networks:
      - ${project.artifactId}-stack-proxy-tier
    depends_on:
      - ${project.artifactId}

启动脚本restart

linux

#!/bin/bash

# 设置脚本在遇到错误时立即退出
set -e

init(){
    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}}') ]]; then
        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."
    fi
  deploy
}

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 in
          init) init;;
          restart)  restart;;
          remove)  status;;
              *)  echo "require init|restart|remove";;
esac

windows

@echo off
setlocal enabledelayedexpansion

if "%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"?>
<assembly
	xmlns="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}
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/984535.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

工作记录 2016-12-22

工作记录 2016-12-22 更新的问题 1、修改了Job Summary的Bill Amount的Bug。 2、修改了Account #的宽度。 3、修改了Clearinghouse Status的默认查询的条件。 4、修改了Upload Files的Add File的bug。 5、Pending Pool、Missing Infos加了Write Off&#xff0c;修改了Histor…

QLoggingCategory类使用

QLoggingCategory类使用 QLoggingCategory的概述 QLoggingCategory是Qt的日志策略类&#xff1b;可以通过声明不同的日志策略对象来输出不同的日志信息。打印信息类型如下&#xff1a;宏 Q_DECLARE_LOGGING_CATEGORY(name) 定义一个返回QLoggingCategory对象函数&#xff0c;…

Linux红帽:RHCSA认证知识讲解(五)从红帽和 DNF 软件仓库下载、安装、更新和管理软件包

Linux红帽&#xff1a;RHCSA认证知识讲解&#xff08;五&#xff09;从红帽和 DNF 软件仓库下载、安装、更新和管理软件包 前言一、DNF 软件包管理基础1.1 核心操作命令安装软件包卸载软件包重新安装软件包 1.2 软件仓库原理 二、配置自定义软件仓库步骤 1&#xff1a;清理默认…

Go本地缓存设计与实现

本地缓存是一个项目中很常见的组件。在很多人的眼中就是一个简单的key-value的map存储即可实现&#xff0c;但实际上&#xff0c;设计一个本地缓存需要考虑的问题远比你想象的多&#xff0c;比如说&#xff0c;本地缓存是将数据存储在内存&#xff0c;若数据量激增突破了内存限…

通义万相2.1开源版本地化部署攻略,生成视频再填利器

2025 年 2 月 25 日晚上 11&#xff1a;00 通义万相 2.1 开源发布&#xff0c;前两周太忙没空搞它&#xff0c;这个周末&#xff0c;也来本地化部署一个&#xff0c;体验生成效果如何&#xff0c;总的来说&#xff0c;它在国内文生视频、图生视频的行列处于领先位置&#xff0c…

Jetson Xavier NX安装CUDA加速的OpenCV

我们使用SDKManager刷机完成后&#xff0c;使用jtop查看&#xff0c;发现OpenCV 是不带CUDA加速的&#xff0c;因此&#xff0c;我们需要安装CUDA加速的OpenCV&#xff0c;这样后续在使用的时候速度会快很多。 首先我们先卸载默认OpenCV sudo apt purge libopencv* -y sudo …

基于PaddleNLP使用DeepSeek-R1搭建智能体

基于PaddleNLP使用DeepSeek-R1搭建智能体 最近在学习DeepSeek&#xff0c;找到了PaddleNLP星河社区大模型&#xff0c;跟着敲写了一遍。内容来源&#xff1a;DeepSeek实战训练营&#xff1a;从云端模型部署到应用开发 - 飞桨AI Studio星河社区-人工智能学习与实训社区 本项目基…

给大家推荐8个好玩有趣的网站

1、Home Apothecary 家庭药房 https://apothecary.tips/zh Home Apothecary&#xff08;家庭药房&#xff09;结合传统中医智慧与现代科学验证&#xff0c;提供涵盖睡眠改善、免疫力提升、肠胃调理、活力增强等健康需求的天然养生饮品配方。精选安神助眠、四季调养、舒缓压力…

使用Beanshell前置处理器对Jmeter的请求body进行加密

这里我们用HmacSHA256来进行加密举例&#xff1a; 步骤&#xff1a; 1.先获取请求参数并对请求参数进行处理&#xff08;处理成String类型&#xff09; //处理请求参数的两种方法&#xff1a; //方法一&#xff1a; //获取请求 Arguments args sampler.getArguments(); //转…

利用paddleocr解决图片旋转问题

由于之前使用easyocr识别图片的时候发现旋转的图片或者倒置的图片效果很差&#xff0c;来利用 cv2.minAreaRect()获取旋转角度&#xff0c;只能解决0-90&#xff0c;对于倒置的图片不能很好解决&#xff0c;因此使用paddleocr中方向分类检测&#xff08;只能返回0&#xff0c;1…

数据结构(蓝桥杯常考点)

数据结构 前言&#xff1a;这个是针对于蓝桥杯竞赛常考的数据结构内容&#xff0c;基础算法比如高精度这些会在下期给大家总结 数据结构 竞赛中&#xff0c;时间复杂度不能超过10的7次方&#xff08;1秒&#xff09;到10的8次方&#xff08;2秒&#xff09; 空间限制&#x…

Python 入

Python 入侵交换机 随着网络安全威胁不断增加&#xff0c;对于网络设备的安全防护变得愈发重要。而交换机作为网络中重要的设备之一&#xff0c;也需要加强安全保护。本文将介绍如何利用Python来入侵交换机&#xff0c;并对其进行漏洞扫描和安全检测。 1. Python 入侵交换机原…

自然语言处理:最大期望值算法

介绍 大家好&#xff0c;博主又来给大家分享知识了&#xff0c;今天给大家分享的内容是自然语言处理中的最大期望值算法。那么什么是最大期望值算法呢&#xff1f; 最大期望值算法&#xff0c;英文简称为EM算法&#xff0c;它的核心思想非常巧妙。它把求解模型参数的过程分成…

RAG 常见分块策略全解析:从原理到代码实践(2025 深度版)

大家好,我是大 F,深耕AI算法十余年,互联网大厂技术岗。 知行合一,不写水文,喜欢可关注,分享AI算法干货、技术心得。 更多文章可关注《大模型理论和实战》、《DeepSeek技术解析和实战》,一起探索技术的无限可能! 引言 在检索增强生成(RAG)系统中,分块策略是决定系统…

【软件逆向】QQ 连连看小游戏去广告与一键消除实现

目录 一、背景介绍 二、去广告实现 2.1 分析广告加载流程 2.2 逆向分析广告加载逻辑 2.3 去广告方案 三、一键消除外挂实现 3.1 分析游戏逻辑 3.2 编写外挂插件 3.3 注入外挂&#xff1a; 四、一键消除效果展示 五、额外扩展 一、背景介绍 QQ 连连看是一款经典的休闲…

小白学Agent技术[5](Agent框架)

文章目录 Agent框架Single Agent框架BabyAGIAutoGPTHuggingGPTHuggingGPT工作原理说明GPT-EngineerAppAgentOS-Copilot Multi-Agent框架斯坦福虚拟小镇TaskWeaverMetaGPT微软UFOAgentScope现状 常见Agent项目比较概述技术规格和能力实际应用案例开发体验比较ChatChain模式 Agen…

AI写论文提示词指令大全,快速写论文

目录 一、十大学术写作提示词1、研究主题2、研究问题3、论文架构4、学术论证5、文献关键要素6、专业文本可读性转换7、学术语言规范化8、提高语言准确性9、多维度、深层论证10、优化文本结构 二、快速写论文提示词1、确认研究选题2、整理相关资料3、快速完成论文大纲4、整合文献…

电子电气架构 ---常见车规MCU安全启动方案

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

HCIP第二讲作业

一、连接拓扑图 二、配置要求 1.学校内部的HTTP客户端可以正常通过域名www.baidu.com访问到百度网络中的HTTP服务器 2.学校网络内部网段基于192.168.1.0/24划分&#xff0c;PC1可以正常访问3.3.3.0/24网段&#xff0c;但是PC2不允许 3.学校内部路由使用静态路由&#xff0c;R1…

Linux第六讲:进程控制

Linux第六讲&#xff1a;进程控制 1.进程创建1.1回顾fork1.2写时拷贝 2.进程终止2.1exit与_exit 3.进程等待3.1进程等待的方法&#xff08;wait和waitpid&#xff09; 4.进程程序替换4.1自定义shell的编写4.1.1输出命令行提示符4.1.2获取用户输入的命令4.1.3命令行分析4.1.4指令…