3.Nginx使用

2.Nginx

公司产品出现瓶颈?

  • 公司项目刚刚上线的时候,并发量小,用户使用的少,所以在低并发的情况下,一个jar包启动应用就够了,然后内部tomcat返回内容给用户。
    16798977401955
  • 但是慢慢的,使用平台的用户越来越多,并发量慢慢增大了,这时候一台服务器满足不了需求了。
    16798981155554
  • 于是我们横向扩展,又增加了服务器。这个时候几个项目启动在不同的服务器上,用户要访问,就需要增加一个代理服务器了,通过代理服务器来帮我们转发和处理请求。
    16798983152553
  • 我们希望这个代理服务器可以帮助我们接收用户的请求,然后将用户的请求按照规则帮我们转发到不同的服务器节点之上。这个过程用户是无感知的,用户并不知道是哪个服务器返回的结果,我们还希望他可以按照服务器的性能提供不同的权重选择。保证最佳体验!所以我们使用Nginx。

什么是Nginx?

  • Nginx是一个高性能的http和方向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。2011年6月1日,nginx 1.0.4发布。
  • 其特点是占有内存少,并发能力强,事实上Nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用Nginx网站用户有:百度、京东、新浪等。在全球活跃的网站中有12.18%的使用比率,大约为2220万个网站。
  • Nginx是一个安装非常的简单、配置文件非常简洁(还能够支持perl语法)、bug非常少的服务。Nginx启动特别容易,并且几乎可以做到7*24不间断运行,及时运行数个月也不需要重新启动,还能够不间断服务的情况下进行软件的版本升级。
  • Nginx代码完全用C语言从头写成,官方数据测试表明能够支持高达5万个并发连接数的相应。

Nginx作用?

http代理,反向代理:作为web服务器最常用的功能之一,尤其是反向代理。

  • 正向代理
    16798989824401
  • 反向代理
    16798989951644

Nginx提供的负载均衡策略有2种:内置策略和扩展策略。内置策略为轮询,加权轮询,ip hash扩展策略,就天马星空,只有你想不到的没有他做不到的。

  • 轮询
    16798991164494
  • 加权轮询
    16798991240316
  • iphash对客户端请求的IP进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题。
    16798996456138

动静分离,在我们的软件开发中,有些请求是需要后台处理的,有些请求是不需要经过后台处理的(如:css、html、jpg、js等文件),这些不需要经过后台处理的文件称为静态文件。让动态网站里的动态网页根据一定规则把不变的资源和经常变得资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作。提高资源响应速度。
16799016034087

  • 目前,通过使用Nginx大大提高了我们网站的响应速度,优化了用户体验,让网站的健壮性更伤一层楼!

Nginx的安装

Windows下安装

  1. 下载Nginx
  1. 启动Nginx
  • 有很多种方法启动Nginx
  • 直接双击nginx.exe,双击后一个黑色的弹窗一闪而过。
  • 打开cmd命令窗口,切换到Nginx解压目录下,输入命令nginx.exe,回车即可。
  1. 检查Nginx是否启动成功
  • 直接在浏览器地址栏输入网站http://localhost:80回车,出现以下页面说明启动成功!
    16799019880994
  1. 配置监听
  • nginx的配置文件是conf目录下的nginx.conf,默认配置的nginx监听的端口为80,如果80端口被占用可以修改为未被占用的端口即可。
    16799021114292
  • 当我们修改了nginx的配置文件nginx.conf时,不需要关闭nginx后重启动nginx,只需要执行命令 nginx -s reloa 即可让改动生效。
  1. 关闭Nginx
  • 如果使用cmd命令窗口启动nginx,关闭cmd窗口是不能结束nginx进程的,可使用两种方法关闭nginx
    • 输入nginx命令nginx -s stop(快速停止nginx)或nginx -s quit(完整有序的停止nginx)
    • 使用taskkilltaskkill /f /t /im nginx.exe
    taskkill 是用来终止进程的,
    /f是强制终止
    /t终止指定的进程和任何由此启动的子进程
    /im 指定的进程名称
    

Linux下安装nginx

  • 下载nginx的压缩包到根目录,官网下载地址:nginx.org/download/nginx-1.17.2.tar.gz

    yum update #更新系统软件
    cd /
    wget nginx.org/download/nginx-1.17.2.tar.gz 
    
  • 解压tar.gz压缩包文件,进去nginx-1.172.2

    tar -xzvf nginx-1.172.2.tar.gz
    cd nginx-1.17.2
    
  • 进入文件夹后进行配置检查

    ./configure
    
  • 通过安装前的配置检查,发现有报错。检查中发现一些依赖库没有找到,这时候需要先安装Nginx的一些依赖库。

    yum -y install pcre* #安装使nginx支持rewrite
    yum -y install gcc-c++
    yum -y install zlib*
    yum -y install zlib*
    yum -y install openssl openssl-devel
    
  • 再次进行操作检查./configure没有发现报错显示,接下来进行编译并安装操作

    // 检查模块支持
    ./configure  --prefix=/usr/local/nginx  --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-mail --with-mail_ssl_module --with-stream --with-stream_ssl_module --with-stream_realip_module --with-stream_ssl_preread_module --with-threads --user=www --group=www
    
  • 这里得特别注意下,你以后需要用到的功能模块是否存在,不然以后添加新的包会比较麻烦。

  • 查看默认安装的模块支持

    • 命令ls nginx-1.17.2查看nginx的文件列表,可以发现里面有一个auto的目录。
    • 在这个auto目录中有一个options文件,这个文件里面保存的就是nginx编译过程中的所有选项配置。
    • 通过命令:cat nginx-1.17.2/auto/options | grep YES就可以查看

nginx编译安装时,怎么查看安装模块

  • 编译并安装
    make && make install
    
  • 这里需要注意,模块的支持跟后续的nginx配置有关,比如SSL,gzip压缩等等,编译安装前最好检查需要配置的模块存不存在。

查看Nginx安装后所在的目录,可以看到已经安装到/usr/local/nginx目录了

    whereis nginx
    &nginx: /usr/local/nginx

启动nginx服务

cd /usr/local/nginx/sbin/
./nginx
  • 服务启动的时候报错了:nginx:[emerg] bind() to 0.0.0.0:80 failed(98:Address already in use),通过命令查看本机网络地址和端口等一些信息,找到被占用的80端口netstat -ntpl的tcp连接,并杀死进程(kill进程pid)
netstat -ntpl
kill 进程PID

继续启动nginx服务,启动成功

./nginx
  • 在浏览器直接访问ip地址,页面出现Welcome to Nginx!则安装成功。

nginx配置

基本结构

main        # 全局配置,对全局生效
├── events  # 配置影响 nginx 服务器或与用户的网络连接
├── http    # 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
│   ├── upstream # 配置后端服务器具体地址,负载均衡配置不可或缺的部分
│   ├── server   # 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块
│   ├── server
│   │   ├── location  # server 块可以包含多个 location 块,location 指令用于匹配 uri
│   │   ├── location
│   │   └── ...
│   └── ...
└── ...

主要配置含义

  • main:nginx的全局设置,对全局生效。
  • events:配置影响nginx服务器或与用户的网络连接。
  • http:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。
  • server:配置虚拟主机的相关参数,一个http中可以有多个server.
  • location:配置请求的路由,以及各种页面的处理情况。
  • upstream:配置后端服务器具体地址,负载均衡配置不可或缺的部分。

nginx.conf 配置文件的语法规则

  1. 配置文件由指令与指令块构成
  2. 每条指令以";"分号结束,指令与参数间以空格符号分隔。
  3. 指令块以{}大括号降多条指令组织在一起。
  4. include语句允许组合多个配合文件以提升可维护性。
  5. 通过#符号添加注释,提高可读性。
  6. 通过$符号使用变量。
  7. 部分指令的参数支持正则表达式,例如常用的location指令。

内置变量

  • nginx常用的内置全局变量,你可以在配置中随意使用:
TCP UDP
$host 请求信息中的Host,如果请求中没Host行,则等于设置的服务器名
$request_method 客户端请求类型,如GET、POST
$remote_addr 客户端的IP地址
$args 请求中的参数
$content_length 请求头中的Content-length字段
$http_user_agent 客户端agent信息
$http_cookie 客户端cookie信息
$remote_port 客户端的端口
$server_protocol 请求使用的协议,如 HTTP/1.1
$server_addr 服务器地址
$server_name 服务器名称
$server_port 服务器的端口号

常用命令

  • 这里列举几个常用的命令:
    nginx -s reload  # 向主进程发送信号,重新加载配置文件,热重启
    nginx -s reopen	 # 重启 Nginx
    nginx -s stop    # 快速关闭
    nginx -s quit    # 等待工作进程处理完成后关闭
    nginx -T         # 查看当前 Nginx 最终的配置
    nginx -t -c <配置路径>  # 检查配置是否有问题,如果已经在配置  目录,则不需要 -c
    
  • 以上命令通过nginx -h就可以查看到,还有其它不常用这里未列出。
  • Linux系统应用管理工具systemd关于nginx的常用命令:
    systemctl start nginx    # 启动 Nginx
    systemctl stop nginx     # 停止 Nginx
    systemctl restart nginx  # 重启 Nginx
    systemctl reload nginx   # 重新加载 Nginx,用于修改配置后
    systemctl enable nginx   # 设置开机启动 Nginx
    systemctl disable nginx  # 关闭开机启动 Nginx
    systemctl status nginx   # 查看 Nginx 运行状态
    

配置nginx开机自启:

利用systemctl命令:

  • 如果用yum install命令安装的nginx,yum命令会自动创建nginx.server文件,直接用命令:
    systemctl enable nginx   # 设置开机启动 Nginx
    systemctl disable nginx  # 关闭开机启动 Nginx
    
  • 就可以设置开机自启,否则需要在系统服务目录里创建nginx.service文件。
  • 创建并打开nginx.service文件:
    vi /lib/systemd/system/nginx.service
    
  • 内容如下:
    [Unit]
    Description=nginx
    After=network.target
      
    [Service]
    Type=forking
    ExecStart=/usr/local/nginx/sbin/nginx
    ExecReload=/usr/local/nginx/sbin/nginx -s reload
    ExecStop=/usr/local/nginx/sbin/nginx -s quit
    PrivateTmp=true
      
    [Install]
    WantedBy=multi-user.target
    
  • :wq保存退出,运行systemctl daemon-reload使文件生效。
  • 这样便可以通过以下命令操作nginx了:
    systemctl start nginx.service # 启动nginx服务
    systemctl enable nginx.service # 设置开机启动
    systemctl disable nginx.service # 停止开机自启动
    systemctl status nginx.service # 查看服务当前状态
    systemctl restart nginx.service # 重新启动服务
    systemctl is-enabled nginx.service #查询服务是否开机启动
    

通过开机启动命令脚本实现开机自启

  • 创建开机启动命令脚本文件:
    vi /etc/init.d/nginx
    
  • 在这个nginx文件中插入一下启动脚本代码,启动脚本代码来源网络复制,实测有效:
    #! /bin/bash
    # chkconfig: - 85 15
    PATH=/usr/local/nginx
    DESC="nginx daemon"
    NAME=nginx
    DAEMON=$PATH/sbin/$NAME
    CONFIGFILE=$PATH/conf/$NAME.conf
    PIDFILE=$PATH/logs/$NAME.pid
    scriptNAME=/etc/init.d/$NAME
    set -e
    [ -x "$DAEMON" ] || exit 0
    do_start() {
    $DAEMON -c $CONFIGFILE || echo -n "nginx already running"
    }
    do_stop() {
    $DAEMON -s stop || echo -n "nginx not running"
    }
    do_reload() {
    $DAEMON -s reload || echo -n "nginx can't reload"
    }
    case "$1" in
    start)
    echo -n "Starting $DESC: $NAME"
    do_start
    echo "."
    ;;
    stop)
    echo -n "Stopping $DESC: $NAME"
    do_stop
    echo "."
    ;;
    reload|graceful)
    echo -n "Reloading $DESC configuration..."
    do_reload
    echo "."
    ;;
    restart)
    echo -n "Restarting $DESC: $NAME"
    do_stop
    do_start
    echo "."
    ;;
    *)
    echo "Usage: $scriptNAME {start|stop|reload|restart}" >&2
    exit 3
    ;;
    esac
    exit 0
    
  • 设置所有人都有对这个启动脚本nginx文件的执行权限:
    chmod a+x /etc/init.d/nginx
    
  • 把nginx加入系统服务中:
    chkconfig --add nginx
    
  • 把服务设置未开机启动:
    chkconfig nginx on
    
  • reboot 重启系统生效,可以使用上面 systemctl 方法相同的命令:
    systemctl start nginx.service # 启动nginx服务
    systemctl enable nginx.service # 设置开机启动
    systemctl disable nginx.service # 停止开机自启动
    systemctl status nginx.service # 查看服务当前状态
    systemctl restart nginx.service # 重新启动服务
    systemctl is-enabled nginx.service #查询服务是否开机启动
    
  • 如果服务启动的时候出现 Restarting nginx daemon: nginxnginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: No such file or directory) nginx not running 的错误,通过nginx -c 参数指定配置文件即可解决.
    /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
    
  • 如果服务启动中出现 nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) 的错误,可以先通过 service nginx stop 停止服务,再启动就好。

配置nginx全局可用

  • 当你每次改了nginx.conf配置文件的内容都需要重新到nginx启动目录去执行命令,或者通过-p参数指向特定目录,会不会感觉很麻烦?
  • 例如: 直接执行 nginx -s reload 会报错 -bash: nginx: command not found,需要到 /usr/local/nginx/sbin 目录下面去执行,并且是执行 ./nginx -s reload
  • 这里有两种方式可以解决,一种是通过脚本对 nginx 命令包装,这里介绍另外一种比较简单:通过把 nginx 配置到环境变量里,用 nginx 执行指令即可。步骤如下:
  1. 编辑 /etc/profile

    vi /etc/profile
    
  2. 在最后一行添加配置,:wq保存

    export PATH=$PATH:/usr/local/nginx/sbin
    
  3. 使配置立刻生效

    source /etc/profile
    
  • 这样就可以愉快的直接在全局使用nginx命令了。
    --

nginx常用功能配置

反向代理

  • 我们最常说的反向代理的是通过反向代理解决跨域问题。
  • 其实反向代理还可以用来控制缓存(代理缓存 proxy cache),进行访问控制等等,以及后来说的负载均衡其实都是通过反向代理来实现的。
    server {
    listen    8080;
        # 用户访问 ip:8080/test 下的所有路径代理到 github
        location /test {
        	proxy_pass   https://github.com;
        }
    
        # 所有 /api 下的接口访问都代理到本地的 8888 端口
        # 例如你本地运行的 java 服务的端口是 8888,接口都是以 /api 开头
        location /api {
            proxy_pass   http://127.0.0.1:8888;
        }
    }
    

访问控制

```
server {
location ~ ^/index.html {
   # 匹配 index.html 页面 除了 127.0.0.1 以外都可以访问
   deny 192.168.1.1;
   deny 192.168.1.2;
   allow all;
    }
}    
```
  • 上面的命令表示禁止192.168.1.1和192.168.1.2两个ip访问,其它全部允许。从上到下的顺序,匹配到了便跳出,可以按你的需求设置。

轮询策略(默认)

  • 每个请求按时间顺序逐一分配到不同的后端服务器,如果有后端服务器挂掉,能自动剔除。但是如果其中某一台服务器压力太大,出现延迟,会影响所有分配在这台服务器下的用户。
    http {
        upstream test.com {
            server 192.168.1.12:8887;
            server 192.168.1.13:8888;
        }
        server {
            location /api {
                proxy_pass  http://test.com;
            }
        }
    }
    

根据服务器权重

  • 例如要配置:10次请求中大概1次访问到8888端口,9次访问到8887端口。
        http {
        upstream test.com {
            server 192.168.1.12:8887 weight=9;
            server 192.168.1.13:8888 weight=1;
        }
        server {
            location /api {
                proxy_pass  http://test.com;
            }
        }
    }   
    

客户端ip绑定(ip_hash)

  • 来自同一个ip的请求永远只分配一台服务器,有效解决了动态网页存在的session共享问题。例如:比如把登录信息保存到了session中,那么跳转到另外一台服务器的时候就需要重新登录了。
  • 所以很多时候我们需要一个客户只访问一个服务器,那么就需要用ip_hash了。
    http {
        upstream test.com {
        	ip_hash;
            server 192.168.1.12:8887;
            server 192.168.1.13:8888;
        }
        server {
            location /api {
                proxy_pass  http://test.com;
            }
        }
    }
    

6种负载均衡策略

  • 通过负载均衡充分利用服务器资源,Nginx目前支持自带4种负载均衡策略,还有2种常用的第三方策略。

轮询策略(默认)

  • 每个请求按时间顺序逐一分配到不同的后端服务器,如果有后端服务器挂掉,能自动剔除。但是如果其中某一台服务器压力太大,出现延迟,会影响所有分配在这台服务器下的用户。
    http {
        upstream test.com {
            server 192.168.1.12:8887;
            server 192.168.1.13:8888;
        }
        server {
            location /api {
                proxy_pass  http://test.com;
            }
        }
    }
    

根据服务器权重

  • 例如要配置:10次请求中大概1次访问到8888端口,9次访问到8887端口:
    http {
        upstream test.com {
            server 192.168.1.12:8887 weight=9;
            server 192.168.1.13:8888 weight=1;
        }
        server {
            location /api {
                proxy_pass  http://test.com;
            }
        }
    }
    

客户端ip绑定(ip_hash)

  • 来自同一个ip的请求永远只分配一台服务器,有效解决了动态网页存在的session共享问题。例如:比如把登录信息保存到session种,那么跳转到另一台服务器的时候就需要重新登录了。
  • 所以很多时候我们需要一个客户只访问一个服务器,那么就需要用ip_hash了。
    http {
        upstream test.com {
        	ip_hash;
            server 192.168.1.12:8887;
            server 192.168.1.13:8888;
        }
        server {
            location /api {
                proxy_pass  http://test.com;
            }
        }
    }
    

最小连接数策略

  • 将请求优先分配给压力较小的服务器,它可以平衡每个队列的长度,并避免向压力大的服务器添加更多的请求。
    http {
        upstream test.com {
        	least_conn;
            server 192.168.1.12:8887;
            server 192.168.1.13:8888;
        }
        server {
            location /api {
                proxy_pass  http://test.com;
            }
        }
    }
    

最快响应时间策略(依赖于第三方Nginx Plus)

  • 依赖于Nginx Plus,优先分配给响应时间最短的服务器。
    http {
        upstream test.com {
        	fair;
            server 192.168.1.12:8887;
            server 192.168.1.13:8888;
        }
        server {
            location /api {
                proxy_pass  http://test.com;
            }
        }
    }
    

按访问url的hash结果(第三方)

  • 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法。
    http {
        upstream test.com {
        	hash $request_uri; 
        	hash_method crc32; 
        	server 192.168.1.12:8887;
        	server 192.168.1.13:8888;
        }
        server {
            location /api {
                proxy_pass  http://test.com;
            }
        }
    }
    
  • 采用HAproxy的loadbalance uri或者nginx的额upstream_hash模块,都可以做到针对url进行哈希算法式idea负载均衡转发。

gzip压缩

  • 开启gzip压缩可以大幅减少http传输过程中文件的大小,可以极大的提高网站的访问速度,基本是必不可少的优化操作;
    gzip  on; # 开启gzip 压缩
    # gzip_types
    # gzip_static on;
    # gzip_proxied expired no-cache no-store private auth;
    # gzip_buffers 16 8k;
    gzip_min_length 1k;
    gzip_comp_level 4;
    gzip_http_version 1.0;
    gzip_vary off;
    gzip_disable "MSIE [1-6]\.";
    
  • 解释一下:
  1. gzip_types:要采用 gzip 压缩的 MIME 文件类型,其中 text/html 被系统强制启用;
  2. gzip_static:默认 off,该模块启用后,Nginx 首先检查是否存在请求静态文件的 gz 结尾的文件,如果有则直接返回该 .gz 文件内容;
  3. gzip_proxied:默认 off,nginx 做为反向代理时启用,用于设置启用或禁用从代理服务器上收到相应内容 gzip 压缩;
  4. gzip_buffers:获取多少内存用于缓存压缩结果,16 8k 表示以 8k*16 为单位获得;
  5. gzip_min_length:允许压缩的页面最小字节数,页面字节数从 header 头中的 Content-Length 中进行获取。默认值是 0,不管页面多大都压缩。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大;
  6. gzip_comp_level:gzip 压缩比,压缩级别是 1-9,1 压缩级别最低,9 最高,级别越高压缩率越大,压缩时间越长,建议 4-6;
  7. gzip_http_version:默认 1.1,启用 gzip 所需的 HTTP 最低版本;
  8. gzip_vary:用于在响应消息头中添加 Vary:Accept-Encoding,使代理服务器根据请求头中的 Accept-Encoding 识别是否启用 gzip 压缩;
  9. gzip_disable 指定哪些不需要 gzip 压缩的浏览器。
  • 其中第2点,普遍是结合前端打包的时候打包成gzip文件后部署到服务器上,这样服务器就可以直接使用gzip的文件了,并且可以把压缩比例提高,这样nginx就不用压缩,也就不会影响速度。一般不追求极致的情况下,前端不用做任何配置就可以使用啦~
  • 附前端webpack开启gzip压缩配置,在vue-cli3的vue.config.js配置文件中:
    const CompressionWebpackPlugin = require('compression-webpack-plugin')
        
    module.exports = {
      // gzip 配置
      configureWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
          // 生产环境
          return {
            plugins: [new CompressionWebpackPlugin({
              test: /\.js$|\.html$|\.css/,    // 匹配文件名
              threshold: 1024,               // 文件压缩阈值,对超过 1k 的进行压缩
              deleteOriginalAssets: false     // 是否删除源文件
            })]
          }
        }
      },
    ...
    

}
```

http服务器

  • nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用nginx来做服务器:
    server {
      listen       80;                                                     
      server_name  localhost;                                           
    
      location / {
          root   /usr/local/app;
          index  index.html;
      }
    }
    
  • 这样如果访问http://ip就会默认访问到/usr/local/app目录下面的index.html,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署,比如一个静态官网。

动静分离

  • 就是把动态混合静态的请求分开。方式主要有两种:
    1.一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案。
    2.一种方法就是动态跟静态文件混合在一起发布,通过Nginx配置来分开。
        # 所有静态请求都由nginx处理,存放目录为	html  
    location ~ \.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {  
        root    /usr/local/resource;
        expires     10h; # 设置过期时间为10小时  
    }  
    
    # 所有动态请求都转发给 tomcat 处理  
    location ~ \.(jsp|do)$ {
        proxy_pass  127.0.0.1:8888;  
    }  
    
  • 注意上面设置了expires,当nginx设置了expires后,例如设置为:expires 10d;那么,所在的location或if的内容,用户在10天内请求的时候,都只会访问浏览器中的缓存,而不会去请求nginx.

请求限制

  • 对于大流量恶意的访问,会造成带宽的浪费,给服务器增加压力。可以通过Nginx对于同一ip的连接数以及并发数进行限制。合理的控制还可以用来防止DDos和CC攻击。
  • 关于请求限制主要使用nginx默认集成的2个模块:
    • limit_conn_module连接频率限制模块。
    • limit_req_module请求频率限制模块。
  • 涉及到的配置主要是:
    • limit_req_zone 限制请求数。
    • limit_conn_zone 限制并发连接数。

通过limit_req_zone限制请求数

```
    http{
        limit_conn_zone $binary_remote_addrzone=limit:10m; // 设置共享内存空间大
        server{
        	location /{
                limit_conn addr 5; # 同一用户地址同一时间只允许有5个连接。
            }
        }
    }

```
  • 如果共享内存空间被耗尽,服务器将会对后续所有的请求返回503(service temporarilly Unavailable)错误。
  • 当多个limit_conn_zone指令被配置时,所有的连接数限制都会生效。比如:下面配置不仅会限制单一IP来源的连接数,同时也会限制单一虚拟服务器的总连接数:
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;
    server {
        limit_conn perip 10; # 限制每个 ip 连接到服务器的数量
        limit_conn perserver 2000; # 限制连接到服务器的总数
    }
    

通过limit_conn_cone限制并发连接数

```
    limit_req_zone $binary_remote_addr zone=creq:10 mrate=10r/s;
    server{
        location /{
            limit_req zone=creq burst=5;
        }
}
```
  • 限制平均每秒不超过一个请求,同时允许超过频率限制的请求数不多于5个。如果不希望超过的请求被延迟,可以用nodelay参数,如:
    limit_req zone=creq burst=5 nodelay;
  • 这里只是简单讲讲,让大家有这个概念,配置的时候可以深入去找找资料。

正向代理

  • 正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并获得的内容返回给客户端。客户端才能使用正向代理,比如我们使用的VPN服务器就是正向代理.
  • 配置正向代理:
    resolver 8.8.8.8 # 谷歌的域名解析地址
    server {
        resolver_timeout 5s; // 设超时时间
        location / {
            # 当客户端请求我的时候,我会把请求转发给它
            # $host 要访问的主机名 $request_uri 请求路径
            proxy_pass http://$host$request_uri;
        }
    }
    
  • 正向代理的对象是客户端,服务器端看不到真正的客户端。

图片防盗链

```
server {
listen       80;    
server_name  *.test;

# 图片防盗链
location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
    valid_referers none blocked server_names ~\.google\. ~\.baidu\. *.qq.com;  # 只允许本机 IP 外链引用,将百度和谷歌也加入白名单有利于 SEO
    if ($invalid_referer){
        return 403;
    }
}

}
```

  • 以上设置就能防止其它网站利用外链访问我们的图片,有利于节省流量。

适配PC或移动设备

  • 根据用户设备不同返回不同样式的站点,以前经常使用的是纯前端自适应布局,但是复杂的网站并不适合响应式,无论是复杂性和易用性上面还是不如分开编写的号,比如我们常见的淘宝,京东。
  • 根据用户请求的user-agent来判断是返回PC还是H5站点:
    server {
    listen 80;
    server_name test.com;
    
    location / {
    	root  /usr/local/app/pc; # pc 的 html 路径
        if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
            root /usr/local/app/mobile; # mobile 的 html 路径
        }
        index index.html;
    }
    

}
```

设置二级域名

  • 新建一个server即可:
    server {
        listen 80;
        server_name admin.test.com; // 二级域名
    
        location / {
            root  /usr/local/app/admin; # 二级域名的 html 路径
            index index.html;
        }
    }
    

配置HTTPS

  • 这里我使用的是cerbot免费证书,但申请一次有效期只有3个月.
  • 先安装cerbot
    wget https://dl.eff.org/cerbot-auto
    chmod a+x certbot-auto
    
  • 申请证书(注意:需要把申请证书的域名先解析到这台服务器上,才能申请)
    sudo ./certbot-auto certonly --standalone --email admin@abc.com -d test.com -d www.test.com
    
  • 执行上面指令,按指示操作。
  • certbot会启动一个临时服务器来完成验证(会占用80端口或443端口,因此需要暂时关闭Web服务器),然后certbot会把证书以文件的形式保存,包括完整的证书链文件和私钥文件。
  • 文件保存在/etc/letsencrypt/live/下面的域名目录下。
  • 修改nginx配置:
    server{
        listen 443 ssl http2; // 这里还启用了 http/2.0
    
        ssl_certificate /etc/letsencrypt/live/test.com/fullchain.pem; # 证书文件地址
        ssl_certificate_key /etc/letsencrypt/live/test.com/privkey.pem; # 私钥文件地址
    
        server_name test.com www.test.com; // 证书绑定的域名
    }
    

配置HTTP转HTTPS

```
server {
    listen      80;
    server_name test.com www.test.com;

    # 单域名重定向
    if ($host = 'www.sherlocked93.club'){
        return 301 https://www.sherlocked93.club$request_uri;
    }

    # 全局非 https 协议时重定向
    if ($scheme != 'https') {
        return 301 https://$server_name$request_uri;
    }

    # 或者全部重定向
    return 301 https://$server_name$request_uri;
}
```
  • 以上配置选择自己需要的一条即可,不用全部加。

单页面项目history路由配置

```
server {
    listen       80;
    server_name  fe.sherlocked93.club;
  
    location / {
        root       /usr/local/app/dist;  # vue 打包后的文件夹
        index      index.html index.htm;
        try_files  $uri $uri/ /index.html @rewrites; # 默认目录下的 index.html,如果都不存在则重定向
  
        expires -1;                          # 首页一般没有强制缓存
        add_header Cache-Control no-cache;
    }

    location @rewrites { // 重定向设置
        rewrite ^(.+)$ /index.html break;
    }
}
``try_files $uri $uri/ /index.html;`,而上面做了一些重定向处理。
  • vue-router官方只有一句话:try_files $uri $uri/ /index.html;而上面作了一些重定向处理。

配置高可用集群(双机热备)


其它功能和技巧配置

代理缓存

访问日志

错误日志

静态资源服务器

禁止指定user_agent

请求过滤

ab命令

泛域名路径分离

泛域名转发


附nginx模块

nginx模块分类

模块清单


Nginx常用命令

cd /usr/local/nginx/sbin/
./nginx 启动
./nginx -s stop 停止     
./nginx -s quit 安全退出
./nginx -s reload   重新加载配置文件
pa aux|grep nginx 查看nginx进程

注意:检查云服务器端口是否开发,或者服务器防火墙是否开放端口,命令如下:

# 开启
service firewalld start
# 重启
service firewalld restart
# 关闭
service firewalld stop
# 查看防火墙规则
firewall-cmd --list-all
# 查询端口是否开放
firewall-cmd --query-port=8080/tcp
# 开放80端口
firewall-cmd --permanent --add-port=80/tcp
# 移除端口
firewall-cmd --permanent --remove-port=8080/tcp
#重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload
# 参数解释
1、firwall-cmd:是Linux提供的操作firewall的一个工具;
2、--permanent:表示设置为持久;
3、--add-port:标识添加的端口;
posted @ 2023-03-29 22:38  gockks  阅读(60)  评论(0)    收藏  举报