前言

1. nginx是一个优秀的事件驱动框架,nginx非常适合开发在传输层以TCP对外提供服务的服务器程序。基于nginx框架开发程序有5个优势:

* nginx将网络、磁盘及定时器等异步事件的驱动都做了非常好的封装,基于它开发将可以忽略这些事情处理的细节

* nginx封装了许多平台无关的接口、容器,适用于跨平台开发

* 优秀的模块化设计,使得开发者可以轻易的复用各种已有的模块,其中既包括基本的读取配置、记录日志等模块,也包括处理请求的诸如http、mail等高级功能模块

* nginx是作为服务器来设计其框架的,因此,它在服务器进程的管理上相当出色,基于它开发服务器程序可以轻松地实现程序的动态升级,子进程的监控、管理,配置项的动态修改生效等。

* nginx充分考虑到各操作系统所擅长的“绝活”,能够使用特殊的系统调用更高效地完成任务时,绝不会去使用低效的通用接口。尤其对于Linux操作系统,nginx不遗余力地做了大量优化。

第一部分

nginx能帮我们做什么

第一章

研究nginx前的准备工作

1. 2012年,nginx荣获年度云计算开发奖,并成为世界第二大web服务器

1.1 nginx是什么?

1. web服务器的基本功能:基于REST架构风格,以统一资源描述符(uniform resource identifier, URI)或统一资源定位符(uniform resource locator, URL)作为沟通依据,通过http为浏览器等客户端程序提供各种网络服务。

2. nginx的竞争对手---Apache,Lighttpd, tomcat,jetty, IIS。他们都是web服务器,或者叫做WWW服务器。、

3. nginx是一个跨平台的web服务器,可运行在Linux,FreeBSD,Solaris,AIX,MacOS,Windows等操作系统上,并且它还可以使用当前操作系统特有的一些高效API来提高自己的性能

1.2 为什么选择nginx

1. nginx具备以下特点

* 更快

* 高扩展性

* 高可靠性

* 低内存消耗

* 单机支持10万以上的并发连接

* 热部署

* 最自由的BSD许可协议

nginx的核心优点还是他能够在支持高并发请求的同时保持高效的服务

1.3.1 Linux操作系统

1. 系统必须是内核为Linux 2.6 及以上版本的操作系统,因为Linux 2.6及以上内核才支持epoll,而在Linux上使用select或poll来解决事件的多路复用,是无法解决高并发压力问题的。

2. uname -a 查询Linux内核版本

1.3.3 磁盘目录

1. nginx编译阶段产生的中间文件存放目录

该目录用于放置configure命令执行后所产生的源文件及目录,以及make命令执行后生成的目标文件和最终连接成功的二进制文件。默认情况下,configure命令会将该目录命名为objs

第十四章

进程间的通信机制

1.  nginx由一个master进程和多个worker进程组成,但master进程或者worker进程中并不会再创建线程(nginx的多线程机制一直停留在测试状态,虽然不排除未来nginx可能发布支持多线程版本的可能性)

14.1

1. nginx框架使用了3种传递消息传递方式:共享内存、套接字、信号

2. nginx主要使用了3种同步方式:原子操作、信号量、文件锁

14.2 共享内存

1. 共享内存是Linux下提供的最基本的进程间通信方法,它通过mmap或者shmget系统调用在内存中创建了一块连续的线性地址空间,而通过munmap或者shmdt系统调用可以释放这块内存

使用共享内存的好处是当多个进程使用同一块共享内存时,在任何一个进程修改了共享内存中的内容后,其他进程通过访问这段共享内存都能够得到修改后的内容

2. nginx各进程间共享数据的主要方式就是使用共享内存,在使用共享内存时,nginx一般是由master进程创建,在master进程fork出worker子进程后,所有的进程开始使用这块内存中的数据

14.3 原子操作

1. 能够执行原子操作的原子变量只有整型,包括无符号整型ngx_atomic_uint_t和有符号整型ngx_atomic_t。这两种类型都使用了volatile关键字告诉C编译器不要做优化。

14.3.1 不支持原子库下的原子操作

14.3.3 自旋锁

1. 基于原子操作,nginx实现了一个自旋锁。

2. 自旋锁是一种非睡眠锁,也就是说,某进程如果试图获得自旋锁,当发现锁已经被其他进程获得时,那么不会使得当前进程进入睡眠状态,而是始终保持进程在可执行状态,每当内核调度到这个进程执行时就持续检查是否可以获取到锁。在拿不到锁时,这个进程的代码将会一直在自旋锁代码处执行,直到其他进程释放了锁且当前进程获取了锁后,代码才会继续向下执行。

3. 自旋锁主要是为多处理器操作系统而设置的,它要解决的共享资源保护场景就是进程使用锁的时间非常短,如果锁的使用时间很久,自旋锁会不太合适,那么它会占用大量的CPU资源

4. ngx_spinlock方法是非常高效的自旋锁,它充分考虑了单处理器和多处理器的系统,对于持有锁时间非常短的场景很有效率

14.4 nginx频道

1. ngx_channel_t频道是nginx master进程与worker进程之间通信的常用工具,它是使用本机套接字实现的。

int socketpair( int d, int type, int portocol, int sv[2]); 创建父子进程间使用的套接字

2. 当socketpair执行成功时,sv[2]这两个套接字具备下列关系:向sv[0]套接字写入数据,将可以从sv[1]套接字中读取到刚写入的数据;同样,向sv[1]套接字写入数据,也可以从sv[0]中读取到写入的数据。

通常,在父子进程通信前,会先调用socketpair方法创建这样一组套接字,在调用fork方法创建出子进程后,将会在父进程中关闭sv[1]套接字,仅使用sv[0]套接字用于向子进程发送数据以及接受子进程发送来的数据;而在子进程中则关闭sv[0]套接字,仅使用sv[1]套接字既可以接受父进程发来的数据,也可以向父进程发送数据

3. master进程如何监控、管理worker子进程?

每次派生一个子进程之前,也就是fork之前,都会先调用socketpair方法,在nginx派生子进程ngx_spawn_process方法中,会首先派生基于TCP的套接字,master正是通过socketpair产生的套接字发送命令的。

14.5 信号

1. Linux提供了以信号传递进程间消息的机制,nginx在管理master进程和worker进程时大量使用了信号。

2. 信号和信号量是完全不同的概念,信号量仅用于同步代码段,而信号则用于传递消息。一个进程可以向另外一个进程或者另外一组进程发送信号消息,通知目标进程执行特定的代码

./nginx -s reload

14.6 信号量

1. 信号量是用来保证两个或多个代码段不被并发访问,是一种保证共享资源有序访问的工具,使用信号量作为互斥锁有可能导致进程睡眠,因此,要谨慎使用。

2. int sem_init( sem_t* sem, int pshared, unsigned int value);

初始化信号量, pshared为0时表示线程间同步,为1时表示进程间同步。

3. int sem_destroy(sem_t *sem)

销毁信号量

4. int sem_post(sem_t *sem);

信号量的值加一

5. int sem_wait(sem_t * sem);

信号量的值减一

14.7 文件锁

1. Linux内核提供了基于文件的互斥锁

int fcntl(int fd, int cmd, struct flock* lock);

fd 是打开的文件句柄,cmd 表示执行的锁操作,lock描述了这个锁的信息。

2. nginx.conf文件中的lock_file配置项指定的文件路径,就是用于文件互斥锁的。

3. 对于文件锁,nginx封装了3个方法:ngx_trylock_fd实现了非阻塞进程,不会使进程进入睡眠状态的互斥锁

ngx_lock_fd 阻塞互斥锁

ngx_unlock_fd 释放互斥锁

14.8 互斥锁

总结:nginx是一个能够并发处理几十万甚至几百万个TCP连接的高性能服务器,因此,在进行进程间通信时,必须充分考虑到不能过分影响正常请求的处理

p20

深入理解Nginx 模块开发与架构解析-陶辉 读书笔记相关推荐

  1. 推荐我的新书《深入理解Nginx:模块开发与架构解析》

    http://www.china-pub.com/STATIC/zt_mb/zt_huodong_2013_3.asp?filename=2013_jsj_nginx_20130401 目录 < ...

  2. 《深入理解NGINX 模块开发与架构解析》之摘抄学习

    1.基于Nginx框架开发程序有5个优势: (1).Nginx将网络.磁盘及定时器等异步事件的驱动都做了非常好的封装,基于它开发将可以忽略这些事件处理的细节; (2).Nginx封装了许多平台无关的接 ...

  3. 《深入理解Nginx 模块开发与架构解析》之高级数据结构摘录

    一.ngx_queue_t双向链表 1.ngx_queue_t容器的优势在于: 1) 实现了排序功能; 2) 它非常轻量级,是一个纯粹的双向链表.它不负责链表元素所占内存的分配,与Nginx封装的ng ...

  4. 后台开发经典书籍--深入理解Nginx模块开发与架构

  5. 《深入理解Nginx:模块开发与架构解析》一3.3 如何将自己的HTTP模块编译进Nginx...

    3.3 如何将自己的HTTP模块编译进Nginx Nginx提供了一种简单的方式将第三方的模块编译到Nginx中.首先把源代码文件全部放到一个目录下,同时在该目录中编写一个文件用于通知Nginx如何编 ...

  6. 《深入理解Nginx:模块开发与架构解析》一1.2 为什么选择Nginx

    1.2 为什么选择Nginx 为什么选择Nginx?因为它具有以下特点: (1)更快 这表现在两个方面:一方面,在正常情况下,单次请求会得到更快的响应:另一方面,在高峰期(如有数以万计的并发请求),N ...

  7. 《深入理解Nginx:模块开发与架构解析》一1.6 Nginx的命令行控制

    1.6 Nginx的命令行控制 在Linux中,需要使用命令行来控制Nginx服务器的启动与停止.重载配置文件.回滚日志文件.平滑升级等行为.默认情况下,Nginx被安装在目录/usr/local/n ...

  8. 《深入理解Nginx-模块开发与架构解析》

    一.研究Nginx前的准备工作 1.常见负载均衡 1)Apache:被设计成了一个重量级的.不支持高并发的Web服务器 2)Lighttpd和Nginx都是轻量级.高性能的Web服务器:欧美前者用的多 ...

  9. 【Linux网络编程】Nginx -- 模块开发(upstream / subrequest)

    [Linux网络编程]Nginx -- 模块开发(upstream / subrequest) [1]upstream VS subrequest 简介 upstream 为访问上游服务器,它把Ngi ...

最新文章

  1. pthread_testcancel和pthread_cancel函数的简单示例
  2. mybatis使用时遇到的一些问题------模糊查询、处理大于号小于号、相关函数替换空值...
  3. JVM垃圾收集器——G1
  4. 不学无数——SpringBoot入门VI
  5. java array使用_Java_ArrayLit详细用法
  6. 2018年度最佳网页设计与开发教程
  7. SVM多分类原理学习
  8. 我的世界正版验证服务器地址,我的世界1.7.10服务器纯净地址大全
  9. 阿里云吴磊创办yunQ云桥,完成银杏谷资本2000万元天使轮融资
  10. excel去掉单元格的隐藏字符
  11. 〖教程〗Ladon提权Win2016/Win10/MSSQL2016
  12. 同样取整,TRUNC函数与INT函数的有什么区别?
  13. 日语假名小写怎么打出来?
  14. 7-2 买电影票 (C语言)
  15. Python的面试题/测试题汇总,带答案
  16. CC2530基础实验四 串口通信
  17. iis 如何修改网站的默认浏览方式
  18. 机智应对,测试面试套路与反套路,我是不可能中套的......
  19. ROCK PI4介绍与上手
  20. 联发科RT2880/RT3052/RT3883/RT5350/RT3352无线路由器wifi芯片

热门文章

  1. 高级语言反汇编程序的函数调用过程
  2. Direct3D 11.1新特性曝光
  3. POS消费机C#例子代码
  4. 利用 LotusScript 灵活操作 Lotus Notes 富文本域
  5. CodeForces - 1358C Celex Update(思维)
  6. CodeForces - 1331E Jordan Smiley(图形转换)
  7. HDU - 6186 CS Course(维护前缀+后缀)
  8. android软件的data使用方法,实例讲解Android中SQLiteDatabase使用方法
  9. STL学习之一(栈(statck))
  10. CImage类显示图片