第一章:Golang语法基础与业务思维断层诊断
许多开发者初学 Go 时,常将其他语言(如 Java 或 Python)的惯性思维直接迁移过来,导致代码虽能运行,却违背 Go 的设计哲学——简洁、明确、面向工程。这种“语法会写,业务不会落地”的现象,本质是语法能力与领域建模能力之间的断层。
类型系统与零值语义的误用
Go 的零值(zero value)不是“未初始化”,而是有明确定义的安全默认值:int 为 ,string 为 "",*T 为 nil。但开发者常因过度依赖显式初始化(如 var s string = ""),反而掩盖了业务意图。正确做法是让零值服务于业务逻辑:
type Order struct {
ID int64
Status string // "" 表示“未提交”,"pending" 表示“待审核”,无需额外 bool 字段
}
此处 Status == "" 即代表初始状态,避免引入冗余字段和状态校验分支。
接口隐式实现带来的抽象错位
Go 接口应由调用方定义,而非实现方预设。常见错误是提前定义大而全的接口(如 UserService 包含 Create/Update/Delete),导致实现体被迫暴露无关方法。健康实践是按上下文精简接口:
// 订单创建场景只需知道“能持久化”
type Saver interface {
Save(context.Context, interface{}) error
}
func ProcessOrder(ctx context.Context, order *Order, s Saver) error {
return s.Save(ctx, order) // 解耦具体存储机制
}
错误处理中的控制流失焦
if err != nil 链式嵌套是 Go 的典型模式,但业务逻辑常被淹没在错误检查中。推荐将错误路径提前退出,并用具名返回值强化语义:
func CalculateDiscount(price float64, coupon *Coupon) (discount float64, err error) {
if price <= 0 {
return 0, errors.New("price must be positive")
}
if coupon == nil {
return 0, nil // 无优惠券,折扣为 0,非错误
}
discount = price * coupon.Rate
return discount, nil
}
| 习惯性写法 | Go 原生推荐方式 | 根本差异 |
|---|---|---|
fmt.Sprintf("%v", x) |
fmt.Sprint(x) |
避免格式字符串开销 |
| 手动管理 goroutine 生命周期 | 使用 context.WithTimeout |
显式传递取消信号 |
map[string]interface{} 处理动态结构 |
定义具体 struct + json.Unmarshal |
类型安全 + IDE 支持 |
第二章:领域建模与实体/值对象设计实践
2.1 领域实体建模:从需求描述到Go结构体契约定义
领域实体建模是将业务语义精准映射为可执行契约的关键跃迁。以电商订单场景为例,原始需求描述:“订单需记录用户ID、创建时间、状态(待支付/已发货/已完成)、商品明细及总金额”。
核心建模原则
- 保持值对象不可变性
- 聚合根明确生命周期边界
- 使用内嵌结构体表达强关联
Go结构体契约定义
type Order struct {
ID uint64 `json:"id" gorm:"primaryKey"`
UserID uint64 `json:"user_id" gorm:"index"`
CreatedAt time.Time `json:"created_at"`
Status OrderStatus `json:"status"`
Items []OrderItem `json:"items" gorm:"foreignKey:OrderID"`
Total Money `json:"total"` // 值对象,含currency与amount
}
// OrderStatus 是限界上下文内受控的枚举类型
type OrderStatus string
const (
StatusPending OrderStatus = "pending"
StatusShipped OrderStatus = "shipped"
StatusCompleted OrderStatus = "completed"
)
逻辑分析:
Order作为聚合根,UserID和CreatedAt为必需标识与时间戳;Status使用自定义字符串枚举,避免int魔法值;Items通过GORM外键约束确保一致性;Money作为值对象封装货币与精度,防止裸float64导致的精度污染。
建模验证对照表
| 需求要素 | 结构体字段 | 约束机制 |
|---|---|---|
| 用户唯一标识 | UserID |
数据库索引+非空 |
| 状态合法性 | OrderStatus |
枚举常量限定 |
| 金额精度保障 | Money |
封装decimal.Decimal |
graph TD
A[需求文本] --> B[识别核心概念]
B --> C[划分聚合边界]
C --> D[定义结构体字段与标签]
D --> E[添加类型约束与验证]
2.2 值对象不可变性实现:封装校验逻辑与零值安全设计
值对象的核心契约是状态不可变与语义完整性。若仅用 final 字段而放任构造时传入非法值,不可变性将形同虚设。
封装校验逻辑于构造阶段
public final class Money {
private final BigDecimal amount;
private final String currency;
public Money(BigDecimal amount, String currency) {
// ⚠️ 零值安全:拒绝 null、负数、空货币码
if (amount == null || amount.compareTo(BigDecimal.ZERO) < 0)
throw new IllegalArgumentException("Amount must be non-negative");
if (currency == null || currency.trim().isEmpty())
throw new IllegalArgumentException("Currency cannot be blank");
this.amount = amount.setScale(2, RoundingMode.HALF_EVEN); // 标准化精度
this.currency = currency.toUpperCase();
}
}
逻辑分析:校验在构造入口完成,避免非法状态“污染”对象生命周期;
setScale()强制两位小数,消除浮点误差歧义;toUpperCase()统一货币码格式,提升等价性判断可靠性。
零值安全设计的三重保障
- ✅ 构造参数非空/有效校验(防御性编程)
- ✅ 内部字段
final+ 私有访问(防篡改) - ✅ 提供
ofNullable()工厂方法处理外部不确定性输入
| 场景 | 推荐方式 | 安全性 |
|---|---|---|
| 可信内部调用 | 直接构造函数 | ★★★★☆ |
| 外部API/DB读取数据 | Money.ofNullable(amount, code) |
★★★★★ |
| 默认兜底值 | Money.zero("USD") |
★★★★☆ |
2.3 聚合根边界划定:通过方法可见性与包级封装落实一致性约束
聚合根的边界不仅是逻辑划分,更是一致性保障的物理防线。Java 中可通过 package-private(默认访问修饰符)配合模块化包结构,天然隔离外部对聚合内部状态的直接修改。
封装实践示例
// Order.java —— 聚合根,public
public class Order {
private final OrderId id;
private final List<OrderItem> items = new ArrayList<>();
// ✅ 允许外部创建,但仅暴露受控行为
public static Order create(OrderId id) {
return new Order(id); // 构造私有,确保完整性
}
// ✅ package-private 方法,仅限同包内 AggregateRoot 工具调用
void addItem(OrderItem item) {
if (items.size() >= 100) throw new IllegalStateException("Max 100 items");
items.add(item);
}
}
该设计将业务规则(如最大项数)嵌入聚合内部,addItem 不对外暴露,避免跨聚合非法调用;仅允许同包内的 OrderService 或工厂类协调操作,形成包级一致性契约。
可见性约束对比表
| 访问修饰符 | 外部包调用 | 同包调用 | 适用场景 |
|---|---|---|---|
public |
✅ | ✅ | 聚合根入口方法(如 create()) |
package-private |
❌ | ✅ | 内部状态变更(如 addItem()) |
private |
❌ | ❌ | 纯内部辅助逻辑 |
核心原则流图
graph TD
A[外部请求] --> B{是否调用聚合根 public API?}
B -->|是| C[触发受控行为链]
B -->|否| D[编译失败:越界访问]
C --> E[内部 package-private 方法校验不变量]
E --> F[持久化前确保一致性]
2.4 领域事件建模:基于接口解耦与同步/异步发布机制选型
领域事件建模的核心在于契约先行、实现后置。通过定义 IDomainEvent 接口统一事件语义,实现发布者与订阅者在编译期解耦:
public interface IDomainEvent { Guid AggregateId { get; } }
public interface IEventPublisher { Task Publish<T>(T @event) where T : IDomainEvent; }
逻辑分析:
IDomainEvent强制聚合根标识,保障溯源能力;IEventPublisher泛型约束确保类型安全,避免运行时反射开销。AggregateId是事件溯源与幂等校验的关键锚点。
数据同步机制
| 场景 | 同步发布 | 异步发布 |
|---|---|---|
| 订单创建后发短信 | ✅ 强一致性要求 | ❌ 事务无法回滚 |
| 库存扣减后更新推荐 | ❌ 阻塞主链路 | ✅ 高吞吐+失败重试 |
发布策略决策流
graph TD
A[事件触发] --> B{是否需事务强一致?}
B -->|是| C[同步调用IEventPublisher]
B -->|否| D[投递至消息队列]
C --> E[业务事务提交后完成]
D --> F[后台消费者处理]
2.5 领域服务抽象:识别跨聚合协作场景并设计无状态服务层
领域服务是协调多个聚合根完成业务操作的无状态中间层,仅封装跨聚合的业务逻辑,不持有任何领域状态。
何时需要领域服务?
- 订单支付需同步更新库存与用户积分(涉及
Order、Inventory、Account三个聚合) - 跨边界校验(如“同一用户24小时内限购3次”需查询历史订单聚合)
- 外部系统协作(调用风控服务后决策是否放行)
典型实现示例
public class OrderFulfillmentService {
public void fulfill(OrderId orderId) {
Order order = orderRepo.findById(orderId); // 聚合A
Inventory inventory = inventoryRepo.findBySku(order.sku()); // 聚合B
if (inventory.deduct(order.quantity())) { // 状态变更在各自聚合内
accountService.addPoints(order.userId(), order.points()); // 调用另一领域服务
order.markFulfilled(); // 最终一致性保障
}
}
}
▶️ 逻辑分析:OrderFulfillmentService 不保存状态,仅编排聚合行为;deduct() 和 addPoints() 均触发各自聚合的领域规则,确保事务边界清晰。参数 orderId 是唯一输入标识,符合无状态契约。
| 场景 | 是否适合领域服务 | 原因 |
|---|---|---|
| 修改订单地址 | ❌ | 单聚合内操作 |
| 创建订单+扣减库存 | ✅ | 涉及 Order + Inventory |
| 生成报表统计 | ❌ | 属于读模型/查询职责 |
graph TD
A[客户端请求] --> B[OrderFulfillmentService]
B --> C[Order Aggregate]
B --> D[Inventory Aggregate]
B --> E[Account Service]
C -->|验证| F[业务规则]
D -->|扣减| G[库存策略]
第三章:DDD分层架构落地关键练习
3.1 应用层编排:Use Case驱动的请求处理流与错误分类传播
应用层编排以业务场景(Use Case)为第一驱动力,将请求生命周期解耦为可组合、可观测的职责链。
错误分类传播机制
错误按语义分为三类,确保下游能精准响应:
| 类型 | 触发场景 | 传播行为 |
|---|---|---|
BusinessError |
参数校验失败、业务规则冲突 | 返回 400,携带领域语义码(如 ORDER_NOT_FOUND) |
SystemError |
DB 连接超时、下游服务不可达 | 返回 503,附 traceID 供链路追踪 |
FatalError |
JVM OOM、线程池耗尽 | 熔断并触发告警,不透传至客户端 |
Use Case 执行流示例
// OrderCreationUseCase.ts
export class OrderCreationUseCase {
async execute(input: CreateOrderInput): Promise<Order> {
const validated = await this.validator.validate(input); // 1. 输入校验 → 可能抛 BusinessError
const persisted = await this.repo.save(validated); // 2. 持久化 → 可能抛 SystemError
await this.eventBus.publish(new OrderCreated(persisted)); // 3. 事件发布 → 异步,不阻塞主流程
return persisted;
}
}
该实现强制错误在对应层级被捕获并分类包装;validator 抛出 BusinessError 由控制器统一格式化,而 repo.save() 的网络异常被封装为 SystemError 并附加重试策略元数据。
graph TD
A[HTTP Request] --> B[UseCase.execute]
B --> C{校验通过?}
C -->|否| D[BusinessError]
C -->|是| E[持久化操作]
E --> F{DB 响应正常?}
F -->|否| G[SystemError]
F -->|是| H[发布领域事件]
3.2 领域层防腐:适配器模式封装外部API,隔离副作用与领域逻辑
领域模型应纯净无染——不依赖HTTP客户端、不感知JSON序列化细节、不处理重试或超时。适配器模式正是这道关键防火墙。
外部API适配器契约
定义抽象接口,将第三方服务行为建模为领域语义:
class PaymentGateway:
def charge(self, payment_id: str, amount: Decimal) -> PaymentResult:
"""领域语义:发起扣款,返回结果而非响应体"""
raise NotImplementedError
payment_id是领域内唯一标识,amount经过货币值封装(非原始 float),PaymentResult是富领域对象,含状态码、失败原因分类(如InsufficientFunds),完全屏蔽 HTTP status code 与 JSON 字段名。
实现类隔离副作用
class StripeAdapter(PaymentGateway):
def __init__(self, client: stripe.http_client.RequestsClient):
self._client = client # 副作用载体仅在此处注入
def charge(self, payment_id: str, amount: Decimal) -> PaymentResult:
try:
resp = self._client.request("POST", "/v1/charges", json={
"amount": int(amount * 100), # 单位转换副作用
"currency": "usd",
"payment_method": payment_id
})
return PaymentResult.success(resp["id"])
except stripe.error.CardError as e:
return PaymentResult.failure(e.code, e.user_message)
stripe.error.CardError被转化为领域异常类型,int(amount * 100)将业务金额转为支付网关要求的整数分单位——所有技术细节被压缩在适配器内。
防腐效果对比
| 维度 | 未适配直接调用 | 适配器封装后 |
|---|---|---|
| 领域实体依赖 | requests.Session |
PaymentGateway 接口 |
| 错误处理 | except HTTPError |
except InsufficientFunds |
| 测试可替代性 | 需Mock网络层 | 直接注入 MockPaymentGateway |
graph TD
A[OrderService] -->|依赖| B[PaymentGateway]
B --> C[StripeAdapter]
C --> D[stripe.http_client]
C --> E[JSON序列化]
C --> F[重试逻辑]
style D fill:#f9f,stroke:#333
style E fill:#f9f,stroke:#333
style F fill:#f9f,stroke:#333
3.3 基础设施层契约:Repository接口定义与内存/SQL双实现验证
Repository 接口抽象了数据访问的统一语义,屏蔽底层存储差异:
public interface UserRepository {
Optional<User> findById(Long id);
List<User> findAll();
void save(User user);
void deleteById(Long id);
}
该接口不暴露 JDBC 或集合操作细节,findById 返回 Optional 避免空指针,save 隐含幂等性契约。
双实现一致性保障
- 内存实现(
InMemoryUserRepository)用于单元测试,响应快、无副作用 - SQL 实现(
JdbcUserRepository)基于 Spring JDBC Template,事务安全
| 特性 | 内存实现 | SQL 实现 |
|---|---|---|
| 延迟 | O(1) | O(log n) 索引查找 |
| 事务支持 | ❌ | ✅ |
| 数据持久化 | ❌(重启丢失) | ✅ |
数据同步机制
使用共享测试套件验证行为一致性:同一测试用例同时运行于两个实现,断言返回值与状态变更完全等价。
第四章:典型业务场景的Go-DDD完整链路实现
4.1 订单创建流程:从DTO绑定、领域校验到事件发布全链路编码
入参绑定与初步过滤
使用 Spring Boot 的 @Valid + 自定义 OrderCreateDTO 进行基础字段约束(如 @NotBlank, @Min(1)),避免空值或非法数量穿透至领域层。
领域校验核心逻辑
public Result<Order> createOrder(OrderCreateDTO dto) {
// 1. 转换为领域对象(含货币、库存等上下文感知)
Order order = Order.from(dto);
// 2. 领域规则校验(非注解式,含业务语义)
if (!warehouseService.hasStock(order.getItemId(), order.getQuantity())) {
return Result.fail("库存不足");
}
// 3. 持久化并生成唯一订单号
orderRepository.save(order);
// 4. 发布领域事件
eventPublisher.publish(new OrderCreatedEvent(order.getId(), order.getTotalAmount()));
return Result.success(order);
}
Order.from(dto) 封装了金额精度归一化(BigDecimal.setScale)与时间戳赋值;hasStock 调用分布式库存服务,含幂等性校验;OrderCreatedEvent 为不可变事件对象,用于后续履约与对账。
关键校验项对比
| 校验阶段 | 执行主体 | 响应延迟 | 典型错误类型 |
|---|---|---|---|
| DTO绑定 | Web层(Spring MVC) | 参数格式/必填缺失 | |
| 领域校验 | 应用服务层 | ~50ms(含RPC) | 业务规则冲突(如超限购) |
graph TD
A[HTTP Request] --> B[DTO Binding & @Valid]
B --> C{校验通过?}
C -->|否| D[400 Bad Request]
C -->|是| E[Order.from DTO → Domain Object]
E --> F[领域规则校验]
F --> G[DB Persist + Event Publish]
4.2 库存扣减Saga:分布式事务模拟与补偿动作的Go函数式编排
Saga模式通过一系列本地事务与显式补偿操作保障最终一致性。在库存服务中,扣减需联动订单创建与支付确认,任一环节失败须触发逆向补偿。
核心编排结构
采用函数式链式调用,每个步骤返回 func() error 类型的补偿闭包:
// 扣减库存并返回补偿函数
deductStock := func(ctx context.Context, skuID string, qty int) (func() error, error) {
if err := db.Exec("UPDATE inventory SET stock = stock - ? WHERE sku_id = ? AND stock >= ?", qty, skuID, qty); err != nil {
return nil, err
}
// 补偿:回滚库存(加回)
compensate := func() error {
return db.Exec("UPDATE inventory SET stock = stock + ? WHERE sku_id = ?", qty, skuID)
}
return compensate, nil
}
逻辑分析:
deductStock执行原子扣减并预生成补偿函数;参数qty控制数量精度,ctx支持超时与取消;补偿函数不带副作用,仅执行幂等回滚。
Saga执行流程
graph TD
A[开始] --> B[扣减库存]
B --> C{成功?}
C -->|是| D[创建订单]
C -->|否| E[触发补偿]
D --> F{成功?}
F -->|否| E
E --> G[结束]
关键设计约束
- 所有补偿动作必须幂等
- 每步状态需持久化至 Saga 日志表
| 步骤 | 参与服务 | 补偿动作 |
|---|---|---|
| 1 | Inventory | 库存回加 |
| 2 | Order | 订单删除 |
| 3 | Payment | 支付撤回 |
4.3 用户权限上下文:基于中间件注入与领域服务协同的ACL控制
权限上下文的生命周期管理
用户请求进入时,AuthContextMiddleware 自动解析 JWT 并构建 PermissionContext 对象,注入到 HttpContext.Items 中供后续服务消费。
public class AuthContextMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var token = context.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
var claims = JwtSecurityTokenHandler.ReadJwtToken(token).Claims;
// 提取租户ID、角色、资源白名单等关键声明
var contextObj = new PermissionContext
{
TenantId = claims.First(c => c.Type == "tid").Value,
Roles = claims.Where(c => c.Type == "role").Select(c => c.Value).ToArray(),
ResourceScope = claims.FirstOrDefault(c => c.Type == "scope")?.Value ?? "default"
};
context.Items[typeof(PermissionContext)] = contextObj;
await next(context);
}
}
该中间件确保权限上下文在请求生命周期内全局可访问,避免重复解析;TenantId 用于多租户隔离,Roles 支持 RBAC 基础判断,ResourceScope 为细粒度 ACL 提供作用域锚点。
领域服务协同校验流程
ACL 校验由 ResourceAuthorizationService 执行,它结合上下文与领域规则动态决策:
| 输入参数 | 类型 | 说明 |
|---|---|---|
resourceId |
string | 目标资源唯一标识 |
operation |
OperationType | create/read/update/delete |
context |
PermissionContext | 中间件注入的上下文 |
graph TD
A[HTTP Request] --> B[AuthContextMiddleware]
B --> C[PermissionContext in HttpContext.Items]
C --> D[ResourceAuthorizationService.AuthorizeAsync]
D --> E{ACL Rule Engine}
E -->|允许| F[执行业务逻辑]
E -->|拒绝| G[返回403]
核心校验逻辑示例
public async Task<bool> AuthorizeAsync(string resourceId, OperationType op, PermissionContext ctx)
{
var policy = await _policyStore.GetPolicyAsync(resourceId); // 加载资源专属策略
return policy.Evaluate(ctx.Roles, ctx.TenantId, op); // 基于角色+租户+操作三元组匹配
}
policy.Evaluate() 内部采用策略模式组合「租户级默认策略」与「资源级覆盖策略」,支持动态热更新,避免硬编码权限判断。
4.4 查询分离实践:CQRS模式下ReadModel构建与缓存穿透防护
在CQRS架构中,ReadModel需独立于WriteModel演进,支持高并发、低延迟查询。其构建核心在于最终一致性同步与防御性缓存策略。
数据同步机制
采用事件驱动方式,监听领域事件异步更新ReadModel:
public class OrderPlacedHandler : IEventHandler<OrderPlaced>
{
private readonly IReadModelRepository _repo;
public async Task Handle(OrderPlaced @event)
{
var readModel = new OrderSummary
{
Id = @event.OrderId,
Status = "Pending",
CreatedAt = @event.Timestamp
};
await _repo.UpsertAsync(readModel); // 幂等写入,避免重复消费
}
}
UpsertAsync确保事件重放安全;@event.Timestamp用于后续时序校验,防止乱序覆盖。
缓存穿透防护
对不存在的订单ID(如恶意构造的order_999999999)统一返回空对象并缓存(逻辑空值):
| 缓存键 | 值类型 | TTL | 说明 |
|---|---|---|---|
read:order:123 |
OrderSummary | 30min | 正常数据 |
read:order:999999999 |
null |
5min | 防穿透,短TTL降压 |
graph TD
A[请求 order_999999999] --> B{Redis是否存在?}
B -->|否| C[查DB]
C --> D{DB存在?}
D -->|否| E[写入 cache null, TTL=5min]
D -->|是| F[写入真实数据]
关键参数:TTL=5min平衡一致性与防护强度;null值需序列化为显式空对象(非JSON null),避免客户端反序列化失败。
第五章:从练习题到生产代码的跃迁路径
真实需求驱动的重构实践
某电商后台订单导出模块最初由实习生用 Python 写成——单文件脚本,硬编码 MySQL 连接字符串,无异常处理,导出 CSV 时直接 pandas.DataFrame.to_csv() 而未设置 encoding='utf-8-sig',导致 Windows Excel 打开乱码。上线后第3天,客服反馈“导出文件打不开”,运维日志显示 UnicodeEncodeError: 'gbk' codec can't encode character '\u2019'。团队未重写,而是以该脚本为起点,分三步演进:① 提取数据库配置至 .env;② 将导出逻辑封装为 OrderExporter 类,注入 DBConnectionPool 和 CSVWriter 接口;③ 增加单元测试覆盖 UTF-8-BOM、空数据集、超长字段截断等边界场景。最终提交记录显示:原始脚本(127行)→ 重构后核心模块(214行)+ 测试(186行)+ 配置(12行)。
可观测性嵌入开发流程
生产环境故障定位耗时从平均47分钟降至≤3分钟的关键动作:在练习题级函数中强制添加结构化日志。例如原练习题中的 def calculate_discount(items) 被改造为:
import structlog
logger = structlog.get_logger()
def calculate_discount(items, order_id: str):
logger.info("discount_calculation_start", order_id=order_id, item_count=len(items))
try:
result = sum(item.price * item.discount_rate for item in items)
logger.info("discount_calculation_success", order_id=order_id, result=result)
return result
except Exception as e:
logger.error("discount_calculation_failed", order_id=order_id, exc_info=e)
raise
配合 Loki 日志查询语句 | json | order_id="ORD-2024-7890" | level == "error",5秒内定位到某类促销券解析失败。
持续交付流水线的渐进集成
下表对比了练习题代码与生产就绪代码在关键维度的差异:
| 维度 | 练习题实现 | 生产就绪版本 |
|---|---|---|
| 错误恢复 | raise ValueError() |
重试3次 + 降级返回默认折扣率 |
| 输入校验 | assert len(items) > 0 |
Pydantic v2 模型 + 自定义校验器 |
| 性能约束 | 无 | @cache(ttl=300) + Redis 缓存键设计 |
| 安全合规 | 明文日志输出敏感字段 | 自动脱敏(正则匹配银行卡号/手机号) |
架构决策的上下文锚定
使用 Mermaid 流程图展示从本地调试到灰度发布的决策路径:
flowchart LR
A[本地运行练习题] --> B{是否通过单元测试?}
B -->|否| C[修复逻辑并补充测试]
B -->|是| D[集成至 CI 流水线]
D --> E{覆盖率 ≥85%?}
E -->|否| F[增加边界测试用例]
E -->|是| G[部署至预发环境]
G --> H{预发监控告警清零?}
H -->|否| I[回滚并分析指标异常点]
H -->|是| J[灰度发布至5%生产流量]
团队知识沉淀机制
每个 PR 合并前必须提交 ./docs/rationale.md,明确记录:① 为何选择 asyncio.gather() 而非 concurrent.futures;② 数据库连接池大小设为 min(32, CPU_COUNT * 4) 的压测依据;③ 字段加密采用 AES-GCM 而非 RSA 的性能基准数据(实测 QPS 提升2.3倍)。这些文档自动同步至内部 Wiki,并被新成员入职培训引用。
