微服务部署实战教程:从零搭建可访问的服务集群
微服务部署的核心不是把代码跑起来,而是让多个服务能互相发现、对外统一入口、出问题能快速定位。
这篇教程用一台 Linux 服务器和 Docker Compose,带你部署两个最小服务(一个用户服务、一个订单服务)并通过 Nginx 暴露出去。
整个过程不依赖 K8s,适合刚接触微服务的读者先跑通链路。
开始前要准备什么
你需要一台能 SSH 登录的 Linux 服务器,建议 2 核 4G 起步,系统用 Ubuntu 22.04 或 CentOS 7+ 均可。
下面命令以 Ubuntu 为例,CentOS 把 apt 换成 yum 即可。
先确认 Docker 和 Compose 已安装:
docker --version
docker compose version
如果没装,按官方文档安装 Docker Engine 和 Compose 插件。
装完后把当前用户加入 docker 组,避免每条命令都加 sudo:
sudo usermod -aG docker $USER
newgrp docker
验证方式:执行 docker run hello-world,能看到 Hello from Docker 说明环境正常。
编写两个最小服务
在服务器上建目录:
mkdir -p ~/microservices/{user-service,order-service,nginx}
cd ~/microservices
每个服务用最简单的 Python HTTP 服务演示,重点是部署结构,不是业务代码。
user-service 的 app.py:
from http.server import BaseHTTPRequestHandler, HTTPServer
class H(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Type','application/json')
self.end_headers()
self.wfile.write(b'{"service":"user","status":"ok"}')
HTTPServer(('0.0.0.0', 8000), H).serve_forever()
order-service 的 app.py 把返回内容改成 {"service":,
"order","status":
"ok"}
端口同样 8000。
各自写一个 Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY app.py .
EXPOSE 8000
CMD ["python", "app.py"]
用 Compose 编排服务
在 ~/microservices 下新建 docker-compose.yml:
services:
user-service:
build: ./user-service
container_name: user-service
restart: always
networks:
- micro-net
order-service:
build: ./order-service
container_name: order-service
restart: always
networks:
- micro-net
nginx:
image: nginx:stable
container_name: nginx-gateway
ports:
- "80:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- user-service
- order-service
networks:
- micro-net
networks:
micro-net:
driver: bridge
关键点:服务之间通过服务名互相访问,比如 nginx 配置里写 user-service:8000,不要写 IP,容器重建后 IP 会变。
配置 Nginx 统一入口
新建 nginx/default.conf:
server {
listen 80;
location /user/ {
proxy_pass http://user-service:8000/;
}
location /order/ {
proxy_pass http://order-service:8000/;
}
}
注意 proxy_pass 末尾的斜杠。
带斜杠会把 /user/ 前缀去掉再转发,不带则原样转发,配错会出现 404。
启动并验证
在 ~/microservices 目录执行:
docker compose up -d --build
看到三个容器都 Started 后,逐一检查:
docker compose ps
curl http://localhost/user/
curl http://localhost/order/
预期分别返回 {"service":"user","status":"ok"} 和 {"service":"order","status":"ok"}。
如果 curl 能通但浏览器打不开,检查服务器安全组或防火墙是否放行 80 端口。
容易踩的坑
- 容器启动顺序:
depends_on只保证启动顺序,不保证服务就绪。生产环境建议加健康检查或在应用层做重试。 - 端口冲突:宿主机 80 端口被占用会导致 nginx 启动失败,用
ss -lntp | grep :80排查。 - 网络隔离:不同 compose 项目默认在不同网络,跨项目访问需要显式声明 external network。
- 日志排查:服务异常先用
docker compose logs -f 服务名看输出,比盲目重启有效。 - 数据持久化:示例是无状态服务,真实数据库要挂载 volume,否则容器删除数据即丢失。
常见疑问
一定要用 K8s 吗? 不一定。
单机或小规模场景用 Compose 足够,等需要自动扩缩容、多节点调度时再迁移。
服务间怎么通信? 同一自定义网络内直接用服务名加端口访问,Docker 内置 DNS 会解析。
怎么更新某个服务? 改完代码后执行 docker compose up -d --build 服务名,只重建该服务,其他不受影响。
整套流程跑通后,你已经有了微服务部署的最小闭环:独立服务、容器编排、统一入口、验证手段。
后续把示例服务替换成真实应用,再按需补充配置中心、服务发现和监控即可。