You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cowboy请求分发前执行操作?节点过载时快速返回503

在Cowboy路由分发前执行预检查的实现方案

当然可以在Cowboy路由分发前执行自定义逻辑,最简洁高效的方式是利用Cowboy中间件机制——你可以在cowboy_router这个路由中间件之前插入自己的中间件,专门处理节点过载检查,无需在每个请求处理器中重复代码。

实现步骤

1. 编写自定义过载检查中间件

创建一个模块(比如overload_check_middleware),实现Cowboy中间件的init/2回调函数。这个函数会在路由分发前被调用:

-module(overload_check_middleware).
-behaviour(cowboy_middleware).

-export([init/2]).

init(Req, Env) ->
    % 这里写你的过载检查逻辑,比如检查进程数、内存占用或者自定义指标
    case is_node_overloaded() of
        true ->
            % 过载时直接返回503响应,终止中间件链
            Req503 = cowboy_req:reply(503,
                #{<<"content-type">> => <<"text/plain">>},
                <<"Service Unavailable">>,
                Req),
            {stop, Req503};
        false ->
            % 正常则继续执行后续中间件(包括路由分发)
            {ok, Req, Env}
    end.

% 示例过载检查函数,根据实际需求实现
is_node_overloaded() ->
    % 比如检查当前进程数是否超过阈值
    {_, ProcessCount} = erlang:statistics(process_count),
    ProcessCount > 10000. % 假设阈值是10000

2. 修改Cowboy启动代码,注入中间件

在启动cowboy时,需要在ProtoOpts的middlewares参数中,把自定义中间件放在cowboy_router之前。默认的中间件链是[cowboy_router, cowboy_handler],我们要插入自己的中间件:

Dispatch = cowboy_router:compile([
    {'_', [
         {"/one", my_handler1, #{}},
         {"/two", my_handler2, #{}},
         {"/three", my_handler3, #{}},
         {"/four", my_handler4, #{}}
    ]}
]),

% 自定义中间件链:先执行过载检查,再路由,最后处理请求
Middlewares = [overload_check_middleware, cowboy_router, cowboy_handler],

cowboy:start_clear(my_http_listener,
    [{port, 8080}],
    #{
        env => #{dispatch => Dispatch},
        middlewares => Middlewares % 注入中间件链
    }
).

关键说明

  • 中间件的执行顺序严格按照middlewares列表的顺序,所以必须把自定义检查放在cowboy_router前面,才能在路由分发前拦截请求。
  • 当中间件返回{stop, Req}时,整个请求处理链会终止,直接返回响应,不会再走到路由和处理器环节,性能开销极低。
  • is_node_overloaded/0函数需要根据你的实际业务场景实现,比如结合监控系统的指标、CPU使用率、队列长度等。

内容的提问来源于stack exchange,提问作者Ted Mosby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 09:50:25