javascript - 带有 session 存储的 NGINX JavaScript 模块(如 Redis)

标签 javascript nginx redis

我知道有可能通过 NGINX 服务器内部的 JS 脚本处理每个请求。

我知道有 Lua Nginx 模块和 Lua Redis 驱动程序,并且可以在 Lua 中编写脚本并直接从 NGINX 服务器使用 Redis。

但是,我想使用 NGINX 的标准功能,并且我更喜欢用 JS 编写代码。我想知道是否可以在 NJS 中使用一些 session 存储?怎么做?特别是,我想使用 Redis 作为 session 存储。

最佳答案

如果避免自己为 Nginx 编译和安装第三方模块,我想用 njs 和 Redis 构建 session 存储的最佳方法是利用内置的 ngx_http_upstream_module模块并设置类似的东西

http {
    [...]

    upstream redis {
        server unix:/var/run/redis/nginx.sock;
    }

    [...]

    js_path conf.d/js/;

    js_import redismiddleware.js;

    [...]

    server {
        [...]

        location /redisadapter {
            internal;

            try_files @dummy @redis;
        }

        location /request-we-are-tracking-no-1/ {
            js_content redismiddleware.processRequestConditional;
        }

        [...]

        location /request-we-are-tracking-no-2/ {
            js_content redismiddleware.processRequestUnconditional;
        }

        [...]
    }
和相应的脚本
var queryString = require('querystring')

function processRequestConditional (request) {
    request.subrequest('/redisadapter', {
        method : 'POST',
        body : queryString.stringify({
          /* data to transfer to Redis */
        })
    }).then(function (response) {
        var reply = {}

        /**
         * parsing and checking feedback from Redis, 
         * saving some data from feedback to reply 
         * object, doing any things as planned, 
         * running any additional routines et 
         * cetera 
         */
        
       if (/* Redis reply is OK */) {
           return reply;
       } else {
           throw new Error('Because we don`t like you!')
       }
    }).then(function (data) {
        /**
         * Making one more subrequest to obtain the content
         * the client is waiting for
         */

         request.subrequest('/secret-url-with-content').then(
            (response) => request.return(response.httpStatus, response.body)
         )
    }).catch((error) {
        /** 
         * Returning to client with response "There will be
         * be no response"
         */
        request.return(403, error.message)
    })
}

function processRequestUnconditional (request) {
    request.subrequest('/redisadapter', {
        method : 'POST',
        body : queryString.stringify({
          /* data to transfer to Redis */
        })
    }).then(function (response) {
        /**
         * parsing and checking feedback from Redis,
         * doing some things, running some or other
         * additional routines depending on reply
         */
    })

    request.subrequest('/secret-url-with-content').then(
        (response) => request.return(response.httpStatus, response.body)
    )
}

export default { processRequestConditional, processRequestUnconditional }
简短的摘要
  • Redis 在 socket 上监听和回复/var/run/redis/nginx.sock
  • 虚拟内部位置 /redisadapter接收来自 njs 脚本的请求,将它们传输到 Redis 并将回复返回给 njs 方法,该方法启动请求序列
  • 为了在某​​个位置与 Redis 建立数据交换,我们控制 Nginx 标准流程并使用自定义 njs 方法维护这些位置
  • 因此,除了 Redis 相关的信息交换例程之外,方法中的代码本身应该实现完整的子例程,即检索请求的内容并将此内容传递回客户端,因为我们从 Nginx
  • 接手了这项工作。
  • 这是通过从服务器到服务器的本地子请求集来实现的,这些子请求对客户端是透明的。 njs 方法完成集合并将请求的内容返回给客户端
  • 上面的示例包含两个方法,processRequestConditional 和 processRequestUnconditional,目的是展示最常用的替代逻辑方法来维护此类任务
  • 第一个,processRequestConditional,演示子请求链 - 即客户端请求的内容,直到 njs 方法忙于其主要任务将下一条数据传输到 Redis session 存储中。而且,如果脚本对Redis的反馈不满意,则完全跳过对客户端的内容请求,而是客户端面临拒绝消息
  • 第二种方法processRequestUnconditional,和上面第一种方法一样,将数据传输到Redis存储中,但是这次客户端请求的命运不取决于Redis反馈的结果,因此同时发出了对内容的二次请求与主要的时间,并在脚本继续与 session 存储进行信息交换时并行流动

  • 当然,我的简短解释在幕后留下了很多细节,但我希望现在基本概念清楚
    随时提出其他问题

    关于javascript - 带有 session 存储的 NGINX JavaScript 模块(如 Redis),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57464963/

    相关文章:

    nginx - 如何将 nginx brotli_static 与 proxy_pass 一起使用?

    c# - Redis ID :xyz is a set of all keys in urn:xyz - no grooming

    javascript - THREE.JS 从 blender 中导出 JSON 模型(包括纹理)

    javascript - 对对象数组中的相似键求和

    javascript - 将表行克隆到另一个表行并修改 HTML

    ubuntu - 通知 http 服务器错误 (Nginx)

    javascript - Jquery 如何在按钮单击后删除并添加一个类,并在其他函数之前延迟时间

    nginx;如果文件存在,则仅使用 try_files 返回响应代码

    ruby-on-rails - Redis 中带有前缀的元素的统计信息

    redis - Spring-xd redis 消息总线从消息中删除 header