右耳菌-邓小白的Java架构师的修炼之路

通过Lua扩展Nginx

2022-07-27  本文已影响0人  右耳菌

1. Nginx的简介

相关内容,可以查看 【Nginx 负载均衡】,这是我之前的一篇文章,这里就懒得再说明一次了。


2. ngx_lua模块

Nginx模块需要用C开发,而且必须符合一系列复杂的规则,最重要的用C开发模块必须要熟悉Nginx的源代码,使得开发者对其望而生畏。

ngx_lua模块通过将lua解释器集成进Nginx,可以采用lua脚本实现业务逻辑。
该模块具备以下特性:

  1. 高并发、非阻塞的处理各种请求。
  2. Lua内建协程,这样就可以很好的将异步回调转换成顺序调用的形式。
  3. 每个协程都有一个独立的全局环境(变量空间),继承于全局共享的、只读的“commandata”。

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

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


3. 协程(Coroutine)

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

  1. 协程并非os线程,所以创建、切换开销比线程相对要小。
  2. 协程与线程一样有自己的栈、局部变量等,但是协程的栈是在用户进程空间模拟的,所以创建、切换开销很小。
  3. 多线程程序是多个线程并发执行,也就是说在一瞬间有多个控制流在执行。而协程强调的是一种多个协程间协作的关系,只有当一个协程主动放弃执行权,另一个协程才能获得执行权,所以在某一瞬间,多个协程间只有一个在运行。
  4. 由于多个协程时只有一个在运行,所以对于临界区的访问不需要加锁,而多线程的情况则必须加锁。
  5. 多线程程序由于有多个控制流,所以程序的行为不可控,而多个协程的执行是由开发者定义的所以是可控的。

Nginx的每个Worker进程都是在epoll或kqueue这样的事件模型之上,封装成协程,每个请求都有一个协程进行处理。这正好与Lua内建协程的模型是一致的,所以即使ngx_lua需要执行Lua,相对C有一定的开销,但依然能保证高并发能力。


4. Nginx进程模型

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

Master进程具体包括如下4个主要功能:
(1) 接收来自外界的信号。
(2) 向各worker进程发送信号。
(3) 监控woker进程的运行状态。
(4) 当woker进程退出后((异常情况下),会自动重新启动新的woker进程。


5. HTTP请求处理



6. ngx_lua指令

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


7. OpenResty


8. ngx_lua 实例

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

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

输出:

$ curl http://127.0.0.1/
$ Hello, world
例子2 例子3 例子4 - 1 例子4 - 2

如果觉得有收获就点个赞吧,更多知识,请点击关注查看我的主页信息哦~

上一篇 下一篇

猜你喜欢

热点阅读