首页 > 其他分享 >openresty 中主要的几种异步执行方式

openresty 中主要的几种异步执行方式

时间:2023-01-30 18:01:41浏览次数:49  
标签:异步 file ngx timer 几种 openresty local

openresty 中主要的几种异步执行方式

openresty宣传是同步非阻塞(100% non-blocking)的,基于事件通知的 Nginx 给我们带来了足够强悍的高并发支持。可以让我们可以使用同步的编程方式实现异步处理,但在我们难免在应用中会使用非openresty api的调用,比如

  • 高 CPU 的调用(压缩、解压缩、加解密等)
  • 高磁盘的调用(所有文件操作)
  • 非 OpenResty 提供的网络操作(luasocket 等)
  • 系统命令行调用(os.execute 等)

在使用异步方式执行代码的时候我们常会用到第三方工具,比如队列,存储。我在这里介绍几种openresty自带的异步api,讲究一个原汤化原食

脱离请求进程 - ngx.timer.at(delay, callback, user_arg1, user_arg2, ...)

timer是一个计时器,他将在delay s 之后起一个轻线程,然后调用callback,user_arg1 ... 等是传入参数

定时器看起来很完美,但是有个缺点

  • 在timer中无法使用cosocket

无法使用cosocket比较致命,在openresty中cosocket是核心中的核心,不能用就等于openresty废了一大半,所以我建议使用timer只做些简单的工作,比如保存文件到硬盘。

但如果一定要做一些比如网络请求,我们可以绕过cosocket,比如使用 resty.http库。

	local ok, err = ngx.timer.at(0, function(_, _file_id,_file_data)
		local args = {
			func = 'erase_words_collection',
			file_id = _file_id
		}
		curl('http://127.0.0.1/async/upload_file', 'POST', nil, _file_data, nil, args)
	end, file_id, file_data)
	if not ok then
		nlog.error('async_util.upload_file: create timer error :'.. tostring(err))
	end

另外openresty 也提供了指令和api 管理timer的数量

  • lua_max_running_timers 指定最大运行的定时器数量(默认值为256)
  • lua_max_pending_timers 指定最大等待运行的定时器的数量(默认值为1024)
  • ngx.timer.running_count()
  • ngx.timer.pending_count()

拆分请求 ngx.thread.*

协程是 openresty异步高效的最基础组件

如果是需要批量任务,那么使用协程是个不错的选择,但也要注意协程数量以及慎用wait any(可以参考我的上一篇文章)

 local capture = ngx.location.capture
 local spawn = ngx.thread.spawn
 local wait = ngx.thread.wait
 local say = ngx.say

 local function fetch(uri)
     return capture(uri)
 end

 local threads = {
     spawn(fetch, "/foo"),
     spawn(fetch, "/bar"),
     spawn(fetch, "/baz")
 }

 for i = 1, #threads do
     local ok, res = wait(threads[i])
     if not ok then
         say(i, ": failed to run: ", res)
     else
         say(i, ": status: ", res.status)
         say(i, ": body: ", res.body)
     end
 end

提前返回响应 - ngx.eof()

看一个官网的例子

 location = /async {
     keepalive_timeout 0;
     content_by_lua_block {
         ngx.say("got the task!")
         ngx.eof()  -- well written HTTP clients will close the connection at this point
         -- access MySQL, PostgreSQL, Redis, Memcached, and etc here...
     }
 }

作用一目了然,这里先完成http响应,然后在后完成比如mysql等存储的访问。
另外还提供了个指令,打开之后可以使链接关闭之后还保持子请求

proxy_ignore_client_abort on;

官网推荐最好使用 ngx.timer.at,但我觉得不如eof

A better way to do background jobs is to use the ngx.timer.at API.

总结

  • 如果是期望请求结束后执行,比较复杂 用 ngx.eof
  • 如果比较简单的异步任务,使用timer
  • 如果是批量的任务 使用thread

标签:异步,file,ngx,timer,几种,openresty,local
From: https://www.cnblogs.com/wenzaicaicai/p/17076851.html

相关文章

  • 通过一个示例形象地理解C# async await异步
    前言相信大家看过不少讲C#asyncawait的文章,博客园就能搜到很多,但还是有很多C#程序员不明白。如果搞不明白,其实也不影响使用。但有人就会疑惑,为什么要用异步?我感觉它更......
  • JS几种常见循环
    常见循环,主要包括有for,for…in,for…of,forEach普通for  switch 遍历数组varnums=[11,12];for(vari=0;i<nums.length;i++){console.info(nums[i]);}/......
  • 验证码的几种处理方式
     针对验证码有如下方法:1>在产品没有上线前,需要找开发先给web验证码留后门,也就是将验证码验证先注释掉2>让开发给web验证码留一个万用验证码,只要输入给定的验证码,就可以......
  • test_bit(置位判断函数)的几种实现方法
    方法一staticinlineinttest_bit(intnr,constvolatilevoid*addr){return(1UL&(((constint*)addr)[nr>>5]>>(nr&31)))!=0UL;}方法二......
  • Redis lazy异步删除
    在学习数据异步或同步删除之前,你首先需要知道,删除操作实际上是包括了两步子操作。子操作一:将被淘汰的键值对从哈希表中去除,这里的哈希表既可能是设置了过期key的哈希表......
  • 线程的生命周期,线程有几种状态
    线程的生命周期:创建-->就绪-->运行-->阻塞-->死亡线程的状态:新建状态(New):新创建了一个线程对象就绪状态(Runable):其它线程调用了该线程的start方法。该状态的线程都在......
  • 异步请求函数return应不应该加await?
    阅读原文......
  • JavaScript中实现sleep睡眠函数的几种简单方法(转)
    转自:JavaScript中实现sleep睡眠函数的几种简单方法一.什么是sleep函数?sleep是一种函数,他的作用是使程序暂停指定的时间,起到延时的效果。javascript好像诶呦提供sleep工......
  • ython爬取异步ajax数据
      使用selenium这个网页自动化测试工具,去获得源码。因为这个工具是等到页面加载完成采取获取的整个页面的代码,所以理论上是可以获得页面完整数据的。 defreque......
  • python执行shell脚本的几种方法
    一、os.system(“command”)这是python自带的执行shell命令的方法,其中最后一个0是这个命令的返回值,为0表示命令执行成功。但是使用system()无法将执行的结果保存起来。i......