缘起
客户要自己部署,我又不想给他开发微服务架构的程序,配套开销也不小。就一个OTA程序,也不想上K8S。所以我打算按以下方式给他交付。
接下来的交给GPT吧
要使用 docker-compose
部署一个 Java Web 程序,通过 Nginx 动态代理,同时支持动态扩展副本,并且保证端口不冲突,可以采取以下方式:
- Nginx 动态代理:配置 Nginx 通过反向代理访问 Java Web 服务。
- 动态扩展副本:可以通过
docker-compose
中的scale
选项来动态扩展副本,但更推荐使用 Docker Compose v3 的replicas
机制,结合 Docker Swarm(或者 Kubernetes)来管理容器副本。 - 端口不冲突:通过 Docker 的内部网络进行通信,不暴露容器的端口外部,除非需要进行外部访问。
下面是一个基本的 docker-compose.yml
示例:
version: '3.7'
services:
web:
image: your-java-web-image:latest # 使用你构建的 Java Web 应用镜像
environment:
- SPRING_PROFILES_ACTIVE=prod # 假设是 Spring Boot 应用,可以设置环境变量
networks:
- app_network
deploy:
replicas: 3 # 设置副本数
expose:
- 8080 # 内部端口,不会暴露给外部
labels:
- "com.docker.swarm.replica=web" # 用于区分服务标签
nginx:
image: nginx:latest
ports:
- "80:80" # 将外部请求转发到 Nginx 的 80 端口
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf # 自定义 Nginx 配置
networks:
- app_network
depends_on:
- web
deploy:
replicas: 1
restart: always
networks:
app_network:
driver: bridge
Nginx 配置(nginx.conf)
Nginx 配置需要根据 Java Web 服务的副本数量来动态代理流量。你可以使用 Nginx 的 upstream
来动态扩展后端服务。下面是一个简单的 nginx.conf
示例:
http {
upstream backend {
server web:8080; # 指向 Docker Compose 中的 web 服务
# 如果有更多副本,可以手动或通过负载均衡器动态加入更多的服务器
}
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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
动态扩展副本
在 Docker Swarm 或 Kubernetes 中部署时,你可以通过 docker service scale
或 Kubernetes 的 ReplicaSet
动态扩展 web
服务的副本数。
在 Swarm 模式下,使用以下命令扩展副本:
docker service scale <service_name>=<replica_count>
如果你使用 Kubernetes,可以通过 kubectl scale
来调整副本数:
kubectl scale deployment <deployment_name> --replicas=<replica_count>
端口不冲突
通过使用 expose
指令,容器的内部端口被暴露给 Docker 网络中的其他容器,但不会与外部端口冲突。Nginx 会将请求路由到容器的内部端口。
这种配置可以实现端口不冲突,因为 Nginx 会处理外部流量并将其转发到 Java Web 应用,而 Web 应用的端口(比如 8080
)仅限于容器内部。