Docker学习路径——6、简单微服务

Docker 微服务基础实战:Tomcat + MySQL + Redis 一站式部署指南

在微服务架构中,应用通常由多个独立服务组成(如 Web 服务器、数据库、缓存)。Docker 让这些组件的部署变得前所未有的简单。本文将手把手教你用 Docker 快速搭建 Tomcat(Web 服务) 三大核心组件,并解决常见配置陷阱,为构建完整微服务系统打下基础。

环境要求

  • 已安装 Docker(参考前文《Docker 安装与核心架构详解》)
  • 开放端口:8080(Tomcat)、3306(MySQL)、6379(Redis)

一、部署 Tomcat:Web 服务基石

问题背景:新版 Tomcat 镜像的"404 陷阱"

官方 tomcat 镜像(Tomcat 10+)默认不包含示例应用,直接访问会返回 404:

原因

为减小镜像体积,官方将 webapps 目录重命名为 webapps.dist,需手动恢复。

方案 1:手动修复官方镜像(推荐学习原理)

步骤 1:启动容器
bash 复制代码
docker run -d -p 8080:8080 --name tomcat10 tomcat
步骤 2:进入容器修复目录
bash 复制代码
# 进入容器
docker exec -it tomcat10 bash

# 删除空 webapps 目录,恢复示例应用
root@container:/usr/local/tomcat# rm -rf webapps
root@container:/usr/local/tomcat# mv webapps.dist webapps

# 退出容器
exit
步骤 3:验证

浏览器访问 http://<服务器IP>:8080,成功显示 Tomcat 欢迎页!

💡 原理
webapps.dist 包含 ROOTdocsexamples 等标准目录,恢复后即可提供默认页面。


方案 2:使用预配置镜像(生产推荐)

社区维护的镜像已解决此问题,开箱即用:

bash 复制代码
# 拉取并运行预配置镜像
docker run -d -p 8081:8080 \
  --name tomcat8 \
  billygoo/tomcat8-jdk8

# 验证(访问 8081 端口)
curl http://localhost:8081

优势

  • 内置 JDK 8(兼容老项目)
  • 已配置好 webapps
  • 无需手动干预

二、部署 MySQL 5.7:持久化数据库

核心需求

  • 数据持久化:避免容器删除导致数据丢失
  • UTF-8 编码:防止中文乱码
  • 安全密码:设置 root 密码

步骤 1:创建宿主机目录结构

bash 复制代码
mkdir -p /opt/mysql/{data,log,conf}
目录 作用
/opt/mysql/data 存储数据库文件
/opt/mysql/log 存储日志文件
/opt/mysql/conf 存储自定义配置

步骤 2:启动 MySQL 容器

bash 复制代码
docker run -d \
  -p 3306:3306 \
  -v /opt/mysql/log:/var/log/mysql \
  -v /opt/mysql/data:/var/lib/mysql \
  -v /opt/mysql/conf:/etc/mysql/conf.d \
  -e MYSQL_ROOT_PASSWORD=000000 \  # 设置 root 密码
  --name mysql5.7 \
  mysql:5.7

⚠️ 关键参数

  • -e MYSQL_ROOT_PASSWORD:必须设置,否则容器启动失败
  • 三个 -v 挂载:确保数据、日志、配置持久化

步骤 3:配置 UTF-8 编码

创建配置文件
bash 复制代码
cat > /opt/mysql/conf/my.cnf <<EOF
[client]
default_character_set=utf8

[mysqld]
collation_server=utf8_general_ci
character_set_server=utf8
EOF
重启生效
bash 复制代码
docker restart mysql5.7

步骤 4:验证数据库操作

bash 复制代码
# 进入容器
docker exec -it mysql5.7 mysql -uroot -p000000

# 在 MySQL 中执行
mysql> SHOW VARIABLES LIKE 'character%';
-- 确认所有 character_set_* 均为 utf8

mysql> CREATE DATABASE test_db;
mysql> USE test_db;
mysql> CREATE TABLE users(id INT, name VARCHAR(20));
mysql> INSERT INTO users VALUES (1, '张三');
mysql> SELECT * FROM users;
+------+--------+
| id   | name   |
+------+--------+
|    1 | 张三   |
+------+--------+

🔒 安全建议

生产环境应:

  1. 使用强密码(非 000000
  2. 创建专用用户(非 root)
  3. 限制网络访问(-p 127.0.0.1:3306:3306

三、部署 Redis:高性能缓存

核心需求

  • 外部访问 :注释 bind 127.0.0.1
  • 关闭保护模式protected-mode no
  • 持久化:启用 AOF 或 RDB
  • 密码认证requirepass <password>

步骤 1:准备配置文件

bash 复制代码
mkdir -p /opt/redis
cat > /opt/redis/redis.conf <<EOF
# 允许外部连接
# bind 127.0.0.1

# 关闭保护模式
protected-mode no

# 必须为 no(Docker 中以非守护进程运行)
daemonize no

# 启用 AOF 持久化
appendonly yes

# 设置密码
requirepass 000000

# 日志文件(留空或注释,避免权限问题)
logfile ""
EOF

⚠️ 关键配置说明

  • daemonize no:Docker 容器要求前台运行,设为 yes 会导致启动失败
  • logfile "":避免因日志目录权限问题崩溃

步骤 2:启动 Redis 容器

bash 复制代码
docker run -d \
  -p 6379:6379 \
  -v /opt/redis/redis.conf:/etc/redis/redis.conf \
  -v /opt/redis/data:/data \
  --name redistest \
  redis \
  /etc/redis/redis.conf  # 指定配置文件路径

步骤 3:验证 Redis 功能

bash 复制代码
# 进入容器
docker exec -it redistest redis-cli -a 000000

# 执行命令
127.0.0.1:6379> SET user:1:name "李四"
OK
127.0.0.1:6379> GET user:1:name
"李四"
127.0.0.1:6379> PING
PONG

步骤 4:调整数据库数量(可选)

Redis 默认 16 个数据库(0-15),可修改:

bash 复制代码
# 编辑配置文件
echo "databases 10" >> /opt/redis/redis.conf

# 重启生效
docker restart redistest

# 验证
127.0.0.1:6379> SELECT 10
(error) ERR DB index is out of range  # 因只有 0-9

四、微服务互联:容器间通信

场景:Tomcat 应用连接 MySQL 和 Redis

方法 1:使用宿主机 IP(简单但耦合)
  • Tomcat 应用中配置:

    properties 复制代码
    db.url=jdbc:mysql://<宿主机IP>:3306/test_db
    redis.host=<宿主机IP>
方法 2:Docker 自定义网络(推荐!)
bash 复制代码
# 创建自定义网络
docker network create micro-net

# 重新启动服务(加入网络)
docker run -d --network micro-net --name mysql-db mysql:5.7 ...
docker run -d --network micro-net --name redis-cache redis ...
docker run -d --network micro-net --name my-tomcat tomcat ...

# 在 Tomcat 容器内直接通过服务名访问
ping mysql-db  # 解析到 MySQL 容器 IP
ping redis-cache  # 解析到 Redis 容器 IP

优势

  • 服务发现自动完成(无需硬编码 IP)
  • 网络隔离(仅 micro-net 内容器可互访)
  • 更安全(默认 bridge 网络所有容器互通)

五、常见问题排查

Q1:Tomcat 启动后无法访问?

  • 检查 :是否修复了 webapps 目录?
  • 验证docker exec tomcat10 ls /usr/local/tomcat/webapps

Q2:MySQL 容器启动失败?

  • 查看日志docker logs mysql5.7
  • 常见原因
    • 未设置 MYSQL_ROOT_PASSWORD
    • 挂载目录权限不足(chown -R 999:999 /opt/mysql

Q3:Redis 连接被拒绝?

  • 检查配置
    • bind 是否注释?
    • protected-mode 是否为 no
  • 验证端口telnet <IP> 6379

六、总结与下一步

组件 关键操作 持久化方案
Tomcat 修复 webapps 或用预配置镜像 无(应用代码应外置)
MySQL 挂载 data/log/conf 目录 Bind Mounts
Redis 自定义 redis.conf Bind Mounts + AOF

🚀 后续学习路径

  1. 编写 Dockerfile:将应用打包为镜像
  2. 使用 docker-compose:一键编排三大服务
  3. 配置 Nginx 反向代理:统一入口
  4. 集成 Spring Boot:开发真实微服务应用

通过本文,你已掌握 Docker 微服务基础组件的部署能力。现在,你可以开始构建自己的云原生应用了!

相关推荐
湖城彭于晏2 小时前
VMware Ubuntu 固定IP + 上网 + 远程访问 完整教程
linux·ubuntu·vmware
一路向北North2 小时前
Spring Security OAuth2.0(13):oAuth2.0微服务解析
java·spring·微服务
剪刀石头布Cheers2 小时前
Ubuntu Hermes安装关键步骤
linux·运维·ubuntu·ai·agent·hermes
汽车仪器仪表相关领域2 小时前
Kvaser Leaf Light HS v2 CB:裸卡式CAN接口新标杆,赋能车载与工业集成测试高效升级
服务器·网络·数据库·人工智能·单元测试·自动化·汽车
AI服务老曹2 小时前
解密万物互联:基于 Docker 的 GB28181/RTSP 统一协议网关与 AI 视频平台架构实践
人工智能·docker·音视频
l1t2 小时前
试用支持postgresql wire协议的duckdb服务器duckgres
服务器·数据库·postgresql
雕刻刀2 小时前
pip离线安装
linux·python·pip
JoyCong19982 小时前
告别频繁输入密码!ToDesk自动解锁功能,实现远程办公“无感”连接
大数据·linux·服务器·网络·电脑·远程操作
咚为2 小时前
从Nginx到Pingora?从 Cloudflare 的架构演进讲起
运维·nginx·架构