NGINX 进程通信机制
来源:互联网 发布:黄乙玲心事谁人知 编辑:程序博客网 时间:2024/06/04 17:57
本文地址:http://blog.csdn.net/spch2008/article/details/38945033
nginx的进程通信分为三种类别:linux 系统与nginx 通信, master 进程与worker进程通信, worker进程间通信。
master进程管理worker进程,本文将追溯nginx 的退出过程。
Linux信号
linux 系统与nginx是通过信号才进行通信的,通过信号控制nginx重启、关闭以及加载配置文件等。
信号发送流程
1. 发送信号
./nginx –s quit 向master进程发送信号
这里有一点是:执行 ./nginx –s quit 实际上是新开了一个master进程,只不过它半路夭折了,即向原master发送信号后,
它就死掉啦。它存在的意义就是向原master发送信号。
2. 获取参数
nginx 通过 -s 知道用户要给nginx 发送信号,会有相应的动作。
3. 获取pid
要发送信号,需要知道master进程的pid,那如何获得呢?nginx 启动的时候将其写入了本地文件中。
file.name即为配置文件中指定pid所在的文件,该文件存放master的pid。通过配置文件中的pid字段,指明存放进程id文件的地址。
4. 发送信号
根据name到ngx_signal_t的名字中去匹配,找到信号,然后通过kill向master发送消息。
信号注册流程
1. 信号定义
简单解释一下,signo为信号的数字表示,而signame为信号的名字,name为nginx定义的信号名,handler为回调函数。比如:
转换后为:{ SIGQUIT, "SIGQUIT", "quit", ngx_signal_handler }, 具体语法规则见附录。然后SIGQUIT会借助于预处理器进行数字的对应,
SIGQUIT为在signal.h中的宏定义。
2. 信号注册
signals 为ngx_signal_t 数组,内部存放所有nginx会处理的信号。上述中,通过sigaction注册信号。
3. 信号处理
设置全局变量ngx_quit 标志为1.
4. 响应信号
sigsuspend将阻塞进程,直到set中的信号到达为止。当有信号达到,调用handler函数,然后ngx_quit被设置为1,此时,通过ngx_signal_worker_processes 向工作进程传递信号。
Socket通信
master进程与worker进程通过sockpair进行通信。在nginx中,将这种通信定义为频道,channel。
master就是通过频道与worker进程通信滴。
1. 频道定义
2. 注册频道
其一:创建频道,其实就是socketpair,在启动worker进程的时候创建频道
设置非阻塞,同时,将ngx_channel赋值。
其二:加入epoll等待数据到来,在worker进程初始化的时候加入
ngx_channel_handler为回调函数。
3. 发送消息
master进程通过ngx_signal_woker_processes向worker进程发送消息。4. 响应消息
worker进程通过ngx_read_channel读取消息,然后根据command判断是什么消息,同时设置worker进程的ngx_quit变量。
5. woker进程受理
worker内部ngx_worker_process_cycle为一个循环,处理事件,当检测到退出标志后,做相应处理
共享内存
worker进程间则是通过比较快速的共享内存进行通信。
1. mmap 匿名
即不与文件关联,不需要创建文件删除文件,简单高效。但有可能有些系统不支持,所以若不支持,采用第二种方案。
2.mmap /dev/zero
与字符设备/dev/zero关联,相当于打开一个文件,但mac os不支持,所以采用第三种方式。
fd = open(“/dev/zero”, O_RDWR);
mmap(NULL, sizeof(int), PROT_READ |PROT_WRITE, MAP_SHARED, fd, 0).
3.shmget 古老的system v获取
繁琐,但所有系统都支持
由master进程创建共享变量,worker进程共享。nginx 解决惊群问题,是通过设置互斥锁,
只有拥有互斥锁的工作进程才能担负与客户建立连接的任务,这个互斥锁就放于共享内存中。
另外,ngin统计连接数,这个全局变量也放于共享内存中,多个工作进程可以去改写这个变量,
当然,需要一些互斥机制。
共享内存一个小例子:
附录
1. #转换为字符
在define宏定义中,#代表将参数转换成字符串, 即“ ”.
#definevalue(n) #n
char *str = value(12345); è str = “12345”
2. ##连接成一个token
在define宏定义中,两个##表示将参数连接起来构成一个标示符
#define value(n) val##n
intval1 = 3;
printf(“%d\n”, value(1)); è val1
3. 字符串连接
//C语言中,“ ”表示空串 不准确
char *str = “123” “456”;
等效
char *str = “123456”;
解析: 相当“123” “456” 红色是一对,空串省略
4. 为什么worker 与master采用socketpair进行通信
worker进程有一个循环,在不停的处理请求,怎样接收master发送的数据呢。而socketpair为一种套接字,将它加入epoll中,通过事件模块获取该套接字,进行处理。ngx_write_channel将数据写入channel。而在ngx_process_cycle.c->ngx_worker_process_init初始化的时候,已经调用ngx_add_channel_event将套接字写入epoll中,后续向套接字写数据,epoll能检测到,并调用注册的回调函数ngx_channel_handler,将相应标志位设1(ngx_quit)。
- NGINX 进程通信机制
- NGINX 进程通信机制
- NGINX 进程通信机制
- 【nginx】 NGINX 进程通信机制
- nginx源码分析--进程间通信机制 & 同步机制
- nginx源码学习——进程间通信机制
- Nginx进程间通信
- nginx 进程间通信
- Nginx---父子进程通信
- Nginx 进程间通信
- 5.Nginx进程通信
- (转)进程通信机制
- 进程通信-消息机制 .
- 进程通信机制概述
- Socket进程通信机制
- 进程间通信机制
- 进程间通信机制
- 进程通信-事件机制
- Redis 集群常见错误
- SQL Server:触发器详解
- Kafka JAAS 安全认证流程
- Android中Service类onStartCommand的返回值问题
- 编写多文件程序(c语言)
- NGINX 进程通信机制
- 哟嘿嘿
- AS3清空数组的三种方法
- 字符串处理功能类StringProcessor
- 2003 求绝对值
- Aidl实现跨进程通信小例子
- Poj 3662 Telephone Lines【二分+SPFA】
- Swift基础(二十九)UIToolBar
- 2016多校联合第三场 HDU5758 Explorer Bo