什么是 Nginx ?

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP(邮件服务)。

Nginx可作为负载均衡服务:Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP代理服务对外进行服务。

Nginx服务功能:
访问控制、虚拟主机、地址跳转、反向代理、负载均衡

高性能的HTTP服务器  

反向代理服务器、七层负载均衡器  

邮件代理服务器
特点

善于处理静态请求

擅长处理高并发

nginx服务开启时,会生成一个master(控制)进程,然后 master 进程会分出多个 worker(工作进程) ,最后每个用户的请求都由 worker 的子线程处理。

用线程处理客户请求,而线程是共享内存的,只需要开启少量的进程,多个线程就可以共享进程的内存。所以占用的内存小

工作模式 master - worker 模式

特点:

Nginx启动后,会有一个master和一个worker进程

Master进程负责处理系统信号、加载配置、管理worker进程

Worker进程负责处理具体的业务逻辑

优点:

工作进程可设置

稳定性好

充分利用多核cpu、提高性能

工作模式

一个请求进来,会有一个worker进程去处理;处理发生阻塞时,worker进程不会一直等,而是处理其他事情,等有结果回来再继续处理这个请求


Nginx 处理客户端请求的过程

Nginx 服务_安装nginx

1、客户端发起访问
2、nginx通过客户端输入的URL判断客户端是要访问动态资源还是静态资源
3、如果是静态资源,那么nginx直接将结果返回给客户端
4、如果是动态资源,那么nginx将请求的数据发送给 fastCGI(快速通用网关接口) ,然后通过 fastcgi_pass 将用户的请求发给 php-fpm。 php-fpm 将动态资源转换成静态后在返回给 Nginx 。Nginx将结果返回给客户端


fastCGI

FastCGI由CGI(通用网关接口)发展而来、采用C/S结构

FastCGI是一种可伸缩的、高速的在HTTP服务器和动态脚本间通信的接口,包括PHP

FastCGI可以将HTTP服务器和脚本解析服务器分离,同时在脚本解析服务器上启动一个或多个脚本解析守护进程,如php-fpm

当HTTP服务器每次遇到动态请求时,直接交付FastCGI进程执行,然后把结果返回给浏览器


php-fpm

Nginx将php动态请求发送给fastcgi管理进程来处理

Php-fpm是一个php fastcgi管理器,只用于PHP解析

Php-fpm提供了更好的PHP进程管理方式,有效控制内存、进程等

PHP编译安装时需要添加—enable-fpm选项

PHP编译安装后需要加载php-fpm配置、启动进程


nginx处理并发

nginx 以 epoll 作为开发模型,处理请求的方式为 异步非阻塞;

epoll 是 Linux 内核的可扩展 I/O 事件通知机制,为系统中基于事件驱动的模型。此模式下nginx可轻松处理百万级的并发连接。

异步非阻塞:调用发出后,该进程继续其他任务,让 I/O 线程去处理,等结果返回时再回来继续执行.

同步阻塞:调用发出后,一直等待消息结果


相关配置

Nginx 服务_安装nginx_02


安装 Nginx

1、安装基础依赖、解压openssl源码包 

[root@zerbufan ~]# yum -y install zlib zlib-devel pcre pcre-devel openssl-devel

2、查看 openssl 的版本 
[root@zerbufan ~]# openssl version  #查看版本 
OpenSSL 1.0.2k-fips  26 Jan 2017    #openssl的版本需要在1.0.2e以上,当前版本满足要求

#若openssl的版本不满足要求可以去下载源码包:https://www.openssl.org/source/
#下载后解压重新安装 1.0.2e以上版本的 openssl 

3、创建 Nginx 用户
[root@zerbufan ~]# useradd -M -s /sbin/nologin nginx

4、安装 Nginx ,若想要Nginx 支持http2协议,那么需要nginx的版本在1.9.5以上

[root@zerbufan nginx-1.13.8]# pwd
/lnmp/nginx-1.13.8      #进入到解压后的目录中 当前nginx的版本为1.13.8  满足要求

# 指定安装位置,开启指定功能
[root@zerbufan nginx-1.13.8]# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-stream
#若刚才重新安装了 openssl 则在执行 ./configure 的时候还需要添加  --with-openssl=/root/lnmp/openssl-1.0.2h  这条选项,没有重新安装则不需要

[root@zerbufan nginx-1.13.8]# echo $?
[root@zerbufan nginx-1.13.8]# make && make install
[root@zerbufan nginx-1.13.8]# echo $?

5、查看nginx的安装信息
[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -V   #查看nginx的安装信息
nginx version: nginx/1.13.8
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-stream
[root@zerbufan ~]# 



6、安装完成后 启动服务、测试 
[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t   #检测配置文件
[root@zerbufan ~]# /usr/local/nginx/sbin/nginx  #开启服务
[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s stop  #停止服务

/usr/local/nginx/sbin/nginx  -s  reload   (热重启,不停止服务)

[root@zerbufan ~]# ss -anpt | grep :80      #查看端口

[root@zerbufan ~]# curl localhost   #访问默认网页测试

配置文件结构

[root@zerbufan ~]# vim /usr/local/nginx/conf/nginx.conf
	
	.....     #全局块,配置影响nginx全局的属性,如用户信息、worker数等
	worker_processes  1;    #控制 worker 进程的数量 一般按照CPU的内核数量设置
        
        pid        /usr/local/nginx/logs/nginx.pid;#主进程PID保存文件
	
	events {  #events块,配置nginx与用户的允许同时建立的网络连接数
		....#使用epoll模型,对于2.6以上的内核,建议使用epoll模型以提高性能
		worker_connections 51200;#工作进程的最大连接数量
	}
	
	http {    #http块,配置代理、缓存等参数
		....       #http全局块
		server {   #server块,配置虚拟主机参数,一个http可有多server
			....
			location [pattern]{ #location块,配置请求路由及对应处理
				...
			}
		
			location (.*)\.php$ {
			    用正则匹配具体的访问对象;
		}

			location [pattern]{
				...#跳转等规则
			}
		}
		
		
		server {   #配置多个server块
			....
			location [pattern]{
				...
			}
			location [pattern]{
				...
			}
		}
	}
	
一个http可以有多个server 、一个 server 就是一个虚拟主机,一个server 可以有多个 location

统计模块 (监控 Nginx 的整体访问情况)

#安装时添加模块选项:--with-http_stub_status_module,nginx内置的状态监控页面,可用于监控nginx的整理访问情况

#在主配置文件的 server 中添加location ,在 location中开启统计模块
[root@zerbufan ~]# vim /usr/local/nginx/conf/nginx.conf
        
        location /nginx_status {
            stub_status on;
        }
修改配置文件后重启服务

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t   #检测配置文件

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s reload #重启服务(热重启)

页面访问:http://域名或IP/nginx_status
#结果分析:
	"Active connections"表示当前的活动连接数;
	"server accepts handled requests"表示已经处理的连接信息;
	三个数字依次表示已经处理的连接数、成功的TCP握手次数、已处理的请求数
	"Reading: 0 Writing: 1 Waiting: 0" 表示正在读取客户端的连接数、响应数据到客户端的数、等待再次请求的连接数

Nginx 服务_反向代理_03

测试

Nginx 服务_访问控制_04

访问控制

基于 用户名、密码的验证访问

1、修改配置文件 
[root@zerbufan ~]# vim /usr/local/nginx/conf/nginx.conf
#在想验证的location下面添加,以根区域为例
        location / {
            root   html;
            index  index.html index.htm index.php;
            #添加下面这两行信息
            auth_basic "welcome you here";
            auth_basic_user_file /usr/local/nginx/html/a.psd;
        }

2、创建认证文件,htpasswd命令是安装包httpd-tools拥有的命令

[root@zerbufan ~]# cd /usr/local/nginx/     #先进入到目录下
[root@zerbufan nginx]# htpasswd -c /usr/local/nginx/html/a.psd user88   #执行命令创建用户名设置用户密码 
New password:           #设置用户密码
Re-type new password:   #再次输入刚才的密码
Adding password for user user88 #创建用户成功

注意:只用第一次创建用户使用 -c 选项;以后再次创建用户需使用 -m 选项

[root@zerbufan nginx]# htpasswd -m /usr/local/nginx/html/a.psd user99
New password: 
Re-type new password: 
Adding password for user user99


3、重启服务
[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t   #检测配置文件

设置访问控制后不要使用热重启
[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s stop
[root@zerbufan ~]# /usr/local/nginx/sbin/nginx

Nginx 服务_安装nginx_05

验证

Nginx 服务_访问控制_06

基于IP地址的访问控制 (顺序优先)

拒绝个别,允许所有
1、编辑配置文件
[root@zerbufan ~]# vim /usr/local/nginx/conf/nginx.conf

        location / {
            root   html;
            index  index.html index.htm index.php;
            deny 192.168.56.101;    #拒绝访问的IP   #注意 deny 和 allow 的顺序
            allow 192.168.56.0/24;  #允许访问的IP
        }

2、重启服务

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s reload

验证

Nginx 服务_安装nginx_07

允许个别,拒绝所有

1、编辑配置文件

[root@zerbufan ~]# vim /usr/local/nginx/conf/nginx.conf
        location / {
            root   html;
            index  index.html index.htm index.php;
            allow 192.168.56.101;   #允许访问的IP
            deny 192.168.56.0/24;   #拒绝访问的IP #注意allow和deny的顺序
        }


2、重启服务

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s reload

验证

Nginx 服务_nginx_08


虚拟主机 (基于域名)

1、#在配置文件中添加不同的 server 区域(一个server 就是一个虚拟主机)
[root@zerbufan ~]# vim /usr/local/nginx/conf/nginx.conf

    server {
        listen       80;
        server_name  www.new.com;

        location / {
            root   html/new;
            index  index.html index.htm;
        }
    }

    server {
        listen       80;
        server_name  www.old.com;

        location / {
            root   html/old;
            index  index.html index.htm;
        }
    }

2、创建虚拟主机网页主目录存放目录
[root@zerbufan ~]# cd /usr/local/nginx/html/    #进入到网页主目录下
[root@zerbufan html]# mkdir ./new   #创建第一个虚拟主机的网页目录存放位置
[root@zerbufan html]# mkdir ./old   #创建第二个虚拟主机的网页目录存放位置
[root@zerbufan html]# echo "new linux" > ./new/index.html   #写 index.html文件
[root@zerbufan html]# echo "old linux" > ./old/index.html

3、重启服务
[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s reload

Nginx 服务_访问控制_09


验证

Nginx 服务_访问控制_10


域名跳转 ( old 跳转到 new )

1、基于上面的虚拟主机进行域名跳转实验

[root@zerbufan ~]# vim /usr/local/nginx/conf/nginx.conf     #编辑配置文件
    server {
        listen       80;
        server_name  www.new.com;

        location / {
            root   html/new;
            index  index.html index.htm;
        }
    }

    server {
        listen       80;
        server_name  www.old.com;

        location / {
             rewrite .*  http://www.new.com permanent;
        }
    }

2、重启服务

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s reload

验证

Nginx 服务_安装nginx_11

实现 https 加密

1、生成证书,默认路径在PREFIX/conf目录下

[root@zerbufan ~]# cd /usr/local/nginx/conf/    #进入目录准备生成证书

#建立服务器私钥,生成RSA密钥
[root@zerbufan conf]# openssl genrsa -out ./cert.key 1024

#需要依次输入国家,地区,组织,email。最重要的是有一个common name,可以写你的名字或者域名。如果为了https申请,这个必须和域名吻合,否则会引发浏览器警报。生成的csr文件交给CA签名后形成服务端自己的证书
[root@zerbufan conf]# openssl req -new -key ./cert.key -out ./cert.csr


#模拟交给 CA机构签名
[root@zerbufan conf]# openssl x509 -req -days 365 -sha256 -in ./cert.csr -signkey ./cert.key -out ./cert.pem

2、修改主配置文件,修改server端口为443、添加验证配置

    #HTTPS server   #这条注释注意不要取消

    server {
        listen       443 ssl;
        server_name  www.new.com;   #要加密的域名
        ssl_certificate      cert.pem;  #证书
        ssl_certificate_key  cert.key;  #证书密钥

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html/new;    #加密的网页主目录存放位置
            index  index.html index.htm;
        }
    }

}

3、重启服务

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s reload

验证

验证时手动输入 https://域名

Nginx 服务_访问控制_12

Nginx 服务_访问控制_13

端口自动跳转 (80 端口 自动跳转到 443 端口)

1、修改配置文件

[root@zerbufan ~]# vim /usr/local/nginx/conf/nginx.conf
    server {
        listen       80;
        server_name  www.old.com;

        location / {
             rewrite .*  http://www.new.com permanent;      #先从old跳转到new
        }
    }
-------------------------------------------
    server {
        listen       80;
        server_name  www.new.com;

        location / {
            rewrite .*  https://www.new.com permanent;  # new 从http跳转到 https
        }
    }

---------------------------------------------

 #开启https的配置
    server {
        listen       443 ssl;          
        server_name  www.new.com;
        ssl_certificate      cert.pem;
        ssl_certificate_key  cert.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html/new;
            index  index.html index.htm;
        }
    }

}

2、重启服务

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s reload

验证

Nginx 服务_访问控制_14

Nginx 服务_安装nginx_15

http2 协议

1、生成证书,默认路径在PREFIX/conf目录下(上面在做端口跳转时已经由证书了,就不用再次生成证书了)

[root@zerbufan ~]# cd /usr/local/nginx/conf/    #进入目录准备生成证书

#建立服务器私钥,生成RSA密钥
[root@zerbufan conf]# openssl genrsa -out ./cert.key 1024

#需要依次输入国家,地区,组织,email。最重要的是有一个common name,可以写你的名字或者域名。如果为了https申请,这个必须和域名吻合,否则会引发浏览器警报。生成的csr文件交给CA签名后形成服务端自己的证书
[root@zerbufan conf]# openssl req -new -key ./cert.key -out ./cert.csr


#模拟交给 CA机构签名
[root@zerbufan conf]# openssl x509 -req -days 365 -sha256 -in ./cert.csr -signkey ./cert.key -out ./cert.pem


2、修改配置文件(基于上面的端口跳转)

    #HTTPS server

    server {
        listen       443 ssl http2;     #在这里直接添加 http2 即可 
        server_name  www.new.com;
        ssl_certificate      cert.pem;
        ssl_certificate_key  cert.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html/new;
            index  index.html index.htm;
        }
    }

}

3、重启服务
[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s reload

验证

Nginx 服务_安装nginx_16

反向代理

1、搭建真实服务,确保真实服务可以正常访问

2、修改nginx 代理服务器的配置文件


    server {
        listen       80;
        server_name  www.xxxx.com;  #客户端访问的域名

        location / {
           proxy_pass http://192.168.56.101:80;     #真实服务器的IP
        }                                           代理其他主机也可填其他域名,实现跳转

2、修改配置文件后重启服务

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s reload

验证

访问代理服务器的域名,展现出真实机的服务页面

Nginx 服务_统计模块_17


负载均衡

1、配置两个被代理的真实服务器

#服务器 1 :192.168.56.101

[root@zerbufan ~]# yum -y install httpd
[root@zerbufan ~]# echo "zhangsan 192.168.56.101" > /var/www/html/index.html
[root@zerbufan ~]# systemctl start httpd

#服务器 2 :192.168.56.10

[root@ngls-lisi ~]# yum -y install httpd
[root@ngls-lisi ~]# echo "lisi 192.168.56.10" > /var/www/html/index.html
[root@ngls-lisi ~]# systemctl start httpd


#这里配置了两个不同的页面 是为了方便区分实验效果。

----------------------

2、配置 nginx 代理服务器的配置文件
        
        #upstream标签需要添加在 server 标签的前面 
    upstream lisi {
                                    #weight 表示权重,数字越大,权重越大。    
        server 192.168.56.101:80 weight=3;  #真实服务器1的ip
        server 192.168.56.10:80 weight=2;   #真实服务器2的IP

        }

    server {
        listen       80;
        server_name  www.xxxx.com;

        location / {
            proxy_pass http://lisi;     #添加反向代理,代理的地址写上面 upstream 声明的名字
            proxy_set_header Host $host;    #重写请求头部,保证网站所有页面都可以访问成功
        }


3、重启服务

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -t

[root@zerbufan ~]# /usr/local/nginx/sbin/nginx -s reload


验证

多次请求 www.xxxx.com 可以看到得到的数据 3次来自服务器1 两次来自服务器2

Nginx 服务_统计模块_18

这里 内容不一样是为了区分实验效果,实际的生产环境中内容应该是一样的