news 2026/10/16 10:33:46

Docker Compose部署SpringBoot+MySQL前后端分离系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Docker Compose部署SpringBoot+MySQL前后端分离系统

我先把这套系统放到一台全新的 Ubuntu 服务器上跑通了一遍,过程比预想的曲折,但最后用 Docker Compose 一键拉起的那一刻,整个前后端分离物业管理系统从数据库到静态页面全部就绪。这篇把整个部署过程掰开揉碎,从环境准备、项目改造、镜像构建到编排上线,按我实际踩过的顺序来写。

1. 从整体架构看清楚要部署什么

1.1 一套典型的 SpringBoot + Layuimini + MySQL 系统长什么样

先别急着敲命令,得先搞清楚这套物业管理系统内部是怎么组织的。它其实是一个标准的"前后端分离"架构:

  • 后端是 SpringBoot 应用,对外暴露的是一组 RESTful API,比如业主信息管理、物业费账单、报修工单、车位管理、公告发布等模块,数据全部落到 MySQL。
  • 前端是 Layuimini。它本身是一个基于 Layui 的轻量后台管理模板,典型的特征是左侧菜单 + 右侧页面的布局方式,菜单导航、Tab 切换这些管理后台的基础交互都已经封装好了,开发的业务页面通过 layui 的模块化机制去加载。
  • 数据层由 MySQL 承担。整个系统最核心的数据,比如房产档案、业主台账、收费记录,都存储在 MySQL 里。

三者在独立环境里各自跑是一回事,"拎到一台服务器上协同工作"又是另一回事。前端页面要能请求到后端 API,后端要能连上数据库,三者之间的网络链路、配置文件、端口关系都必须提前设计好。

1.2 为什么这套项目特别适合用 Docker 来部署

如果不用 Docker,传统部署流程大概是:服务器上手动装 JDK、装 MySQL、装 Nginx,然后把 jar 包丢进去启动,把前端静态文件拷到 Nginx 目录。问题在于:

  • 环境不一致:开发机上是 JDK 8,服务器上是 JDK 11,多字节码版本直接启动失败。
  • 依赖残留:以前装过别的项目的 MySQL,端口冲突、配置残留,排查起来极其痛苦。
  • 回滚困难:改了几行代码重新部署,结果把服务器环境搞乱了,想回退到上一个版本基本靠重装。

Docker 的思路是"把环境和应用打包成一个标准化的容器镜像"。开发的时候保证镜像里的环境跟本地一致,部署的时候不管服务器底层的系统是什么样,只要跑 Docker,镜像里的应用就是同一个运行环境。尤其是物业管理系统这种典型的"SpringBoot + 静态前端 + MySQL"三件套,天然适合用容器编排来管理。

2. 部署前的准备工作:服务器、项目、环境逐个到位

2.1 Ubuntu 服务器上安装 Docker 与环境初始化

我在一台 Ubuntu 20.04 的服务器上操作,系统版本不同命令会有微小差异,但思路完全相同。安装 Docker 本身不复杂,注意几个环节:

# 更新系统包索引 sudo apt update # 安装 Docker 依赖 sudo apt install -y apt-transport-https ca-certificates curl # 安装 docker-ce、docker-compose-plugin sudo apt install -y docker.io docker-compose-plugin # 启动并设置开机自启 sudo systemctl enable docker sudo systemctl start docker

这里有一个我建议你一开始就做的动作:给当前用户加入 docker 组,否则每次执行 docker 命令都要加 sudo,长期操作无比痛:

sudo usermod -aG docker $USER newgrp docker

之后需要配置 Docker 的 registry mirror。不配置的话,拉取 MySQL、Nginx 这类公共镜像时可能很慢,尤其在一些网络环境下会频繁超时。在/etc/docker/daemon.json中写入:

{ "registry-mirrors": ["https://docker.mirrors.example.com"] }

具体用哪个 mirror 地址,要根据你服务器的实际网络环境来选择,没有统一答案。改完重启 Docker:

sudo systemctl restart docker

这一步属于"不配置也能用,但配置了体验天差地别"的操作。实测在未配置 mirror 的情况下拉一个 MySQL 镜像可能要分多次才成功,配置之后一次性完成。

2.2 后端项目的配置改造与打包

SpringBoot 项目开发时,application-dev.yml里的数据库地址通常是localhost:3306。但部署到 Docker 容器后,后端容器跟 MySQL 容器是分开的两个容器,localhost 指向的是容器自己,根本连不到数据库。

所以需要为生产环境单独准备一份配置。我个人的做法是新增一个application-prod.yml:

server: port: 8080 spring: datasource: url: jdbc:mysql://mysql-container:3306/property_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: Root@123456 driver-class-name: com.mysql.cj.jdbc.Driver logging: file: name: /logs/property-system.log

这里的mysql-container是后面要创建的 MySQL 容器名。在 Docker 自定义网络中,容器之间可以通过容器名互相访问,这是容器通信的关键机制。

配置激活方式:

java -jar property-system.jar --spring.profiles.active=prod

或者通过环境变量SPRING_PROFILES_ACTIVE=prod传入。

然后进行 Maven 打包:

mvn clean package -DskipTests

打包完成后,确认target目录下生成了可执行的 jar 包。这里要注意:确保容器里运行的是打出来的 jar,而不是依赖 IDE 启动。

2.3 前端 Layuimini 项目的构建产物

Layuimini 是基于 Layui 的后台模板,多数项目的组织形式是 HTML + JS + CSS 的静态资源,没有复杂的 Webpack 构建流程。所谓"打包",就是把整个前端工程目录整理好,确保index.html、page、lib、assets等目录结构完整。

如果你拿到的项目需要编译,通常是 npm 管理:

npm install npm run build

构建完成后,dist/目录里就是纯静态文件。把dist目录拷贝到服务器上,后面直接挂载给 Nginx 容器即可。

这里有 一个很多人会忽略的细节:Layuimini 的前端页面内部请求后端 API 时,通常会定义一个全局变量,比如站点的 base URL。这个地址如果写死成http://localhost:8080,部署到生产环境后浏览器会直接请求用户本机的 8080 端口,属于典型的低级事故。需要在前端代码里找一下config.js或类似的配置文件,把 API 地址改成"与页面同源的相对路径",比如/api,这样后续通过 Nginx 反向代理就能解决跨域和地址问题。

3. 先跑数据层:MySQL 容器部署与初始化

3.1 创建目录结构与数据卷

部署之前,我在服务器上规划了一个清晰的目录结构,避免文件乱扔,后面排查问题时能快速定位:

mkdir -p /opt/property-system cd /opt/property-system mkdir -p mysql/{data,init} mkdir -p backend mkdir -p frontend
  • mysql/data:MySQL 数据目录的宿主机映射,容器删了数据还在。
  • mysql/init:初始化 SQL 脚本,容器首次启动时自动执行。
  • backend:后端 jar 包和 Dockerfile。
  • frontend:前端静态资源。

把项目的property_db.sql放到mysql/init目录下。这个 SQL 文件里应该包含建库建表语句以及初始数据(比如管理员账号、基础字典数据)。

3.2 启动 MySQL 容器并验证初始化

MySQL 官方镜像有一个很实用的机制:容器首次启动时,会自动执行/docker-entrypoint-initdb.d/目录下的.sql文件。这意味着你不需要手动进容器执行 SQL,只要把初始化脚本挂载进去,首次启动就能自动完成建库。

启动命令:

docker run -d \ --name mysql-container \ --restart always \ -p 3306:3306 \ -e TZ=Asia/Shanghai \ -e MYSQL_ROOT_PASSWORD=Root@123456 \ -e MYSQL_DATABASE=property_db \ -v /opt/property-system/mysql/data:/var/lib/mysql \ -v /opt/property-system/mysql/init:/docker-entrypoint-initdb.d \ mysql:5.7 \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_general_ci

关键点逐一说明:

  • --restart always:容器意外退出或服务器重启后自动拉起,生产环境必须配置。
  • -e TZ=Asia/Shanghai:设置容器时区,不设置的话 MySQL 默认 UTC 时间,日志时间和国内时间相差 8 个小时,排查问题时候会很别扭。
  • --character-set-server=utf8mb4:字符集必须和初始化 SQL 文件里的表结构保持一致,否则容易出现中文乱码。
  • MYSQL_DATABASE=property_db:会自动创建一个空库。但如果初始化 SQL 里已经有CREATE DATABASE语句,后面的执行会受到影响。我自己更倾向于初始化 SQL 中只包含表结构和数据,不包含建库语句,交给环境变量来处理。

验证初始化是否完成:

# 查看启动日志 docker logs -f mysql-container # 进入容器检查表结构 docker exec -it mysql-container mysql -uroot -pRoot@123456

在 MySQL 命令行里执行USE property_db; SHOW TABLES;,能正常列出表就代表初始化成功。

3.3 数据持久化的坑:为什么必须挂载数据目录

MySQL 容器如果不挂载数据目录,容器删除后数据就全没了。这听起来像废话,但实际操作中真的很常见——有人为了升级镜像版本,直接删了老容器重建,结果业主数据、缴费记录全部丢失。

即使挂载了数据目录,也要注意:如果 MySQL 数据目录里已经有了初始化数据,再次挂载新的initSQL 目录时,/docker-entrypoint-initdb.d下的脚本不会重复执行。因为镜像的初始化逻辑只在数据目录为空的情况下运行。所以,初始化 SQL 的执行时机是第一次启动且 data 目录为空时,之后想要改表结构,需要手动进容器执行脚本,或者专门跑一个一次性容器。

4. 后端上线:SpringBoot 容器化全流程

4.1 编写多阶段构建 Dockerfile

后端项目最经典的方案是用多阶段构建:第一阶段用 Maven 镜像完成编译打包,第二阶段用 JRE 镜像作为运行环境。这样做的好处是最终镜像体积小,不包含 Maven、JDK 等构建期工具。

在backend目录下创建Dockerfile:

FROM maven:3.8-openjdk-8 AS builder WORKDIR /build COPY pom.xml . COPY src ./src RUN mvn clean package -DskipTests FROM openjdk:8-jre-alpine WORKDIR /app COPY --from=builder /build/target/property-system.jar /app/app.jar ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone EXPOSE 8080 ENTRYPOINT ["java", "-jar", "/app/app.jar", "--spring.profiles.active=prod"]

注意几个细节:

  • Java 版本必须和项目保持一致。项目基于 JDK 8,就用 openjdk 8;如果是较新的 SpringBoot 3.x,JDK 版本至少 17,镜像要换成eclipse-temurin:17-jre。
  • 时区在镜像构建时就写入,避免在启动命令里再处理。
  • ENTRYPOINT里直接激活prod配置,不需要额外传参,减少部署时的手动操作。

4.2 构建后端镜像并配置网络

先把 jar 包和相关文件拷贝到服务器/opt/property-system/backend目录,然后构建镜像:

cd /opt/property-system/backend docker build -t property-backend:1.0 .

构建完成之后,先创建一个自定义网络,让容器之间可以通过容器名互相访问:

docker network create property-net

然后启动后端容器:

docker run -d \ --name backend-container \ --restart always \ --network property-net \ -p 8080:8080 \ -v /opt/property-system/logs:/logs \ -e SPRING_PROFILES_ACTIVE=prod \ property-backend:1.0

这里最重要的一行是--network property-net。有了这个自定义网络,容器之间不依赖 IP 地址,直接用容器名就能解析,比如后端容器里访问mysql-container:3306。如果不用同一个网络,后端容器是连不到 MySQL 的。

日志挂载是另一个必要操作:-v /opt/property-system/logs:/logs。SpringBoot 日志文件路径在application-prod.yml中配置为/logs/property-system.log,这个目录被挂载到宿主机,日志不会因为容器重建而丢失,排查问题时也方便直接tail -f宿主机上的日志。

验证后端是否启动了:

docker logs -f backend-container

出现 "Started Application in x.xxx seconds" 就代表启动成功。如果日志里报UnknownHostException: mysql-container,说明网络没接对;如果是Connection refused,大概率是 MySQL 还没初始化完成。

4.3 后端容器的启动顺序问题

一个很常见的现象:后端容器启动时 MySQL 还没就绪,SpringBoot 的数据源初始化直接失败,整个应用启动报错退出。

解决这个问题有几个思路:

  • 在应用层面配置连接重试:SpringBoot 默认数据源初始化失败就抛异常,可以引入连接重试机制。
  • 在容器层面让后端晚点启动:这种方式依赖于脚本化,不够优雅。
  • 用 docker-compose 的 healthcheck + depends_on:等 MySQL 健康后再启动后端,这才是比较规范的方案。

我实际采用的方式是 docker-compose 中的健康检查机制,在后面的编排部分会详细展开。

5. 前端接入:Layuimini 静态资源 + Nginx 容器

5.1 编写 Nginx 配置

前端容器用的是 Nginx,它承担两个任务:一是托管 Layuimini 静态资源,二是把/api请求反向代理到后端容器。

在frontend目录下创建nginx.conf:

server { listen 80; server_name _; root /usr/share/nginx/html; index index.html; # 处理 Layuimini 的静态资源 location / { try_files $uri $uri/ /index.html; } # API 反向代理到 SpringBoot location /api/ { proxy_pass http://backend-container:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }

解释两个关键配置:

  • try_files $uri $uri/ /index.html;:如果请求的路径在静态目录中找不到对应文件,就回退到index.html。这对 Layuimini 这类多页面应用很管用,刷新子页面时不会返回 404。
  • location /api/配合proxy_pass http://backend-container:8080/;:这里的/很关键,它在转发时会把/api前缀去掉。比如浏览器请求/api/owner/list,Nginx 转发给后端的是/owner/list。所以后端 Controller 的 RequestMapping 不需要带/api前缀。如果你想保留/api/前缀,proxy_pass就不要加末尾的/。

另外,Layuimini 前端页面如果请求的是/api/...相对路径,浏览器访问的是http://服务器IP/api/...,同源情况下不存在跨域问题。如果开发阶段前端直接请求后端 8080 端口,配置了跨域,部署时通过 Nginx 反向代理之后这些跨域配置就不需要了。

5.2 启动 Nginx 容器

确认前端静态资源已经上传到/opt/property-system/frontend/dist目录,然后启动:

docker run -d \ --name frontend-container \ --restart always \ --network property-net \ -p 80:80 \ -v /opt/property-system/frontend/dist:/usr/share/nginx/html \ -v /opt/property-system/frontend/nginx.conf:/etc/nginx/conf.d/default.conf \ nginx:1.20

端口映射到宿主机 80。如果你的服务器上已经有 Nginx 或其他服务占用了 80 端口,可以先sudo lsof -i:80查一下占用情况,或者把宿主端口改为 8088(-p 8088:80)。

然后验证整个链路:

# 浏览器访问 http://服务器IP/ # 服务器上验证 API 是否可用 curl http://localhost/api/owner/list curl http://localhost/api/login

通过浏览器能看到 Layuimini 的登录页,输入管理员账号能正常进入系统,菜单能展开、列表能加载出来,整套系统就通了。

5.3 前端容器与后端容器协作的网络细节

有一个我在真实项目中踩过的坑:前后端容器都在同一个自定义网络property-net里,但是 Nginx 的proxy_pass第一次配置时我写的是http://127.0.0.1:8080/。结果浏览器请求/api的时候 Nginx 一直返回 502。原因很简单:Nginx 容器内部的 127.0.0.1 指向自己,不是宿主机的 8080 端口,更不是后端的地址。

在 Docker 网络模式下,容器之间要通信,应该使用对方容器的名称作为主机名,也就是http://backend-container:8080/。Docker 内置的 DNS 服务会把容器名解析成对应的容器 IP。

如果确实希望从容器访问宿主机的端口,可以用host.docker.internal这种方式,但这不是跨容器通信的正确姿势。

6. 一键编排:用 docker-compose 替代手动命令

6.1 手动执行 docker run 的问题

前面几步我都是手动执行 docker run,每一步之间需要记住容器名、网络、挂载参数,整体操作非常琐碎。而且有一个前面提到的问题——后端容器和 MySQL 容器的启动顺序没有保证,后端很容易在 MySQL 还没就绪时启动。

docker-compose 把三个容器的定义写在一个 YAML 文件里,一条命令完成创建、启动、网络配置。它还支持健康检查,可以在 MySQL 真正可用之后再启动后端。

6.2 编写 docker-compose.yml

在/opt/property-system下创建docker-compose.yml:

version: "3.8" services: mysql: image: mysql:5.7 container_name: mysql-container restart: always environment: TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: Root@123456 MYSQL_DATABASE: property_db volumes: - ./mysql/data:/var/lib/mysql - ./mysql/init:/docker-entrypoint-initdb.d ports: - "3306:3306" healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-pRoot@123456"] interval: 10s timeout: 5s retries: 5 start_period: 30s backend: build: ./backend container_name: backend-container restart: always depends_on: mysql: condition: service_healthy environment: TZ: Asia/Shanghai SPRING_PROFILES_ACTIVE: prod volumes: - ./logs:/logs ports: - "8080:8080" frontend: image: nginx:1.20 container_name: frontend-container restart: always depends_on: - backend volumes: - ./frontend/dist:/usr/share/nginx/html - ./frontend/nginx.conf:/etc/nginx/conf.d/default.conf ports: - "80:80"

几个编排要点:

  • healthcheck段是解决启动顺序的关键。MySQL 容器启动后,mysqladmin ping能通了就表示可用了,此时才开始启动后端,基本能避免数据库连接失败的报错。
  • depends_on配合condition: service_healthy表示依赖服务必须健康可用,这是新版 docker-compose 的写法,旧版本可能不支持condition,需要docker compose插件。
  • 网络不需要手动创建。compose 会为这个项目自动创建一个默认网络,所有 service 都加入其中,容器名就是服务名对应的主机名。
  • build: ./backend表示后端镜像如果本地不存在,会按照./backend/Dockerfile自动构建。

6.3 启动、查看状态与日常运维

启动整个系统:

cd /opt/property-system docker compose up -d

查看容器运行状态:

docker compose ps

如果后端启动还是报数据库连接失败,可以看健康检查的细节:

docker inspect --format='{{json .State.Health}}' mysql-container

日常运维常用命令:

# 查看所有容器日志 docker compose logs -f # 只查看后端日志 docker compose logs -f backend # 重启某个服务 docker compose restart backend # 停止全部服务(容器会被删除,数据卷里的数据保留) docker compose down # 停止并删除数据卷(慎用,数据会全没) docker compose down -v

docker compose down不会删除./mysql/data挂载的数据,因为这是 bind mount,不是 compose 管理的数据卷。这其实是个好设计:日常更新版本、重建服务时,数据完全不受影响。

7. 实际部署中的常见问题与排查记录

7.1 问题速查表

现象可能原因排查思路
后端日志报UnknownHostException: mysql-container后端容器和 MySQL 容器不在同一网络docker network inspect property-net检查两个容器是否都在里面
后端日志报Communications link failureMySQL 未就绪或密码错误先docker compose ps看 MySQL 是否 healthy,再确认 MYSQL_ROOT_PASSWORD 与 JDBC 密码一致
浏览器打开页面是空白或 403前端静态资源挂载路径不对确认dist目录完整,docker exec -it frontend-container ls /usr/share/nginx/html查看目录内容
API 请求 502Nginx 代理地址写错检查proxy_pass是http://backend-container:8080而不是 127.0.0.1
API 请求 404代理路径少了一层或后端路由对不上确认location /api/中的proxy_pass末尾是否有/,前后缀被正确处理
中文乱码数据库字符集不是 utf8mb4检查 MySQL 容器启动参数--character-set-server=utf8mb4,以及建表语句是否指定 charset
时区差 8 小时容器时区未设置检查所有 service 的TZ=Asia/Shanghai环境变量
镜像拉取超时未配置 registry mirror修改/etc/docker/daemon.json后重启 Docker

7.2 镜像拉取慢与超时问题

新环境第一次docker compose up要拉 mysql、nginx 等镜像,网络不好时会超时。我建议在部署前先把必要的镜像手动拉一遍,确认拉取成功后,再执行 compose:

docker pull mysql:5.7 docker pull nginx:1.20

如果反复超时,优先改 Docker 镜像源。改完重启之后重新拉取。

7.3 MySQL 容器一直处于 starting 状态

compose 启动后docker compose ps显示 mysql 容器一直 not healthy,大概率是初始化 SQL 文件里有语法错误。找到问题脚本,修正后需要清理数据目录重新初始化:

docker compose down sudo rm -rf mysql/data/* docker compose up -d

因为 MySQL 镜像的初始化脚本只会在数据目录为空时执行一次。如果数据目录里已经有半初始化的数据,脚本不会重新执行,你会一直卡在奇怪的状态。

7.4 前端登录后接口报 404

前面说过,Nginx 配置里location /api/配合proxy_pass http://backend-container:8080/,会把/api前缀去掉。如果后端 Controller 是通过/api/owner/list来定义路由的,这一个/就会导致请求找不到对应接口。

遇到这种情况,把proxy_pass改为http://backend-container:8080(去掉末尾的/),这样 Nginx 会把完整的/api/owner/list转发给后端。到底用哪种,取决于后端路由本身带不带/api前缀。上线前用 curl 测一下实际转发路径最靠谱。

7.5 容器重启后数据还在吗

这个问题在实战中问的人最多。只要数据卷挂载正确,容器删了重建,数据都在。验证方式是看宿主机目录:

ls /opt/property-system/mysql/data

如果这个目录下有文件,说明 MySQL 数据是落盘在宿主机上的。反过来,如果目录是空的,就要检查 compose 文件里是不是漏了volumes配置。

整套流程走下来,最大感受是:所谓 Docker 实战部署,难点通常不在 Docker 命令本身,而在于搞清楚应用之间的依赖关系和配置细节。数据库连接地址什么时候用容器名、Nginx 反代保持还是去掉路径、时区和字符集有没有统一,这些才是真正影响系统能否跑起来的关键。

最后留一个小建议:部署完成后,把docker-compose.yml、nginx.conf、Dockerfile、application-prod.yml这四类核心文件整理进项目仓库的docs/deploy目录。后续任何人接手,只要有一条 Linux 命令和这套文件,五分钟内就能复制出完整环境。这比任何部署文档都可靠。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 10:33:16

硬件设计的本质:系统性工程决策与物理约束闭环

1. 这不是画电路图,而是给机器“定骨骼”和“塑神经”“什么是硬件设计(Hardware Design)?”——这个问题我被问过不下两百次,提问者身份跨度极大:刚进电子系大一的学生、转行做嵌入式开发的程序员、想自研…

作者头像 李华
网站建设 2026/10/16 10:33:10

OpenClaw生产级高可用部署:性能调优与稳定性实战指南

这个系列的读者应该都有体会:OpenClaw在本地或者单机环境跑起来非常简单,装好依赖、配好模型Key、启动服务,一个能帮你查资料、写周报、管日程的AI助理就能用了。但真要让它7x24小时在线,随时响应,不卡死、不丢任务、不…

作者头像 李华
网站建设 2026/10/16 10:32:38

Spring Boot 整合 ElasticSearch 7.6.x 实战:版本选型、环境搭建与性能调优

1. 为什么在 Spring Boot 项目里选 ElasticSearch 7.6.x 而不是别的版本很多人在技术选型时容易陷入一个误区:看到 ElasticSearch 出了新版本就无脑升级,结果项目跑到一半发现客户端不兼容、API 大改、文档对不上。我自己在这个问题上反复折腾过好几轮&a…

作者头像 李华
网站建设 2026/10/16 10:32:37

从零配置Samba:Linux与Windows文件共享实战与排障指南

Samba 这个词,做 Linux 运维的人早晚都会碰上。说白了,它就是让 Linux 服务器和 Windows 电脑之间互相共享文件的那座桥。公司里最常见的场景是这样的:一台服务器跑着 Linux,上面挂着几块大硬盘,人事要传制度文件、开发…

作者头像 李华
网站建设 2026/10/16 10:30:50

Flink HDFS Sink exactly-once 原理与四阶段文件生命周期解析

1. 这不是“开个开关”就能搞定的事:Flink HDFS Sink 的 exactly-once 本质是状态协同问题很多人第一次看到“Flink HDFS Sink 支持 exactly-once”这句话时,下意识反应是:哦,那我只要把enableCheckpointing打开、setSemantic(Exa…

作者头像 李华
网站建设 2026/10/16 10:29:16

SolarWinds NPM 12.0.1部署实战:从SNMP轮询到告警报表的监控体系构建

简介:SolarWinds网络性能监视器(NPM)12.0.1 / Orion Package 12.1是网络运维领域常用的监控工具,面向网络管理员与IT运维人员,用于统一采集路由器、交换机、服务器等设备的运行数据,包括CPU利用率、内存占用…

作者头像 李华