Nginx学习笔记 - day01

文章目录

  • nginx的模块
    • 按结构分类
    • 按功能分类
  • 工作原理
  • 进程模型
    • master 进程
    • worker 进程
  • Nginx+FastCGI
    • 什么是FastCGI
    • 运行原理
    • spawn-fcgi和php-fpm
  • Nginx+php-fpm
    • 配置文件
  • nginx的多进程IO模型
    • 优点
    • nginx的异步非阻塞
  • nginx的事件模型
    • epoll的优点
  • nginx 的优化
    • 减小nginx编译后文件大小
    • 为特定的CPU指定CPU类型编译
    • 利用 TCMalloc 优化nginx
    • 针对nginx的内核参数优化
    • 针对nginx的php-fpm优化
    • nginx.conf优化


nginx的模块

按结构分类

核心模块: HTTP模块, EVENT模块, MAIL模块

基础模块: HTTP Access模块, HTTP FastCGI模块, HTTP Proxy模块, Http Rewrite模块

第三方模块: HTTP Upstream Request Hash模块, Notice模块, HTTP Access Key模块

按功能分类

Handlers(处理器模块): 直接处理请求, 并进行输出内容和修改headers信息等操作, 一般只能有一个

Filters(过滤器模块): 此类模块主要对其他处理器模块输出的内容进行修改, 最后由nginx输出

Proxies(代理模块): 此模块是nginx的http upstream之类的模块, 主要与后端一些服务(FastCGI)等进行交互,实现服务代理和负载均衡等功能。

工作原理

- 当它接到一个HTTP请求时, nginx仅仅是通过查找配置文件将此次请求映射到一个location
- 在location中所配置的各个指令则会启动不同的模块去完成工作, 因此模块可以看做Nginx真正的劳动工作者
- 通常一个location中的指令会涉及一个handler模块和多个filter模块
- handler模块负责处理请求, 完成响应内容的生成, 而filter模块对响应内容进行处理

进程模型

- 在工作模式上, 分为单工作进程和多工作进程两种模式
	- 单worker进程模式, 除主进程外, 还有一个worker进程, worker进程是单线程的
	- 多worker进程模式下, 每个worker进程包含多个线程

- nginx默认为单工作进程模式, 启动之后, 会有一个master进程和多个worker进程

master 进程

- 主要用来管理worker进程
	- 接收来自外界的信号
	- 向各worker进程发送信号
	- 监控worker进程的运行状态
	- 当worker进程异常退出后, 自动启动新的worker进程

- master进程充当整个进程组与用户的交互接口, 同时对进程进行监护
- 它不需要处理网络事件, 不负责业务的执行
- 只负责管理worker进程来实现重启服务, 平滑升级, 更换日志文件, 配置文件实时生效等功能

worker 进程

- 基本的网络事件, 由worker进程处理
- 多个worker进程之间是对等且独立的, 同等竞争来自客户端的请求

Nginx+FastCGI

什么是FastCGI

- 它是一个可伸缩的, 高速的在HTTP server和动态脚本语言间通信的接口
  大多数流行的HTTP server都支持FastCGI, 包括Apache, Nginx, lighttpd等

- FastCGI采用C/S结构, 可以将HTTP服务器和脚本解析服务器分开
  同时在脚本解析服务器上启动一个或多个脚本解析守护进程
  当HTTP服务器每次遇到动态程序时, 可以直接将其交付给FastCGI来执行, 结果返回给浏览器
  这种方式让HTTP服务器专一的处理静态请求, 并将动态脚本服务器的结果返回给Client

运行原理

- 为了调用CGI程序, 还需要一个FastCGI的wrapper, 用来启动线程
- wrapper绑定在.sock文件或端口上
- 当nginx将CGI请求发送给socket的时候, wrapper接收到请求, 然后fork一个新的线程, 
  这个线程调用解释器或者外部的程序处理脚本, 并读取返回的数据
- 将数据通过FastCGI接口, 沿着sock传回nginx
- 最终返回的数据发送给客户端

spawn-fcgi和php-fpm

- 它们是两个支持php的FastCGI进程管理器
- HTTPServer完全解放出来, 更好的进行相应和处理并发
- spawn-fcgi
	- spawn-fcgi是http服务器lighttpd的一部分, 目前已经独立出来, 一般与lighttpd配合使用
	- 在高并发访问的时候, 会出现内存泄露, 甚至自动重启FastCGI的问题
	- 容易崩溃, 需要crontab对状态做监控
- php-fpm
	- 作为php插件开发, 安装的时候和php源码一起编译, 性能优秀一些
	- 高并发方面, 至少不会自动重启FastCGI(:-D)
	- cpu和内存控制方面都比spawn-fcgi好, 不易崩溃

Nginx+php-fpm

- 在php5.3.3后, 已经集成了php-fpm, 不在是第三方的包
- 编译的时候, 增加 -enable-fpm 参数即可开启php-fpm
- 一般web都做同一入口, 把php请求都发送到同一个文件上, 然后再文件里通过"REQIEST_URI"实现路由

配置文件

- 常见的次序, 从外到内依次是 [http] -> [server] -> [location]
- 缺省的继承关系是从外到内, 也就是内层块会自动获取外层块的值作为默认值
""" 示例配置文件 """

server {
    listen 80;
    server_name exp.com;
    root /xx;
    """
    index 不应该定义在location中, 会出现重复
    直接定义在server中, 通过继承生效
    """
    index index.html index.htm index.php;
  
    location / {
    	"""
    	1. 尽量适用try_files指令而不是if
    	2. 下边这个逻辑
    		1. 当用户请求 http://www.exp.com/a 时,这里的 $uri 就是 /a
    		2. 如果存在就返回
    		3. 目录中没有叫 a 的文件。然后就看 $uri/,增加了一个 /,也就是看有没有名为 a 的目录
    		4. 再没有找到的话, 跳转到http://www.exp.com/index.php
    	"""
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        try_files $uri = 400;
        """
        直接引入fastcgi.conf文件, 它比fastcgi_params多定义了一行
        fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        """
        include fastcgi.conf;
        """
        也可以
        fastcgi_pass unix:/xx/xx/xx/xx.sock
        """
        fastcgi_pass 127.0.0.1:9000; # 也可以 fastcgi_pass unix:/xx/xx/xx/xx.sock
    }
}

nginx的多进程IO模型

优点

- 独立进程不需要加锁, 减少开销
- 排错方便, 便于开发
- 不会相互影响, 降低影响

nginx的异步非阻塞

- 请求过来 --> 建立连接 --> 接收数据 --> 读写操作 --> 返回数据
- 读写操作这一步, 当io等待的时候, cpu在不同进程间切换, 检查哪个进程完成了io, 继续下一步操作
- 注意cpu切换也是有开销的

nginx的事件模型

事件模型 描述
select 标准方法, 是编译时默认选择的方法, 可以使用 --with-select_module 和 --without-select_module 来启用或禁用它
poll 标准方法, 可以使用配置参数 --with-poll_module 和 --without-poll_module 来启用或禁用这个模块
kqueue 高效方法, 在FreeBSD 4.1+, OpenBSD 2.9+, MacOS X和使用双处理器的MacOS X系统使用可能造成内核崩溃
epoll 对于linux来说, 只有它是高效方法

epoll的优点

推荐设置worker的个数为cpu的核数, 更多的worker数, 只会导致进程来竞争cpu资源了, 从而带来不必要的上下文切换
nginx为了更好的利用多核特性, 提供了cpu亲缘性的绑定选项, 我们可以将某一个进程绑定在某一个核上
这样就不会因为进程的切换带来cache的失效, 像这种小的优化在nginx中非常常见
nginx在做4个字节的字符串比较时, 会将4个字符转换成一个int型, 再作比较, 以减少cpu的指令数等

nginx 的优化

减小nginx编译后文件大小

"""
编译nginx默认使用debug模式进行, 信息量会很大
可以修改相关源码, 取消debug模式
"""

# 在源码目录下找到 auto/cc/gcc 文件, 删除或注释下边两行, 可以取消debug模式

# debug
CFLAGS="$CFLAGS -g"

为特定的CPU指定CPU类型编译

"""
在编译Nginx时,默认的GCC编译参数是“-O”,要优化GCC编译,可以使用以下两个参数
1. --with-cc-opt='-O3'
2. --with-cpu-opt=CPU #为特定的 CPU 编译, 有效的值包括:
	pentium, pentiumpro, pentium3, # pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64 
"""

# 要确定cpu类型, 可以通过下边这个命令
cat /proc/cpuinfo | grep "model name"

利用 TCMalloc 优化nginx

TCMalloc库在内存分配效率和速度上要高很多,这在很大程度上提高了服务器在高并发情况下的性能,从而降低了系统的负载

针对nginx的内核参数优化

# 将下边的参数加入 /etc/sysctl.conf 中
net.ipv4.tcp_max_tw_buckets = 6000  # timewait 最大数量
net.ipv4.ip_local_port_range = 1024 65000  # 开放端口
net.ipv4.tcp_tw_recycle = 1 # 选项用于设置启用timewait快速回收
net.ipv4.tcp_tw_reuse = 1 # 选项用于设置开启重用, 允许将TIME-WAIT sockets重新用于新的TCP连接
net.ipv4.tcp_syncookies = 1 # 当出现SYN等待队列溢出时,启用cookies进行处理
net.core.somaxconn = 262144 
net.core.netdev_max_backlog = 262144 
net.ipv4.tcp_max_orphans = 262144 
net.ipv4.tcp_max_syn_backlog = 262144 
net.ipv4.tcp_synack_retries = 1 # 内核放弃连接之前发送SYN+ACK包的数量
net.ipv4.tcp_syn_retries = 1 # 在内核放弃建立连接之前发送SYN包的数量
net.ipv4.tcp_fin_timeout = 1 
net.ipv4.tcp_keepalive_time = 30 # 表示当keepalive启用时, TCP发送keepalive消息的频度, 单位小时

# 生效
/sbin/sysctl -p

针对nginx的php-fpm优化

  • 增加FastCGI的进程数

      4G内存的服务器上, 将FastCGI的子进程数调到200, 就可以获取最佳效果
    
  • 增加 PHP-FPM打开文件描述符的限制

      打开 php-fpm.conf
      修改  “1024”  将1024改为4096或更大
    
      这个值和系统参数文件打开数有联系, 修改文件打开数
      在 /etc/security/limits.conf 加入
      hard nofile 65535
      soft nofile 65535
    
  • 适当增加max_requests

       标签max_requests指明了每个children最多处理多少个请求后便会被关闭, 默认的设置是500
        500 
    

nginx.conf优化

# 假设是8核cpu
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000

# 使用epoll模式
use epoll

# 每个工作进程的最大连接数
work_connects 65535

# 请求头大小, 请求头缓冲大小
client_header_buffer_size 16k
large_client_header_buffers 4 32k

# 开启gzip
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-JavaScript text/css

application/xml;
gzip_vary on;

# 缓存静态文件:
location ~* ^.+\.(swf|gif|png|jpg|js|css)$ {
root /usr/local/ku6/ktv/show.ku6.com/;
expires 1m;

你可能感兴趣的:(nginx)