Loading

Nginx使用指南

Nginx 是一款广泛使用的高性能 HTTP 和反向代理服务器,它以事件驱动的方式处理请求,能够高效地管理大量并发连接。Nginx 的配置灵活,支持丰富的功能模块,如负载均衡、缓存支持、HTTP认证等,这使得它成为搭建现代Web应用和服务的理想选择。其稳定性高、资源消耗少,易于维护和扩展,特别是在处理静态文件及用作反向代理时表现出色。

一、nginx 安装与配置

1. 安装与启动

服务器安装 Nginx 一般只需两行命令:

# 安装nginx
yum install -y nginx
# 启动nginx
systemctl start nginx
# 查看nginx运行状态
systemctl status nginx

2. 配置文件

Nginx 的配置文件一般位于/etc/nginx目录下。主要关注nginx.confconf.d目录。

我们基本只需要关注文件nginx.confconf.d目录,下面是一份nginx.conf配置文件,不懂也不要怕,基本都不需要改动,默认80服务已经开启了。

    user nginx; # nginx进行运行的用户。指定 Nginx 进程的运行用户。在此,Nginx 将以 nginx 用户的身份运行。这是出于安全考虑,避免使用 root 用户运行服务。
    worker_processes auto; # 指定 Nginx 的工作进程数量
    error_log /var/log/nginx/error.log; # 错误日志
    pid /run/nginx.pid; # 指定 Nginx 主进程的 PID 文件路径

    include /usr/share/nginx/modules/*.conf; # 引入 Nginx 模块配置文件

    # 用于设置与工作进程有关的事件处理参数
    events {
        worker_connections 1024; # 指定每个 Nginx 工作进程可以打开的最大连接数
    }

    http {
        # 定义日志格式。变量含义:$remote_addr: 客户端 IP 地址、$remote_user: 客户端用户(如果有)、$time_local: 本地时间、$request: 请求行(请求方法、URI 和协议)、$status: 响应状态码、$body_bytes_sent: 发送给客户端的字节数、$http_referer: 来源页面、$http_user_agent: 客户端的用户代理信息、$http_x_forwarded_for: 经过的代理链的 IP 地址
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
        # 日志的存储位置和格式。将日志记录到 /var/log/nginx/access.log 文件中,使用上面定义的 main 格式
        access_log /var/log/nginx/access.log main;

        sendfile            on; # 启用高效的文件传输
        tcp_nopush          on; # 在发送大文件时优化 TCP 包的传输
        tcp_nodelay         on; # 确保小数据包立即发送,减少延迟
        keepalive_timeout   65; # 设置 HTTP keep-alive 连接的超时时间
        types_hash_max_size 4096; # 设置 MIME 类型哈希表的最大大小

        include             /etc/nginx/mime.types; # 引入 MIME 类型配置文件,使 Nginx 能够根据文件扩展名确定文件类型
        default_type        application/octet-stream; # 设置默认的 MIME 类型

        # *** 引入的nginx配置文件,可以放在 Nginx 配置文件的多个层级中,方便管理 ***
        include /etc/nginx/conf.d/*.conf;

        # 定义一个虚拟主机配置
        server {
            listen 80; # 服务启动的端口
            listen  [::]:80; # 支持ipv6协议。[::]: 这是 IPv6 的表示方式,表示所有可用的 IPv6 地址
            server_name _; # 指定服务器的域名或IP地址。在这里使用 _ 表示匹配所有的请求,适用于没有特别指定的域名的情况
            root /usr/share/nginx/html; # 设置服务器的根目录为 /usr/share/nginx/html。Nginx 将从这个目录提供静态文件
            
            error_page 404 /404.html; # 找不到资源重定向到404页面
            location = /40x.html {}; # 定义处理 /40x.html 的空位置块,通常是用于预防直接访问该页面
            
            error_page 500 502 503 504 /50x.html; # 系统错误重定向50x页面
            location = /50x.html {}; # 定义处理 /50x.html 的空位置块,同样用于防止直接访问
        }
        # server {
        #    listen 443; # 支持https协议
        #    server_name _;
        #    root /usr/share/nginx/html;
        #    ...
        # }
    }

我们可以看到该文件分成了多层,我们逐层分析一下

第一层:

  • user 指定 Nginx 进程的运行用户。通常在主配置文件的最上方进行设置,以便控制整个 Nginx 实例的权限
  • error_log 指定访问日志的存储路径和格式。一般在 http 块中设置,也可以在 server 或 location 块中覆盖
  • http 定义与 HTTP 相关的配置。http 块是 Nginx 配置的核心部分,通常包含多个 server 块
    ...

第二层(http):

  • log_format 定义日志格式。通常在 http 块中设置,也可以在 server 或 location 块中覆盖
  • access_log 指定访问日志的存储路径和格式。通常在 http 块中设置,也可以在 server 或 location 块中覆盖
  • include 引入其他配置文件。通常用于将多个配置文件合并为一个,便于管理。可以灵活地放置在 http、server 和 location 块中,具体取决于配置文件的组织结构和需求
  • server 定义虚拟主机配置。通常包含 listen、server_name 和 location 等指令,用于配置服务器的监听端口、域名和路径
    ...

第三层(server):

  • listen 指定监听的端口号。通常用于配置服务器的监听端口,以便接收客户端的请求
  • server_name 指定服务器的域名或 IP 地址。通常用于配置虚拟主机的域名或 IP 地址,以便区分不同的服务器,_ 通常用于匹配所有未特别指定的请求
  • root 指定服务器的根目录。通常用于设置服务器提供静态文件的位置,如 HTML、CSS 和 JavaScript 等。可在 server 或 location 块中设置,影响请求的文件查找路径
  • error_page 定义错误页面。通常用于配置自定义的错误页面,如 404、50x 等状态码对应的页面
  • location 定义 URL 路径匹配规则。通常用于根据请求的 URI 或其他特征,将请求映射到不同的处理逻辑
    ...

第三层(location):

  • alias 定义路径别名。通常用于将请求的 URI 重定向到另一个路径,如将 /images/logo.png 映射到 /usr/share/nginx/html
  • index 指定默认文件。通常用于配置默认的页面,如 index.html、index.php 等
  • try_files 尝试访问指定文件。通常用于配置文件查找路径,如当请求的 URI 不存在时,尝试访问其他文件
    ...

3. 配置文件拆分

在http下可以有多个Server,启动多个服务,但如果都写在一个文件里面,文件就越来越大了,那么为了便于管理多个服务,我们要对nginx.conf进行拆分。

conf.d目录下一般是空的,我们新建文件web.conf或者任意命名的以.conf结尾的文件,即可被Nginx使用。

因为在nginx.conf中有include /etc/nginx/conf.d/*.conf; 我们通过这一行语句发现,include帮助我们引用conf.d下以.conf结尾的配置文件。

完成后执行nginx指令

# 检查nginx配置文件是否正确,如果错误会提示具体的错误信息
nginx -t
# 重新启动nginx服务
nginx -s reload

观察日志,此时发现Nginx就重新启动了,读取的是新的配置文件。

其他操作nginx的指令

nginx -s stop
nginx -s start

二、部署单页面应用

我们快速创建一个Vue单页面应用,这里使用npm create vue@latest快速创建,然后修改App.vue文件

<script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
  <header>

    <div class="wrapper">
      <h1>Nginx 测试应用</h1>

      <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/about">About</RouterLink>
      </nav>
    </div>
  </header>

  <RouterView />
</template>

<style scoped>
</style>

然后运行npm i, npm run build生成dist目录,将该目录文件迁移到服务器的目录/usr/share/nginx/html下。

修改上述新建的web.conf文件,修改为如下内容:

server {
    # 监听的端口为 9000
    listen 9000; 
    # 指定服务器的名称为 localhost。这通常用于本地开发和测试
    server_name localhost; 
    # 虚拟主机(服务器)配置的根路径
    root /usr/share/nginx/html;
    location / {
        # 当请求 URI 匹配到这个 location 时,Nginx 会使用 alias 指定的路径,而不是 root 指定的路径
        alias	/usr/share/nginx/html/dist/;
        index   index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
}

初始情况下服务器需要配置安全组规则,允许相关端口被访问。

最后访问外网IP:9000,发现页面正常渲染了。

上述demo的路由模式是history模式,即便在/about下,刷新页面也是正常的,因为上面的location中配置了try_files

三、配置反向代理、负载均衡

1. 反向代理

反向代理的用途很多,这里我们看一个常用的,代理请求的接口。我们在发布时前端的域名和后端api服务的域名经常不一致,此时就可以使用Nginx配置反向代理来解决这个问题。

代理的时候要注意添加必要的参数,帮助后端获取一些客户端的请求数据,例如:

    server {
        location /api {
            # 指定将匹配到的请求转发到指定的后端服务器。所有以 /api 开头的请求将被转发到 http://backend1.example.com。例如,请求 /api/data 将被转发到 http://backend1.example.com/api/data
            proxy_pass http://backend1.example.com;
            # 将原始请求的 Host 头传递给后端服务器
            proxy_set_header Host $host; 
            # 将客户端的真实 IP 地址传递给后端服务器
            proxy_set_header X-Real-IP $remote_addr; 
            # 将经过的代理链中的 IP 地址传递给后端服务器。$proxy_add_x_forwarded_for 变量会自动附加当前客户端的 IP 地址到原有的 X-Forwarded-For 头中
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

2. 负载均衡

Nginx可以作为负载均衡服务器使用,通过配置upstream来分发流量,同时可以配置一些参数:

  • weight设置每个后端服务器的权重,权重越高,获得的请求比例越多
  • ip_hash:将来自同一 IP 地址的请求始终转发到同一台后端服务器,适合需要保持会话的场景
  • max_fails: 设置在将后端服务器标记为不可用之前允许的最大请求失败次数
  • backup标记某个后端服务器为备用服务器,只有在其他服务器不可用时才会被使用
  • down 将某个后端服务器标记为暂时不可用
    # 定义一个名为 backend 的上游服务器组
    upstream backend {
        ip_hash; # 启用 IP 哈希
        server backend1.example.com;
        server backend2.example.com;
        server backend3.example.com weight=5;
        server backend4.example.com max_fails=5;
        server backend4.example.com backup;
        server backend4.example.com down;
    }
    server {
        location /api {
            # 使用 upstream 定义的服务器组
            proxy_pass http://backend;
            proxy_set_header Host $host; 
            proxy_set_header X-Real-IP $remote_addr; 
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

四、配置 nginx 日志

Nginx日志也是很重要的一个内容,在我们请求资源出现问题时,要排查请求的资源是否到达Nginx,而且请求日志可以记录很多有用的信息。

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

    access_log  /var/log/nginx/access.log  main gzip buffer=32k;

nginx日志主要涉及 access_log,log_format:

  • log_format: 日志格式,通过nginx内置的变量来读取和排列,通常默认即可
  • access_log: 日志输出的地址、使用格式、是否压缩、buffer是否当日志大于32k后吸入磁盘

五、其他常用配置

1. 配置Gzip压缩

作为前端性能优化的一种方式,Gzip是简单且有效的,尽管目前前端对于静态资源会进行压缩,但Gzip依然可以在网络传输过程中对文件进行压缩

下面这些字段可以放在httpserverlocation指令模块

    http {
        # 开启关闭
        gzip on;
        # 压缩的文件类型
        gzip_types text/plain text/css application/javascript;
        # 过小的文件没必要压缩
        gzip_min_length 1000; # 单位Byte
        gzip_comp_level 5; # 压缩比,默认1,范围时1-9,值越大压缩比最大,但处理最慢,所以设置5左右比较合理。
    }

2、配置请求头

underscores_in_headers允许客户端请求在http请求中添加以下划线格式命名的参数

该字段可以放在http指令模块

    http {
        underscores_in_headers on;
    }

client_max_body_size允许客户端上传文件最大不超过10M,在开发上传接口时一定要注意,否则导致上传失败

该字段可以放在httpserverlocation指令模块

http {
    client_max_body_size 10m;
}

3. 浏览器缓存配置

缓存也是前端优化的一个重点,合理的缓存可以提高用户访问速度

该字段可以放在httpserverlocation指令模块。配置浏览器缓存的有三个地方

1)后端服务,配置请求头

后端根据语言不同,配置关键字段即可

2)代理服务器(Nginx)配置缓存请求头

location / {
    # / 匹配到的资源有效期设置为1d
    expires 1d;
    # /设置资源有效期604800秒,即7天
    # expires max-age=604800;
    
    # 设置浏览器可以被缓存,设置7天后资源过期
    add_header Cache-Control "public, max-age=604800";
    # 阻止浏览器缓存动态内容
    # add_header Cache-Control "no-cache, no-store, must-revalidate";
    # 禁用浏览器缓存
    # add_header Cache-Control "no-store, private, max-age=0";
}

我们发现响应头的过期时间更新了

3)在前端资源中通过meta声明缓存信息

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Expires" content="0">

4. 跨域处理

通过反向代理,已经处理了请求域名和端口不一致的跨域问题,但有局限性。 Nginx有专门方法配置请求资源的跨域

该字段可以放在serverlocation指令模块,通过配置头部字段,做跨域处理

server {
    location / {
        # 允许所有来源的跨域请求
        add_header Access-Control-Allow-Origin *;
        
        # 允许特定的HTTP方法(GET、POST等)
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE";

        # 允许特定的HTTP请求头字段
        add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";

        # 响应预检请求的最大时间
        add_header Access-Control-Max-Age 3600;

        # 允许携带身份凭证(如Cookie)
        add_header Access-Control-Allow-Credentials true;

        # 处理 OPTIONS 预检请求
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE";
            add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
            add_header Access-Control-Max-Age 3600;
            add_header Access-Control-Allow-Credentials true;
            add_header Content-Length 0;
            add_header Content-Type text/plain;
            return 204;
        }
    }
}

5. 访问控制

allowdeny控制 IP 允许和拒绝,字段可以放在serverlocation指令模块

server {
    listen 80;
    server_name example.com;

    location /admin {
        allow 192.168.1.0/24;  # 允许特定 IP
        deny all;              # 拒绝所有其他访问
    }

    location /public {
        # 允许所有访问
        allow all;
    }

    location / {
        deny all;  # 拒绝所有其他访问
    }
}
posted @ 2024-11-03 15:02  卡布奇诺y  阅读(228)  评论(0编辑  收藏  举报