Nginx 从入门到实践,万字详解!(下)

简介: 最近越来越频繁地遇到需要配置反向代理的场景,在自己搭建博客的时候,也不可避免要用到 Nginx,所以这段时间集中学习了一下 Nginx,同时做了一些笔记,希望也可以帮助到大家~ 😜这篇文章会在 CentOS 环境下安装和使用 Nginx,如果对 CentOS 基本操作还不太清楚的,可以先看看 <半小时搞会 CentOS 入门必备基础知识> 一文先做了解。相信作为开发者,大家都知道 Nginx 的重要,废话不多说,一起来学习吧。

10. 配置负载均衡


负载均衡在之前已经介绍了相关概念了,主要思想就是把负载均匀合理地分发到多个服务器上,实现压力分流的目的。


主要配置如下:


http {
  upstream myserver {
    # ip_hash;  # ip_hash 方式
    # fair;   # fair 方式
    server 127.0.0.1:8081;  # 负载均衡目的服务地址
    server 127.0.0.1:8080;
    server 127.0.0.1:8082 weight=10;  # weight 方式,不写默认为 1
  }
  server {
    location / {
      proxy_pass http://myserver;
      proxy_connect_timeout 10;
    }
  }
}
复制代码


Nginx 提供了好几种分配方式,默认为轮询,就是轮流来。有以下几种分配方式:


  1. 轮询,默认方式,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务挂了,能自动剔除;
  2. weight,权重分配,指定轮询几率,权重越高,在被访问的概率越大,用于后端服务器性能不均的情况;
  3. ip_hash,每个请求按访问 IP 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决动态网页 session 共享问题。负载均衡每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的;
  4. fair(第三方),按后端服务器的响应时间分配,响应时间短的优先分配,依赖第三方插件 nginx-upstream-fair,需要先安装;


11. 配置动静分离


动静分离在之前也介绍过了,就是把动态和静态的请求分开。方式主要有两种,一种 是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案。另外一种方法就是动态跟静态文件混合在一起发布, 通过 Nginx 配置来分开。


通过 location 指定不同的后缀名实现不同的请求转发。通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。具体 expires 定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。此种方法非常适合不经常变动的资源。(如果经常更新的文件,不建议使用 expires 来缓存),我这里设置 3d,表示在这 3 天之内访问这个URL,发送一个请求,比对服务器该文件最后更新时间没有变化。则不会从服务器抓取,返回状态码 304,如果有修改,则直接从服务器重新下载,返回状态码 200。


server {
  location /www/ {
    root /data/;
    index index.html index.htm;
  }
  location /image/ {
    root /data/;
    autoindex on;
  }
}
复制代码


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


当主 Nginx 服务器宕机之后,切换到备份 Nginx 服务器


微信截图_20220427183849.png


首先安装 keepalived,


yum install keepalived -y
复制代码


然后编辑 /etc/keepalived/keepalived.conf 配置文件,并在配置文件中增加 vrrp_script 定义一个外围检测机制,并在 vrrp_instance 中通过定义 track_script 来追踪脚本执行过程,实现节点转移:


global_defs{
   notification_email {
        acassen@firewall.loc
   }
   notification_email_from Alexandre@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30 // 上面都是邮件配置,没卵用
   router_id LVS_DEVEL     // 当前服务器名字,用hostname命令来查看
}
vrrp_script chk_maintainace { // 检测机制的脚本名称为chk_maintainace
    script "[[ -e/etc/keepalived/down ]] && exit 1 || exit 0" // 可以是脚本路径或脚本命令
    // script "/etc/keepalived/nginx_check.sh"    // 比如这样的脚本路径
    interval 2  // 每隔2秒检测一次
    weight -20  // 当脚本执行成立,那么把当前服务器优先级改为-20
}
vrrp_instanceVI_1 {   // 每一个vrrp_instance就是定义一个虚拟路由器
    state MASTER      // 主机为MASTER,备用机为BACKUP
    interface eth0    // 网卡名字,可以从ifconfig中查找
    virtual_router_id 51 // 虚拟路由的id号,一般小于255,主备机id需要一样
    priority 100      // 优先级,master的优先级比backup的大
    advert_int 1      // 默认心跳间隔
    authentication {  // 认证机制
        auth_type PASS
        auth_pass 1111   // 密码
    }
    virtual_ipaddress {  // 虚拟地址vip
       172.16.2.8
    }
}
复制代码


其中检测脚本 nginx_check.sh,这里提供一个:


#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
    /usr/sbin/nginx # 尝试重新启动nginx
    sleep 2         # 睡眠2秒
    if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
        killall keepalived # 启动失败,将keepalived服务杀死。将vip漂移到其它备份节点
    fi
fi
复制代码


复制一份到备份服务器,备份 Nginx 的配置要将 state 后改为 BACKUPpriority 改为比主机小。


设置完毕后各自 service keepalived start 启动,经过访问成功之后,可以把 Master 机的 keepalived 停掉,此时 Master 机就不再是主机了 service keepalived stop,看访问虚拟 IP 时是否能够自动切换到备机 ip addr


再次启动 Master 的 keepalived,此时 vip 又变到了主机上。


13. 适配 PC 或移动设备


根据用户设备不同返回不同样式的站点,以前经常使用的是纯前端的自适应布局,但无论是复杂性和易用性上面还是不如分开编写的好,比如我们常见的淘宝、京东......这些大型网站就都没有采用自适应,而是用分开制作的方式,根据用户请求的 user-agent 来判断是返回 PC 还是 H5 站点。


首先在 /usr/share/nginx/html 文件夹下 mkdir 分别新建两个文件夹 PCmobilevim 编辑两个 index.html 随便写点内容。


cd /usr/share/nginx/html
mkdir pc mobile
cd pc
vim index.html   # 随便写点比如 hello pc!
cd ../mobile
vim index.html   # 随便写点比如 hello mobile!
复制代码


然后和设置二级域名虚拟主机时候一样,去 /etc/nginx/conf.d 文件夹下新建一个配置文件 fe.sherlocked93.club.conf


# /etc/nginx/conf.d/fe.sherlocked93.club.conf
server {
  listen 80;
  server_name fe.sherlocked93.club;
  location / {
    root  /usr/share/nginx/html/pc;
    if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
      root /usr/share/nginx/html/mobile;
    }
    index index.html;
  }
}
复制代码


配置基本没什么不一样的,主要多了一个 if 语句,然后使用 $http_user_agent 全局变量来判断用户请求的 user-agent,指向不同的 root 路径,返回对应站点。

在浏览器访问这个站点,然后 F12 中模拟使用手机访问:


微信截图_20220427183858.png


可以看到在模拟使用移动端访问的时候,Nginx 返回的站点变成了移动端对应的 html 了。


14. 配置 HTTPS


具体配置过程网上挺多的了,也可以使用你购买的某某云,一般都会有免费申请的服务器证书,安装直接看所在云的操作指南即可。


我购买的腾讯云提供的亚洲诚信机构颁发的免费证书只能一个域名使用,二级域名什么的需要另外申请,但是申请审批比较快,一般几分钟就能成功,然后下载证书的压缩文件,里面有个 nginx 文件夹,把 xxx.crtxxx.key 文件拷贝到服务器目录,再配置下:


server {
  listen 443 ssl http2 default_server;   # SSL 访问端口号为 443
  server_name sherlocked93.club;         # 填写绑定证书的域名
  ssl_certificate /etc/nginx/https/1_sherlocked93.club_bundle.crt;   # 证书文件地址
  ssl_certificate_key /etc/nginx/https/2_sherlocked93.club.key;      # 私钥文件地址
  ssl_session_timeout 10m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;      #请按照以下协议配置
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; 
  ssl_prefer_server_ciphers on;
  location / {
    root         /usr/share/nginx/html;
    index        index.html index.htm;
  }
}
复制代码


写完 nginx -t -q 校验一下,没问题就 nginx -s reload,现在去访问 https://sherlocked93.club/ 就能访问 HTTPS 版的网站了。


一般还可以加上几个增强安全性的命令:


add_header X-Frame-Options DENY;           # 减少点击劫持
add_header X-Content-Type-Options nosniff; # 禁止服务器自动解析资源类型
add_header X-Xss-Protection 1;             # 防XSS攻击
复制代码


15. 一些常用技巧


15.1 静态服务


server {
  listen       80;
  server_name  static.sherlocked93.club;
  charset utf-8;    # 防止中文文件名乱码
  location /download {
    alias           /usr/share/nginx/html/static;  # 静态资源目录
    autoindex               on;    # 开启静态资源列目录
    autoindex_exact_size    off;   # on(默认)显示文件的确切大小,单位是byte;off显示文件大概大小,单位KB、MB、GB
    autoindex_localtime     off;   # off(默认)时显示的文件时间为GMT时间;on显示的文件时间为服务器时间
  }
}
复制代码


15.2 图片防盗链


server {
  listen       80;        
  server_name  *.sherlocked93.club;
  # 图片防盗链
  location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
    valid_referers none blocked server_names ~\.google\. ~\.baidu\. *.qq.com;  # 只允许本机 IP 外链引用,感谢 @木法传 的提醒,将百度和谷歌也加入白名单
    if ($invalid_referer){
      return 403;
    }
  }
}
复制代码


15.3 请求过滤


# 非指定请求全返回 403
if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
  return 403;
}
location / {
  # IP访问限制(只允许IP是 192.168.0.2 机器访问)
  allow 192.168.0.2;
  deny all;
  root   html;
  index  index.html index.htm;
}
复制代码


15.4 配置图片、字体等静态文件缓存


由于图片、字体、音频、视频等静态文件在打包的时候通常会增加了 hash,所以缓存可以设置的长一点,先设置强制缓存,再设置协商缓存;如果存在没有 hash 值的静态文件,建议不设置强制缓存,仅通过协商缓存判断是否需要使用缓存。


# 图片缓存时间设置
location ~ .*\.(css|js|jpg|png|gif|swf|woff|woff2|eot|svg|ttf|otf|mp3|m4a|aac|txt)$ {
  expires 10d;
}
# 如果不希望缓存
expires -1;
复制代码


15.5 单页面项目 history 路由配置


server {
  listen       80;
  server_name  fe.sherlocked93.club;
  location / {
    root       /usr/share/nginx/html/dist;  # vue 打包后的文件夹
    index      index.html index.htm;
    try_files  $uri $uri/ /index.html @rewrites;  
    expires -1;                          # 首页一般没有强制缓存
    add_header Cache-Control no-cache;
  }
  # 接口转发,如果需要的话
  #location ~ ^/api {
  #  proxy_pass http://be.sherlocked93.club;
  #}
  location @rewrites {
    rewrite ^(.+)$ /index.html break;
  }
}
复制代码


15.6 HTTP 请求转发到 HTTPS


配置完 HTTPS 后,浏览器还是可以访问 HTTP 的地址 http://sherlocked93.club/ 的,可以做一个 301 跳转,把对应域名的 HTTP 请求重定向到 HTTPS 上


server {
    listen      80;
    server_name www.sherlocked93.club;
    # 单域名重定向
    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;
    # 以上配置选择自己需要的即可,不用全部加
}
复制代码


15.7 泛域名路径分离


这是一个非常实用的技能,经常有时候我们可能需要配置一些二级或者三级域名,希望通过 Nginx 自动指向对应目录,比如:


  1. test1.doc.sherlocked93.club 自动指向 /usr/share/nginx/html/doc/test1 服务器地址;
  2. test2.doc.sherlocked93.club 自动指向 /usr/share/nginx/html/doc/test2 服务器地址;


server {
    listen       80;
    server_name  ~^([\w-]+)\.doc\.sherlocked93\.club$;
    root /usr/share/nginx/html/doc/$1;
}
复制代码


15.8 泛域名转发


和之前的功能类似,有时候我们希望把二级或者三级域名链接重写到我们希望的路径,让后端就可以根据路由解析不同的规则:


  1. test1.serv.sherlocked93.club/api?name=a 自动转发到 127.0.0.1:8080/test1/api?name=a
  2. test2.serv.sherlocked93.club/api?name=a 自动转发到 127.0.0.1:8080/test2/api?name=a


server {
    listen       80;
    server_name ~^([\w-]+)\.serv\.sherlocked93\.club$;
    location / {
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        Host $http_host;
        proxy_set_header        X-NginX-Proxy true;
        proxy_pass              http://127.0.0.1:8080/$1$request_uri;
    }
}
复制代码


16. 最佳实践


  1. 为了使 Nginx 配置更易于维护,建议为每个服务创建一个单独的配置文件,存储在 /etc/nginx/conf.d 目录,根据需求可以创建任意多个独立的配置文件。
  2. 独立的配置文件,建议遵循以下命名约定 <服务>.conf,比如域名是 sherlocked93.club,那么你的配置文件的应该是这样的 /etc/nginx/conf.d/sherlocked93.club.conf,如果部署多个服务,也可以在文件名中加上 Nginx 转发的端口号,比如 sherlocked93.club.8080.conf,如果是二级域名,建议也都加上 fe.sherlocked93.club.conf
  3. 常用的、复用频率比较高的配置可以放到 /etc/nginx/snippets 文件夹,在 Nginx 的配置文件中需要用到的位置 include 进去,以功能来命名,并在每个 snippet 配置文件的开头注释标明主要功能和引入位置,方便管理。比如之前的 gzipcors 等常用配置,我都设置了 snippet。
  4. Nginx 日志相关目录,内以 域名.type.log 命名(比如 be.sherlocked93.club.access.logbe.sherlocked93.club.error.log )位于 /var/log/nginx/ 目录中,为每个独立的服务配置不同的访问权限和错误日志文件,这样查找错误时,会更加方便快捷。

感谢 @木法传 的提醒,Nginx 设置防盗链的时候,可以将百度和 google 设置为白名单,利于 SEO


网上的帖子大多深浅不一,甚至有些前后矛盾,在下的文章都是学习过程中的总结,如果发现错误,欢迎留言指出~


参考文档:

  1. Nginx中文文档
  2. Nginx安装,目录结构与配置文件详解
  3. Keepalived安装与配置
  4. Keepalived+Nginx实现高可用
  5. Nginx与前端开发
  6. 跨域资源共享 CORS 详解 - 阮一峰的网络日志
  7. 前端开发者必备的nginx知识
  8. 我也说说Nginx解决前端跨域问题,正确的Nginx跨域配置
  9. vue-router history模式nginx配置并配置静态资源缓存 | HolidayPenguin
  10. nginx重定向,全局https,SSL配置,反代配置参考
  11. Nginx 入门教程



相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
3月前
|
缓存 负载均衡 应用服务中间件
高性能网络编程技术 Nginx 的概念与实践
Nginx 是一款高性能、轻量级的Web服务器和反向代理服务器,它在网络编程技术领域中被广泛应用。本文将详细介绍Nginx的概念和实践,包括其核心原理、功能特点、优势和应用场景等方面。同时,还将深入探讨如何使用Nginx进行高性能网络编程,结合实际案例进行分析。
|
3月前
|
存储 缓存 负载均衡
Nginx入门笔记
Nginx入门笔记
109 0
|
1月前
|
弹性计算 算法 应用服务中间件
倚天使用|Nginx性能高27%,性价比1.5倍,基于阿里云倚天ECS的Web server实践
倚天710构建的ECS产品,基于云原生独立物理核、大cache,结合CIPU新架构,倚天ECS在Nginx场景下,具备强大的性能优势。相对典型x86,Http长连接场景性能收益27%,开启gzip压缩时性能收益达到74%。 同时阿里云G8y实例售价比G7实例低23%,是Web Server最佳选择。
|
3月前
|
缓存 负载均衡 应用服务中间件
高性能网络编程技术 Nginx 的概念与实践
在当今互联网时代,高性能网络编程技术越来越受到重视。Nginx 作为一款高性能、高可靠性的 Web 服务器,拥有广泛的应用和优异的性能表现。本文将介绍 Nginx 的基本概念、架构以及实践技巧,帮助读者更好地理解和使用这一工具。
|
4月前
|
负载均衡 前端开发 应用服务中间件
NGINX高可用之keepalived+nginx主从模式+主主模式配置实践
NGINX高可用之keepalived+nginx主从模式+主主模式配置实践
117 1
|
4月前
|
负载均衡 算法 应用服务中间件
Nginx+Tomcat实现反向代理与负载均衡入门
Nginx+Tomcat实现反向代理与负载均衡入门
182 0
|
4月前
|
负载均衡 网络协议 应用服务中间件
当当网266买来的1399页Nginx笔记,原来我入门都不算
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。
当当网266买来的1399页Nginx笔记,原来我入门都不算
|
5月前
|
负载均衡 应用服务中间件 nginx
nginx配置和热部署实践
nginx配置和热部署实践
85 0
|
9月前
|
弹性计算 缓存 算法
Nginx性能高27%,性价比1.5倍,基于阿里云倚天ECS的Web server实践
倚天710构建的ECS产品,基于云原生独立物理核、大cache,结合CIPU新架构,倚天ECS在Nginx场景下,具备强大的性能优势。 相对典型x86,Http长连接场景性能收益27%,开启gzip压缩时性能收益达到74%。 同时阿里云G8y实例售价比G7实例低23%,是Web Server最佳选择。
|
11月前
|
Prometheus 运维 监控
带你读《企业级云原生白皮书项目实战》——3.2.9 nginx controller 最佳调度部署实践
带你读《企业级云原生白皮书项目实战》——3.2.9 nginx controller 最佳调度部署实践
160 0