目录

  • 1.ngx_lua模块
  • 2.协程(Coroutine)
  • 3.Nginx进程模型
  • 4.HTTP请求
  • 5.ngx_lua指令
  • 6.OpenRestry
  • 7.nginx_lua实例


1.ngx_lua模块

ngx_lua模块通过将lua解释器集成进,可以采用lua脚本实现业务逻辑。

该模块具备以下功能:
高并发非阻塞的处理各种请求。
Lua内建协程,这样可以很好的将异步回调转换成顺序调用的形式。
每个协程都有一个独立的全局环境(变量空间),继承于全局共享、只读的"comman data"。

得益于Lua协程的支持,ngx_lua在处理10000个并发请求时只需要很少的内存。根据测试ngx_lua处理每个请i去只需要2KB的内存,如果使用LuaJIT则会更少。

ngx_lua非常适合用于实现可扩展的、高并发的服务

2.协程(Coroutine)

协程类似一种多线程,与多线程的区别有:

协程并非OS线程,所以创建、切换开销比线程相对要小。
协程与线程一样有自己的栈、局部变量等,但是协程的栈是在用户进程空间模拟的,所以创建、切换开销很小。

多线程程序是多个线程并发执行,也就是说在一瞬间有多个控制流在执行。而协程强调的是一种多个协程间协作的关系,只有当一个协程主动放弃执行权,另一个协程才能获得执行权,所以在某一瞬间,多个协程间只有一个在运行。

由于多个协程时只有一个在运行,所以对于临界区的访问不需要加锁,而多线程的情况则必须加锁。
多线程程序由于有多个控制流,所以程序的行为不可控,而多个协程的执行是由开发者定义的所以是可控的

Nginx的每个 Worker进行都是在epoll或kqueue这样的事件模型之上,封装成协程,每个请求都有一个协程进行处理。

这正好与Lua内建协程的模型是一致的,所以即使ngx_lua需要执行Lua,相对C有一定的开销,但是依然能保证高并发能力

3.Nginx进程模型

Nginx采用多进程模型,单Master–多Worker,Master进程主要用来管理Worker进程。
Worker进程采用单线程、非阻塞的事件模型(Event Loop,事件循环)来实现端口的监听及客户端请求的处理和响应,同时Worker还要处理来自Master的信号。Worker进程个数一般设置为机器CPU核数。

Master进程具体包括如下4个主要功能

接受来自外界的信号

向各个worker进程发送信号

监控worker进程的运行状态

当worker进程退出后(异常情况下),会自动重新启动新的worker进程。

nginx基于线程池设置当前线程优先级 nginx 协程_Lua

4.HTTP请求

工作在7层模型之上OSI,通常用做HTTP的负载均衡、反向代理,接受到HTTP请求后,对这个请求进行处理,处理之后可以通过反向代理转发到后端服务器上,进行计算,返回结果它,它再返回给客户端。Nginx处理每个HTTP请求是分阶段的,分为11个阶段,不同阶段做不同工作。

lua可以给nginx开发模块,扩展功能,也是对不同阶段进行扩展,例如:日志阶段,开发日志模块。

  • 划分阶段,架构清晰,可以在不同阶段进行扩展。

阶段

说明

post-read

读取请求内容阶段,nginx读取并解析完请求头之后立即开始运行

server-rewrite

server请求地址重写阶段

find-config

配置查找阶段,用来完成当前请求与location配置块之间的配对工作

rewrite(常用)

location请求重写阶段,当ngx_rewrite指令用于location中,就是在这个阶段运行的。

post-rewrite

请求地址重写提交阶段,当nginx完成rewrite阶段所有要求的内部跳转动作,如果rewrite阶段有这个要求的话

preaccess

访问权限检查准备阶段,ngx_limit_req和ngx_limit_zone在这个阶段运行,ngx_limit_req可以控制请求的访问频率,ngx_limit_zone可以控制访问的并发度

access

权限检查阶段,ngx_access在这个阶段运行,配置指令多是执行访问控制相关的任务,如检查用户的访问权限,检查用户的来来源IP是否合法

post-access

访问权限检查提交阶段

try-files

配置项try_files处理阶段

content

内容产生阶段,是所有请求处理阶段中最为重要的阶段,因为这个阶段的指令通常是用来生成HTTP响应内容的

log

日志模块处理阶段。

5.ngx_lua指令

ngx_lua属于nginx的一部分,它的执行都包含在nginx的11个步骤之中了,响应的处理阶段可以做到插入式处理,即可插拔式架构,不过nginx_lua并不是所有的阶段都会运行的;
另外指令可以在http、server、server if、location、location if几个范围进行配置:

指令

所处处理阶段

使用范围

解释

init_by_lua、init_by_lua_file

loading-config

http

nginx Master进程加载配置时执行;通常用于初始化全局配置/预加载Lua模块

init_work_by_lua、init_work_by_lua_file

starting-worker

http

每个Nginx Worker进程启动时调用的计时器,如果Master进程不允许则会在init_by_lua之后调用;通常用于定时拉取配置/数据,或者后端服务的健康检查

set_by_lua、set_by_lua_file

rewrite

server,server,if,location,location if

设置nginx变量,可以实现复杂的赋值逻辑;此处是阻塞的,Lua代码要做到非常快;

rewrite_by_lua、rewrite_by_lua_file

rewrite tail

http,server,location,location if

rewrite阶段处理,可以实现复杂的转发/重定向逻辑;

access_by_lua、access_by_lua_file

access tail

http,server,location,location if

请求访问阶段处理,用于访问控制

content_by_lua、content_by_lua_file

content

location,location if

内容处理器,接收请求处理并输出响应

header_filter_by_lua、header_filter_by_lua_file

output-header-filter

http,server,location,location if

设置header和cookie

body _filter_by_lua、body_filter_by_lua_file

output-body-filter

http,server,location,location if

对响应数据进行过滤,比如截断、替换。

log_by_lua、log_by_lua_file

log

http,server,location,location if

log阶段处理,比如记录访问量/统计平均响应时间

6.OpenRestry

概念:OpenRestry是一个基于Nginx与Lua的高性能Web平台,其内部集成了大量精良的Lua库、第三方模板以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网关。

工作原理:OpenRestry通过汇聚各种设计精良的Nginx模块(主要由 OpenResty 团队自主开发),从而将Nginx有效地变成一个强大的通用Web应用平台。这样,Web开发人员和系统工程师可以使用Lua脚本语言调用Nginx支持的各种C以及Lua模块,快速构造出足以胜任10K乃至1000K以上单机并发连接的高性能Web应用系统。

目标:OpenRestry的目标是让你的Web服务直接跑在Nginx服务内部,充分利用Nginx的非阻塞I/O模型,不仅仅对HTTP客户端请求,甚至对远程后端诸如MySQL PostgreSQL Memcached Redis等都进行一致的高性能响应。

  • 有了Lua之后,Ngnix不只是做简单的转发,还可以支持动态脚本,写逻辑,甚至可以访问数据库,成为业务服务器。

7.nginx_lua实例

content_by_lua:内容处理器,接收请求处理并输出响应。

该指令工作正在Nginx处理流程的content阶段,即内容产生阶段,是所有请求处理阶段中最为重要的阶段,因为这个阶段的指令通常是用来生成HTTP响应内容的;

nginx基于线程池设置当前线程优先级 nginx 协程_Nginx_02


输出:

$curl http://127.0.0.1/
$Hello,world