16

关于OpenResty里的ngx.on_abort

 5 years ago
source link: https://blog.huoding.com/2020/04/13/812
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

关于 OpenResty 里的 ngx.on_abort ,官方文档里是这样说明的:

Registers a user Lua function as the callback which gets called automatically when the client closes the (downstream) connection prematurely.

也就是说:当客户端提前关闭连接的时候,在 ngx.on_abort 里注册的函数会被触发,下面做个实验看看,把如下代码加入 nginx.conf,并 reload 进程使其生效:

lua_check_client_abort on;

location /test_http {
    content_by_lua_block {
        ngx.on_abort(function(a)
            ngx.log(ngx.ERR, "abort")
        end)

        ngx.sleep(100)
    }
}

开启两个命令行窗口:一个 tail -f error.log,另一个 curl http://localhost/test_http。因为我在代码里设置了 sleep,所以 curl 无疑会卡住,通过执行 Ctrl+c 强行终止,以此构造出一个客户端提前关闭连接的场景,此时我们在 tail 窗口就能看到输出了 log,由此可知当客户端提前关闭连接的时候,在 http 的情况下, ngx.on_abort 里注册的函数会被触发。

不过如果你仔细查看和 ngx.on_abort 相关的 lua_check_client_abort 的文档,会发现:

According to the current implementation, however, if the client closes the connection before the Lua code finishes reading the request body data via ngx.req.socket, then ngx_lua will neither stop all the running “light threads” nor call the user callback (if ngx.on_abort has been called). Instead, the reading operation on ngx.req.socket will just return the error message “client aborted” as the second return value (the first return value is surely nil).

也就是说,当客户端提前关闭连接的时候,如果 ngx.req.socket 中的数据没有被读取,那么 ngx.on_abort 里注册的函数不会被触发。实际上指的就是非 http 情况,也就是自己处理 socket 的情况,比如 websocket:

lua_check_client_abort on;

location /test_websocket {
    content_by_lua_block {
        ngx.on_abort(function()
            ngx.log(ngx.ERR, "abort")
        end)

        local server = require "resty.websocket.server"
        local wb = server:new()

        while true do
            local data, typ, err = wb:recv_frame()

            if wb.fatal then
                ngx.log(ngx.ERR, "failed to receive frame: ", err)
                return ngx.exit(444)
            end
        end
    }
}

然后通过一个网页来调用如上的 websocket 服务:

<script>
new WebSocket("ws://127.0.0.1/test_websocket");
</script>

与之前不同的是,因为我们要执行网页中的 javascript 代码,所以必须通过浏览器来执行 test_websocket 请求,而不是 curl,当请求发出后,会连接 websocket,直接关闭浏览器,以此构造出一个客户端提前关闭连接的场景,此时我们在 tail 窗口就能看到输出了 log,但是却不是 ngx.on_abort 的 log,而是 wb.fatal 的 log,由此可知当客户端提前关闭连接的时候,在 websocket 的情况下, ngx.on_abort 里注册的函数不会被触发。

于是我们得出结论:通过 ngx.on_abort 检测客户端是否提前断开连接的方法,仅仅对 http 场景有效,对其它需要要手动处理 socket 数据的场景(比如 websocket)无效,对于此类场景,可以读取 socket 数据,通过报错信息来判断客户端是否提前关闭了连接。


Recommend

  • 14

    基于ngx_lua模块的waf开发实践 zhangsan

  • 7

    ngx_lua_waf适应多站点情况的研究 zhangsan

  • 51
    • seven.ooo 6 years ago
    • Cache

    Laravel Pjax 总是 abort(422)

    使用 spatie/laravel-pjax 的时候遇到总是 abort(422) 的情况,查了一圈大多说原因是渲染的页面里找不到监听的 pjax container。 可检查过后我的页面里都是有 id="pj...

  • 28
    • www.cnblogs.com 4 years ago
    • Cache

    ngx_align 值对齐宏

    ngx_align 值对齐宏 ngx_align 为nginx中的一个值对齐宏。主要在需要内存申请的地方使用,为了减少在不同的 cache line 中内存而生。 // d 为需要对齐的 // a 为对齐宽度,必须为 2 的幂 // 返回对齐值 #define ngx...

  • 17

    Example of Angular 4 Pagination Using ngx-pagination This tutorial help to implement Angular 4 pagination into HTML table using ngx-pagination.I will demonstrate how to implement HTML listing with pagination us...

  • 19
    • www.digitalocean.com 3 years ago
    • Cache

    How To Use ngx-translate with Angular

    Tutorial How To Use ngx-translate with Angular Angular Introduction At some point,...

  • 4
    • nginx.org 3 years ago
    • Cache

    Module ngx_http_ssl_module

    Module ngx_http_ssl_module The ngx_http_ssl_module module provides the necessary support for HTTPS. This module is not built by default, it should be enabled with the --with-http_ssl_module configu...

  • 6
    • fann.im 2 years ago
    • Cache

    ngx_lua vs Go

    ngx_lua vs Go Nov 7, 2015 由于移动互联网的火爆,前后端分离的开发模式越来越流行:后端通过 API 提供数据,前端 native or web 做数据展示交互。那么谁能把吐数据这件事做的又快又好,谁就比...

  • 3
    • www.jansora.com 2 years ago
    • Cache

    Openresty 常用的 ngx 包和方法

    openresty 都有哪些 ngx 包或方法 OpenResty 是一个基于 Nginx 和 LuaJIT 的 Web 平台,提供了大量的模块和库以便开发高性能的 Web 应用。以下是一些常见的 OpenResty 与 Nginx 相关的 ngx 模块和方法: ngx_http_lua_mo...

  • 13
    • nginx.org 1 year ago
    • Cache

    Module ngx_http_proxy_module

    Module ngx_http_proxy_module The ngx_http_proxy_module module allows passing requests to another server. Example Configurationlocation / { proxy_pass http://localhost:8000; pro...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK