5.OpenResty系列之深入理解(一)

本文基于Centos8进行实践,请读者自行安装OpenResty。

1. 内部调用

进入默认安装路径

cd /usr/local/openresty/nginx/conf
vim nginx.conf
        location /sum {
            # 只允许内部调用
            internal;
            content_by_lua_block {
                local args = ngx.req.get_uri_args()
                ngx.print(tonumber(args.a) + tonumber(args.b))
            }
        }
2. 并行请求
        location /multi {
            content_by_lua_block {
                local start_time = ngx.now()
                local res1, res2 = ngx.location.capture_multi( {
                        {"/sum", {args={a=3, b=8}}},
                        {"/sum", {args={a=3, b=8}}}
                })
                ngx.say("status:", res1.status, " response:", res1.body)
                ngx.say("status:", res2.status, " response:", res2.body)
                ngx.say("time used:", ngx.now() - start_time)
           }    
        }

3. 流水线方式跳转
        location /exec {
            content_by_lua_block {
                ngx.exec("/sum?a=6&b=8")
            }
        }

ngx.redirect为重定向,比如访问baidu.com会重定向https://baidu.com,
ngx.exec方法与ngx.redirect是完全不同的,前者纯粹内部跳转并且没有引入任何额外 HTTP信号

4. 获取GET与POST参数
        location /print_param {
            content_by_lua_block {
                local arg = ngx.req.get_uri_args()
                for k,v in pairs(arg) do
                        ngx.say("[GET ] key:", k, " v:", v)
                end
                ngx.req.read_body() 
                local arg = ngx.req.get_post_args()
                for k,v in pairs(arg) do
                        ngx.say("[POST] key:", k, " v:", v)
                end
            }   
        }
5. 在内部方法中传参
location /test {
       content_by_lua_block {
           local res = ngx.location.capture(
                    '/print_param',
                    {
                       method = ngx.HTTP_POST,
                       args = ngx.encode_args({a = 1, b = '2&'}),
                       body = ngx.encode_args({c = 3, d = '4&'})
                   }
                )
           ngx.say(res.body)
       }
   }

6. 获取请求body
        # 默认读取 body
        lua_need_request_body on;

        location /get_body_data {
            content_by_lua_block {
                local data = ngx.req.get_body_data()
                ngx.say("hello ", data)
            }
        }

7. 输出响应体

ngx.say 与 ngx.print 均为异步输出

如何优雅处理响应体过大的输出?

如果响应体比较小,这时候相对就比较随意,但是如果响应体过大,是不能直接调用 API 完成响应体输出的。响应体过大,分两种情况:

① 输出内容本身体积很大,例如大文件下载
② 输出内容本身是由各种碎片拼凑的,碎片数量庞大,例如应答数据是某地区所有地址数据

第①个情况,要利用HTTP 1.1特性CHUNKED编码来完成,利用 CHUNKED 格式,把一个大的响应体拆分成多个小的应答体,分批、有节制的响应给请求方

# 开启chunked编码
chunked_transfer_encoding on;
location /download_large_file {
    content_by_lua_block {
        -- ngx.var.limit_rate = 1024*1024
        local file, err = io.open(ngx.config.prefix() .. "data.db","r")
        if not file then
            ngx.log(ngx.ERR, "open file error:", err)
            ngx.exit(ngx.HTTP_SERVICE_UNAVAILABLE)
        end

        local data
        while true do
            data = file:read(1024*1024)
            if nil == data then
                break
            end
            ngx.print(data)
            ngx.flush(true)
        end
        file:close()
    }
}

我们在/usr/local/openresty/nginx目录下准备data.db文件,按块读取本地文件内容(每次1MB),并以流式方式进行响应。

第②个情况,其实就是要利用 ngx.print 的特性了,它的输入参数可以是单个或多个字符串参数,也可以是 table 对象

local table = {
     "hello, ",
     {"world: ", true, " or ", false,
         {": ", nil}}
 }
 ngx.print(table)

将输出:

hello, world: true or false: nil

也就是说当有非常多碎片数据时,没有必要一定连接成字符串后再进行输出。完全可以直接存放在 table 中,用数组的方式把这些碎片数据统一起来,直接调用 ngx.print(table) 即可。这种方式效率更高,并且更容易被优化

欢迎关注公众号算法小生

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/266158.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt 多线程用法

文章目录 开发平台QThread 类 moveToThreadQtConcurrent::run QFutureWatcherQThreadPool QRunnable 开发平台 项目说明OSwin10 x64Qt6.6compilermsvc2022构建工具cmake QThread 类 moveToThread 写一个简单的例子吧,比较容易理解,方便入门. 也可以看出这种方式,对于线程…

服务器IBM x3650 m2 管理口访问故障处理

服务器的内存告警后,连接管理口查看信息,管理口状态灯显示正常,但是无法ping通和访问。 处理过程如下: 1、在centos 6.6中安装ipmitool,替换为阿里云的yum源,然后安装。 # wget -O /etc/yum.repos.d/Cen…

Unity自带的NavMesh寻路组件

最近看了一下Unity自带的NavMesh寻路组件,先说一下基本的使用: 首先先把AI Navgation的package包给安装上。 给场景地图添加上NavMeshSurface组件,然后进行烘焙,烘焙出对应的场景地图文件。 给移动物体添加对应的Nav MeshAgent组…

【雷达原理】雷达测速原理及实现方法

一、雷达测速原理 1.1 多普勒频率 当目标和雷达之间存在相对运动时,若雷达发射信号的工作频率为,则接收信号的频率为,其中为多普勒频率。将这种由于目标相对于辐射源运动而导致回波信号的频率发生变化的现象称为多普勒效应。 如图1-1所示&a…

FATFS文件系统

文件系统是为了存储和管理数据,而在存储设备上建立的一种组织结构。 Windows常用的文件系统: 1、FAT12 2、FAT16 3、FAT32 4、exFAT 5、NTFS FAT:File Alloction Table 文件分配表 在小型的嵌入式存储设备大多…

Bwapp学习笔记

1.基本sql语句 #求绝对值 select abs(-1) from dual; #取余数 select mod(10,3); #验证show databases结果是取之于schemata表的 show databases; select schema_name from information_schema.schemata; #查询当前的数据库 select database(); -- 查询数据库版本 s…

Java研学-Servlet 基础

一 概述 1 介绍 Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动…

【数据结构】什么是树?

🦄个人主页:修修修也 🎏所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 📌树的定义 📌树的相关概念 📌线性结构与树结构的对比 📌树的抽象数据类型 📌树的存储结构 &#x1f38…

叮咚,微信年度聊天报告(圣诞节版)请查收~丨GitHub star 16.8k+

微信年度聊天报告——圣诞节特别版,快发给心仪的ta吧~ 开源地址 GitHub开源地址:https://github.com/LC044/WeChatMsg 我深信有意义的不是微信,而是隐藏在对话框背后的一个个深刻故事。未来,每个人都能拥有AI的陪伴,…

Docker - 镜像 | 容器 日常开发常用指令 + 演示(一文通关)

目录 Docker 开发常用指令汇总 辅助命令 docker version docker info docker --help 镜像命令 查看镜像信息 下载镜像 搜索镜像 删除镜像 容器命令 查看运行中的容器 运行容器 停止、启动、重启、暂停、恢复容器 杀死容器 删除容器 查看容器日志 进入容器内部…

2024年【北京市安全员-B证】考试题库及北京市安全员-B证模拟试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年【北京市安全员-B证】考试题库及北京市安全员-B证模拟试题,包含北京市安全员-B证考试题库答案和解析及北京市安全员-B证模拟试题练习。安全生产模拟考试一点通结合国家北京市安全员-B证考试最新大纲…

直接插入排序【从0-1学数据结构】

文章目录 💗 直接插入排序Java代码C代码JavaScript代码稳定性时间复杂度空间复杂度 我们先来学习 直接插入排序, 直接排序算是所有排序中最简单的了,代码也非常好实现,尽管直接插入排序很简单,但是我们依旧不可以上来就直接写代码,一定要分析之后才开始写,这样可以提…

手写线程池

手写线程池 线程池原理 线程池的组成主要分为3个部分,这三部分配合工作就可以得到一个完整的线程池: 任务队列,存储需要处理的任务,由工作的线程来处理这些任务 通过线程池提供的API函数,将一个待处理的任务添加到任…

从归并排序引申到排序链表-图解

从归并排序引申到排序链表 文章目录 从归并排序引申到排序链表归并排序递归版非递归版 排序链表递归版非递归版 归并排序 递归版 //合并排序public static void mergeSort(int[] nums) {mergeSortHelper(0, nums.length, nums); //没有-1}private static void mergeSortHelper…

python 使用 pip 安装第三方库 导入不成功

本文是什么意思呢? 就是你需要使用一些库安装老师或者网上说的 通过pip 安装下载了第三方库,但是使用 import xxx from xxx import xx ,pycharm ide 导入的下面还有红色波浪线,导入不成功。 这是什么原因? 这是pyc…

飞天使-k8s知识点5-kubernetes基础名词扫盲

文章目录 deploymentspodNodeserviceskubectl 实现应用伸缩kubectl 实现滚动更新kubernetes架构 deployments 中文文档 http://docs.kubernetes.org.cn/251.htmldeployment是用来创建和更新应用的,master 会负责将创建好的应用实例调度到集群中的各个节点 应用实例…

Qt 开源项目

Qt 开源项目 Omniverse View链接技术介绍 QuickQanava链接技术介绍QField链接技术介绍 AtomicDEX链接技术介绍 Status-desktop链接技术介绍 Librum链接技术介绍 A Simple Cross-Platform ReaderQPrompt链接技术介绍 GCompris链接技术介绍 Scrite链接技术介绍 QSkinny链接技术介…

力扣思维题——寻找重复数

题目链接:https://leetcode.cn/problems/find-the-duplicate-number/description/?envTypestudy-plan-v2&envIdtop-100-liked 这题的思维难度较大。一种是利用双指针法进行计算环的起点,这种方法在面试里很难说清楚,也很难想到。大致做…

银河麒麟v10 二进制安装包 安装mysql 8.35

银河麒麟v10 二进制安装包 安装mysql 8.35 1、卸载mariadb2、下载Mysql安装包3、安装Mysql 8.353.1、安装依赖包3.2、安装Mysql3.3、安装后配置 1、卸载mariadb 由于银河麒麟v10系统默认安装了mariadb 会与Mysql相冲突,因此首先需要卸载系统自带的mariadb 查看系统…

Quartz.NET 事件监听器

1、调度器监听器 调度器本身收到的一些事件通知,接口ISchedulerListener,如作业的添加、删除、停止、挂起等事件通知,调度器的启动、关闭、出错等事件通知,触发器的暂停、挂起等事件通知,接口部分定义如下&#xff1a…