微服务架构入门教程 — 现代应用架构

适用人群:有后端开发经验的开发者
学习时长:约2-3天(每天3小时)
重要程度:★★★☆☆(进阶必学)

一、微服务是什么?

微服务是一种架构风格,将应用拆分为一组小型、独立部署的服务,每个服务运行在自己的进程中。

对比项单体架构微服务架构
部署整体部署独立部署
技术栈统一可以不同
扩展整体扩展按需扩展
复杂度代码复杂运维复杂
适用场景小型项目大型项目

二、微服务核心组件

┌─────────────────────────────────────────────────────────┐
│                     客户端(Web/APP)                     │
└─────────────────────────┬───────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────┐
│                    API 网关(Gateway)                    │
│              路由、限流、认证、日志                        │
└─────────────────────────┬───────────────────────────────┘
                          │
        ┌─────────────────┼─────────────────┐
        ▼                 ▼                 ▼
┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│  用户服务     │  │  订单服务     │  │  商品服务     │
│  (User)      │  │  (Order)     │  │  (Product)   │
└──────┬───────┘  └──────┬───────┘  └──────┬───────┘
       │                 │                 │
       ▼                 ▼                 ▼
┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│  用户数据库   │  │  订单数据库   │  │  商品数据库   │
└──────────────┘  └──────────────┘  └──────────────┘


三、API 网关

3.1 网关职责

✅ 路由转发:将请求转发到对应服务
✅ 负载均衡:分发流量到多个实例
✅ 认证授权:统一身份验证
✅ 限流熔断:保护后端服务
✅ 日志监控:记录请求日志
✅ 协议转换:HTTP ↔ gRPC

3.2 常用网关

网关语言特点
KongLua功能最全、插件丰富
APISIXLua高性能、国产
Spring Cloud GatewayJavaSpring生态
NginxC轻量级、高性能
TraefikGo云原生、自动发现

3.3 Nginx 作为网关

# 微服务网关配置
upstream user-service {
    server 192.168.1.10:8081;
    server 192.168.1.11:8081;
}

upstream order-service {
    server 192.168.1.20:8082;
    server 192.168.1.21:8082;
}

upstream product-service {
    server 192.168.1.30:8083;
}

server {
    listen 80;
    server_name api.example.com;
    
    # 用户服务
    location /api/users/ {
        proxy_pass http://user-service;
        proxy_set_header X-Request-ID $request_id;
    }
    
    # 订单服务
    location /api/orders/ {
        proxy_pass http://order-service;
        proxy_set_header X-Request-ID $request_id;
    }
    
    # 商品服务
    location /api/products/ {
        proxy_pass http://product-service;
        proxy_set_header X-Request-ID $request_id;
    }
    
    # 限流
    limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s;
    
    location /api/ {
        limit_req zone=api burst=200 nodelay;
    }
}


四、服务间通信

4.1 同步通信(HTTP/gRPC)

// Go - HTTP调用其他服务
func getUserFromService(userId int) (*User, error) {
    resp, err := http.Get(fmt.Sprintf("http://user-service/api/users/%d", userId))
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    var user User
    json.NewDecoder(resp.Body).Decode(&user)
    return &user, nil
}

// Go - gRPC调用(更高效)
// 需要定义.proto文件,生成代码后调用

4.2 异步通信(消息队列)

# Python - RabbitMQ
import pika

# 生产者
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='order_created')

channel.basic_publish(
    exchange='',
    routing_key='order_created',
    body=json.dumps({'order_id': 123, 'user_id': 456})
)
connection.close()

# 消费者
def callback(ch, method, properties, body):
    data = json.loads(body)
    print(f"收到订单:{data}")
    # 处理订单...

channel.basic_consume(queue='order_created', on_message_callback=callback)
channel.start_consuming()

// Node.js - Redis消息队列
const Redis = require('ioredis')
const redis = new Redis()

// 发布消息
await redis.publish('order:created', JSON.stringify({
    orderId: 123,
    userId: 456
}))

// 订阅消息
redis.subscribe('order:created')
redis.on('message', (channel, message) => {
    const data = JSON.parse(message)
    console.log('收到消息:', data)
})


五、服务注册与发现

5.1 Consul

# 安装Consul
docker run -d --name consul -p 8500:8500 consul:latest

# 服务注册(HTTP API)
curl -X PUT http://localhost:8500/v1/agent/service/register -d '{
    "ID": "user-service-1",
    "Name": "user-service",
    "Tags": ["v1"],
    "Address": "192.168.1.10",
    "Port": 8081,
    "Check": {
        "HTTP": "http://192.168.1.10:8081/health",
        "Interval": "10s"
    }
}'

# 服务发现
curl http://localhost:8500/v1/catalog/service/user-service

5.2 etcd(K8S使用)

// Go - etcd服务注册
cli, _ := clientv3.New(clientv3.Config{
    Endpoints: []string{"localhost:2379"},
})

// 注册服务
cli.Put(context.Background(), "/services/user-service/instance-1", 
    "192.168.1.10:8081", 
    clientv3.WithLease(lease.ID))

// 发现服务
resp, _ := cli.Get(context.Background(), "/services/user-service/", 
    clientv3.WithPrefix())


六、熔断与限流

6.1 熔断器模式

// Go - 使用gobreaker
import "github.com/sony/gobreaker"

cb := gobreaker.NewCircuitBreaker(gobreaker.Settings{
    Name:        "user-service",
    MaxRequests: 3,
    Interval:    10 * time.Second,
    Timeout:     30 * time.Second,
    ReadyToTrip: func(counts gobreaker.Counts) bool {
        return counts.ConsecutiveFailures > 5
    },
})

// 使用熔断器
result, err := cb.Execute(func() (interface{}, error) {
    return getUserFromService(userId)
})

6.2 限流

// Go - 令牌桶限流
import "golang.org/x/time/rate"

// 每秒100个请求,突发200
limiter := rate.NewLimiter(100, 200)

func handler(w http.ResponseWriter, r *http.Request) {
    if !limiter.Allow() {
        http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
        return
    }
    // 处理请求
}

# Nginx限流
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s;

server {
    location /api/ {
        limit_req zone=api burst=200 nodelay;
        proxy_pass http://backend;
    }
}


七、Docker Compose 微服务编排

version: '3.8'

services:
  # API网关
  gateway:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx/gateway.conf:/etc/nginx/nginx.conf
    depends_on:
      - user-service
      - order-service
      - product-service

  # 用户服务
  user-service:
    build: ./services/user
    environment:
      - DATABASE_URL=mysql://root:password@user-db:3306/user_db
      - REDIS_URL=redis://redis:6379/0
    depends_on:
      - user-db
      - redis

  # 订单服务
  order-service:
    build: ./services/order
    environment:
      - DATABASE_URL=mysql://root:password@order-db:3306/order_db
      - RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672
    depends_on:
      - order-db
      - rabbitmq

  # 商品服务
  product-service:
    build: ./services/product
    environment:
      - DATABASE_URL=mysql://root:password@product-db:3306/product_db
    depends_on:
      - product-db

  # 数据库
  user-db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: user_db
    volumes:
      - user_db_data:/var/lib/mysql

  order-db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: order_db
    volumes:
      - order_db_data:/var/lib/mysql

  product-db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: product_db
    volumes:
      - product_db_data:/var/lib/mysql

  # 消息队列
  rabbitmq:
    image: rabbitmq:3-management
    ports:
      - "5672:5672"
      - "15672:15672"

  # 缓存
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

  # 服务发现(可选)
  consul:
    image: consul:latest
    ports:
      - "8500:8500"

volumes:
  user_db_data:
  order_db_data:
  product_db_data:


八、微服务最佳实践

✅ 服务拆分:按业务领域拆分(用户、订单、商品)
✅ 数据库独立:每个服务有自己的数据库
✅ API网关:统一入口,处理认证、限流
✅ 服务注册发现:Consul/etcd/Nacos
✅ 配置中心:统一管理配置
✅ 链路追踪:Jaeger/Zipkin
✅ 日志聚合:ELK Stack
✅ 监控告警:Prometheus + Grafana
✅ 熔断限流:Hystrix/Resilience4j
✅ 容器化部署:Docker + Kubernetes


九、何时使用微服务

适合微服务

✅ 团队规模大(>10人)
✅ 业务复杂度高
✅ 需要独立部署和扩展
✅ 技术栈多样化需求
✅ 高可用性要求

不适合微服务

❌ 小型项目
❌ 团队规模小(<5人)
❌ 业务简单
❌ 运维能力不足
❌ 初创公司快速迭代


学习建议

  1. 先理解单体架构的痛点,才能理解微服务的价值
  2. 从简单的服务拆分开始,不要一开始就过度设计
  3. 掌握Docker和Docker Compose,这是微服务的基础
  4. 学习API网关配置,统一入口是关键
  5. 了解服务间通信,同步(HTTP/gRPC)和异步(消息队列)

下一步学习

返回首页