nginx安装及配置 & 支持 https

1.nginx概述

Nginx 是一个免费、开源、高性能、轻量级的 HTTP 和反向代理服务器,
也是一个电子邮件(IMAP/POP3)代理服务器,其特点是占有内存少,并发能力强。

Nginx 由内核和一系列模块组成,内核提供 Web 服务的基本功能,
如启用网络协议,创建运行环境,接收和分配客户端请求,处理模块之间的交互。

#nginx模块
Nginx 的各种功能和操作都由模块来实现。Nginx 的模块从结构上分为:
>> 核心模块:HTTP 模块、EVENT 模块和 MAIL 模块。
>> 基础模块:HTTP Access 模块、HTTP FastCGI 模块、HTTP Proxy 模块和 HTTP Rewrite 模块。
>> 第三方模块:HTTP Upstream Request Hash 模块、Notice 模块和 HTTP Access Key 模块及用户自己开发的模块。

这样的设计使 Nginx 方便开发和扩展,也正因此才使得 Nginx 功能如此强大。

Nginx 的模块默认编译进 Nginx 中,如果需要增加或删除模块,
需要重新编译 Nginx,这一点不如 Apache 的动态加载模块方便。

如果有需要动态加载模块,可以使用由淘宝网发起的 Web 服务器 Tengine,
在 Nginx 的基础上增加了很多高级特性,完全兼容 Nginx,已被国内很多网站采用。

#Nginx 有很多扩展版本:
>> 开源版 nginx.org
>> 商业版 NGINX Plus
>> 淘宝网发起的 Web 服务器 Tengine
>> 基于 Nginx 和 Lua 的 Web 平台 OpenResty

2.nginx安装

https://wiki.ubuntu.org.cn/Nginx (ubuntu安装nginx)

官网 http://nginx.org/

关键模块

静态页面拦截规则  location(在server里)
反向代理      proxy_pass(在location里)
负载均衡      upstream(在server外)

2.1 cd /user/local/software

cd /user/local/software   目录下(没有的话,就创建)

2.2 上传nginx包及高可用包到该目录下

nginx-1.6.2.tar.gz
keepalived-1.2.18.tar.gz
nginx包.png

2.3 解压至 /usr/local下

tar -zxf nginx-1.6.2.tar.gz /usr/local

2.4 下载所需要的依赖库文件:

yum install pcre
yum install pcre-devel
yum install zlib
yum install zlib-devel

2.5 进行configure配置

cd nginx-1.6.2 && ./configure --prefix=/usr/local/nginx 

下图代表成功

nginx安装成功时表现.png

查看是否报错:
报错1:error: C compiler cc is not found
解决方案1:
安装gcc-c++包
命令:yum -y install gcc-c++
-y:所有的询问均选择yes

2.6 编译安装(cd 到 /usr/local/nginx-1.6.2目录下)

make && make install

2.7 启动nginx

cd /usr/local/nginx目录下: 看到如下4个目录
 ....conf 配置文件  
 ... html 网页文件
 ...logs  日志文件 
 ...sbin  主要二进制程序
启动命令:
/usr/local/nginx/sbin/nginx -s start

2.8 查看是否启动成功

netstat -ano | grep 80 
或
ps -ef|grep nginx
查看nginx进程.png

2.9 关闭命令

/usr/local/nginx/sbin/nginx -s stop

2.10 重启命令

/usr/local/nginx/sbin/nginx -s reload

2.11 浏览器访问地址:看到欢迎页面即可

http://192.168.0.100:80

利用nginx访问页面.png

若是失败:可能为80端口被占用等。
lsof -i:80查看进程pid,然后kill -9 pid即可

2.12 常用命令

nginx -s stop :快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。
nginx -s quit :平稳关闭Nginx,保存相关信息,有安排的结束web服务。
nginx -s reload :因改变了Nginx相关配置,需要重新加载配置而重载。
nginx -s reopen :重新打开日志文件。
nginx -c filename :为 Nginx 指定一个配置文件,来代替缺省的。
nginx -t :不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。
nginx -v:显示 nginx 的版本。
nginx -V:显示 nginx 的版本,编译器版本和配置参数。
nginx反向代理.jpg

3.nginx配置文件

3.1 Nginx 配置语法

>> 配置文件由指令和指令块构成
>> 每条指令以分号(;)结尾,指令和参数间以空格符分隔
>> 指令块以大括号{}将多条指令组织在一起
>> include 语句允许组合多个配置文件以提高可维护性
>> 使用 # 添加注释
>> 使用 $ 定义变量
>> 部分指令的参数支持正则表达式

3.2 nginx配置模块

nginx.conf.png

3.2.1 全局块

全局配置部分用来配置对整个 Server 都有效的参数。
主要会设置一些影响 Nginx 服务器整体运行的配置指令,
包括配置运行 Nginx 服务器的用户(组)、允许生成的 Worker Process 数,
进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等。

3.2.2 Events 块

Events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,
常用的设置包括是否开启对多 Work Process 下的网络连接进行序列化,
是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,
每个 Word Process 可以同时支持的最大连接数等。

3.2.3 HTTP 块

这算是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义
等绝大多数功能和第三方模块的配置都在这里。 
需要注意的是:HTTP 块也可以包括 HTTP 全局块、Server 块。

1.HTTP 全局块
HTTP 全局块配置的指令包括文件引入、MIME-TYPE 定义、
日志自定义、连接超时时间、单链接请求数上限等。

2.Server 块
这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,
该技术的产生是为了节省互联网服务器硬件成本。
每个 HTTP 块可以包括多个 Server 块,而每个 Server 块就相当于一个虚拟主机。
而每个 Server 块也分为全局 Server 块,以及可以同时包含多个 Locaton 块。
2.1 全局 Server 块:
也被叫做“虚拟服务器”部分,它描述的是一组根据不同server_name指令逻辑分割的资源,
这些虚拟服务器响应 HTTP 请求,因此都包含在 HTTP 部分。
最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置。
2.2 Location 块:
一个 Server 块可以配置多个 Location 块。
这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),
对虚拟主机名称 (也可以是 IP 别名)之外的字符串(例如前面的 /uri-string)进行匹配,对特定的请求进行处理。
地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

3.3 nginx配置文件详解

#定义Nginx运行的用户和用户组
user www www; 

#nginx进程数,<=CPU数 
worker_processes 4; 

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

#日志文件存放路径 access_log path [format [buffer=size | off]]
access_log /data/nginx/logs/lazyegg.com/web/access.log combinedio;

#进程pid文件
#pid        logs/nginx.pid;

#指定进程可以打开的最大描述符:数目
#工作模式与连接数上限
##这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。
#这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。
worker_rlimit_nofile 65535;

#################################  events  ###############################
events {
    accept_mutex [on|off] #on时,可以避免惊群效应。是否打开Ningx的负载均衡锁;此锁能够让多个worker进轮流地、序列化地与新的客户端建立连接;而通常当一个worker进程的负载达到其上限的7/8,master就尽可能不再将请求调度此worker;
    lock_file /path/to/lock_file;#lock文件
    accept_mutex_delay #ms; accept锁模式中,一个worker进程为取得accept锁的等待时长;如果某worker进程在某次试图取得锁时失败了,至少要等待#ms才能再一次请求锁;
    multi_accept on|off;#是否允许一次性地响应多个用户请求;默认为Off;
    use [epoll|rtsig|select|poll];#定义使用的事件模型,建议让nginx自动选择;
    worker_connections  1024;#每个进程最大连接数(最大连接=连接数x进程数)每个worker允许同时产生多少个链接,默认1024
    
    #keepalive 超时时间
    keepalive_timeout 60;

    #客户端请求头部的缓冲区大小。
    client_header_buffer_size 4k;

    #这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
    open_file_cache max=65535 inactive=60s;
    #这个是指多长时间检查一次缓存的有效信息。
    open_file_cache_valid 80s;
        #open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。
    open_file_cache_min_uses 1;

    #语法:open_file_cache_errors on | off 默认值:open_file_cache_errors off 使用字段:http, server, location 这个指令指定是否在搜索一个文件是记录cache错误.
    open_file_cache_errors on;
}

##############################   http    ##################################

#设定http服务器,利用它的反向代理功能提供负载均衡支持
http{
    #文件扩展名与文件类型映射表
    include mime.types;

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

    #默认编码
    charset utf-8;

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

    #客户端请求头部的缓冲区大小。
    client_header_buffer_size 32k;

    #客户请求头缓冲大小。
    large_client_header_buffers 4 64k;

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

    #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
    sendfile on;

    #开启目录列表访问,适合下载服务器,默认关闭。
    autoindex on;

    #此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
    tcp_nopush on;

    tcp_nodelay on;

    #长连接超时时间,单位是秒
    keepalive_timeout 120;

    #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;

    #gzip模块设置
    gzip on; #开启gzip压缩输出
    gzip_min_length 1k;    #最小压缩文件大小
    gzip_buffers 4 16k;    #压缩缓冲区
    gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
    gzip_comp_level 2;     #压缩等级
    gzip_types text/plain application/x-javascript text/css application/xml;    #压缩类型,默认就已经包含textml,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
    gzip_vary on;

    #开启限制IP连接数的时候需要使用
    #limit_zone crawler $binary_remote_addr 10m;

    #日志文件输出格式 这个位置相于全局设置
    #$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;
    #$remote_user:用来记录客户端用户名称;
    #$time_local: 用来记录访问时间与时区;
    #$request: 用来记录请求的url与http协议;
    #$status: 用来记录请求状态;成功是200,
    #$body_bytes_sent :记录发送给客户端文件主体内容大小;
    #$http_referer:用来记录从那个页面链接访问过来的;
    #$http_user_agent:记录客户浏览器的相关信息;
    #通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
    log_format access '$remote_addr - $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" $http_x_forwarded_for';

    #负载均衡配置
    upstream lazyegg.net {

        #upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
        server 192.168.80.121:80 weight=3;
        server 192.168.80.122:80 weight=2;
        server 192.168.80.123:80 weight=3;

        #nginx的upstream目前支持4种方式的分配
        #1、轮询(默认)
        #每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
        #2、weight
        #指定轮询权重,weight和访问比率成正比,用于后端服务器性能不均的情况。
        #例如:
        #upstream bakend {
        #    server 192.168.0.14 weight=10;
        #    server 192.168.0.15 weight=10;
        #}
        #2、ip_hash
        #每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
        #例如:
        #upstream bakend {
        #    ip_hash;
        #    server 192.168.0.14:88;
        #    server 192.168.0.15:80;
        #}
        #3、fair(第三方)
        #按后端服务器的响应时间来分配请求,响应时间短的优先分配。
        #upstream backend {
        #    server server1;
        #    server server2;
        #    fair;
        #}
        #4、url_hash(第三方)
        #按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
        #例:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法
        #upstream backend {
        #    server squid1:3128;
        #    server squid2:3128;
        #    hash $request_uri;
        #    hash_method crc32;
        #}

        #tips:
        #upstream bakend{#定义负载均衡设备的Ip及设备状态}{
        #    ip_hash;
        #    server 127.0.0.1:9090 down;
        #    server 127.0.0.1:8080 weight=2;
        #    server 127.0.0.1:6060;
        #    server 127.0.0.1:7070 backup;
        #}
        #在需要使用负载均衡的server中增加 proxy_pass http://bakend/;

        #每个设备的状态设置为:
        #1.down表示单前的server暂时不参与负载
        #2.weight为weight越大,负载的权重就越大。
        #3.max_fails:允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream模块定义的错误
        #4.fail_timeout:max_fails次失败后,暂停的时间。
        #5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

        #nginx支持同时设置多组的负载均衡,用来给不用的server来使用。
        #client_body_in_file_only设置为On 可以讲client post过来的数据记录到文件中用来做debug
        #client_body_temp_path设置记录文件的目录 可以设置最多3层目录
        #location对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡
    }

       #虚拟主机的配置
    server {
        #监听端口
        listen 80;

        #域名可以有多个,用空格隔开
        server_name lazyegg.net;
        #默认入口文件名称
        index index.html index.htm index.php;
        root /data/www/lazyegg;

        #对******进行负载均衡
        location ~ .*.(php|php5)?$
        {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi.conf;
        }

        #图片缓存时间设置
        location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires 10d;
        }

        #JS和CSS缓存时间设置
        location ~ .*.(js|css)?$
        {
            expires 1h;
        }

        #定义本虚拟主机的访问日志
        access_log  /usr/local/nginx/logs/host.access.log  main;
        access_log  /usr/local/nginx/logs/host.access.404.log  log404;

        #对 "/connect-controller" 启用反向代理
        location /connect-controller {
            proxy_pass http://127.0.0.1:88; #请注意此处端口号不能与虚拟主机监听的端口号一样(也就是server监听的端口)
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;

            #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            #以下是一些反向代理的配置,可选。
            proxy_set_header Host $host;

            #允许客户端请求的最大单文件字节数
            client_max_body_size 10m;

            #缓冲区代理缓冲用户端请求的最大字节数,
            #如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了。
            #无论使用firefox4.0还是IE8.0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误
            client_body_buffer_size 128k;

            #表示使nginx阻止HTTP应答代码为400或者更高的应答。
            proxy_intercept_errors on;

            #后端服务器连接的超时时间_发起握手等候响应超时时间
            #nginx跟后端服务器连接超时时间(代理连接超时)
            proxy_connect_timeout 90;

            #后端服务器数据回传时间(代理发送超时)
            #后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
            proxy_send_timeout 90;

            #连接成功后,后端服务器响应时间(代理接收超时)
            #连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)
            proxy_read_timeout 90;

            #设置代理服务器(nginx)保存用户头信息的缓冲区大小
            #设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头,默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小
            proxy_buffer_size 4k;

            #proxy_buffers缓冲区,网页平均在32k以下的设置
            #设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k
            proxy_buffers 4 32k;

            #高负荷下缓冲大小(proxy_buffers*2)
            proxy_busy_buffers_size 64k;

            #设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长
            #设定缓存文件夹大小,大于这个值,将从upstream服务器传
            proxy_temp_file_write_size 64k;
            #返回根路径地址(相对路径:相对于/usr/local/nginx/)
            root   html;
            #默认访问文件
            index  index.html index.htm;
        }

        #本地动静分离反向代理配置
        #所有jsp的页面均交由tomcat或resin处理
        location ~ .(jsp|jspx|do)?$ {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:8080;
        }
    }
    
    # HTTPS server
    server {
        listen       443 ssl; # 监听443端口
        server_name  www.zy.com; # 定义使用www.zy.com访问

        ssl_certificate      cert.pem;  # ssl证书文件位置
        ssl_certificate_key  cert.key;  # ssl证书key的位置

        # ssl配置参数(可选)
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        # 数字签名
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

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

3.4 Nginx 配置:动静分离

Nginx 动静分离简单来说就是把动态跟静态请求分开,
不能理解成只是单纯的把动态页面和静态页面物理分离。

严格意义上说应该是动态请求跟静态请求分开,
可以理解成使用 Nginx 处理静态页面,Tomcat 处理动态页面。

动静分离从目前实现角度来讲大致分为两种:
>> 纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案; 
>> 动态跟静态文件混合在一起发布,通过 Nginx 来分开。 

通过 Location 指定不同的后缀名实现不同的请求转发。
通过 Expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。

具体 Expires 定义:
是给一个资源设定一个过期时间,也就是说无需去服务端验证,
直接通过浏览器自身确认是否过期即可, 所以不会产生额外的流量。

此种方法非常适合不经常变动的资源(如果经常更新的文件, 不建议使用 Expires 来缓存)。

以设置 3d 为例,表示在这 3 天之内访问这个 URL,发送一个请求,
比对服务器该文件最后更新时间没有变化,则不会从服务器抓取,
返回状态码 304,如果有修改,则直接从服务器重新下载,返回状态码 200。

步骤大致为

#1.服务器找个目录存放自己的静态文件

#2.修改 nginx.conf
server {
    listen       80;
    server_name  localhost;
    location /static/ {
        root   /usr/data/www;
    }
    location /image/ {
         root /usr/data/;
         autoindex on;
    }
}

#3.重新加载配置文件
nginx -s reload

3.5 Nginx 的 rewrite 配置

https://www.jianshu.com/p/a8261a1a64f8

4.正则表达式

字符 描述
~ 区分大小写匹配
~* 不区分大小写匹配
!~ 区分大小写不匹配
!~* 不区分大小写不匹配
-f及!-f 判断是否存在文件
-d和!-d 判断是否存在目录
-e和!-e 判断是否存在文件或目录
-x和!-x 判断文件是否可执行
\ 将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“$”则匹配“$”
^ 匹配输入字符串的起始位置
$ 匹配输入字符串的结束位置
* 匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
+ 匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“oll”,但不能匹配“o”
? 匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,"?"等效于"{0,1}"
. 匹配除“\n”之外的任何单个字符
.\n 匹配包括“\n”在内的任意字符,请使用诸如之类的模式。
(pattern) 匹配括号内pattern并可以在后面获取对应的匹配,常用9属性获取小括号中的匹配内容,要匹配圆括号字符需要(Content)

5.nginx中的server_name与listen详解

"server_name:"

可以设置基于域名的虚拟主机, 不同的域名会通过请求头的Host字段, 
匹配到特定的server块, 转发到对应的虚拟主机

server_name在收到请求后的匹配逻辑和location的匹配逻辑类似
(支持正则匹配; 支持多域名匹配, 多域名间以空格分开)

5.1 假设将某一个server的端口修改为8081

listen配置.png
cd 到/etc/sysconfig/下,找到iptables文件,添加如下一行,端口放行记录
开启某端口.png
保存退出后(centos7执行下述命令)
systemctl restart iptables.service #重启防火墙使配置生效
systemctl enable iptables.service #设置防火墙开机启动
访问[http://192.168.0.100:80](http://192.168.1.172/)81即可

5.2 安全加固 (此处有大坑)

此处若是在某个server的listen上同时加上ip及端口,则其优先级更高
另一个不加ip的server, 无法生效
listen是socket层面的事情,而server_name只是url的解析,
当然只有监听到的请求才能被解析,于是这就回到了一个tcp监听端口的问题:
如果serverA监听不指定ip,则相当于监听0.0.0.0:port,
ServerB监听指定ip1:port,此时如果请求指定ip1必然会被ServerB接收到并处理,
可以通过(netstat或者lsof等工具检查nginx进程的端口绑定情况)
server {
  listen 192.168.0.100:8080; # 将listen处设置为nginx所在服务器的ip及端口
}

server {
  listen 8081; # 上一个server配置完, 这里将无法生效...(坑坑坑)
}

6.nginx配置ssl证书 --> 支持 https访问

6.1 生成证书

6.1.1 生成证书方法1:

在nginx.conf同级目录下 ---> 执行下述命令

mkdir nginx-ssl
cd nginx-ssl
# 生成一个 私钥, 生成该私钥时, 会让输入密码, 比如 123456
openssl genrsa -aes128 -out cert.key 2048
# 如果后续再使用此文件, 需要重复输入上一步设置的密码, 那么可以执行下述命令实现免密
openssl rsa -in cert.key -out cert.key
# 创建服务器证书的申请文件 cert.csr, 
# 其中Country Name填CN,Common Name填主机名也可以不填,如果不填浏览器会认为不安全.
# (例如你以后的url为https://zy.com/xxxx....这里就可以填 zy.com),其他的都可以不填.
openssl req -new -key cert.key -out cert.csr
# 生成一个 CA 证书请求
openssl req -new -x509 -key cert.key -out ca.crt -days 3650
# 自己签发证书: 创建自当前日期起有效期为期十年的服务器证书 cert.pem
openssl x509 -req -days 3650 -in cert.csr -CA ca.crt -CAkey cert.key -CAcreateserial -out cert.pem


此时,共生成5个文件(cert.key, cert.pem --> 这俩文件配置到 nginx 中):
ca.crt
ca.srl
cert.csr
cert.key
cert.pem

6.1.2 Let's Encrypt

https://letsencrypt.org/zh-cn/getting-started/

通常,如果网站需要支持 HTTPS 协议,网站管理员则要从 SSL 证书供应商处购买 SSL 证书,Let's Encrypt 除外。

Let's Encrypt 是一个免费、开放,自动化的证书颁发机构,由 ISRG(Internet Security Research Group)运作。
ISRG 是一个关注网络安全的公益组织,其赞助商包括 
Mozilla、Akamai、Cisco、EFF、Chrome、IdenTrust、Facebook等公司。
ISRG 的目的是消除资金和技术领域的障碍,全面推进网站从HTTP到HTTPS过度的进程。

目前,包括FireFox、Chrome在内的主流浏览器都支持Let's Encrypt证书,
已经有不少用户在真实项目中使用Let's Encrypt证书。
Let's Encrypt免费SSL证书的有效期是90天,到期后可以再续期,这样也就可以变相长期使用了。 

6.1.3 直接购买

由GlobalSign、GeoTrust、Verisign等全球公认的数字证书颁发机构颁发的SSL证书。
或国内相关代理厂商也可.

https://www.globalsign.com/
https://www.geotrust.com/
http://www.verisign.com/

6.2 在server块中配置 ssl 的支持

server {
    listen       443 ssl; # 监听443端口
    server_name  localhost; # 定义使用www.zy.com访问
    
    ssl on;
    #证书及秘钥配置
    ssl_certificate      /etc/nginx/nginx-ssl/cert.pem;  # ssl证书文件位置
    ssl_certificate_key  /etc/nginx/nginx-ssl/cert.key;  # ssl证书key的位置
    ssl_protocols TLSv1.1 TLSv1.2 SSLv2 SSLv3; # 支持的 TLS/SSL 协议
    #数字签名
    ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers on;
    #ssl_verify_client on; #双向认证
    #ssl_client_certificate ca.crt;#双向认证

    # ssl配置参数(可选)
    #ssl_session_cache    shared:SSL:1m;
    #ssl_session_timeout  5m;

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

nginx -s reload重新加载配置文件或重启nginx即可

https访问.png

6.3 常见问题

6.3.1 生成秘钥时, 输入了密码, 导致重启nginx后, 报错如下:

密码错误.png
解决方案:
参考 6.1.1 中生成秘钥后的下一步. (即实现免密功能)

7.nginx 原理及参数优化配置

7.1概述

Nginx 默认采用多进程工作方式,Nginx 启动后,会运行一个 Master 进程和多个 Worker 进程。

其中 Master 充当整个进程组与用户的交互接口,同时对进程进行监护,
管理 Worker 进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。

Worker 用来处理基本的网络事件,Worker 之间是平等的,他们共同竞争来处理来自客户端的请求。

7.2 master-workers 的机制

Nginx-Master-Worker.jpg
#master-workers 的机制的好处?
可以使用 nginx-s reload 热部署。
每个 Worker 是独立的进程,不需要加锁,省掉了锁带来的开销。
采用独立的进程,可以让互相之间不会影响,一个进程退出后,
其他进程还在工作,服务不会中断,Master 进程则很快启动新的 Worker 进程。

#需要设置多少个 Worker?
Nginx 同 Redis 类似都采用了 IO 多路复用机制,每个 Worker 都是一个独立的进程,
但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求,即使是成千上万个请求也不在话下。
每个 Worker 的线程可以把一个 CPU 的性能发挥到极致。
所以 Worker 数和服务器的 CPU 数相等是最为适宜的。
设少了会浪费 CPU,设多了会造成 CPU 频繁切换上下文带来的损耗。
[
#设置 worker 数量。
 worker_processes 4 
#work 绑定 cpu(4 work 绑定 4cpu)。 
 worker_cpu_affinity 0001 0010 0100 1000 
#work 绑定 cpu (4 work 绑定 8cpu 中的 4 个) 。 
 worker_cpu_affinity 0000001 00000010 00000100 00001000
]
连接数 worker_connection:这个值是表示每个 Worker 进程所能建立连接的最大值。
所以,一个 Nginx 能建立的最大连接数,应该是 worker_connections * worker_processes。
>> 对于 HTTP 请求本地资源来说,能够支持的最大并发数量是 
worker_connections * worker_processes,
>> 对于 HTTP 1.1 的浏览器每次访问要占两个连接。所以普通的静态访问最大并发数是
worker_connections * worker_processes / 2。
>> 如果是 HTTP 作为反向代理来说,最大并发数量应该是 
worker_connections * worker_processes / 4。
因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。
Nginx 请求处理流程.jpg

7.3 Nginx 是如何实现高并发的?

Nginx 采用的是多进程(单线程)&多路 IO 复用模型,异步,非阻塞。

一个主进程Master,多个工作进程Worker,
每个Worker进程可以处理多个请求 ,
Master 进程主要负责收集、分发请求。

每当一个请求过来时,Master 就拉起一个 Worker 进程负责处理这个请求。
同时 Master 进程也负责监控 Woker 的状态,保证高可靠性。

Nginx的 Work 进程,为了应对高并发场景,采取了Reactor模型(也就是 I/O 多路复用,NIO)。

I/O 多路复用模型:
在 I/O 多路复用模型中,最重要的系统调用函数就是Select(其他的还有epoll等)。
该方法能够同时监控多个文件描述符的可读可写情况(每一个网络连接其实都对应一个文件描述符),
当其中的某些文件描述符可读或者可写时,Select 方法就会返回可读以及可写的文件描述符个数。

Work 进程使用 I/O 多路复用模块同时监听多个 FD(文件描述符),
当 Accept、Read、Write 和 Close 事件产生时,操作系统就会回调 FD 绑定的事件处理器。
这时候 Work 进程再去处理相应事件,而不是阻塞在某个请求连接上等待。
这样就可以实现一个进程同时处理多个连接。
每一个 Worker 进程通过 I/O 多路复用处理多个连接请求。

为了减少进程切换(需要系统调用)的性能损耗,
一般设置 Worker 进程数量和 CPU 数量一致。

7.4 Nginx 常见的优化配置

>> 调整 worker_processes:
指 Nginx 要生成的 Worker 数量,最佳实践是每个 CPU 运行 1 个工作进程。
>> 最大化 worker_connections。
>> 启用 Gzip 压缩:
压缩文件大小,减少了客户端 HTTP 的传输带宽,因此提高了页面加载速度。
>> 为静态文件启用缓存。
>> 禁用 access_logs(不太好):
访问日志记录,它记录每个 Nginx 请求,因此消耗了大量 CPU 资源,从而降低了 Nginx 性能。

参考资源
https://mp.weixin.qq.com/s/wC_TURy_zpLUdA0gIcJD3w (nginx核心参考)

你可能感兴趣的:(nginx安装及配置 & 支持 https)