OLC 架构概览

项目定位

OLC (Overload Control Library) 是一个 Python 过载控制库,为 Web 服务提供限流和过载保护能力。

核心能力:

  • QPS 限流:基于令牌桶的每秒请求数控制
  • 并发限流:基于信号量的并发数控制
  • 配额限流:基于配额桶的总量控制(含响应配额模式)
  • 准入控制:允许/拒绝/动态准入三种模式
  • 自适应算法:PID 等算法动态调整限流阈值
  • 集群限流:基于 Redis + Lua 脚本的分布式限流

架构总览

HTTP 请求
   │
   ▼
┌─────────────────────┐
│  Framework Adapter  │  (FastAPI / Flask / Django)
│  (提取标签 + 拦截)   │
└─────────┬───────────┘
          │ OlcControlRequest(tags, token_number)
          ▼
┌─────────────────────┐
│     OLC.process()   │
│  创建 OlcContext     │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────────────────────────────────┐
│              Handler Chain (责任链)               │
│                                                  │
│  GroupMatcherHandler → AdmissionHandler          │
│        → FlowHandler → StatisticHandler          │
│                                                  │
│  in_coming: 前置判定(匹配→准入→限流→统计)        │
│  out_coming: 后置处理(统计→限流回补→准入→匹配)   │
└─────────┬───────────────────────────────────────┘
          │
          ▼
┌─────────────────────┐
│  context.result      │
│  block=True/False    │
│  block_msg           │
│  tokens_to_deduct    │
└─────────┬───────────┘
          │
          ▼
   block=True → 返回 429 响应
   block=False → 执行业务逻辑 → OLC.clean() 释放资源

核心流程

请求处理流程 (OLC.process)

  1. 创建 OlcContext,包含 OlcControlRequestOlcControlResult
  2. 检查全局开关 sdk_config.switch,若关闭则直接返回
  3. 执行责任链 OlcHandlerChain.chain.in_coming(context, groups)
  4. 返回 OlcContext,由适配器根据 context.result.block 决定是否放行

资源释放流程 (OLC.clean)

  1. 检查全局开关
  2. 执行责任链 OlcHandlerChain.chain.out_coming(context)
  3. out_coming 中:
    • StatisticHandler:递减并发计数
    • FlowHandler:处理响应配额模式的令牌调整(tokens_to_deduct

责任链执行顺序

顺序 Handler in_coming 职责 out_coming 职责
1 GroupMatcherHandler 根据请求标签匹配规则分组 无特殊处理
2 AdmissionHandler 准入判定(allow/deny/dynamic) 无特殊处理
3 FlowHandler 流控判定(获取令牌/回滚) 响应配额令牌调整
4 StatisticHandler 递增并发计数 递减并发计数

短路机制:当某个 Handler 判定拒绝后,设置 context.stop = True,后续 Handler 的 in_coming 跳过核心逻辑但仍传递到下一个节点。

关键设计模式

单例模式

OLC 中大量使用单例模式管理全局状态,统一约定如下:

class SomeManager:
    _instance = None
    _lock = threading.Lock()  # 或 RLock

    @classmethod
    def get_instance(cls) -> "SomeManager":
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = cls()
        return cls._instance

使用单例的类:OLCOlcConfigManagerOlcRuleManagerOlcRuleConvertOlcAlgManagerOlcRateLimiterFactoryAdmissionFactoryOlcCollectorManagerOlcConfigPluginManagerOlcScheduleManagerDimensionEvent

责任链模式

AbsBoxHandler 定义了双向链式调用:

  • in_coming(context, groups):前置处理,通过 next_in_coming() 传递到下一个 Handler
  • out_coming(context):后置处理,通过 next_out_coming() 传递到 private Handler(即 in_coming 方向的前一个 Handler)

链的构建在 OlcHandlerChain 中静态完成:

chain = DefaultBoxHandlerChain()
chain.add_last_box(GroupMatcherHandler())
chain.add_last_box(AdmissionHandler())
chain.add_last_box(FlowHandler())
chain.add_last_box(StatisticHandler())

工厂模式

  • OlcRateLimiterFactory:根据 FlowControlModePolicyType 创建对应的限流器实例,内部使用 SafeTTLCache 缓存
  • AdmissionFactory:根据 AdmissionType 创建准入控制器实例

观察者模式

基于 blinker 库实现事件总线:

class Event:
    OLC_CLEAN_RULE = signal('OLC_CLEAN_RULE', '规则更新事件')

规则变更时发送事件:Event.get_instance().OLC_CLEAN_RULE.send()

各缓存组件订阅该事件以清理缓存:Event.get_instance().OLC_CLEAN_RULE.connect(self.subscribe_clean)

插件模式

配置源通过 Stub 抽象和 OlcConfigPluginManager 实现插件化:

class Stub(ABC):
    def get_olc_config_rules(self) -> Optional[str]: ...

class OlcConfigPluginManager:
    def register_stub(self, name, stub): ...
    def get_stub_plugin(self, name): ...

线程模型

线程 启动位置 职责 生命周期
配置热加载 PropertiesManager._start_watcher 定期检查配置文件修改时间,变更时重新加载 daemon 线程,随主进程退出
规则刷新 OlcRuleConvert.start_task 定期从配置源拉取规则并更新缓存 通过 OlcScheduleManager 管理
算法刷新 OlcAlgRefreshManager.start 定期刷新动态限流器的算法参数 通过 OlcScheduleManager 管理
集群限流刷新 OlcClusterLimiterRefresh.start 定期刷新集群限流器的令牌 daemon 线程
采集器 AbsCollector.start 定期采集资源指标 通过 OlcScheduleManager 管理

锁策略

  • threading.Lock:用于单例的 get_instance() 双重检查锁(OLC、OlcConfigManager、AdmissionFactory、Event、Dimension)
  • threading.RLock:用于需要重入的场景(OlcRuleManager、OlcRateLimiterFactory、OlcRuleConvert、GroupMatcher、PropertiesManager)

目录结构

olc/
├── adapters/           # 框架适配器(FastAPI 等)
│   └── fastapi/       # FastAPI 中间件适配器
├── admission/          # 准入控制(Allow/Deny/Dynamic)
├── alg/               # 自适应算法
│   └── flow/          # 流控算法(PID 等)
├── bean/              # 数据模型(请求/结果/规则/标签/维度)
├── cache/             # 线程安全 TTL 缓存
├── collector/         # 资源采集器
│   └── vllm_resource/ # vLLM 资源采集
├── config/            # 配置管理(Properties 加载/热加载)
├── control/           # 控制逻辑(责任链/Handler/Matcher)
│   ├── context/       # 请求上下文
│   ├── handler/       # 四大 Handler
│   ├── handler_chain/ # 责任链构建
│   └── matcher/       # 标签/策略匹配器
├── encryptor/         # 配置加密/解密
├── event/             # 事件总线(blinker)
├── exception/         # 异常定义
├── limit/             # 限流器
│   ├── cluster/       # 集群限流(Redis + Lua)
│   └── node/          # 单机限流
│       ├── dynamic/   # 动态限流器
│       └── static/    # 静态限流器(QPS/并发/配额)
├── remote/            # HTTP 客户端
├── resource/          # 静态资源
│   └── redis/
│       └── lua_scripts/ # 集群限流 Lua 脚本
├── rule/              # 规则管理(转换/缓存/查询)
├── statistic/         # 并发统计
├── stub/              # 配置源插件
├── task_schedule/     # 定时任务调度
└── utils/             # 工具函数