微服务架构
1. 微服务基本概念
微服务架构是将单一应用拆分为一组小型服务的风格:
// 用户服务示例
type UserService struct {
repo UserRepository
}
func (s *UserService) GetUser(id string) (*User, error) {
return s.repo.FindByID(id)
}
// 订单服务示例
type OrderService struct {
repo OrderRepository
}
func (s *OrderService) CreateOrder(userID string, items []Item) (*Order, error) {
// 验证用户存在(可能调用用户服务)
// 创建订单
return s.repo.Create(userID, items)
}
微服务特点:
- 每个服务有独立的代码库
- 独立部署和扩展
- 轻量级通信(通常HTTP/REST或gRPC)
- 独立的数据存储
2. 服务间通信方式
REST API
// 用户服务HTTP客户端
type UserServiceClient struct {
baseURL string
client *http.Client
}
func (c *UserServiceClient) GetUser(id string) (*User, error) {
resp, err := c.client.Get(fmt.Sprintf("%s/users/%s", c.baseURL, id))
if err != nil {
return nil, err
}
defer resp.Body.Close()
var user User
if err := json.NewDecoder(resp.Body).Decode(&user); err != nil {
return nil, err
}
return &user, nil
}
gRPC
// user_service.proto
service UserService {
rpc GetUser (GetUserRequest) returns (UserResponse);
}
message GetUserRequest {
string id = 1;
}
message UserResponse {
string id = 1;
string name = 2;
string email = 3;
}
// gRPC客户端实现
conn, err := grpc.Dial("user-service:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("连接失败: %v", err)
}
defer conn.Close()
client := pb.NewUserServiceClient(conn)
user, err := client.GetUser(context.Background(), &pb.GetUserRequest{Id: "123"})
3. 服务发现与负载均衡
使用Consul服务发现
// 服务注册
func registerService(serviceName, address string, port int) {
config := api.DefaultConfig()
client, err := api.NewClient(config)
if err != nil {
panic(err)
}
registration := &api.AgentServiceRegistration{
ID: fmt.Sprintf("%s-%s", serviceName, uuid.New().String()),
Name: serviceName,
Port: port,
Address: address,
Check: &api.AgentServiceCheck{
HTTP: fmt.Sprintf("http://%s:%d/health", address, port),
Interval: "10s",
Timeout: "5s",
},
}
if err := client.Agent().ServiceRegister(registration); err != nil {
panic(err)
}
}
// 服务发现
func discoverService(serviceName string) (string, error) {
config := api.DefaultConfig()
client, err := api.NewClient(config)
if err != nil {
return "", err
}
services, _, err := client.Health().Service(serviceName, "", true, nil)
if err != nil {
return "", err
}
if len(services) == 0 {
return "", fmt.Errorf("服务 %s 未找到", serviceName)
}
service := services[0]
return fmt.Sprintf("http://%s:%d", service.Service.Address, service.Service.Port), nil
}
4. API网关模式
// 使用Gin实现简单API网关
func main() {
r := gin.Default()
// 用户服务路由
userGroup := r.Group("/users")
{
userGroup.GET("/:id", func(c *gin.Context) {
// 调用用户服务
userServiceURL := getServiceURL("user-service")
resp, err := http.Get(fmt.Sprintf("%s/users/%s", userServiceURL, c.Param("id")))
// 处理响应...
})
}
// 订单服务路由
orderGroup := r.Group("/orders")
{
orderGroup.POST("/", func(c *gin.Context) {
// 调用订单服务
orderServiceURL := getServiceURL("order-service")
resp, err := http.Post(orderServiceURL+"/orders", "application/json", c.Request.Body)
// 处理响应...
})
}
r.Run(":8080")
}
5. 分布式系统挑战与解决方案
| 挑战 | 解决方案 |
|---|---|
| 服务发现 | Consul, Eureka, etcd |
| 配置管理 | Consul KV, etcd, Spring Cloud Config |
| 负载均衡 | Nginx, Traefik, Envoy |
| 断路器 | Hystrix, Resilience4j, gobreaker |
| 分布式追踪 | Jaeger, Zipkin, OpenTelemetry |
| 日志聚合 | ELK, Fluentd, Loki |
| 监控 | Prometheus, Grafana |
// 使用gobreaker实现断路器
func main() {
cb := gobreaker.NewCircuitBreaker(gobreaker.Settings{
Name: "user-service",
Timeout: 30 * time.Second,
ReadyToTrip: func(counts gobreaker.Counts) bool {
return counts.ConsecutiveFailures > 5
},
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_, err := cb.Execute(func() (interface{}, error) {
return callUserService(r)
})
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
// 处理成功响应...
})
http.ListenAndServe(":8080", nil)
}
提示:微服务架构提供了灵活性和可扩展性,但也带来了复杂性。建议从单体架构开始,只在真正需要时拆分服务。
