Nginx与阻塞操作

借用"OpenResty最佳实践"的话

https://moonbingbing.gitbooks.io/openresty-best-practices/ngx_lua/block_io.html

Nginx 为了减少系统上下文切换,它的 worker 是用单进程单线程设计的,事实证明这种做法运行效率很高。

Nginx 要么是在等待网络讯号,要么就是在处理业务(请求数据解析、过滤、内容应答等),没有任何额外资源消耗。

举个栗子

最近在做app的数据上报后台服务,当前有这样一个需求,客户端想上传一些文件(日志文件、订单回执等)。

后台服务用的是OpenResty,使用了它的upload模块(好像是春哥写的),客户端使用http协议post方法上传文件。

其中比较蛋疼的一个问题如下:

我想把客户端上传的文件,按照用户id,上传时间存入到每个用户独立的文件夹中。

比如A用户的id是123456789,那我收到client上传的文件后,写入 /data/upload/123456789/20170909/ 文件夹下面。

那就得去创建这个文件夹,最初我是在lua脚本中调用 os.excute("mkdir -p /data/upload/123456789/20170909")

后来想想,这样做不是不行,当然可以实现功能。

但是应该这样做吗?肯定不应该这样做的。

前面说了 Nginx 是单进程、单线程设计,像文件上传这种写磁盘(相比业务逻辑运算)非常慢的操作,如果让Nginx去做,业务处理能力就会大打折扣。

类似的,磁盘操作/阻塞式网络操作/系统调用等,都是比较慢的,尽量想想其他好的方案去代替Nginx直接做会阻塞的操作。

当前有两个想法:

  1. 把文件上传服务,单独抽离出来,不要跟业务逻辑服务放在一起
  2. OpenResty收到客户端上传的文件之后,转发给文件上传服务器,让文件上传服务器去做磁盘操作。

心得  

所以不要使用OpenResty去做一些可能会阻塞的操作,比如下面的一些操作

  1. 高CPU的调用(压缩、解压缩、加解密)
  2. 高磁盘的调用(所有的文件操作)
  3. 非OpenResty提供的网络操作(luasocket等)
  4. 系统命令行调用(os.excute等)
时间: 2024-08-26 05:39:23

Nginx与阻塞操作的相关文章

linux内核驱动入门之阻塞操作实验:glob

首先,先来了解一下设备的阻塞与非阻塞操作以及实现阻塞操作的方法: 1.设备的阻塞与非阻塞操作: 阻塞操作是指,在执行设备操作时,若不能获得资源,则进程被挂起直到满足可操作的条件再进行操作.非阻塞操作是指,当进程不能进行设备操作时,并不挂起,它或者放弃,或者不停地查询,直到可以进行操作为止. 2.实现阻塞操作的方法: 在linux驱动程序中,可以使用等待队列(wait queue)来实现阻塞访问. 一,glob字符设备驱动程序的编写,把文件名命名为glob.c,源代码如下: #include <l

Nginx日常维护操作(3)

一.简明nginx常用命令 1. 启动 Nginx /sbin/nginx service nginx start 2. 停止 Nginx /sbin/nginx -s stop /sbin/nginx -s quit -s都是采用向 Nginx 发送信号的方式. 3. Nginx 重载配置 /sbin/nginx -s reload 上述是采用向 Nginx 发送信号的方式,或者使用service nginx reload 4. 指定配置文件 /sbin/nginx -c /usr/local

linux下串口的阻塞和非阻塞操作

有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY:第二个是可以在打开串口之后通过fcntl()函数进行控制. 阻塞的定义: 对于read,block指当串口输入缓冲区没有数据的时候,read函数将会阻塞在这里,移植到串口输入缓冲区中有数据可读取,read读到了需要的字节数之后,返回值为读到的字节数: 对于write,block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将阻塞,一直到串口输出缓冲区中剩

nginx服务相关操作

安装目录 和大多软件一样一般安装在 /usr/local/ 目录下 /usr/local/ 命令man Usage: nginx [-?hvVt] [-s signal] [-c filename] [-p prefix] [-g directives] Options: -?,-h : this help -v : show version and exit -V : show version and configure options then exit -t : test configur

Linux设备驱动程序学习 高级字符驱动程序操作[阻塞型I/O和非阻塞I/O]【转】

转自:http://blog.csdn.net/jacobywu/article/details/7475432 阻塞型I/O和非阻塞I/O 阻塞:休眠 非阻塞:异步通知 一 休眠 安全地进入休眠的两条规则: (1) 永远不要在原子上下文中进入休眠,即当驱动在持有一个自旋锁.seqlock或者 RCU锁时不能睡眠:关闭中断也不能睡眠.持有一个信号量时休眠是合法的,但你应当仔细查看代码:如果代码在持有一个信号量时睡眠,任何其他的等待这个信号量的线程也会休眠.因此发生在持有信号量时的休眠必须短暂,而

nginx+lua打造10K qps+的web应用

背景篇 由于项目流量越来越大,之前的nginx+php-fpm的架构已经难以承受峰值流量的冲击,春节期间集群负载一度长时间维持0%的idle,于是这段时间逐渐对旧系统进行重构. 受高人指点,发现lua这个好东西.因此在技术选型上,我们使用lua代替部分的php逻辑,比如请求的过滤.lua是一种可以嵌入nginx配置文件的动态语言,结合nginx的请求处理过程(参见另一篇博文),lua可以在这些阶段接管请求的处理. 我们的环境使用openresty搭建,openresty包括了很多nginx常用扩

Nginx 的线程池与性能剖析

http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt158 正如我们所知,NGINX采用了异步.事件驱动的方法来处理连接.这种处理方式无需(像使用传统架构的服务器一样)为每个请求创建额外的专用进程或者线程,而是在一个工作进程中处理多个连接和请求.为此,NGINX工作在非阻塞的socket模式下,并使用了epoll 和 kqueue这样有效的方法. 因为满负载进程的数量很少(通常每核CPU只有一个)而且恒定,所以任务切换只消耗很少的内

HttpLuaModule——翻译(Nginx API for Lua) (转)

现在我已经将翻译的内容放到:http://wiki.nginx.org/HttpLuaModuleZh Nginx API for Lua Introduction 各种各样的*_by_lua和*_by_lua_file配置文件服务在都在nginx.conf文件内.这些LUA API只能运行在这些配置文件里面. 这个API有两个标准的包NGX和NDK.这个包在ngx_lua内默认的包. 这个软件包可以这样的引入外部的文件 local say = ngx.say module(...) funct

菜鸟nginx源码剖析 框架篇(一) 从main函数看nginx启动流程(转)

俗话说的好,牵牛要牵牛鼻子 驾车顶牛,处理复杂的东西,只要抓住重点,才能理清脉络,不至于深陷其中,不能自拔.对复杂的nginx而言,main函数就是“牛之鼻”,只要能理清main函数,就一定能理解其中的奥秘,下面我们就一起来研究一下nginx的main函数. 1.nginx的main函数解读 nginx启动显然是由main函数驱动的,main函数在在core/nginx.c文件中,其源代码解析如下,涉及到的数据结构在本节仅指出其作用,将在第二节中详细解释. nginx main函数的流程图如下: