Nginx与LUA(5)

news2024/11/17 17:33:29

您好,我是湘王,这是我的CSDN博客,欢迎您来,欢迎您再来~


Nginx诞生以来就获赞无数,反向代理、负载均衡、流量限制与流量扩展都是它的拿手好戏。基本上是互联网应用的主流入口,和计算、即时通讯、存储一样,是一种基础且通用的组件,而且对性能和稳定性有很高的要求。

对业务来讲,Nginx又是业务直接和外部交流的接入点,对二次开发和动态变化又有着强烈的以及一些定制化的需求,因此出现了LUA这种嵌入式的脚本语言,它能揉和以及处理各种不同的Nginx上游输出(proxy、log等)。这就像Java的成功依赖于丰富的生态应用一样,OpenResty就是建立在Nginx + LUA之上的一种「生态」:一个基于Nginx与Lua的高性能Web平台,其内部集成了大量的Lua库、第三方模块以及大多数的依赖项。

通过揉和、拼接众多设计良好的Nginx模块,OpenResty有效地把Nginx转变成一个强大的Web应用服务器,它可以随心所欲地做复杂的访问控制、业务处理和安全检测。

基于OpenResty,开发人员可以使用Lua脚本语言对Nginx核心以及现有的各种Nginx模块进行脚本编程,构建出可以处理一万以上并发请求的超高性能的Web应用,可以随意操控、分发、复制、限制、缓存响应头、Cookie及外部存储中的数据信息。有了OpenResty,Nginx不再是一个简单的HTTP服务器,而是可以扩展成为全功能的Web应用服务器了。

安装也很简单,以CentOS为例:

yum install -y readline-devel pcre-devel openssl-devel gcc

cd ~

wget https://openresty.org/download/openresty-1.17.8.2.tar.gz

tar -xvzf openresty-1.17.8.2.tar.gz

cd openresty-1.17.8.2

./configure

gmake && gmake install

先停止之前的nginx服务:

/usr/local/nginx/sbin/nginx -s stop

将默认启动的原生nginx改为openresty:

vi /etc/rc.local

将/usr/local/nginx/sbin/nginx改为/usr/local/openresty/nginx/sbin/nginx:

启动OpenResty:

/usr/local/nginx/sbin/nginx -p /usr/local/openresty/nginx/

访问页面:http://服务器IP/

如果成功,就会出现欢迎页面:

如果不加-p /usr/local/openresty/nginx/参数,是无法启动和停止OpenResty的

/usr/local/nginx/sbin/nginx -p /usr/local/openresty/nginx/

/usr/local/nginx/sbin/nginx -s stop -p /usr/local/openresty/nginx/

访问http://服务器IP/正常

访问http://服务器IP/test?username=test1出现404错误

这是因为此时的配置文件启用的是openresty中的配置文件,所以需要修改一下配置:

拷贝/usr/local/nginx/conf/nginx.conf中的内容到/usr/local/openresty/nginx/conf/nginx.conf

打开端口日志

tail -f /home/work/logs/nginx/8080.log

tail -f /home/work/logs/nginx/9090.log

访问http://服务器IP/test?username=test1

发现之前的流量复制功能也能正常工作,说明OpenResty配置完全正常。

也可以直接使用openresty自带的nginx启动(后续服务都以这种方式启动)

启动:/usr/local/openresty/nginx/sbin/nginx

重启:/usr/local/openresty/nginx/sbin/nginx -s reload

停止:/usr/local/openresty/nginx/sbin/nginx -s stop

编辑lua配置文件,先停止单一的nginx服务:

/usr/local/nginx/sbin/nginx -s stop -p /usr/local/openresty/nginx/

编辑nginx.conf文件:

vi /usr/local/openresty/nginx/conf/nginx.conf

在http部分添加配置:

lua_package_path "/usr/local/openresty/lualib/?.lua;;"; #lua 模块

lua_package_cpath "/usr/local/openresty/lualib/?.so;;"; #c 模块

用openresty启动:

/usr/local/openresty/nginx/sbin/nginx

在/usr/local/openresty/nginx/conf目录下创建一个lua.conf:

echo > /usr/local/openresty/nginx/conf/lua.conf

编辑lua.conf文件:

vi /usr/local/openresty/nginx/conf/lua.conf

给lua.conf增加内容:

server {

listen 80;

server_name _;

}

在nginx.conf的http中包含lua.conf

重启openresty并测试是否正常:

/usr/local/openresty/nginx/sbin/nginx -s reload

/usr/local/openresty/nginx/sbin/nginx -t

测试用lua打印出「hello world」,就要先在lua.conf中server部分添加配置:

location /lua {

default_type 'text/html';

content_by_lua 'ngx.say("hello world")';

}

测试配置是否正确:

/usr/local/openresty/nginx/sbin/nginx -t

重启服务:

/usr/local/openresty/nginx/sbin/nginx -s reload

访问地址就可以看到打印出来的内容:

http://服务器IP/lua

把lua代码放在nginx中,会随着代码的变更导致维护困难,因此应该把lua代码移到外部文件中存储:nginx.conf ⊂ lua.conf ⊂ code.lua(⊂是数学符号中的「包含」的意思,这个的意思是让nginx配置文件包含lua配置文件,让lua配置文件再引用实际的lua代码脚本)。

创建保存lua代码的目录:

mkdir /usr/local/openresty/nginx/conf/lua

增加lua代码文件:

vi /usr/local/openresty/nginx/conf/lua/helloworld.lua

增加一行(最外层没有单引号''):

ngx.say("hello world lua")

修改lua.conf:

content_by_lua_file conf/lua/helloworld.lua; # conf是相对于nginx安装目录而言

lua_code_cache off; # 关闭缓存(便于开发调试,线上生产环境一般都需要打开)

关闭缓存重启后收看到报警:

nginx: [alert] lua_code_cache is off; this will hurt performance in /usr/local/openresty/nginx/conf/lua.conf:7

重启服务:

/usr/local/openresty/nginx/sbin/nginx -s reload

再次访问同样能看到结果:

http://服务器IP/lua

lua可以做很多,包括但不限于:

1、HTTP请求都需要接收请求、处理并输出响应

2、请求包含请求参数、请求头、Body体等信息

3、服务器通过对请求的处理,输出客户端需要的内容

4、响应内容包含响应状态码、响应头和响应内容体

例如输出请求的lua脚本,可以这样写:

vi /usr/local/openresty/nginx/conf/lua.conf

server {

listen 80;

server_name _;

location /request {

default_type 'text/html';

lua_code_cache off;

# 设置nginx变量

set $a $host;

# nginx内容处理

content_by_lua_file conf/lua/request.lua;

# 内容体处理完成后调用

echo_after_body "ngx.var.a = $a";

}

}

创建创建request.lua:

vi /usr/local/openresty/nginx/conf/lua/request.lua

-- 声明nginx变量

local var = ngx.var

ngx.say("ngx.var.a : ", var.a)

var.a = 2;

-- 处理请求头

local headers = ngx.req.get_headers()

ngx.say("=== headers begin ===")

ngx.say("Host : ", headers["Host"])

ngx.say("user-agent : ", headers["user-agent"])

ngx.say("user-agent : ", headers.user_agent)

for k, v in pairs(headers) do

ngx.say(k, ": ", v)

end

ngx.say("=== headers end ===")

-- 处理get参数

ngx.say("=== get args begin ===")

local uri_args = ngx.req.get_uri_args()

for k, v in pairs(uri_args) do

ngx.say(k, ": ", v)

end

ngx.say("=== get args end ===")

-- 处理post参数

ngx.req.read_body()

ngx.say("=== post args begin ===")

local post_args = ngx.req.get_post_args()

for k, v in pairs(post_args) do

ngx.say(k, ": ", v)

end

ngx.say("=== post args end ===")

-- http协议版本

ngx.say("ngx.req.http_version:", ngx.req.http_version())

-- 请求方法

ngx.say("ngx.req.get_method:", ngx.req.get_method())

-- 未解析的请求头

ngx.say("ngx.req.raw_header:", ngx.req.raw_header())

-- 未解析的请求body

ngx.say("ngx.req.get_body_data:", ngx.req.get_body_data())

可以测试一下看看结果:

重启服务:

/usr/local/openresty/nginx/sbin/nginx -s reload

执行curl命令看看效果:

curl -XPOST 'http://服务器IP/request?a=1&b=2' -d 'c=3&d=4'

再比如输出响应的lua脚本,可以这样写:

vi /usr/local/openresty/nginx/conf/lua.conf

server {

listen 80;

server_name _;

location /request {

default_type 'text/html';

lua_code_cache off;

# 设置nginx变量

set $a $host;

# nginx内容处理

content_by_lua_file conf/lua/request.lua;

# 内容体处理完成后调用

echo_after_body "ngx.var.a = $a";

}

location /response {

default_type "text/html";

lua_code_cache off;

content_by_lua_block {

ngx.print("hello")

ngx.flush()

ngx.sleep(1)

ngx.say("world")

return ngx.exit(200)

}

}

}

重启服务:

/usr/local/openresty/nginx/sbin/nginx -s reload

执行curl命令:

curl 'http://服务器IP/response'

一些开发建议:

OpenResty由于集成了大量的lua库和第三方库,因此最好将这些依赖单独放到一次,便于管理,可以参考其他语言的开发习惯,将代码分项目、分层、分包管理。例如:

com.xiangwang.lua.mysql

com.xiangwang.lua.redis

com.xiangwang.lua.page

com.xiangwang.lua... ...


感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python批量下载modis数据(可筛选日期、范围、数据类型)

找了一圈下modis数据的,有的不能空间筛选有的不能下初级产品(也可能没找到),不甚满意,自己搞了个 0 前言 用到的主要依赖是selenium,下载网站是https://ladsweb.modaps.eosdis.nasa.gov,环境是…

ensp实现不同VLAN之间的通信

1.VLAN的基本配置 一个简单的VLAN实验&#xff0c;基本配置如图。 其中交换机为S5700。 在只对四台PC配置IP地址&#xff0c;交换机不用配置后&#xff0c;四台PC可以互相ping通。 下面是对交换机配置VLAN的方法 <Huawei>sys #进入系统视图 [Huawei…

钉钉搭和金蝶云星空接口打通对接实战

数据源系统:阿里宜搭宜搭是阿里巴巴自研的基于钉钉和阿里云的低代码平台&#xff0c;可让用户通过简单的拖拽、配置即可完成应用搭建&#xff0c;为每个组织提供低门槛、高效率的数字化业务应用生产新模式。有效缩减企业应用开发时间&#xff0c;助力企业数字化升级。对接目标系…

第四层:友元与函数成员别样定义

文章目录前情回顾友元友元的概念友元的目的友元的关键字友元的两种种用法全局函数做友元类做友元函数成员的别样定义有缘人学友元&#xff0c;急速突破第四层本章知识点&#xff08;图片形式&#xff09;&#x1f389;welcome&#x1f389; ✒️博主介绍&#xff1a;一名大一的…

Python怎么获取节假日信息?

“holidays” 是一个 Python 第三方库&#xff0c;它可以用来解析和处理节假日信息。 该库提供了一系列函数&#xff0c;可以用来检查某一天是否是节假日、获取某一年中所有节假日的列表等。它支持多种国家和地区的节假日&#xff0c;例如美国、加拿大、澳大利亚、英国等。 “…

【软件架构思想系列】分层架构

- 分层架构 -今天谈下架构设计中的分层思想和分层模型。架构思维概述对于架构思维本身仍然是类似系统思维&#xff0c;结构化思维&#xff0c;编程思维等诸多思维模式的一个合集。由于架构的核心作用是在业务现实世界和抽象的IT实现之间建立起一道桥梁&#xff0c;因此…

CUDA编程笔记(4)

文章目录前言1.CUDA的计时程序2.CUDA程序的计时影响GPU加速的关键总结前言 怎么才能看出使用cuda编程&#xff0c;提高了程序的性能&#xff0c;一般都是通过比较程序运行的时间来验证。所以熟悉程序的运行时间的计时&#xff0c;可以查看优化的性能效果。 1.CUDA的计时程序 …

每日亿题(面试题)

每日亿题(面试题) new Fn和new Fn()有什么区别&#xff1f; 1.首先如果是为传参数的情况下结果是相同的 2.如果是获取属性new Fn() 正常执行&#xff0c;而 new Fn 报错 3.不带括号不能给构造函数传参 分析比较 opacity: 0、visibility: hidden、display: none 优劣和适用…

Spring看这一篇文章就够了

第一章 Spring简介 第1节 Spring的介绍 Spring官网地址 1https://spring.ioSpring的介绍 1Spring是一个开放源代码的设计层面框架&#xff0c;他解决的是业务逻辑层和其他各层的松耦合问题&#xff0c;因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003年兴起的一…

4.2w字,详细的带你认识基础I/O【Linux--基础IO】

前言 相信大家最开始都挺疑惑的&#xff0c;什么I/O。在计算机操作系统中&#xff0c;所谓的I/O实则就是输入&#xff08;Input&#xff09;和输出&#xff08;Output&#xff09;&#xff0c;也可以理解为读&#xff08;Read&#xff09;和写&#xff08;Write&#xff09;&…

Linux常用命令——tar命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) tar Linux下的归档使用工具&#xff0c;用来打包和备份。 补充说明 tar命令可以为linux的文件和目录创建档案。利用tar&#xff0c;可以为某一特定文件创建档案&#xff08;备份文件&#xff09;&#xff0c;也…

mysql 基本组成

1 mysql 基本组成 1.1、mysql连接器的工作流程: 1.2、查看连接状态: show processlist; Note:客户端太长时间没动静 就自动断开 这个时间是由wait_timeout参数控制的,默认8h 长连接短链接 长连接是链接成功后,如果客户端持续有请求,则使用同一个链接[尽量使用长连接,因为每次…

组件间通信

1、Vue组件的嵌套关系 1.1、认识组件的嵌套 前面我们是将所有的逻辑放到一个App.vue中&#xff1a; 在之前的案例中&#xff0c;我们只是创建了一个组件App&#xff1b;如果我们一个应用程序将所有的逻辑都放在一个组件中&#xff0c;那么这个组件就会变成非常的臃肿和难以维…

【网络通信】【电信运营商实战工程师】思科设备篇-思科设备园区网实战

电信运营商实战工程师系列文章. 思科设备篇-思科设备园区网实战. 文章目录1. 思科设备链路捆绑实战2. 思科设备VRRP、HSRP实战3. 思科设备ACL实战全集4. 思科设备RIP协议实战5. 思科设备OSPF协议全集-理论6. 思科设备OSPF协议全集-实战1. 思科设备链路捆绑实战 知识点&#xff…

【中科微北斗+GPS模块经纬度数据解析详细教程-附免费代码工程】

中科微北斗GPS模块经纬度数据解析详细教程-附免费代码工程简介准备工作PC端需要用到的工具代码下载地址GD32F103C8T6最小系统板代码实现GD32串口引脚定义如下&#xff1a;串口的初始化串口0初始化代码&#xff1a;串口1初始化代码串口的输入串口0的输入代码如下&#xff1a;串口…

嵌入式Linux-线程的开始

1. 线程的开始 1.1 线程的含义 学习了进程相关的知识内容&#xff0c;对进程有了一个比较全面的认识和理解&#xff0c;从今开始呢&#xff0c;我们要学习一个新的概念&#xff0c;叫做线程&#xff01; 那什么是线程呢? 与进程类似&#xff0c;线程是允许应用程序并发执行…

java中的方法2023016

定义方法&#xff08;VS函数&#xff09;&#xff1a; 方法是类或对象的行为特征的抽象&#xff0c;方法是类或对象最重要的组成部分。但从功能上来看&#xff0c;方法完全类似于传统结构化程序设计里的函数。区别是&#xff1a;Java里的方法不能独立存在&#xff0c;所有的方法…

《精力管理》阅读笔记

目录 什么是精力及如何管理精力 高效表现有节奏——劳逸结合的平衡 管理精力的三个步骤 明确目标——知道什么最重要才能全情投入 正视现实——你的精力管理做得如何 付诸行动——积极仪式习惯的力量 精力管理的四个基本原则 体能精力——为身体添柴加火 情感精力——把…

微信小程序----全局数据共享

1.什么是全局数据共享 全局数据共享&#xff08;又叫做:状态管理&#xff09;是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有:Vuex、Redux、MobX等。 2.小程序中的全局数据共享方案 在小程序中&#xff0c;可使用 mobx-miniprogram 配合 mobx-miniprog…

【SAP Abap】X档案:SAP Native SQL 简介及本地数据库访问实现方式(EXEC SQL、ADBC、AMDP)

SAP Native SQL 简介及本地数据库访问实现方式&#xff08;EXEC SQL、ADBC、AMDP&#xff09;1、SAP Open SQL 与 Native SQL 的特点2、实现方式方式一&#xff1a;Native SQL&#xff08;Exec SQL&#xff09;&#xff08;1&#xff09;获取单值&#xff08;2&#xff09;获取…