1. 为什么需要Docker Compose部署高可用集群
在传统部署方式中,搭建一个包含MySQL、Tomcat和Nginx的高可用集群通常需要以下步骤:
- 在每台服务器上手动安装配置每个组件
- 编写复杂的启动脚本
- 配置服务间的网络连接
- 设置健康检查和故障转移机制
这个过程不仅耗时耗力,而且容易出错。我曾经在一个项目中手动部署这样的集群,光是调试各服务间的网络连接就花了整整两天时间。
Docker Compose的出现完美解决了这些问题。通过定义YAML文件,我们可以:
- 一次性声明所有服务及其配置
- 自动创建服务间的专用网络
- 方便地扩展服务实例数量
- 实现服务的自动重启和故障转移
提示:Docker Compose特别适合中小型项目的集群部署,对于大型生产环境,建议考虑Kubernetes等更专业的编排工具。
2. 环境准备与Docker Compose安装
2.1 系统要求
- Linux服务器(推荐Ubuntu 20.04+或CentOS 7+)
- Docker Engine 20.10.0+
- 至少4GB内存(MySQL 2GB + Tomcat 1GB + Nginx 512MB)
- 10GB可用磁盘空间
2.2 Docker安装
# Ubuntu示例 sudo apt-get update sudo apt-get install -y docker.io sudo systemctl enable --now docker2.3 Docker Compose安装
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose2.4 验证安装
docker --version docker-compose --version3. 编写docker-compose.yml文件
3.1 基础结构
version: '3.8' services: mysql: # MySQL配置 tomcat: # Tomcat配置 nginx: # Nginx配置 networks: app_net: driver: bridge3.2 MySQL服务配置
mysql: image: mysql:8.0 container_name: mysql_primary environment: MYSQL_ROOT_PASSWORD: securepassword MYSQL_DATABASE: app_db MYSQL_USER: app_user MYSQL_PASSWORD: userpassword volumes: - mysql_data:/var/lib/mysql - ./mysql/conf.d:/etc/mysql/conf.d ports: - "3306:3306" networks: - app_net healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 3 deploy: replicas: 1 restart_policy: condition: on-failure3.3 Tomcat服务配置
tomcat: image: tomcat:9.0 container_name: tomcat_app volumes: - ./webapp:/usr/local/tomcat/webapps/ROOT environment: - CATALINA_OPTS=-Xms512m -Xmx1024m depends_on: mysql: condition: service_healthy networks: - app_net deploy: replicas: 2 restart_policy: condition: on-failure3.4 Nginx服务配置
nginx: image: nginx:1.21 container_name: nginx_lb volumes: - ./nginx/conf.d:/etc/nginx/conf.d - ./nginx/logs:/var/log/nginx ports: - "80:80" - "443:443" depends_on: - tomcat networks: - app_net deploy: restart_policy: condition: on-failure3.5 完整docker-compose.yml示例
version: '3.8' services: mysql: image: mysql:8.0 # ... 上述MySQL配置 tomcat: image: tomcat:9.0 # ... 上述Tomcat配置 nginx: image: nginx:1.21 # ... 上述Nginx配置 volumes: mysql_data: networks: app_net: driver: bridge4. Nginx负载均衡配置
4.1 创建Nginx配置文件
在项目目录下创建nginx/conf.d/default.conf:
upstream tomcat_cluster { server tomcat:8080; } server { listen 80; server_name localhost; location / { proxy_pass http://tomcat_cluster; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }4.2 负载均衡算法选择
Nginx支持多种负载均衡算法:
- 轮询(默认)
- 加权轮询
- IP哈希
- 最少连接
对于Tomcat应用,我推荐使用least_conn算法:
upstream tomcat_cluster { least_conn; server tomcat:8080; }4.3 健康检查配置
upstream tomcat_cluster { least_conn; server tomcat:8080 max_fails=3 fail_timeout=30s; } server { # ... 其他配置 location /health { proxy_pass http://tomcat_cluster/health; health_check; } }5. MySQL高可用配置
5.1 主从复制配置
修改MySQL配置文件mysql/conf.d/replication.cnf:
[mysqld] server-id=1 log-bin=mysql-bin binlog-format=ROW binlog-do-db=app_db5.2 添加从节点
在docker-compose.yml中添加:
mysql_replica: image: mysql:8.0 container_name: mysql_replica environment: MYSQL_ROOT_PASSWORD: securepassword volumes: - mysql_replica_data:/var/lib/mysql - ./mysql/conf.d:/etc/mysql/conf.d command: > --server-id=2 --log-bin=mysql-bin --binlog-format=ROW --relay-log=mysql-relay-bin --log-slave-updates=ON --read-only=ON --replicate-do-db=app_db depends_on: - mysql networks: - app_net5.3 配置主从关系
# 在主库执行 docker exec -it mysql_primary mysql -uroot -psecurepassword -e "CREATE USER 'replica'@'%' IDENTIFIED BY 'replica_password'; GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%'; FLUSH PRIVILEGES;" # 在从库执行 docker exec -it mysql_replica mysql -uroot -psecurepassword -e "CHANGE MASTER TO MASTER_HOST='mysql', MASTER_USER='replica', MASTER_PASSWORD='replica_password', MASTER_AUTO_POSITION=1; START SLAVE;"6. 部署与验证
6.1 启动集群
docker-compose up -d6.2 验证服务状态
docker-compose ps6.3 测试Tomcat应用
curl http://localhost6.4 测试MySQL主从复制
# 在主库插入数据 docker exec -it mysql_primary mysql -uroot -psecurepassword -e "USE app_db; CREATE TABLE test(id INT); INSERT INTO test VALUES(1);" # 在从库查询数据 docker exec -it mysql_replica mysql -uroot -psecurepassword -e "USE app_db; SELECT * FROM test;"6.5 测试Nginx负载均衡
# 多次访问查看响应是否来自不同Tomcat实例 for i in {1..5}; do curl -I http://localhost; done7. 常见问题与解决方案
7.1 端口冲突问题
如果遇到端口冲突,可以:
- 修改docker-compose.yml中的端口映射
- 停止占用端口的服务
- 使用
netstat -tulnp | grep <端口号>查找冲突进程
7.2 容器启动顺序问题
使用depends_on和healthcheck确保服务启动顺序正确:
services: app: depends_on: db: condition: service_healthy7.3 数据持久化问题
确保重要数据使用volumes持久化:
volumes: mysql_data: driver: local7.4 内存不足问题
调整容器内存限制:
services: mysql: deploy: resources: limits: memory: 2G8. 性能优化建议
8.1 MySQL优化
[mysqld] innodb_buffer_pool_size=1G innodb_log_file_size=256M innodb_flush_log_at_trx_commit=28.2 Tomcat优化
CATALINA_OPTS="-server -Xms1024m -Xmx2048m -XX:MaxMetaspaceSize=512m"8.3 Nginx优化
worker_processes auto; worker_connections 1024; keepalive_timeout 65; gzip on;9. 监控与日志管理
9.1 容器日志查看
docker-compose logs -f9.2 自定义日志配置
services: tomcat: logging: driver: "json-file" options: max-size: "10m" max-file: "3"9.3 使用cAdvisor监控
services: cadvisor: image: gcr.io/cadvisor/cadvisor:v0.47.0 volumes: - /:/rootfs:ro - /var/run:/var/run:rw - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro ports: - "8080:8080" networks: - app_net10. 扩展与升级
10.1 扩展Tomcat实例
docker-compose up -d --scale tomcat=310.2 升级服务版本
修改docker-compose.yml中的镜像版本后:
docker-compose pull docker-compose up -d10.3 添加新服务
services: redis: image: redis:6.2 networks: - app_net在实际项目中,我发现这种部署方式特别适合中小型Web应用的快速部署。通过Docker Compose,原本需要数天的部署工作现在只需几分钟就能完成,而且配置可以版本化管理,方便团队协作和环境一致性维护。