Docker实战:图床后端部署微服务

蒸汽
蒸汽
发布于 2025-02-15 / 31 阅读
0
0

Docker实战:图床后端部署微服务

本文搭建的docker==镜像==和前后端==源码==可私信我哦^^

1.概述

本文基于 《图床共享云存储》进行部署上的改进,如需了解项目请先阅读本站的《图床单机搭建》与《图床项目详解》文章^^

之前的图床采用单机架构,本文带来用docker容器+微服务的方式部署该项目,为项目增加亮点

拓展:

  • docker

  • k8s

优势: 为什么要用docker+微服务?

  • 解耦合,方便调整与拓展开发单个模块

  • 避免了一个模块崩溃而整个项目崩溃,例如文件系统崩溃了导致整个图床项目不可访问

  • 方便拓展与管理(例如添加storage增加容灾备份节点)

2.项目架构

本文将项目解耦为三个微服务,分别是:

  • fastdfs+nginx

  • http-server + redis

  • mysql

3.部署步骤

3.1镜像构建方式

一般docker镜像的构建有三种方式可选:

  • Dockerfile 通过编写dockerfile文件的方式,一键启动构建后等待构建完成即可 优势:中间过程省事,不需要处理 缺点:在项目环境搭建复杂的情况下不好编写dockerfile文件,复杂

  • commit方式 通过搭建一个基础容器,在容器中搭建好环境后再commit成一个新镜像 优势:过程完全可见 劣势:需要自己搭建,过程较繁琐

  • 原生搭建+copy方式 当搭建基础容器时(比如ubuntu容器),可能出现项目编译需要内核支持的情况,但是拉取构建的ubuntu镜像是精简版的内核,没法支持编译(笔者在之前搭建dpdk环境的时候无法通过基础ubuntu容器编译dpdk,采用的是宿主机编译好后采用docker cp的方式,具体参见本站博客《docker 基础命令详解》)

3.2容器搭建流程

  • docker-compose docker-compose是xxxxx。

version: '3.8'

services:
  tc_mysql:
    image: tc_mysql:v1.0
    container_name: tc_mysql
    # networks:
    #   my_net:
    #     ipv4_address: 172.17.0.2
    restart: unless-stopped
    ports:
      - "3306:3306"
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 3s
      retries: 5

  fastdfs_nginx:
    image: tc_fastdfs_nginx:v2
    container_name: tc_fastdfs_nginx
    # networks:
    #   my_net:
    #     ipv4_address: 172.17.0.3
    restart: unless-stopped
    ports:
      - "8080:80"
      - "443:443"
    command: /usr/local/bin/init_fastdfs.sh  # 关键修改:直接调用脚本
    volumes:
      # 挂载脚本(如果镜像中没有内置)
      - ./init_fastdfs.sh:/usr/local/bin/init_fastdfs.sh:ro
      - ./tmp:/root
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/"]
      interval: 10s
      timeout: 3s
      retries: 3

  tc_server:
    image: tc_server:v1.1
    container_name: tc_server
    restart: unless-stopped
    ports:
      - "8081:8080"
    command: /usr/local/bin/init_server.sh  # 修改启动命令
    volumes:
      - ./init_server.sh:/usr/local/bin/init_server.sh:ro
      - ./tmp:/root
    depends_on:
      tc_mysql:
        condition: service_healthy
      fastdfs_nginx:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8081/"]
      interval: 10s
      timeout: 3s
      retries: 3

# networks:
#   my_net:
#     driver: bridge
#     ipam:
#       config:
#         - subnet: 172.17.0.0/24

# # 将配置文件挂载到容器外
# volumes:
#   - ./configs/tc_http_server.conf:/tc/tc-src/buile_new/tc_http_server.conf:ro

# # 增强健康检查
#   tc_mysql:
#     healthcheck:
#       test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
#       interval: 5s
#       timeout: 3s
#       retries: 5

#   fastdfs_nginx:
#     healthcheck:
#       test: ["CMD", "curl", "-f", "http://localhost/health"]
#       interval: 10s
#       timeout: 3s
#       retries: 3

#   tc_server:
#     depends_on:
#       tc_mysql:
#         condition: service_healthy
#       fastdfs_nginx:
#         condition: service_healthy
#!/bin/bash
# 自动替换 FastDFS 配置文件中 tracker_server 的 IP

# 获取本容器在 Docker 网络中的 IP(推荐两种方式任选其一)
# 方式1:通过 hostname 获取(适用于大多数情况)
CONTAINER_IP=$(hostname -i | awk '{print $1}')

# 方式2:通过 eth0 接口获取(更精确)
# CONTAINER_IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')

# ---------- 获取 tc_server 容器的实际IP ----------
# 通过 Docker DNS 解析服务名(关键改动)
TC_SERVER_IP=$(getent hosts tc_server | awk '{print $1}')

# 配置文件路径
CONF_FILE="/etc/fdfs/mod_fastdfs.conf"

# 配置文件storage.conf路径
STORAGE_CONF_FILE="/etc/fdfs/storage.conf"

# 配置文件nginx.conf路径
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"

# 执行替换操作(保留原端口号)
sed -i "s/^tracker_server=.*:\([0-9]\+\)$/tracker_server=${CONTAINER_IP}:\1/" "${CONF_FILE}"

# 执行替换操作(保留原端口号)
sed -i "s/^tracker_server =.*:\([0-9]\+\)$/tracker_server=${CONTAINER_IP}:\1/" "${STORAGE_CONF_FILE}"

# ---------- Nginx 配置替换(关键新增部分)----------
# 替换所有 proxy_pass 中的 tc_server 为实际IP(保留端口号)
sed -i "s/\btc_server\b/${TC_SERVER_IP}/g" "${NGINX_CONF_FILE}"


# 验证修改结果
echo "修改后的 tracker_server 配置:"
grep "^tracker_server" "${CONF_FILE}"

echo -e "\n==== Nginx 代理后端IP ===="
grep "proxy_pass" "${NGINX_CONF_FILE}"

# 启动Tracker服务
/etc/init.d/fdfs_trackerd start

# 启动Storage服务
/etc/init.d/fdfs_storaged start

# 启动Nginx(必须前台运行)
/usr/local/nginx/sbin/nginx -g "daemon off;"

# 保持容器运行(备用命令)
# tail -f /dev/null
#!/bin/bash
# 自动替换配置文件中的动态IP

# 获取本容器IP
CONTAINER_IP=$(hostname -i | awk '{print $1}')

# 获取其他服务的IP(Docker DNS解析)
MYSQL_IP=$(getent hosts tc_mysql | awk '{print $1}')
FASTDFS_IP=$(getent hosts fastdfs_nginx | awk '{print $1}')

# 配置文件路径
CONFIG_FILE="/tc/tc-src/buile_new/tc_http_server.conf"

#build文件夹路径
BUILD_PATH="/tc/tc-src/buile_new"

# 执行替换操作
sed -i \
  -e "s/^web_server_ip=.*/web_server_ip=${CONTAINER_IP}/" \
  -e "s/^storage_web_server_ip=.*/storage_web_server_ip=${FASTDFS_IP}/" \
  -e "s/^tuchuang_master_host=.*/tuchuang_master_host=${MYSQL_IP}/" \
  -e "s/^tuchuang_slave_host=.*/tuchuang_slave_host=${MYSQL_IP}/" \
  "${CONFIG_FILE}"

# 启动redis服务
redis-server &

cd /tc/tc-src/buile_new/
# 启动tc_http_server
./tc_http_server -g "daemon off;"

# 验证修改
echo "==== 修改后的关键配置 ===="
grep -E "web_server_ip|storage_web_server_ip|tuchuang_.*_host" "${CONFIG_FILE}"
  • fastdfs 本项目fastdfs构建复杂,涉及多个conf文件,nginx搭建,nginx重编译,过程复杂,笔者希望过程可见,采用commit方式,在一个基础ubuntu镜像中搭建。

fastdfs+nginx容器构建命令

mkdir -p /tmp
docker run -it -p 8080:80 -v /tmp:/root --name myfastdfs_nginx <镜像id> /bin/bash
#注意:一定要修改端口映射,否则将会导致nginx与宿主机80端口冲突!
#注意:一定要挂载volume,因为分布式场景下源码有bug,需要fastdfs与http_server挂载共同的/root/tmp目录

进入容器后,修改mod_fastdfs.conf中的tracker_server ip, storage.conf 中的tracker_server ip,

​
ifconfig #查看容器ip
docker inspect <容器id> | grep IPAddress #宿主机查看容器ip

修改storage.conf中的tracker_ip
修改mod_fastdfs.conf中的tracker_ip
修改nginx.conf中的路由的主机地址

/etc/init.d/fdfs_trackerd start
/etc/init.d/fdfs_storaged start
./usr/local/nginx/sbin/nginx
  • redis redis模块单一,在本项目中没有改动,直接dockerfile处理即可,或者拉取对应版本的镜像 redis可以直接放在back-end container中也可以

redis-server & #后台运行redis-server
  • mysql

FROM mysql:8.0
​
# 设置 root 用户的密码
ENV MYSQL_ROOT_PASSWORD=123456
ENV MYSQL_DATABASE=0voice_tuchuang
ENV MYSQL_USER=qhr
ENV MYSQL_PASSWORD=123456
​
# 复制数据库初始化 SQL 文件
COPY 0voice_tuchuang.sql /docker-entrypoint-initdb.d/
​
EXPOSE 3306
#启动容器
docker run -d --name tc-mysql -e MYSQL_ROOT_PASSWORD=yourpasswd -p 3306:3306 mysql:v1.0
​
#连接测试
mysql -h 127.0.0.1 -P 3306 -u root -p
  • http_server 采用docker cp的方式,在编译好项目后导入基础镜像中

docker run -it -v tmp:/root --name tc-server <镜像id> /bin/bash
cd /tc/tc-src/build/

vim tc_http_conf #修改内容如下

web_server_ip
mysql_ip
storage_web_ip
client_path
  • 安装fastdfs及相关依赖

  • 安装mysql相关依赖

  • 编译

  • 修改tc_http_conf

    • web_server_ip

    • mysql_ip

    • storage_web_ip

    • client_path

  • 修改/etc/fdfs/client.conf(貌似不需要了)

后续: 后续将优化为==k3s==编排多种容器


评论