首页 > 系统相关 >Nginx与LUA(7)

Nginx与LUA(7)

时间:2023-01-23 21:45:18浏览次数:40  
标签:协程 coroutine resume nginx Nginx 线程 conf LUA

您好,我是湘王,这是我的博客园。值此新春佳节,我给您拜年啦~祝您在新的一年中所求皆所愿,所行皆坦途,展宏“兔”,有钱“兔”,多喜乐,常安宁!

 


 

 

软件开发中,除了进程和线程,还有协程的概念。但是在搞清楚协程这个概念之前,需要明白什么是进程和线程。

进程一般是应用程序的启动实例,进程拥有代码和打开的文件资源、数据资源、独立的内存空间,例如,独立部署的jar包、运行的redis、mongodb程序等,都可以成为进程。

而线程从属于进程,是应用程序的实际执行者,一个进程至少包含一个主线程,或者有更多的子线程,线程拥有自己的栈空间。

看起来,在同一时刻多个线程是同时执行的,也就是并发执行的,但由于若干个线程对应同一个CPU,所以同一个时刻其实只有一个线程是处于执行状态的。在一个时间片内执行哪个线程是不确定的,只能控制线程的优先级,但真正的线程调度是由CPU决定的。

 

 

 

般情况下,各个线程都是比较独立的,各自也有明确的生命周期,如初始化、可运行、运行中、阻塞、销毁等不同的状态。

 

 

 

如果线程之间需要协作或者通信,那么可以通过volatile关键字、wait/notify方法、JUC工具类,或者是消息队列MQ实现。无论如何,线程都会涉及到线程锁、状态切换及上下文切换。

协程是一种比线程更加轻量级的存在,是「线程中的线程」。协程也拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协程共享全局变量和其它内容。

 

 

 

协程不被操作系统管理,而是完全由线程内部控制,由程序显式的进行,需要多个程序彼此协作才能完成功能,这就是协程名字的由来。

协程不是进程也不是线程,它是通过特殊的函数来实现的——这个特殊的函数可以在某个地方「挂起」,之后可以重新在其他的地方继续运行。

一个线程之内可有多个这样特殊的函数,也就是有多个协程同时运行,但多个协程的运行只能是「串行」的——一个协程运行时,其他协程必须要挂起。同时还要明确:协程也是有切换的,但它的切换不是像进程或线程那样由操作系统完成,而是由用户完成的,所以切换效率比进程或线程高。或者可以打一个这样的比方:协程类似于正在同步中的多线程,而在等待同一个线程锁的几个线程也类似于协程。

协程是LUA中引入的概念,由于OpenResty是对LUA的封装,因此也自然就具备了协程特性。

具体来说,resume和yeild是Lua协程的核心。首次调用时,resume的参数会直接传递给协程函数。非首次调用时,resume的另一个参数会成为yield的返回值,而yield的参数,也会成为resume额外的返回值。

 

 

 

coroutine.create(function)会传一个函数作为参数来创建协程,返回coroutine,当遇到resume时就唤醒函数调用。

而coroutine.yield()使正在执行的函数挂起,传递给yeild的参数会作为resume的额外返回值。

先来验证coroutine.create和coroutine.resume。

修改Nginx配置文件,将原来的include lua.conf改为xiecheng.conf。

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

 

 

 

修改xiecheng.conf内容:

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

 

 

 

修改完成后重启openresty:

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

访问浏览器:

http://IP地址/xiecheng

可以看到三次结果都不同:这其实就是resume返回值的三种情况

 

 

 

其他的协程方法包括:

1、coroutine.isyieldable(),表示如果正在运行的协程可以挂起,则返回true(只有主协程(线程)和C函数是无法让出的);

2、coroutine.running(),用来判断当前执行的协程是不是主线程,如果是就返回true;

3、coroutine.status(function),返回表示协程状态的字符串:

running:正在执行中的协程;

suspended:还未结束却被挂起(调用了yeild或还没开始运行)的协程;

normal:协程A resume协程B时,协程A所处的状态就是normal;

dead:发生错误或正常终止的协程,如果这时候对它调用resume,将返回false和错误消息,就像刚才展示的那样。

修改配置文件验证语法:

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

 

 

 

修改完成后重启openresty:

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

访问浏览器:

http://IP地址/xiecheng3

 

 

 

协程时序图:

 

 

 

通过以上语法,可以得到几个关于OpenResty协程的知识:

1、所有的协程都是通过resume和yield协作的,这是协程的核心所在,可以说没有resume和yield的协作,就没有协程;

2、resume和yield都是由开发者控制的,除此之外,是不会有任何其他第三方系统干预的,但线程就不一样;

3、函数从哪里挂起,恢复时就从哪里开始执行,关于这一点,可以尝试在r1中的coroutine.yield("b")前后各加上一行ngx.print()语句来验证。

这只是Lua协程的很小一部分,Lua中没有线程和异步编程的概念,但对于并发执行却提供了协程的方式,这确实有点奇怪。ngx_lua模块对协程做了封装,可以直接通过ngx.thread API来调用。其原理就是协程A在运行中发现自己忙,则把CPU使用权让出来给协程B使用,最后协程A能从中断位置继续执行,本地还是CPU独占的单线程。

 

 


 

 

节日期间,您仍然可以随时咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~再次祝您兔年吉祥,万事胜意!

标签:协程,coroutine,resume,nginx,Nginx,线程,conf,LUA
From: https://www.cnblogs.com/xiangwang1111/p/17065559.html

相关文章

  • nginx添加身份认证
    前言有一些静态网站资源,我们不希望所有人都可以访问,那么可以简单使用nginx内置模块实现身份认证。实现修改配置文件:auth_basic"nginxbasichttptest";auth_basic_us......
  • Nginx 系列 | (转)Nginx 上传文件:client_max_body_size 、client_body_buffer_size
    原文:http://php-note.com/article/detail/488client_max_body_sizeclient_max_body_size默认1M,表示客户端请求服务器最大允许大小,在“Content-Length”请求头中指......
  • nginx索引静态文件
    前言针对nas服务器文件下载或者需要索引一些静态二进制文件的地方,可以利用nginx自带的索引文件功能实现。root/var/www/html;#索引目录autoindexon;autoindex_exact_......
  • nginx索引静态文件
    前言针对nas服务器文件下载或者需要索引一些静态二进制文件的地方,可以利用nginx自带的索引文件功能实现。root/var/www/html;#索引目录autoindexon;autoindex_exact......
  • nginx http2 导致safari浏览器XMLHttpRequest cannot load错误
    环境说明nginx:1.22.0safari:13+curl:7.68.0ubuntu:20.04问题说明[Error]Thenetworkconnectionwaslost.[Error]XMLHttpRequestcannotloadxxxduetoaccesscon......
  • Nginx+Keepalived实现web服务器高可用
    1、Nginx业务背景现公司需求快速搭建web服务器,对外提供给用户web服务。需求拆分需要基于http协议的软件,搭建服务实现介绍  常见用法:1)web服务器软件httpdhttp协议同类......
  • caddyserver nginx adaper 简单说明
    caddyserver包含了一个强大的adapter架构设计,我们可以方便的进行caddyserver扩展nginx扩展的处理核心也是基于adapter模块扩展的,通过解析nginx.conf文件,然后转换......
  • 深入浅出学习透析Nginx服务器的架构分析及原理分析「底层技术原理+运作架构机制」
    Nginx再次回顾也许你已经忘记了Nginx是做什么的?我来再次给你夯实一下概念。多协议反向代理Nginx是个高性能的Web和反向代理服务器及HTTP服务器,它能反向代理HTTP,HTTPS和邮件......
  • 配置nginx的上游服务器,实现将发送给nginx 的请求转发给网关
    首先需要在nginx的nginx.conf的http模块配置上游服务器  再将nginx中的conf.d中的任意一个配置文件中配置server模块  如果网关是通过host的方式进行匹配,需要......
  • Nginx与LUA(6)
    您好,我是湘王,这是我的博客园。值此新春佳节,我给您拜年啦~祝您在新的一年中所求皆所愿,所行皆坦途,展宏“兔”,有钱“兔”,多喜乐,常安宁!  如前所述,OpenResty是一个基于Ngin......