Bootstrap

Linux入门攻坚——39、Nginx入门

Nginx:engine X
    Tengine:淘宝改进维护的版本
    Registry:

使用了libevent库:高性能的网络库
    epoll()函数

Nginx特性
  模块化设计、较好的扩展性;(但不支持动态加载模块功能,淘宝的版本支持)
  高可靠性:一个主控进程master,多个子进程worker
    master  -->  worker
  低内存消耗:
    10K个keep-alive模式下的connection,仅需2.5MB的内存;
  支持热部署:配置文件等更新,无需重启,就可以更新,即不停机而更新配置文件、日志文件滚动、升级程序版本;
  支持事件驱动、AIO(异步IO)、mmap;

Nginx基本功能
  静态资源的web服务器,能缓存打开的文件描述符;
  http、smtp、pop3协议的反向代理服务器;
  缓存加速、负载均衡;
  支持FastCGI(fpm,LNMP),uWSGI(Python)等;
  模块化(非DSO机制)、过滤器zio、SSI及图像的大小调整;
  支持SSL;
    反向代理服务器:反向代理服务器位于用户与目标服务器之间,但对用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。
  ● 正向代理和代理服务器
正向代理即通常所说的代理,用于代表内部网络用户向Internet上的服务器(或称外部服务器,通常为Web服务器)发出连接请求,并接收响应结果,执行该代理功能的服务器称为代理服务器。使用代理服务器访问外部网络时,客户端必须在局域网设置中指明代理服务器的地址以及要代理的服务的端口号。
  ● 反向代理和代理服务器
反向代理的方向与正向代理相反,指代表外部网络用户向内部服务器发出请求,即接收来自Internet上用户的连接请求,并将这些请求转发给内部网络上的服务器,然后将从内部服务器上得到的响应返回给Internet上请求连接的客户:执行反向代理服务的服务器称为反向代理服务器,反向代理服务器对外部用户表现为一个服务器。

反向代理服务器具有负载均衡功能和缓存加速功能。

Nginx扩展功能
  基于名称和IP的虚拟主机;
  支持keepalive
  支持平滑升级
  定制访问日志、支持使用日志缓冲区提供日志存储性能;
  支持url rewrite
  支持路径别名
  支持基于IP及用户的访问控制
  支持速率限制,支持并发数限制
Nginx的基本架构
  一个master进程,生成一个或多个worker进程
  事件驱动:epoll(边缘触发)、kqueue、/dev/poll
    复用器支持:select,poll,rt signal
    支持sendfile,sendfile64
    支持AIO,mmap

sendfile:对一个客户端请求的资源的读写过程基本如下:用户空间进程-->read系统调用-->磁盘IO将文件从磁盘DMA到内核空间缓存-->内存拷贝到用户空间缓存-->打包为响应报文 -->send系统调用 --> 用户空间缓存拷贝到内核写缓存-->网络IO,通过网卡发送。sendfile则是从磁盘-->内核缓存 --> 内核网络缓存,减少了数据拷贝,加快速度。

Nginx的工作模式:非阻塞、事件驱动、由一个master进程生成多个worker线程,每个worker响应n个请求;worker * n

Nginx的模块类型
  核心模块
  Standard HTTP modules
  Optional HTTP modules
  Mail modules
  3rd party modules

Nginx的安装方法:
  源码:编译安装
  制作好的程序包:rpm包

Nginx的编译安装
  1)下载一个源码包:nginx-1.6.3.tar.gz 
   2)编译需要的程序包:pcre-devel,pcre-devel‌是一个开发工具包,包含了用于编写和编译使用Perl兼容正则表达式(PCRE——Perl Compatible Regular Expressions)的程序的库文件和头文件。PCRE库提供了一系列函数,用于文本匹配和处理,广泛应用于各种编程语言和软件工具中‌。
    yum install pcre-devel
    3)执行./configure,可以使用 --help查看帮助:

--with开头的一般是默认没有启动,需要配置启动的,--without开头的一般是默认启动,如不需要需要配置关闭。

编译参数可能会根据版本的不同进行变化,./configure --help查看编译参数列表,常见的选项如下:
--prefix=<path> - 安装路径,如果没有指定,默认为/usr/local/nginx。 
--sbin-path=<path> - nginx可执行命令的文件,如果没有指定,默认为<prefix>/sbin/nginx。 
--conf-path=<path> - 在没有使用-c参数指定的情况下nginx.conf的默认位置,如果没有指定,默认为<prefix>/conf/nginx.conf。 
--pid-path=<path> - nginx.pid的路径,如果没有在nginx.conf中通过“pid”指令指定,默认为<prefix>/logs/nginx.pid。 
--lock-path=<path> - nginx.lock文件路径,如果没有指定,默认为<prefix>/logs/nginx.lock。 
--error-log-path=<path> - 当没有在nginx.conf中使用“error_log”指令指定时的错误日志位置,如果没有指定,默认为<prefix>/logs/error.log。 
--http-log-path=<path> - 当没有在nginx.conf中使用“access_log”指令指定时的访问日志位置,如果没有指定,默认为<prefix>/logs/access.log。 
--user=<user> - 当没有在nginx.conf中使用“user”指令指定时nginx运行的用户,如果没有指定,默认为“nobody”。 
--group=<group> - 当没有在nginx.conf中使用“user”指令指定时nginx运行的组,如果没有指定,默认为“nobody”。 
--builddir=DIR - 设置构建目录。 
--with-rtsig_module - 启用rtsig模块。
--with-select_module –without-select_module - 如果在configure的时候没有发现kqueue, epoll, rtsig或/dev/poll其中之一,select模块始终为启用状态。 
--with-poll_module –without-poll_module - 如果在configure的时候没有发现kqueue, epoll, rtsig或/dev/poll其中之一,poll模块始终为启用状态。 
--with-http_ssl_module - 启用ngx_http_ssl_module,启用SSL支持并且能够处理HTTPS请求。需要OpenSSL,在Debian系统中,对应的包为libssl-dev。 
--with-http_realip_module - 启用ngx_http_realip_module 
--with-http_addition_module - 启用ngx_http_addition_module 
--with-http_sub_module - 启用ngx_http_sub_module 
--with-http_dav_module - 启用ngx_http_dav_module 
--with-http_flv_module - 启用ngx_http_flv_module 
--with-http_stub_status_module - 启用”server status”(服务状态)页 
--without-http_charset_module - 禁用ngx_http_charset_module 
--without-http_gzip_module - 禁用ngx_http_gzip_module,如果启用,需要zlib包。 
--without-http_ssi_module - 禁用ngx_http_ssi_module 
--without-http_userid_module - 禁用ngx_http_userid_module 
--without-http_access_module - 禁用ngx_http_access_module 
--without-http_auth_basic_module - 禁用ngx_http_auth_basic_module 
--without-http_autoindex_module - 禁用ngx_http_autoindex_module 
--without-http_geo_module - 禁用ngx_http_geo_module 
--without-http_map_module - 禁用ngx_http_map_module 
--without-http_referer_module - 禁用ngx_http_referer_module 
--without-http_rewrite_module - 禁用ngx_http_rewrite_module。如果启用,需要PCRE包。 
--without-http_proxy_module - 禁用ngx_http_proxy_module 
--without-http_fastcgi_module - 禁用ngx_http_fastcgi_module 
--without-http_memcached_module - 禁用ngx_http_memcached_module 
--without-http_limit_zone_module - 禁用ngx_http_limit_zone_module 
--without-http_empty_gif_module - 禁用ngx_http_empty_gif_module 
--without-http_browser_module - 禁用ngx_http_browser_module 
--without-http_upstream_ip_hash_module - 禁用ngx_http_upstream_ip_hash_module 
--with-http_perl_module - 启用ngx_http_perl_module 
--with-perl_modules_path=PATH - 为perl模块设置路径 
--with-perl=PATH - 为perl库设置路径 
--http-client-body-temp-path=PATH - 为http连接的请求实体临时文件设置路径,如果没有指定,默认为<prefix>/client_body_temp 
--http-proxy-temp-path=PATH - 为http代理临时文件设置路径,如果没有指定,默认为<prefix>/proxy_temp 
--http-fastcgi-temp-path=PATH - 为http fastcgi临时文件设置路径,如果没有指定,默认为<prefix>/fastcgi_temp 
--without-http - 禁用HTTP服务 
--with-mail - 启用IMAP4/POP3/SMTP代理模块 
--with-mail_ssl_module - 启用ngx_mail_ssl_module 
--with-cc=PATH - 设置C编译器路径 
--with-cpp=PATH - 设置C预处理器路径 
--with-cc-opt=OPTIONS - 变量CFLAGS中附加的参数,用于FreeBSD中的PCRE库,同样需要指定–with-cc-opt=”-I /usr/local/include”,如果我们使用select()函数则需要同时增加文件描述符数量,可以通过–with-cc-opt=”-D FD_SETSIZE=2048”指定。 
--with-ld-opt=OPTIONS - 通过连接器的附加参数,用于FreeBSD中的PCRE库,同样需要指定–with-ld-opt=”-L /usr/local/lib”。 
--with-cpu-opt=CPU - 指定编译的CPU,可用的值为: pentium, pentiumpro, pentium3, pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64 
--without-pcre - 禁用PCRE库文件,同时将禁用HTTP rewrite 模块,如果要在”location”指令中使用正则表达式,同样需要PCRE库。
--with-pcre=DIR - 设置PCRE库源文件路径。 
--with-pcre-opt=OPTIONS - 在编译时为PCRE设置附加参数。 
--with-md5=DIR - 设置md5库源文件路径。 
--with-md5-opt=OPTIONS - 在编译时为md5设置附加参数。 
--with-md5-asm - 使用md5汇编源。 
--with-sha1=DIR - 设置sha1库源文件路径。 
--with-sha1-opt=OPTIONS - 在编译时为sha1设置附加参数。 
--with-sha1-asm - 使用sha1汇编源。 
--with-zlib=DIR - 设置zlib库源文件路径。 
--with-zlib-opt=OPTIONS - 在编译时为zlib设置附加参数。 
--with-zlib-asm=CPU - 为指定的CPU使用zlib汇编源进行优化,可用值为: pentium, pentiumpro。 
--with-openssl=DIR - 设置openssl库源文件路径。 
--with-openssl-opt=OPTIONS - 在编译时为openssl设置附加参数。 
--with-debug - 启用debug记录。 
--add-module=PATH - 增加一个在PATH中的第三方模块。 
--user 和--group指定运行使用的用户和组,先建立:
groupadd -r nginx
useradd -g niginx -r nginx
./configure --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf --user=nginx --group=nginx --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module --with-http_mp4_module --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi
make && make install
mkdir -pv /var/tmp/nginx/{client,fastcgi,proxy,uwsgi}

启动nginx:/usr/local/nginx/sbin/nginx
查看启动结果:ss -tnlp

80端口是nginx在监听。使用ps aux查看进程:

一个master process,一个worker process。

4)访问测试:http://192.168.147.133

5)在配置文件/etc/nginx/nginx.conf中,能看到配置项:worker_processes  1,所以在ps中看到worker进程只有一个。

Nginx配置文件
  main配置段:全局配置段
  event:定义event模型工作特性
  http {} :定义http协议相关配置

  配置指令:要以分号结尾
  语法格式:directive value1 [value2...]

  支持使用变量:
    内置变量:模块会提供自带内建变量定义
    自定义变量:set var_name value

  主配置段的指令:
    用于调试、定位问题
    正常运行必备的配置
    优化性能的配置
    事件相关的配置

Niginx的I/O模型
  non-blocking、event-driven、aio

主配置段的指令
  正常运行的必备配置:
    1、user USERNAME [GROUPNAME],指定运行worker的用户和组:user nginx nginx
    2、pid /path/to/pid_file,指定nginx守护进程的pid文件:pid /var/run/nginx/nginx.pid
    3、worker_rlimit_nofile #,指定所有worker进程所能打开的最大文件句柄数 
    4、worker_rlimit_core #,
  性能优化相关的配置
    1、worker_processes #,worker进程的打开个数,通常应略少于CPU物理核心数;
    2、worker_cpu_affinity cpumask...,
        优点:提升缓存的命中率;
        context switch:会产生CPU的不必要的消耗;
      cpumask:使用8位:0000 0001等
    3、timer_resolution,计时器解析度,降低此值,可减少gettimeofday()系统调用次数;
    4、worker_priority number,指明worker进程的nice值:-20,19 --> 100,139
  事件相关的配置
    1、accept_mutex {off | on},master调度用户请求至各worker进程时使用的负载均衡锁,on表示能让多个worker轮流地、序列化地去响应新请求;
    2、lock_file file,accept_mutex用到的锁文件路径;
    3、use  [epoll | rssig | select | poll],指明使用的事件模型,建议让Nginx自行选择;
    4、worker_connections #,设定单个worker进程所能处理的最大并发连接数量; 

  用于调试、定位问题的配置
    1、daemon {on | off},是否以守护进程方式运行nginx,调试时应该设置为off;
    2、master_process {on | off},是否以master/worker模型来运行nginx;调试时可以设置为off;
    3、error_log 位置 级别,若要使用debug级别,需要在编译nginx时使用了--with_debug选项;

总结:常需要进行调整的参数
  worker_processes,worker_connections,worker_cpu_affinity,worker_priority

新改动配置生效的方式
  nginx -s reload    或者:stop,quit,reopen

Nginx作为Web服务器时使用的配置
  http {  }:由ngc_http_core_module模块所引入;
配置框架
  http{
    upstream{}
    server{
        location URL{
            root “/path/to/somedir”;
            ...
         } # 类似于httpd中的<Location>,用于定义URL与本地文件系统的映射关系;
        location URL {
            if ... {
                ...
            }
        }
    } # 每个server类似于httpd中的一个<VirtualHost>;
     server{ ... } 
}
注意:与http相关的指令仅能够放置于http、server、location、upstream、if上下文,但有些指令仅应用于这5种上下文中的某些种;

配置指令
  1、server {},定义一个虚拟主机。

  2、listen ,指定监听地址和端口
    listen address[:port]、listen port 、listen unix:path

  3、server_name NAME [。。。];后可跟多个主机,名称还可使用正则表达式(~)或通配符;
    (1)先做精确匹配检查;
    (2)左侧通配符匹配检查:*.ceshi.com
    (3)右侧通配符检查:mail.*
    (4)正则表达式匹配检查:~^.*\.ceshi\.com$
    (5)default_server;

  4、root path;设置资源;路径映射,用于指明请求的URL所对应的资源所在的文件系统上的起始路径;

  5、location [ = | ~ | ~* | ^~] uri {...}
        location @name {...}
        功能:允许根据用户请求的URI来匹配定义的各location:匹配到时,此请求将被相应的location配置块中的配置所处理,例如做访问控制等功能。
        =:精确匹配检查
        ~:正则表达式模式匹配检查,区分字符大小写;
        ~*:正则表达式模式匹配检查,不区分字符大小写;
        ^~:URI的前半部分匹配,不支持正则表达式;
  匹配的优先级:精确匹配(=)、^~、~、~*、不带任何符号的location;

  6、alias path;用于location配置段,定义路径别名
    注意:root表示指明路径为对应的location "/" URL;alias表示路径映射,即location指令后定义的URL是相对于alias所指明的路径而言;
    location /images/ {
        root /vhosts/web1;
    }
    http://www.ceshi.com/images/a.jpg  <-- /vhosts/web1/images/a.jpg
    location /images/ {
        alias /www/pic;
    }
    http://www.ceshi.com/images/a.jpg <-- /www/pic/a.jpg

  7、index file,默认主页面:index index.php index.html;

  8、error_page,错误页面:error_page code [...] [ =code ] URI | @name
    根据http响应状态码来指明特定的错误页面;
    error_page 404  /404_customed.html
    [ = code ]:以指定的响应码进行响应,而不是默认的原来的响应,默认表示以新资源的响应码为其响应码;

=号的使用效果:

  9、基于IP的访问控制机制
    allow IP/Network;
    deny IP/Network;

只放行一个网段:

  10、基于用户的访问控制
    basic,digest
    auth_basic “”;
    auth_basic_user_file  /PATH/TO/PASSWD_FILE;  账号密码文件建议使用htpasswd来创建。

提示信息好像没有显示出来。

  11、https服务器
      生成私钥,生成证书签署请求,并获得证书;
      

在私有CA目录下生成CA的私钥,放置在private子目录中:
(umask 077;openssl genrsa -out private/cakey-nginx.pem 2048)
生成自签证书,位于CA目录:
openssl req -new -x509 -key private/cakey-nginx.pem -out cacert-nginx.pem -days 365
以上是创建私有CA的步骤,以下是为nginx服务器生成证书:
nginx服务器自身生成私钥:
(umask 077;openssl genrsa -out nginx.key 1024)
nginx服务器生成证书签发申请文件:
openssl req -new -key nginx.key -out nginx.csr
注意这一步中的CN要写准确网址,这个网址是对外服务的网址,如这里使用www.myngx.com
CA签发证书:
openssl ca -in nginx.csr -out nginx.crt -days 365
配置nginx的配置文件:

nginx重新加载配置后:

客户端修改一下hosts文件:

客户端可以以www.myngx.com访问:

因为私有CA证书没有导入浏览器,浏览器无法验证服务器证书,选择继续访问,可以https访问网站了。

  12、stub_status {on | off},仅能用于location上下文

  13、rewrite regex replacement flag,URL重写(重定向),如:
      rewrite ^/images/(.*\.jpg)$ /imgs/$1 break;
      http://www.myngx.com/images/a/b/c/1.jpg --> /imgs/a/b/c/1.jpg
    flag:
        last:一旦此rewrite规则重写完成后,不再被后面其他的rewrite规则进行处理,而是由User Agent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程。
        break:一旦此rewrite规则重写完成后,由UserAgent对新的URL重新发起请求,且不再被当前location内的任何rewrite规则所检查。
        redirect:以302响应码(临时重定向)返回新的URL。
        permanent:以301响应码(永久重定向)返回新的URL。

  14、if,语法:if (condition) {...}
    应用环境:server,location
      condition:
        (1)变量名:变量值为空串,或者以“0”开始,则为false,其他均为true;
        (2)以变量为操作数构成的比较表达式,可使用=,!=等比较操作符进行测试;
        (3)正则表达式的模式匹配操作:
            ~:区分大小写的模式匹配检查;
            ~*:不区分大小写的模式匹配检查;
            !~和!~*:对上面两种测试取反;
        (4)测试路径为文件可能性:-f,!-f
        (5)测试指定路径为目录的可能性:-d,!-d
        (6)测试文件的存在性:-e,!-e
        (7)检查文件是否有执行权限:-x,!-x
    例如:if ($http_user_agent ~* MSIE){
                    rewrite ^(.*)$ /msie/$1 break;
                }

  15、防盗链
        location ~* \.(jpg|gif|jpeg|png)$ {
          valid_referer none blocked www.myngx.com;
          if ($invalid_referer) {
                rewrite ^/ http://www.myngx.com/xxx.html;
          }
        }

  16、定制访问日志格式
        log_format 

  注意:此处可用变量为nginx各模块内建变量。

网络连接相关的配置

  1、keepalive_timeout # :长连接的超时时长,默认75s;
  2、keepalive_requests #:在一个长连接上所能够允许请求的最大资源数;
  3、keepalive_disable [msie6|safari|none] :为指定类型的User Agent禁用长连接
  4、tcp_nodelay on|off :是否对长连接使用TCP_NODELAY选项;
  5、client_header_timeout #:读取http请求报文首部的超时时长;
  6、client_body_timeout # :读取http请求报文body部分的超时时长;
  7、send_timeout #:发送响应报文的超时时长;

fastcgi的相关配置:
  LNMP:php启用fpm模型;

;