高性能web服务器之Nginx使用详解(进阶篇)

创作不易,如果觉得这篇文章对你有帮助,欢迎各位老铁点个赞呗,您的支持是我创作的最大动力!

文章目录

  • 1 前言
  • 2 Nginx核心配置文件
    • 2.1 Nginx文件结构
    • 2.2 Nginx核心配置文件
  • 3 Nginx之动静分离
    • 3.1 Nginx动静分离是什么
    • 3.2 Nginx动静分离配置
  • 4 Nginx日志配置以及切割
    • 4.1 日志的配置
    • 4.2 日志的切割
      • 4.2.1 为什么要进行日志切割
      • 4.2.2 如何进行日志切割
      • 4.2.3 使用定时任务进行日志的切割
  • 5 Nginx配置https
    • 5.1 什么是https
    • 5.2 为什么要配置https
    • 5.3 配置https
      • 5.3.1 什么是SSL证书
      • 5.3.2 SSL证书的作用
      • 5.3.3 颁发SSL证书
      • 5.3.4 在Nginx中配置HTTPS
    • 5.4 Nginx服务器禁止ip访问
    • 5.5 最终nginx文件配置
  • 6 Nginx实现限流
  • 7 Nginx实现防盗链

1 前言

上一篇 高性能web服务器之Nginx使用详解 中,介绍了Nginx的环境搭建,以及一些基础的使用,本文将介绍一些Nginx使用时的高级应用。

2 Nginx核心配置文件

下面简单介绍下Nginx的核心配置文件/usr/local/nginx/conf/nginx.conf,更详细的配置,可以参考我的另一篇博文:https://blog.csdn.net/smilehappiness/article/details/106676066

2.1 Nginx文件结构

nginx文件结构如下:

...    #全局块

events {   #events块
   ...
}

http {  #http块
    ...   #http全局块
    
    server  {  #server块
    
        ...       #server全局块
        
        location [PATTERN] {  #location块
            ...
        }
        
        location [PATTERN]{
            ...
        }
    }
    
    server{
      ...
    }
    
    ...     #http全局块
}
  • 全局块
    该全局块配置影响nginx全局的指令。全局配置,一般包含运行nginx服务器的用户组nginx进程pid存放路径日志存放路径配置文件引入,允许生成worker process数等。

  • events块
    配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数选取哪种事件驱动模型处理连接请求是否允许同时接受多个网路连接开启多个网络连接序列化等。

  • http块
    可以嵌套多个server配置代理缓存日志定义等绝大多数功能和第三方模块的配置。

    比如: 文件引入mime-type定义日志自定义是否使用sendfile传输文件连接超时时间单连接请求数等。

  • server块
    配置虚拟主机的相关参数,一个http中可以有多个server。

  • location块
    配置请求的路由,以及页面资源的映射路径等。

    注:
    块配置项一定会用大括号把一系列所属的配置项全包含进来,块配置项可以嵌套,内层块直接继承外层块,当内外层块中的配置发生冲突时,以内层块为准。

2.2 Nginx核心配置文件

  • 下面给大家上一个配置文件,方便老铁们理解

    ########### 每个指令必须有分号结束。#################
    
    #user administrator administrators;  #配置用户或者组,默认为nobody nobody
    #worker_processes 2;  #允许生成的进程数,默认为1,这里一般设置为cpu核心数相等
    #pid /nginx/pid/nginx.pid;   #指定nginx进程运行文件存放地址
    error_log log/error.log debug;  #指定日志路径,级别。这个设置可以放入全局块,http块,server块,级别依次为:debug|info|notice|warn|error|crit|alert|emerg
    
    events {
        accept_mutex on;   #设置网路连接序列化,防止惊群现象发生,默认为on
        multi_accept on;  #设置一个进程是否同时接受多个网络连接,默认为off
        #use epoll;      #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
        worker_connections  1024;  #最大连接数(指定同一时间最多可开启的文件数,对于linux来说,一个进程就会开启一个文件去处理),默认为1024,可以设置为65535(ulimit -h 65535)
    }
    
    http {
        include       mime.types;   #文件扩展名与文件类型映射表
        default_type  application/octet-stream; #默认文件类型
        #access_log off; #取消服务日志    
        
        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #              '$status $body_bytes_sent "$http_referer" '
        #              '"$http_user_agent" "$http_x_forwarded_for"'; #自定义配置 If the format is not specified then the predefined “combined” format is used.
    
        access_log log/access.log myFormat;  #combined为日志格式的默认值
        
        sendfile on;   #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块
        sendfile_max_chunk 100k;  #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限
        keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块中进行配置
    
        upstream app{   
          server 127.0.0.1:9091;
          server 127.0.0.1:9092 backup;  #热备
        }
        
        server {
            keepalive_requests 120; #单连接请求上限次数。
            listen       80;   #监听端口
            server_name  127.0.0.1;   #监听地址(ip或者域名)  
    
    		error_page 404 500 https://www.baidu.com; #错误页   
            location  ~*^.+$ {       #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
               #root path;  #根目录
               #index index.html index.htm;  #设置默认页
               proxy_pass  http://app;  #请求转向app定义的服务器列表
               deny 127.0.0.1;  #拒绝的ip
               allow 172.18.5.54; #允许的ip           
            } 
        }
    }
    
  • 上面是nginx的基本配置,需要注意的有以下几点:
    惊群现象:一个网路连接到来,多个睡眠的进程被同时叫醒,但只有一个进程能获得链接,这样会影响系统性能

    每个指令必须有分号结束。

3 Nginx之动静分离

3.1 Nginx动静分离是什么

Nginx动静分离,指的是静态资源请求由Nginx 处理,动态资源请求由tomcat或其他web服务器处理。

Nginx主要用于部署静态资源,比如部署静态网站,如果我们是一个动态网站,比如Java开发的动态网站,那么动态网站里面肯定有一些静态资源,像图片、css、html、js、视频、音频、文档等等,这些静态资源如果使用tomcat等服务器部署,效率并不高,而采用nginx部署则大大提高性能。

3.2 Nginx动静分离配置

在负载均衡服务器的服务器上, Nginx根据客户端请求的URI判断请求的是否为静态资源,如果请求的 URI包含了jpg、png、.js、.html等信息,则由处理静态请求的服务器处理(部署 Nginx)。如果请求的URI包含了 .php、.jsp等字段,则由处理动态请求的服务器处理(部署 Tomcat)。

动静分离是实际应用中常见的一种场景,动态资源,由tomcat或其他web服务器完成,静态资源,如图片、css、js等由nginx服务器完成。

动静分离充分发挥它们各自的优势,从而达到更高效合理的架构,如下图所示:
高性能web服务器之Nginx使用详解(进阶篇)_第1张图片

nginx中配置静态资源,有以下两种方式:

  • 第一种方式
    通过在nginx.conf配置文件中添加静态资源的location进行匹配,比如:

    当访问静态资源的时候,从linux服务器的静态资源目录/opt/static目录下获取(静态资源目录可以根据个人习惯设置)

    location ~ .*\.(js|css|htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
       		root /opt/static;
    }
    

    location后面的参数说明:
    ~ 表示正则匹配,也就是说后面的内容可以是正则表达式匹配
    第一个点 . 表示匹配任意字符
    * 表示匹配一个或多个字符
    \ 是转义字符,是后面这个点的转义字符
    | 表示或者
    $ 表示结尾
    整个配置表示以 .后面括号里面的这些后缀结尾的文件都由nginx服务器处理

    以上localtion匹配的最终效果:
    访问资源的时候,如:http://域名/umi.jshttp://域名/app.csshttp://域名/index.htmlhttp://域名/hello.pdfhttp://域名/test.png等,都可以通过Nginx服务器,映射到静态资源目录/opt/static下,去获取资源。

  • 第二种方式
    通过在nginx.conf配置文件中配置静态资源所在目录实现,比如:

    location ~ .*/(css|js|img|image) {
          root   /opt/static;
    }
    

    Localtion匹配的最终效果: hello/css、hello/js、hello/picture/img、*/image等
    如,访问以下请求时,可以访问到目录下的资源
    http://域名/css/index.csshttp://域名/admin/js/index.css

    注意: nginx是把ip:80端口映射成你的root路径(比如笔者这里是 /opt/static),假设你需要这样http://域名/css/index.css访问资源,则需要配置资源的位置为: /opt/static/css/index.css

    放置静态资源的目录,要注意一下目录权限问题,如果权限不足,可能会出现403错误,使用以下命令,给目录赋予权限 chmod 744 filename

    Nginx动静分离,结合负载均衡一起使用,进行如下配置即可:

    upstream app1 { 
        server  ip:91 weight=3; 
        server  域名 weight=2;  
    }
    
    location /admin{
        proxy_pass http://app1;
    }
    location ~ .*/(css|js|img|image) {
          root   /opt/static;
    }
    

    以上配置中,请求http://ip/admin,会分发到请求服务器,加载动态的数据,而请求http://ip/static/js/index.js,就会直接访问nginx服务器下的静态资源

4 Nginx日志配置以及切割

4.1 日志的配置

nginx服务,日志也是必不可少的,下面使用自定义日志配置:

 log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

参数说明
$remote_addr$http_x_forwarded_for 用以记录客户端的ip地址
$remote_user 用来记录客户端用户名称
$time_local 用来记录访问时间与时区
$request 用来记录请求的url与http协议
$status 用来记录请求状态;成功是200
$body_bytes_sent 记录发送给客户端文件主体内容大小
$http_referer 用来记录从那个页面链接访问过来的
$http_user_agent 记录客户端浏览器的相关信息

官网日志配置: http://nginx.org/en/docs/http/ngx_http_log_module.html

4.2 日志的切割

4.2.1 为什么要进行日志切割

当nginx服务器运行一段时间之后,日志文件特别的大,不方便查看日志,这时候,可以按照实际的情况,进行日志文件的切分。

4.2.2 如何进行日志切割

使用以下命令:
/usr/local/nginx/sbin/nginx -s reopen
使用-s reopen参数可以重新打开日志文件,这样可以先把当前日志文件改名或转移到其他目录中进行备份,再重新打开时就会生成新的日志文件,这个功能使得日志文件不至于过大 ,进行日志切分后,方便查找日志。

Linux下我们可以直接把日志文件mv走,但是当你mv移走后新的日志文件没有重新生成,一般linux下用的文件句柄,文件被打开情况下你mv走文件,但是原来操作这个文件的进程还是有这个文件的inode等信息,原进程还是读写原来的文件,而此时我们只需要执行一下reopen,则会生成新的日志文件。

操作步骤:

  • mv原文件到新文件夹中,此时nginx还是会把日志信息写到这个旧日志文件(写入新日志目录位置的旧日志文件中了)
  • 调用/usr/local/nginx/sbin/nginx -s reopen用来打开新日志文件,这样nginx会把新日志信息写入到这个新的日志文件中,这样就完成了日志的切割工作, 同时切割过程中没有日志的丢失。

4.2.3 使用定时任务进行日志的切割

一般来说,不会手动进行日志的切割,通常会使用Linux的定时任务,去定周期的进行日志的切割,可以根据公司实际情况,根据日志产生的数据量,来合理的设置定时任务的周期。
(不会使用Linux定时任务的童鞋们,可以参考我的另一篇博文https://blog.csdn.net/smilehappiness/article/details/105180845脑补一下)

为了更高效地完成此工作,可以采用定时任务+脚本实现

  • 脚本配置如下:

    #!/bin/bash
    date=`date +%Y%m%d%`
    logpath1=/usr/local/nginx/logs/
    logpath2=/opt/logs/nginx/
    mv $logpath1/access.log $logpath2/access-$date.log
    mv $logpath1/error.log $logpath2/error-$date.log
    /usr/local/nginx/sbin/nginx -s reopen
    

    日志的路径可以根据个人习惯指定,博主这里,把日志移动到/opt/logs/nginx/路径下,所以需要创建这个用来存放日志的目录/opt/logs/nginx/,以后,我可以去这个路径下查看nginx的运行日志情况。

    使用以下命令创建目录:
    mkdir -pv /opt/logs/nginx/ -p表示递归创建 -v表示显示目录创建信息

    如果没有Linux操作基础的童鞋们,可以参考博主的文章 Linux使用详解,10分钟带你玩转Linux基础操作 进行入门。

  • 配置定时任务
    首先,把上面的这个shell脚本,放到一个文件logCrontab.sh中,并放到目录/usr/local/nginx/logs下,接着,然后创建定时任务

    使用命令:
    crontab -e

    添加如下内容,每日23点进行日志切割:

    * 23 * * * /usr/local/nginx/logs/logCrontab.sh
    

    然后就可以根据实际情况,完成日志的切割啦。

    注意:
    有可能没有执行权限:-bash: /usr/local/nginx/logs/logCrontab.sh: Permission denied

    进入/usr/local/nginx/logs/目录,使用以下命令,设置可执行权限:
    chmod 777 logCrontab.sh 或者 chmod +x logCrontab.sh
    在这里插入图片描述
    可以使用以下命令,查看定时任务执行情况:
    tail -f /var/log/cron

5 Nginx配置https

5.1 什么是https

HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 [1] 。HTTPS 在HTTP 的基础下加入SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个系统提供了身份验证与加密通讯方法。它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面 [2] 。(百度百科)

HTTPS 是以安全为目标的 HTTP 通道,即 HTTP 下加入 SSL 加密层,HTTPS 不同于 HTTP 的端口,HTTP默认端口为80,HTTPS默认端口为443,现在大部分网站都实现了https。
比如访问京东和百度:https://www.baidu.com/、https://www.jd.com/。

5.2 为什么要配置https

HTTP 协议虽然使用极为广泛, 但是却存在不小的安全缺陷, 主要是其数据的明文传送和消息完整性检测的缺乏, 而这两点恰好是网络支付, 网络交易等新兴应用中安全方面最需要关注的。

使用http容易被攻击,同事攻击者也可以从网络中获取普通用户的隐秘信息,包括手机号码,身份证号码,信用卡号等重要资料,导致严重的安全事故。

5.3 配置https

Nginx中配置HTTPS比较简单,主要有以下两个步骤:

  • 签署可信任的SSL证书
  • 在Nginx中配置HTTPS

5.3.1 什么是SSL证书

SSL证书是一种数字证书,它使用Secure Socket Layer协议在浏览器和Web服务器之间建立一条安全通道,从而实现:
1、数据信息在客户端和服务器之间的加密传输,保证双方传递信息的安全性,不可被第三方窃听;
2、用户可以通过服务器证书验证他所访问的网站是否真实可靠;

5.3.2 SSL证书的作用

SSL证书主要有两个功能: 加密身份证明,证书需要购买,比如:https://www.wosign.com

5.3.3 颁发SSL证书

笔者这里,自己签发一个证书,用来演示。实际开发中,为了保证数据交互的安全性,在企业里面都会够买一个https的SSL证书,一般都是在阿里云或者腾讯云购买SSL证书,整个配置步骤都是完全一样的。

颁发不受浏览器信任的SSL证书:

通过openssl来生成,如果Linux中没有安装openssl,需要安装一下
执行以下命令:
yum install openssl openssl-devel -y

具体步骤如下:

  • 生成一个RSA密钥(私钥)
    执行以下命令:
    openssl genrsa -out nginx-private.key 2048

  • 生成一个证书请求
    执行以下命令:
    openssl req -new -key nginx-private.key -out nginx-private.csr -subj "/C=CN/ST=ShangHai/L=ShangHai/O=smilehappiness Inc./OU=Web Security/CN=smilehappiness .cn"

    参数说明:
    C字段:Country,单位所在国家,为两位数的国家缩写,如:CN表示中国
    ST字段:State/Province,单位所在州或省;
    L字段:Locality,单位所在城市/或县区;
    O字段:Organization,此网站的单位名称;
    OU字段:Organization Unit,下属部门名称,也常常用于显示其他证书相关信息,如证书类型,证书产品名称或身份验证类型或验证内容等
    CN字段:Common Name,网站的域名

  • 自己签发SSL证书
    执行以下命令:
    openssl x509 -req -days 365 -in nginx-private.csr -signkey nginx-private.key -out nginx-private.crt

5.3.4 在Nginx中配置HTTPS

添加Nginx的ssl模块支持,最终是要重新编译出一个新的nginx可执行程序

  • 如果之前安装时没有加入ssl模块,则需要到解压的nginx目录下执行
    ./configure --with-http_ssl_module

    当执行上面语句,出现./configure: error: SSL modules require the OpenSSL library.
    则需要安装openssl
    执行以下命令:
    yum -y install openssl openssl-devel

    依赖错误解决后再执行./configure --with-http_ssl_module

  • 然后执行make 命令,(得到一个新的nginx可执行程序)
    注意: 不要make install,否则会覆盖掉之前的nginx配置

  • 备份原来的nginx(如果不需要原来的也可以不备份)
    执行以下命令:
    cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.back

  • 把新编译出来的nginx覆盖旧的
    执行以下命令:
    先停止nginx服务,然后再进行nginx可执行程序覆盖
    /usr/local/nginx/sbin/nginx -s quit
    cp ./objs/nginx /usr/local/nginx/sbin/nginx

    当然啦,如果在第一次安装nginx时,都依赖了这个ssl模块,就不用这么麻烦了。

配置HTTPS server:
使用以下命令,编辑nginx.conf
vim /usr/local/nginx/conf/nginx.conf

server {
    # Nginx 版本为 nginx/1.15.0 以上请使用 listen 443 ssl 代替 listen 443 和 ssl on
    #listen       443 ssl;
    # 禁止ip访问
    listen 443 ssl default_server;
    # 填写绑定证书的域名
    server_name  www.domain.cn;
     # 禁止ip访问
    server_name _;

    # 证书文件名称
    ssl_certificate      /usr/local/nginx/nginx-private.crt;
    # 私钥文件名称
    ssl_certificate_key  /usr/local/nginx/nginx-private.key;

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

    #请按照以下协议配置
    #ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
    #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

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

大致配置都差不多,如果有问题,参照腾讯云或者阿里云配置即可。

配置参数说明:
ssl_session_cache shared:SSL:1m;
所有工作进程之间共享缓存,缓存大小以字节为单位指定,一兆字节可以存储大约4000个session,每个共享缓存都应该有一个任意名称,具有相同名称的缓存可以用于多个虚拟服务器,Nginx官方提示使用shared,性能会更高。

ssl_session_timeout 5m;
指定客户端可以重用会话参数的时间

ssl_ciphers HIGH:!aNULL:!MD5;
指定启用的密码,密码以OpenSSL库可以理解的格式指定

ssl_prefer_server_ciphers on
设置协商加密算法时,优先使用我们服务端的加密套件,而不是客户端浏览器的加密套件

至此,SSL证书就配置完成了。
第一次访问,由于博主是自己生成的证书,浏览器不信任,会弹出红色警告,点继续访问就行了。如果是实际项目中,使用公司购买的SSL证书,SSL证书都是有效的,就会显示绿色,如:
在这里插入图片描述
高性能web服务器之Nginx使用详解(进阶篇)_第2张图片

官方文档: http://nginx.org/en/docs/http/configuring_https_servers.html

5.4 Nginx服务器禁止ip访问

如果考虑安全性,可以设置禁止ip访问,这样黑客或者其他有心者,就不能通过ip或者他们的域名访问你的ip服务资源了。

具体配置也比较简单,如果是http访问,新添加如下server即可:

# http禁止IP直接访问网站 
server {
    listen 80 default;
    server_name _;
    return 403;
}

如果是https禁止ip访问,需要在ssl配置那里设置:

# https禁止IP直接访问网站(这种方式如果不好用,可以使用下面5.5中,域名的判断方式处理)
server {
    # 禁止ip访问
    listen 443 ssl default_server;
    # 填写绑定证书的域名
    server_name  www.domain.cn;
     # 禁止ip访问
    server_name _;
	return 403;
	
    # 证书文件名称
    ssl_certificate      /usr/local/nginx/nginx-private.crt;
    # 私钥文件名称
    ssl_certificate_key  /usr/local/nginx/nginx-private.key;
}

禁止访问如下所示:
高性能web服务器之Nginx使用详解(进阶篇)_第3张图片
一般来说,可以设置一些禁止访问的友好界面,看起来更好看。

5.5 最终nginx文件配置

worker_processes  4;

events {
      worker_connections  65535;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        # 监听80端口
        listen       80;
        #填写绑定证书的域名
        server_name www.domain.cn;

        #把http的域名请求转成https,这个是HTTP自动跳转HTTPS的安全配置(可选)让其自动将HTTP的请求重定向到HTTPS
        return 301 https://$host$request_uri;

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

    }

    server {
        # Nginx 版本为 nginx/1.15.0 以上请使用 listen 443 ssl 代替 listen 443 和 ssl on
        listen       443 ssl;
        # 填写绑定证书的域名
        server_name  www.domain.cn;
		# https禁止ip访问
        if ($host != 'www.domain.cn') {
               return 500;
        }

        # 证书文件名称
	    ssl_certificate      /usr/local/nginx/nginx-private.crt;
	    # 私钥文件名称
	    ssl_certificate_key  /usr/local/nginx/nginx-private.key;

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

        #请按照以下协议配置
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

        #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        #ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

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

    }

    # http禁止IP直接访问网站
    server {
        listen 80 default;
        server_name _;
        return 403;
    }

 }

6 Nginx实现限流

更新中,敬请期待…

7 Nginx实现防盗链

更新中,敬请期待…

本文参考资料:
Nginx官方文档: http://nginx.org/en/docs/
nginx配置:https://www.runoob.com/w3cnote/nginx-setup-intro.html

写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,希望尽自己的努力,做到更好,大家一起努力进步!

如果有什么问题,欢迎大家评论,一起探讨,代码如有问题,欢迎各位大神指正!

给自己的梦想添加一双翅膀,让它可以在天空中自由自在的飞翔!

你可能感兴趣的:(Linux,Nginx,分布式专题,nginx,linux)