Nignx

Posted 黑夜天星

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nignx相关的知识,希望对你有一定的参考价值。

httpd MPM(多路处理模块):

  prefork:进程模型,两级结构,主进程master负责生成 子进程,每个子进程负责响应一个请求

  worker:线程模型,三级结构,主进程master负责生成子 进程,每个子进程负责生成多个线程,每个线程响应一个 请求

  event:主进程master负责生成子进程,每个子进程响应 多个请求

IO模型

I/O: 网络IO:本质是socket读取       磁盘IO: 磁盘的读写

每次IO,都要经由两个阶段: 第一步:将数据从文件先加载至内核内存空间(缓冲区) ,等待数据准备完成,时间较长

              第二步:将数据从内核缓冲区复制到用户空间的进程的内 存中,时间较短

同步/异步:关注的是消息通信机制

  • 同步:synchronous,调用者自已主动等待被调用者返回消 息,才能继续执行
  • 异步:asynchronous,被调用者通过状态、通知或回调机 制主动通知调用者被调用者的运行状态

阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态

  • 阻塞:blocking,指IO操作需要彻底完成后才返回到用户 空间,调用结果返回之前,调用者被挂起
  • 非阻塞:nonblocking,指IO操作被调用后立即返回给用户 一个状态值,无需等到IO操作彻底完成,最终的调用结果 返回之前,调用者不会被挂起

I/O模型: 阻塞型、非阻塞型、复用型、信号驱动型、异步

同步阻塞IO模型

同步阻塞IO模型是最简单的IO模型,用户线程在内核进行 IO操作时被阻塞。

用户线程通过系统调用read发起IO读操作,由用户空间转到 内核空间。内核等到数据包到达后,然后将接收的数据拷贝 到用户空间,完成read操作。

用户需要等待read将数据读取到buffer后,才继续处理接收 的数据。整个IO请求的过程中,用户线程是被阻塞的,这导 致用户在发起IO请求时,不

能做任何事情,对CPU的资源利 用率不够。

同步非阻塞IO模型

用户线程发起IO请求时立即返回。但并未读取到任何数据, 用户线程需要不断地发起IO请求,直到数据到达后,才真正 读取到数据,继续执行。

即 “轮询”机制

整个IO请求的过程中,虽然用户线程每次发起IO请求后可以 立即返回,但是为了等到数据,仍需要不断地轮询、重复请 求,消耗了大量的CPU的资源 

是比较浪费CPU的方式,一般很少直接使用这种模型,而是在 其他IO模型中使用非阻塞IO这一特性

IO多路复用模型

本模型会阻塞进程,但是进程是阻塞在select或者poll这两个系统调用上 ,而不是阻塞在真正的IO操作上

用户首先将需要进行IO操作添加到select中,继续执行做其他的工作(异 步),同时等待select系统调用返回。当数据到达时,IO被激活,

select 函数返回。用户线程正式发起read请求,读取数据并继续执行。

从流程上来看,使用select函数进行IO请求和同步阻塞模型没有太大的区 别,甚至还多了添加监视IO,以及调用select函数的额外操作,效率更差 。

并且阻塞了两次,但是第一次阻塞在select上时,select可以监控多个 IO上是否已有IO操作准备就绪,即可达到在同一个线程内同时处理多个 IO

请求的目的。而不像阻塞IO那种,一次只能监控一个IO

虽然上述方式允许单线程内处理多个IO请求,但是每个IO请求的过程还 是阻塞的(在select函数上阻塞),平均时间甚至比同步阻塞IO模型还要 长。

如果用户线程只是注册自己需要的IO请求,然后去做自己的事情, 等到数据到来时再进行处理,则可以提高CPU的利用率

IO多路复用是最常使用的IO模型,但是其异步程度还不够“彻底”,因 为它使用了会阻塞线程的select系统调用。因此IO多路复用只能称为异步 阻塞IO

模型,而非真正的异步IO

IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备 读取,它就通知该进程

IO多路复用适用如下场合:  

当客户处理多个描述符时(一般是交互式输入和网络套接口), 必须使用I/O复用

当一个客户同时处理多个套接口时,这种情况是可能的,但很少 出现

当一个TCP服务器既要处理监听套接口,又要处理已连接套接口 ,一般也要用到I/O复用。

当一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用

当一个服务器要处理多个服务或多个协议,一般要使用I/O复用

信号驱动IO模型

信号驱动IO:signal-driven I/O

就是说用户进程可以通过sigaction系统调用注册一个信号处 理程序,然后主程序可以继续向下执行,当有IO操作准备就 绪时,由内核通知

触发一个SIGIO信号处理程序执行,然后 将用户进程所需要的数据从内核空间拷贝到用户空间

此模型的优势在于等待数据报到达期间进程不被阻塞。用户 主程序可以继续执行,只要等待来自信号处理函数的通知 ;该模型并不常用

异步IO模型

异步IO与信号驱动IO最主要的区别是信号驱动IO是由内核 通知何时可以进行IO操作,而异步IO则是由内核告诉我们 IO操作何时完成了。具体来说就是,

信号驱动IO当内核通知 触发信号处理程序时,信号处理程序还需要阻塞在从内核空 间缓冲区拷贝数据到用户空间缓冲区这个阶段,而异步IO直 接是在

第二个阶段完成后内核直接通知可以进行后续操作了

相比于IO多路复用模型,异步IO并不十分常用,不少高性能 并发服务程序使用IO多路复用模型+多线程任务处理的架构基 本可以满足需求。况且目前

操作系统对异步IO的支持并非特 别完善,更多的是采用IO多路复用模型模拟异步IO的方式( IO事件触发时不直接通知用户线程,而是将数据读写完毕后

放到用户指定的缓冲区中)

I/O模型的具体实现

Select:Linux实现对应,I/O复用模型

Poll:Linux实现,对应I/O复用模型

Epoll:Linux实现,对应I/O复用模型,具有信号驱动I/O模型 的某些特性

Kqueue:FreeBSD实现,对应I/O复用模型,具有信号驱动 I/O模型的某些特性

/dev/poll:SUN的Solaris实现,对应I/O复用模型,具有信号 驱动I/O模型的某些特性

Iocp Windows实现,对应第5种(异步I/O)模型

Nigix默认epoll,性能及其优秀!

nginx介绍

Nginx:engine X ,2002年,开源,商业版

http协议:web服务器(类似于httpd)、http reverse proxy(类似于httpd)、imap/pop3 reverse proxy,tcp

NGINX is a free, open-source, high-performance an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server

二次开发版:Tengine, OpenResty

官网:http://nginx.org

LNMP架构图:

 

Nignx架构:

 

 

正向代理和反向代理

特性:  模块化设计,较好的扩展性 ; 高可靠性  ; 支持热部署:不停机更新配置文件,升级版本,更换日志文件 ;低内存消耗:10000个keep-alive连接

模式下的非活动连接,仅 需要2.5M内存 ; event-driven,aio,mmap,sendfile

基本功能: ----静态资源的web服务器 ----http协议反向代理服务器 ----pop3/imap4协议反向代理服务器 ----FastCGI(lnmp),uWSGI(python)等协议

      ----模块化(非DSO),如zip,SSL模块 ----tcp,udp代理

nginx架构

nginx的程序架构: master/worker结构

 一个master进程: 负载加载和分析配置文件、管理worker进程、平滑升级

一个或多个worker进程 处理并响应用户请求

缓存相关的进程: cache loader:  载入缓存对象 cache manager:管理缓存对象

nginx模块:模块分类: 核心模块:core module

           标准模块:  HTTP 模块: ngx_http_* HTTP Core modules( 默认功能) HTTP Optional modules (需编译时指定)

                  Mail 模块 ngx_mail_*

                  Stream模块 ngx_stream_*

           第三方模块

nginx的功用:静态的web资源服务器 html,图片,js,css,txt等静态资源

         结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求

       http/https协议的反向代理

       imap4/pop3协议的反向代理

       tcp/udp协议的请求转发(反向代理)

nginx的安装:官方: http://nginx.org/packages/centos/7/x86_64/RPMS

       Fedora-EPEL: https://mirrors.aliyun.com/epel/7/x86_64/

yum  -y install  nginx

安装前脚本已经创建nginx用户

启动nginx(注意用nginx启动,必须用nginx -s stop停,用systemctl start nginx 启动必须用systemctl stop nginx 停)

nginx -t  检测配置文件语法   -T 检测的同时输出配置文件

Nginx:默认为启动nginx   -h 查看帮助选项   -t 测试nginx语法错误   -c filename 指定配置文件(default: /etc/nginx/nginx.conf)  

-s signal 发送信号给master进程,signal可为:stop, quit,reopen, reload(reload 很多时候不生效)

nginx配置

配置文件的组成部分: 主配置文件:nginx.conf   子配置文件 include conf.d/*.conf   

主配置文件的配置指令: directive    value    [value2 ...];

注意: (1) 指令必须以分号结尾

    (2) 支持使用配置变量 内建变量:由Nginx模块引入,可直接引用

             自定义变量:由用户使用set命令定义 set variable_name value;

             引用变量:$variable_name 

配置文件主要配置设置 main(全区设置)    

            http(协议配置)

            upstream(负载均衡服务器设置)

            server、location(URL匹配特定 位置设置)

1)全局配置

#Nginx的worker进程运行用户以及用户组 user nobody nobody;

#Nginx开启的进程数 worker_processes 2;worker_processes auto;

#也可以下参数指定了哪个cpu分配给哪个进程, #worker_processes 4 #4核CPU #worker_cpu_affinity 0001 0010 0100 1000

#定义全局错误日志定义类型,[debug|info|notice|warn|crit] error_log logs/error.log info;

#指定进程ID存储文件位置 pid logs/nginx.pid;

2)服务配置  :非虚拟主机的配置或公共配置,需要定义在server之外,http之内;

http段参数详解:

1. #文件扩展名与文件类型映射表 include mime.types;

2.#默认文件类型 default_type application/octet-stream;

3.#日志相关定义 #log_format main \'$remote_addr - $remote_user [$time_local] "$request" \'

          # \'$status $body_bytes_sent "$http_referer" \'

          # \'"$http_user_agent" "$http_x_forwarded_for"\';  

#1.$remote_addr 与$http_x_forwarded_for 用以记录客户端的ip地址;

#2.$remote_user :用来记录客户端用户名称;

#3.$time_local :用来记录访问时间与时区;

#4.$request :用来记录请求的url与http协议;

#5.$status :用来记录请求状态;

#6.$body_bytes_sent :记录发送给客户端文件主体内容大小;

#7.$http_referer :用来记录从那个页面链接访问过来的;

#8.$http_user_agent :记录客户端浏览器的相关信息

4.. #access_log logs/access.log main;

5. #只记录更为严重的错误日志,减少IO压力  error_log logs/error.log crit;

6.#默认编码 #charset utf-8;

7.#服务器名字的hash表大小  server_names_hash_bucket_size 128;

8. #客户端请求单个文件的最大字节数 client_max_body_size 8m;

9. #指定来自客户端请求头的hearerbuffer大小  client_header_buffer_size 32k;

10. #指定客户端请求中较大的消息头的缓存最大数量和大小 arge_client_header_buffers 4 64k;

11.#开启高效传输模式。sendfile on;

12.#防止网络阻塞 tcp_nopush on;       tcp_nodelay on;

13. #客户端连接超时时间,单位是秒  keepalive_timeout 60;

14.#客户端请求头读取超时时间 . client_header_timeout 10;

15. #设置客户端请求主体读取超时时间 client_body_timeout 10;

16. #响应客户端超时时间 send_timeout 10;

17.#FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。

  fastcgi_connect_timeout 300; 

  fastcgi_send_timeout 300; 

  fastcgi_read_timeout 300; 

  fastcgi_buffer_size 64k;

  fastcgi_buffers 4 64k;

  fastcgi_busy_buffers_size 128k;

  fastcgi_temp_file_write_size 128k;

18.#gzip压缩输出

   gzip on;

   gzip_min_length 1k;

   gzip_buffers 4 16k; 

   gzip_http_version 1.0; 68.

   gzip_comp_level 2;

   gzip_types text/plain application/x-javascript text/css application/xml;

        gzip_vary on( #前端缓存服务器缓存经过压缩的页面 73. )

LNMP的企业应用实战(现基于LNMP的电子商务网站)

一、环境准备:centos系统、nginx源码、yum源,selinux和防火墙设置好。

二、安装步骤: 1.下载nginx源代码,并编译安装到/usr/local/nginx目录中

        2.yum方式安装mariadb、mariadb-server、php-mysql、php、php-fpm

        3.下载小米商城源码,解压缩到/data/web目录,修改权限为nobody

三、修改配置文件: 1.修改nginx配置,把nginx.conf.default模板复制为配置文件进行修改,指定网站访问目录为 /data/web

          并设置默认用户和配置与php-fpm交互

          2.修改/etc/php.ini中功能配置 #修改时钟配置 date.timezone = Asia/Shanghai #可以在php.ini中设置

           short_open_tag = On,在/etc/php-fpm.d/www.conf把user和group的值改为nobody

四、访问应用配置修改 1.修改server段加上默认工作路径,可访问到网站程序

           2.修改php扩展解析文件路径 修改为 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

五、网站部署和验证 1.打开http://ip/ebak 后台恢复系统 账号 admin 密码 123456

          2.配置连接数据库并连接到数据库

          3.恢复网站数据信息,并验证http://ip/index.php能 正常访问

          4.登陆后台,并查看网站日常操作页面(账号和密码为admin admin888)

设置和测试页面:

后台管理界面

压力测试:ab  -c 10  -n 100 http://www.heiye.com/index.php (需要把127.0.0.1指向本机)  用dstat查看负载和网络,cpu利用

4.配置Nginx的特定需求配置

配置Nginx状态监控页面 :

#Nginx运行状态,StubStatus模块获取Nginx自启动的工作状态( 编译时要开启对应功能) location /status {

#启用StubStatus的工作访问状态 stub_status on;

#指定StubStaus模块的访问日志文件 access_log logs/nginxstatus.log;

#Nginx认证机制(需Apache的htpasswd命令生成) #auth_basic "nginxstatus";

#用来认证的密码文件 auth_basic_user_file ../htpasswd; } 访问:http://IP/NginxStatus(测试就不加密码验证相关)

nginx状态页面各段含义

Active connections:当前活动的客户端连接数;

accepts:已经接受的客户端连接总数量;

handled:已经处理过后客户端连接总数量;

requests:客户端的总的请求数量;

Readking:正在读取的客户端请求的数量;

Writing:正向其发送响应报文的连接数量;

Waiting:等待其发出请求的空闲连接数量

Nginx实现路由-URL重定向

rewrite功能就是,使用nginx提供的全局变量或自己设置的变量, 结合正则表达式和标志位实现url重写以及重定向。rewrite只能放在

server{},location{},if{}中,并且只能对域名后边的除去传递的参 数外的字符串起作用

举例:http://www.heiye.com/index.php =>http://www.magedu.com/new/index.php 表明看rewrite和location功能有点像,都能实现跳转,

主要区别在于rewrite是在同 一域名内更改获取资源的路径,而location是对一类路径做控制访问或反向代理, 可以proxy_pass到其他机器。

很多情况下rewrite也会写在location里,它们的执行 顺序是:

1、执行server块的rewrite指令

2、执行location匹配

3、执行选定的location中的rewrite指令 如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件;循环超 过10次,

则返回500 Internal Server Error错误。 语法rewrite regex replacement [flag];

Nginx实现路由-URL重定向 flag标志位

last : 相当于Apache的[L]标记,表示完成rewrite break : 停止执行当前虚拟主机的后续rewrite指令集

redirect : 返回302临时重定向,地址栏会显示跳转后的地址

permanent : 返回301永久重定向,地址栏会显示跳转后的地址 因为301和302不能简单的只返回状态码,还必须有重定向的URL,

这就是return指令无法返回301,302的原因了。

这里 last 和 break 区别有点难以理解: last一般写在server和if中,而break一般使用在location中 ,last不终止重写后的url匹配,即新的url

会再从server走一遍匹配流 程,而break终止重写后的匹配 break和last都能组织继续执行后面的rewrite指令

举例:抵挡恶意攻击重定向 if ($http_user_agent ~ "ApacheBench")       { rewrite ^(.*)$ /404.html break; }   #对于用户agent进行判断,如果

是不合理agent,可直接跳转到处理页面,也可以return直接 返回代码。 

常见全局变量

$host : 请求主机头字段,否则为服务器名称。

$http_user_agent : 客户端agent信息

$http_cookie : 客户端cookie信息

$limit_rate : 这个变量可以限制连接速率。

$request_method : 客户端请求的动作,通常为GET或POST。

$remote_addr : 客户端的IP地址。

$request_filename : 当前请求的文件路径,由root或alias指令与URI请 求生成。

$scheme : HTTP方法(如http,https)。

$server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。

$server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。

$server_name : 服务器名称。

$server_port : 请求到达服务器的端口号。

$request_uri : 包含请求参数的原始URI,不包含主机名,如: ”/foo/bar.php?arg=baz”

基于ssl加密会话案例

ssl_certificate file; #证书文件路径;

ssl_certificate_key file;证书对应的私钥文件;

ssl_ciphers ciphers;指明由nginx使用的加密算法,可以是 OpenSSL库中所支持各加密套件;

ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2]; #指明支持的ssl协议版本,默认为后三个;

ssl_session_cache off | none | [builtin[:size]] [shared:name:size]; 指明ssl会话缓存机制;

builtin:使用OpenSSL内置的ssl会话缓存 ,对机制为各worker私有;

shared:在各worker之间使用一个共 享的缓存;

name:独有名称;

size:缓存空间大小;

ssl_session_timeout time; #ssl会话超时时长;即ssl session cache中的缓存有效时长

配置基于SSL的Nginx加密会话

生成ssl密钥

5.Nginx企业级优化

1、开启Epoll模型,开启多请求处理机制以内核复制模式,来提高处理性能

use epoll;#event段

multi_accept on; #worker按串行方式来处理连接,一个连接只有一个worker被唤醒,其他的处于休眠状态

sendfile on; #http段 避免内核缓冲区数据和用户缓冲区数据之间的拷贝

2、设置Nginx进程和CPU的亲和性,减少进程上下文切换

worker_processes 4;#main

worker_cpu_affinity auto;

3、设置最大连接数和最大文件数,提升并发

worker_connections 65535;    #event段

worker_rlimit_nofile 65535; #main段

4、设置连接超时时间和网络参数优化,提升连接复用率

keepalive_timeout 60; #http段

tcp_nodelay on; # 提高高频发送小数据报文的实时性

tcp_nopush on; #允许将 HTTP 应答首部与数据内容在同一个报文中发出

5、开启Nginx压缩功能,节省带宽

gzip on | off; #启用或禁用gzip压缩响应报文;#http段

gzip_comp_level level; #压缩比,1-9,默认为1;#http段

gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x- httpd-php image/jpeg image/gif image/png; #定义压缩类型

6、基于Nginx的LNMP架构优化,fastcgi性能优化、PHP性能参数优化

fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m; #为FastCGI缓存指定一个文件路径、目录结构等级、关键字区域存储时间和非活动删 除时间

fastcgi_connect_timeout 300; #指定连接到后端FastCGI的超时时间。 fastcgi_send_timeout 300; #指定向FastCGI传送请求的超时时间,

这个值是已经完成两次握手后向 FastCGI传送请求的超时时间。

fastcgi_read_timeout 300; #指定接收FastCGI应答的超时时间,这个值是已经完成两次握手后接收 FastCGI应答的超时时间。

fastcgi_buffer_size 64k; #用于指定读取FastCGI应答第一部分需要用多大的缓冲区

fastcgi_buffers 4 64k; #指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求

fastcgi_busy_buffers_size 128k; #默认值是fastcgi_buffers的两倍。

fastcgi_temp_file_write_size 128k; #表示在写入缓存文件时使用多大的数据块,默认值是 fastcgi_buffers的两倍。

fastcgi_cache TEST; #表示开启FastCGI缓存并为其指定一个名称

fastcgi_cache_valid 200 302 1h; fastcgi_cache_valid 301 1d; fastcgi_cache_valid any 1m; #用来指定应答代码的缓存时间,实例中的值表示将

200和302应答缓 存一个小时,将301应答缓存1天,其他应答均缓存1分钟。

PHP-FPM企业级性能优化

1、设置脚本超时时间,自动结束的php脚本,以释放占用的资源

request_terminate_timeout = 30

2、调整php-fpm的进程工作模式,,static(静态)或者dynamic(动态)

pm = dynamic |static

pm.max_children:静态方式下开启的php-fpm进程数量。

pm.start_servers:动态方式下的起始php-fpm进程数量。

pm.min_spare_servers:动态方式下的最小php-fpm进程数量。

pm.max_spare_servers:动态方式下的最大php-fpm进程数量。

pm.max_requests = 500 php-fpm进程最多处理多少个请求后销毁

#比如说512M的虚拟机,建议pm.max_spare_servers设置为20(512*0.8/20)。

3、开启慢查询日志  

request_slowlog_timeout = 1   慢查询日志时间

slowlog = /var/log/php-fpm/www-slow.log #日志路径

4、修改打开最大文件数

ulimit -n 65535

rlimit_files = 65535 #php-fpm配置 

 

补充:

1.nginx和apache的优缺点比较:(nginx基于epoll而apache基于select,nginx异步非阻塞,apache同步阻塞)

nginx相对于apache的优点: 
  轻量级,同样起web 服务,比apache 占用更少的内存及资源 
  抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能 
  高度模块化的设计,编写模块相对简单 
  社区活跃,各种高性能模块出品迅速啊 
apache 相对于nginx 的优点: 
  rewrite ,比nginx 的rewrite 强大 
  模块超多,基本想到的都可以找到 
  少bug ,nginx 的bug 相对较多 
  超稳定 

并不是所有的情况下都是epoll 大获全胜的,如果本身提供静态服务的就只有寥寥几个文件,apache 的select 模型或许比epoll 更高性能

 

以上是关于Nignx的主要内容,如果未能解决你的问题,请参考以下文章