nginx在X-RateLimit-Remaining标头中设置limit_req的剩余计数

时间:2015-09-15 06:48:38

标签: nginx server devops

我实际上有点惊讶,经过几个小时的谷歌搜索后我找不到任何东西,但问题如下:

我希望nginx可以作为我的API的限制。

我的配置文件包含一个引用良好的<?xml version="1.0" encoding="utf-8"?> <?define ProductVersion = "1.0.0"?> <?define ProductUpgradeCode = "{E8DFD614-41F6-4592-AD7A-27EA8A49C82E}"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"> <Product Id="*" UpgradeCode="$(var.ProductUpgradeCode)" Name="Eyes Relax" Version="$(var.ProductVersion)" Manufacturer="Ourdark" Language="1033"> <Package Manufacturer="Ourdark" InstallerVersion="100" Languages="1033" Compressed="yes" /> <Media Id="1" Cabinet="WHSDiskManagement.1.1.0.0.cab" EmbedCab="yes" /> <Property Id="WHSLogo">1</Property> <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="ProgramFilesFolder" Name="PFiles"> <Directory Id="WHS" Name="Eyes Relax"> <Component Id="EyesRelax" Guid="{78534F5E-FC72-49E6-AF11-4F2068EA7571}"> <File Id="RelaxEyes.exe.config" Name="RelaxEyes.exe.config" Source="RelaxEyes\bin\Debug\RelaxEyes.exe.config" Vital="yes" KeyPath="no" DiskId="1"/> <File Id="RelaxEyes.exe" Name="RelaxEyes.exe" Source="RelaxEyes\bin\Debug\RelaxEyes.exe" Vital="yes" KeyPath="yes" DiskId="1"/> <ServiceInstall Id="ServiceInstaller" Type="ownProcess" Vital="yes" Name="Eyes Relax" DisplayName="Eyes Relax" Description="Eyes Relax" Start="auto" Account="NT AUTHORITY\LocalService" ErrorControl="ignore" Interactive="no"> </ServiceInstall> <ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="Eyes Relax" Wait="yes" /> </Component> </Directory> </Directory> </Directory> <Feature Id="ProductFeature" Title="WHSDiskManagement" Level="1"> <ComponentRef Id="EyesRelax" /> </Feature> </Product> </Wix> 示例:

limit_req_zone

以及包含预期limit_req_zone $binary_remote_addr zone=limit:2m rate=10r/m;

location指令

我希望将nginx附加标头添加到limit_req zone=limit nodelay;X-RateLimit-Remaining属性的响应消息中。基本上,nginx使用X-RateLimit-Reset的活动计数来填充rate=10r/m和相同X-RateLimit-Remaining值的时间范围,以填充rate=10r/m以及刷新前剩余的秒数。< / p>

X-RateLimit-Reset

思考?可能?很想避免让应用程序获得这些数字。

3 个答案:

答案 0 :(得分:0)

我会说这对于nginx的上游版本是不可能的。

您可以通过http://nginx.org/r/limit_req找到limit_req指令的文档,该指令重定向到http://nginx.org/docs/http/ngx_http_limit_req_module.html#limit_req,这最终表明该模块中没有任何已知变量。

看着http://ngx.su/src/http/modules/ngx_http_limit_req_module.c证实了这一猜想。

另一种选择是查看http://nginx.org/docs/varindex.html,其中列出了所有变量-寻找limit只会使您进入$limit_rate,这是一个不相关的变量。


P.S。考虑limit_req是通过泄漏桶方法完成的。

如果不进一步讨论细节或编造东西(维基百科的文章非常多!),我想以一致且可操作的方式向最终用户提供此信息可能并不简单。

答案 1 :(得分:0)

就像@cnst的答案一样,没有合适的变量来保存所需的值,如果您确实想要此消息,则可以实现lua函数来保存此消息。 Nginx配置如下:

http {
    limit_req_zone $binary_remote_addr zone=login:10m rate=2r/s;
    limit_req_status 429;
    limit_conn_status 429;

    server {
        listen       80;
        server_name  [removed];
        set $x-ratelimit-ramaining 0;
        set $x-ratelimit-reset 0;
        access_by_lua_file your_file_name.lua;

        location / {
            limit_req zone=limit nodelay;

            proxy_pass http://reverse-proxy-example;
            add_header  X-RateLimit-Remaining $x-rate-limit-remaining;
            add_header  X-RateLimit-Reset $x-ratelimit-reset;
        }
}

因此,每个请求都将触发lua脚本,并且您可以在lua函数中更新变量$x-rate-limit-remaining $x-ratelimit-reset

答案 2 :(得分:-3)

来自Packngo

Packet功能可能非常适合您需要执行的操作。

来自packngo的样本:

func (r *Response) populateRate() {
    // parse the rate limit headers and populate Response.Rate
    if limit := r.Header.Get(headerRateLimit); limit != "" {
        r.Rate.RequestLimit, _ = strconv.Atoi(limit)
    }
    if remaining := r.Header.Get(headerRateRemaining); remaining != "" {
        r.Rate.RequestsRemaining, _ = strconv.Atoi(remaining)
    }
    if reset := r.Header.Get(headerRateReset); reset != "" {
        if v, _ := strconv.ParseInt(reset, 10, 64); v != 0 {
            r.Rate.Reset = Timestamp{time.Unix(v, 0)}
        }
    }
}