194 lines
6.0 KiB
Markdown
194 lines
6.0 KiB
Markdown
# common
|
||
|
||
公共代码集合
|
||
|
||
---
|
||
|
||
## ✅ 微服务十大核心原则(实战导向)
|
||
|
||
> 这些不是理论教条,而是无数团队踩坑后总结出的“生存法则”。
|
||
|
||
---
|
||
|
||
### 1. **单一职责 & 高内聚(Single Responsibility)**
|
||
- 每个微服务应围绕 **一个明确的业务能力**(如“用户管理”、“支付”、“通知”)。
|
||
- ❌ 不要按技术分层拆服务(如“所有 DB 服务”、“所有 API 服务”)。
|
||
- ✅ 建议用 **DDD(领域驱动设计)** 划分限界上下文(Bounded Context)。
|
||
|
||
> 📌 口诀:**“一个服务,一个事”**
|
||
|
||
---
|
||
|
||
### 2. **自治性(Autonomy)**
|
||
- 服务应能 **独立开发、测试、部署、扩展、故障恢复**。
|
||
- 依赖越少越好;跨服务调用必须有 **降级、熔断、超时** 机制。
|
||
- 使用 **契约测试(Contract Testing)** 保证接口兼容(如 Pact)。
|
||
|
||
> 🔧 工具推荐:
|
||
> - gRPC + Protobuf(强契约)
|
||
> - OpenAPI(REST)
|
||
> - WireMock / Pact(契约测试)
|
||
|
||
---
|
||
|
||
### 3. **数据私有(Database per Service)** ← 你已掌握!
|
||
- 每个服务独占数据存储,**禁止跨服务直连数据库**。
|
||
- 跨服务数据交互靠:
|
||
- **同步**:API(gRPC/HTTP)
|
||
- **异步**:事件(Kafka / RabbitMQ / Pulsar)
|
||
|
||
> 💡 技巧:用 **事件溯源(Event Sourcing) + CQRS** 构建复杂查询视图。
|
||
|
||
---
|
||
|
||
### 4. **无状态(Stateless)**
|
||
- 服务实例本身不保存会话或状态(状态存 Redis / DB / Cookie)。
|
||
- 好处:**水平扩展容易**,K8s 可随意扩缩容。
|
||
|
||
> ⚠️ 例外:批处理、流计算等有状态场景可用 StatefulSet,但要谨慎。
|
||
|
||
---
|
||
|
||
### 5. **可观测性(Observability)三件套**
|
||
微服务没有可观测性 = 盲人开车!
|
||
|
||
| 组件 | 作用 | 工具推荐 |
|
||
|------|------|--------|
|
||
| **Logging** | 记录结构化日志 | Zap / Logrus + Loki / ELK |
|
||
| **Metrics** | 监控性能指标 | Prometheus + Grafana |
|
||
| Assistant | 追踪请求链路 | Jaeger / Zipkin / OpenTelemetry |
|
||
|
||
> ✅ 必做:
|
||
> - 所有日志带 `trace_id`
|
||
> - 所有 gRPC 调用自动埋点
|
||
> - 关键路径加自定义指标(如“登录成功率”)
|
||
|
||
---
|
||
|
||
### 6. **弹性设计(Resilience)**
|
||
网络不可靠!必须假设:
|
||
- 其他服务会宕机
|
||
- 网络会延迟或丢包
|
||
|
||
✅ 必备机制:
|
||
- **超时(Timeout)**:每个调用设上限(如 1s)
|
||
- **重试(Retry)**:带退避策略(指数退避)
|
||
- **熔断(Circuit Breaker)**:失败太多就短路(如 Hystrix / Sentinel)
|
||
- **限流(Rate Limiting)**:保护自己不被压垮
|
||
- **降级(Fallback)**:返回默认值或缓存数据
|
||
|
||
> 🛠 Go 推荐库:
|
||
> - `go-resiliency`
|
||
> - `sony/gobreaker`
|
||
> - 自研中间件(结合 context + retry)
|
||
|
||
---
|
||
|
||
### 7. **API 优先(API-First Design)**
|
||
- 先定义 `.proto`(gRPC)或 OpenAPI(REST),再写代码。
|
||
- 客户端 SDK 自动生成(如 `protoc-gen-go`)。
|
||
- 版本管理:**向后兼容优先**,避免频繁改接口。
|
||
|
||
> 📁 目录建议:
|
||
> ```
|
||
> api/
|
||
> ├── user/v1/user.proto
|
||
> └── order/v1/order.proto
|
||
> ```
|
||
|
||
---
|
||
|
||
### 8. **基础设施即代码(IaC) & GitOps**
|
||
- 数据库、K8s、网关配置全部代码化(Terraform / Helm / Kustomize)。
|
||
- 所有变更通过 Git PR 触发自动化部署。
|
||
- 环境一致性:dev / staging / prod 配置几乎相同。
|
||
|
||
> ✅ 好处:**“一键重建整个环境”**
|
||
|
||
---
|
||
|
||
### 9. **安全内建(Security by Default)**
|
||
- **mTLS**:服务间通信加密(Istio / Linkerd)
|
||
- **RBAC**:基于角色的访问控制
|
||
- **敏感信息**:用 Vault / K8s Secret 管理,不硬编码
|
||
- **输入校验**:所有 API 参数严格验证(如 `validator.v10`)
|
||
|
||
> 🔒 原则:**“零信任网络”** —— 不信任任何内部流量。
|
||
|
||
---
|
||
|
||
### 10. **演进式设计(Evolutionary Architecture)**
|
||
- 不追求“一次性完美架构”
|
||
- 用 **Strangler Fig Pattern(绞杀者模式)** 逐步替换旧系统
|
||
- 定期做 **架构重构** 和 **技术债清理**
|
||
|
||
> 🌱 微服务是“种出来的”,不是“画出来的”。
|
||
|
||
---
|
||
|
||
## 🧱 推荐架构分层(Go 微服务)
|
||
|
||
```
|
||
user-service/
|
||
├── api/ # .proto 文件(对外契约)
|
||
├── cmd/ # main 入口
|
||
├── internal/
|
||
│ ├── handler/ # gRPC/HTTP handlers(薄层)
|
||
│ ├── service/ # 业务逻辑(核心)
|
||
│ ├── repository/ # 数据访问(接口 + mysql 实现)
|
||
│ └── model/ # 领域模型(与 DB 解耦)
|
||
├── pkg/ # 可共享工具(谨慎!)
|
||
├── deploy/ # K8s / Docker 配置
|
||
└── go.mod
|
||
```
|
||
|
||
> 🔑 关键:`internal/` 禁止被外部 import,强制通过 API 交互。
|
||
|
||
---
|
||
|
||
## 🚫 微服务常见反模式(务必避开!)
|
||
|
||
| 反模式 | 后果 |
|
||
|-------|------|
|
||
| 分布式单体 | 失去微服务所有优势 |
|
||
| 共享数据库 | 强耦合,无法独立演进 |
|
||
| 同步调用链过长(A→B→C→D) | 故障放大,雪崩风险 |
|
||
| 无监控无告警 | 出问题找不到原因 |
|
||
| 手动部署 | 发布慢,易出错 |
|
||
|
||
---
|
||
|
||
## ✅ 最后建议:从小做起,逐步完善
|
||
|
||
1. **先保证“能跑”**:一个服务 + 独立 DB + gRPC API
|
||
2. **加上可观测性**:日志 + Metrics + Tracing
|
||
3. **加上弹性机制**:超时 + 重试
|
||
4. **加上 CI/CD**:自动化测试 & 部署
|
||
5. **再考虑事件驱动、CQRS、Service Mesh...**
|
||
|
||
> 🌟 **好的微服务架构不是设计出来的,而是在约束和实践中演化出来的。**
|
||
|
||
---
|
||
|
||
# 增加服务器步骤
|
||
|
||
代码
|
||
1. go module 命名:`git.hlsq.asia/mmorpg/service-${服务名}`
|
||
2. `deploy、config` 修改
|
||
|
||
common
|
||
1. 在 `discover\common\define.go` 定义服务发现
|
||
2. 在 `net\grpc\service` 实现客户端发现
|
||
|
||
public
|
||
1. 在 `Proto\RpcServer\sources` 定义gRPC服务
|
||
|
||
db
|
||
1. 创建独立db,命名为`${服务名}_db`
|
||
|
||
quickly
|
||
1. `MySQL Model` 增加数据库配置
|
||
2. `更新Common` 增加项目配置
|
||
|
||
gateway
|
||
1. 在 `internal\net\http_gateway\router.go` 定义路由 |