多容器应用编排 #
应用架构设计 #
典型Web应用架构 #
text
┌─────────────────────────────────────────────────────┐
│ Web应用架构 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ │
│ │ CDN │ │
│ └────┬────┘ │
│ │ │
│ ┌────▼────┐ ┌─────────┐ │
│ │ Nginx │────→│ App │ │
│ │(反向代理)│ │(Node.js)│ │
│ └─────────┘ └────┬────┘ │
│ │ │
│ ┌───────────────┼───────────────┐ │
│ │ │ │ │
│ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │
│ │ MySQL │ │ Redis │ │ MQ │ │
│ │(主数据库)│ │ (缓存) │ │(消息队列)│ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
└─────────────────────────────────────────────────────┘
基础编排示例 #
简单Web应用 #
yaml
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./html:/usr/share/nginx/html
depends_on:
- app
app:
image: node:18-alpine
working_dir: /app
volumes:
- ./app:/app
command: npm start
environment:
- NODE_ENV=production
depends_on:
- db
- redis
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mydb
volumes:
- mysql-data:/var/lib/mysql
redis:
image: redis:alpine
volumes:
- redis-data:/data
volumes:
mysql-data:
redis-data:
服务发现与通信 #
网络配置 #
yaml
version: '3.8'
services:
web:
image: nginx:alpine
networks:
- frontend
ports:
- "80:80"
app:
image: myapp
networks:
- frontend
- backend
environment:
- DB_HOST=db
- REDIS_HOST=redis
db:
image: mysql:8.0
networks:
- backend
redis:
image: redis:alpine
networks:
- backend
networks:
frontend:
backend:
internal: true
服务依赖 #
yaml
version: '3.8'
services:
app:
image: myapp
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
db:
image: mysql:8.0
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
负载均衡 #
Nginx负载均衡 #
yaml
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- app1
- app2
- app3
app1:
image: myapp
environment:
- INSTANCE_ID=1
networks:
- app-network
app2:
image: myapp
environment:
- INSTANCE_ID=2
networks:
- app-network
app3:
image: myapp
environment:
- INSTANCE_ID=3
networks:
- app-network
networks:
app-network:
nginx.conf #
nginx
upstream backend {
server app1:3000;
server app2:3000;
server app3:3000;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
使用scale扩展 #
bash
# 启动服务
docker-compose up -d
# 扩展app服务到5个实例
docker-compose up -d --scale app=5
# nginx配置需要使用动态发现
# 或使用Docker Swarm模式
数据库主从复制 #
MySQL主从配置 #
yaml
version: '3.8'
services:
mysql-master:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mydb
MYSQL_REPLICATION_MODE: master
MYSQL_REPLICATION_USER: repl
MYSQL_REPLICATION_PASSWORD: repl
volumes:
- mysql-master-data:/var/lib/mysql
- ./master.cnf:/etc/mysql/conf.d/master.cnf
networks:
- db-network
mysql-slave:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_REPLICATION_MODE: slave
MYSQL_REPLICATION_USER: repl
MYSQL_REPLICATION_PASSWORD: repl
MYSQL_MASTER_HOST: mysql-master
MYSQL_MASTER_PORT: 3306
volumes:
- mysql-slave-data:/var/lib/mysql
- ./slave.cnf:/etc/mysql/conf.d/slave.cnf
depends_on:
- mysql-master
networks:
- db-network
volumes:
mysql-master-data:
mysql-slave-data:
networks:
db-network:
master.cnf #
ini
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
slave.cnf #
ini
[mysqld]
server-id = 2
relay-log = relay-bin
read_only = 1
Redis集群 #
Redis Sentinel #
yaml
version: '3.8'
services:
redis-master:
image: redis:alpine
command: redis-server
networks:
- redis-network
redis-slave:
image: redis:alpine
command: redis-server --slaveof redis-master 6379
depends_on:
- redis-master
networks:
- redis-network
sentinel:
image: redis:alpine
command: redis-sentinel /etc/redis/sentinel.conf
volumes:
- ./sentinel.conf:/etc/redis/sentinel.conf
depends_on:
- redis-master
networks:
- redis-network
networks:
redis-network:
sentinel.conf #
ini
sentinel monitor mymaster redis-master 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
消息队列集成 #
RabbitMQ #
yaml
version: '3.8'
services:
rabbitmq:
image: rabbitmq:3-management-alpine
ports:
- "5672:5672"
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: admin
volumes:
- rabbitmq-data:/var/lib/rabbitmq
networks:
- app-network
producer:
image: myapp-producer
environment:
- RABBITMQ_HOST=rabbitmq
depends_on:
- rabbitmq
networks:
- app-network
consumer:
image: myapp-consumer
environment:
- RABBITMQ_HOST=rabbitmq
depends_on:
- rabbitmq
networks:
- app-network
deploy:
replicas: 3
volumes:
rabbitmq-data:
networks:
app-network:
完整应用示例 #
电商应用 #
yaml
version: '3.8'
services:
# 前端网关
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
networks:
- frontend
depends_on:
- frontend
- api
# 前端应用
frontend:
image: myapp-frontend
networks:
- frontend
environment:
- API_URL=http://api:8000
# API网关
api:
image: myapp-api
networks:
- frontend
- backend
environment:
- USER_SERVICE=http://user-service:8001
- PRODUCT_SERVICE=http://product-service:8002
- ORDER_SERVICE=http://order-service:8003
depends_on:
- user-service
- product-service
- order-service
# 用户服务
user-service:
image: myapp-user-service
networks:
- backend
environment:
- DB_HOST=user-db
- REDIS_HOST=redis
depends_on:
- user-db
- redis
# 商品服务
product-service:
image: myapp-product-service
networks:
- backend
environment:
- DB_HOST=product-db
- REDIS_HOST=redis
depends_on:
- product-db
- redis
# 订单服务
order-service:
image: myapp-order-service
networks:
- backend
environment:
- DB_HOST=order-db
- REDIS_HOST=redis
- MQ_HOST=rabbitmq
depends_on:
- order-db
- redis
- rabbitmq
# 数据库
user-db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: user_db
volumes:
- user-db-data:/var/lib/mysql
networks:
- backend
product-db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: product_db
volumes:
- product-db-data:/var/lib/mysql
networks:
- backend
order-db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: order_db
volumes:
- order-db-data:/var/lib/mysql
networks:
- backend
# 缓存
redis:
image: redis:alpine
volumes:
- redis-data:/data
networks:
- backend
# 消息队列
rabbitmq:
image: rabbitmq:3-management-alpine
ports:
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: admin
volumes:
- rabbitmq-data:/var/lib/rabbitmq
networks:
- backend
volumes:
user-db-data:
product-db-data:
order-db-data:
redis-data:
rabbitmq-data:
networks:
frontend:
backend:
internal: true
小结 #
本节学习了多容器应用编排:
- 应用架构设计
- 服务发现与通信
- 负载均衡配置
- 数据库主从复制
- Redis集群配置
- 消息队列集成
- 完整应用示例
下一步 #
接下来,让我们学习 Compose网络与存储,深入了解Compose中的网络和存储配置。