Nginx 配置反向代理

目录

关键字

Nginx,正向代理,方向代理,博客建站

背景环境

我在搭建个人博客的过程中遇到一个问题,我的博客服务的端口是 1313,我的域名是 qinyangx.top。我希望能够通过 qinyangx.top 直接访问到服务器上 1313 端口的博客服务。 但是实际情况是我并不能直接通过 qinyangx.top 访问到博客服务,需要加上端口号,qinyangx.top:1313,这就很糟糕。为了解决这个问题就需要使用反向代理。

环境

系统:Ubuntu

理解过程

简单的解决方案

为了解决这个问题,最简单的方法并不是使用反向代理,而是直接把博客服务使用 80 端口启动。因为 HTTP 协议默认使用 80 端口,浏览器在访问 http:// 开头的 URL 时,默认会连接到 80 端口。但是的缺点就是难以在同一服务器上运行多个 Web 服务,而且无法实现负载均衡等功能。

正向代理和反向代理

正向代理

举个栗子,用户通过机器 A 访问外部网站,这就是正向代理,用户知道自己在使用代理。

反向代理

比如,我建站的场景,我只知道我访问了 qinyangx.top 的 80 端口,但是我并不知道 Web 服务实际运行在 1313 端口。Nginx 作为反向代理,隐藏了后端服务的细节。客户端直接与 Nginx 交互,Nginx 与 Web 服务交互。

正向代理和反向代理对比

特性 反向代理(我的案例) 正向代理
位置 客户端和 Web 服务之间 客户端和外部服务器之间
客户端感知 客户端不知道 Web 服务的存在 客户端知道代理的存在
主要用途 隐藏后端服务、负载均衡 访问控制、缓存加速、匿名访问
配置位置 服务器端配置 客户端配置使用代理
典型应用 Web 服务器负载均衡、API 网关 公司内部网络代理、VPN

解决过程

安装 nginx

# 安装nginx
sudo apt install nginx -y

# 启动nginx
sudo systemctl start nginx

# 设置nginx为开机自启动
sudo systemctl enable nginx

# 检查配置是否正确
sudo nginx -t

#重启nginx配置
sudo nginx -s reload
 
#重启nginx服务
sudo systemctl restart nginx.service

nginx 配置

nginx 配置文件位置

nginx 的配置通常位于/etc/nginx 下。通过 vim nginx.config 查看,发现两行如下配置:

nginx_config1

这里需要理解 include 指令,include 指令用于把分散的多个配置文件,都引入到主配置文件中,方便维护管理。

如果 conf.d 目录下面有多个 conf 文件,加载的顺序又是怎样的呢?

nginx 加载配置文件会按照文件的命名排序进行加载,也就说 a.conf 会比 b.conf 先加载,然后将所有配置文件合并成一个文件。

执行 nginx -T 命令就可以查看到 nginx 加载配置文件的顺序,并且能显示每个文件的内容,此时可以只显示加载的文件的名称来查看具体的加载顺序,执行命令:

nginx -T|grep "# configuration file"

nginx_t

配置内容

# http块是全局配置块,包含所有HTTP相关的配置
http {
    # 引入MIME类型配置文件
    include       mime.types;
    # 默认MIME类型,当无法识别文件类型时使用
    default_type  application/octet-stream;
    # 启用高效文件传输模式
    sendfile        on;
    # 客户端连接保持超时时间,单位秒
    keepalive_timeout  65;

    # server块定义虚拟主机配置
    server {
        # 监听端口
        listen       80;
        # 服务器名称或域名,支持多个域名用空格分隔
        server_name qinyangx.top;

        # location块,作用是把nginx接收到的请求字符串,比如qinyangx.top/api/hello,对除了虚拟主机名称以外的字符串进行匹配处理
        # 一个server块可以有多个location块
        # / 默认配置
        location / {
            # 根目录路径,相对路径为nginx安装目录下的html目录
            root   html;
            # 默认索引文件,按顺序查找
            index  index.html index.htm;
        }

        # 自定义错误页面,当出现500/502/503/504错误时返回50x.html
        error_page   500 502 503 504  /50x.html;
        # 精确匹配50x.html请求
        location = /50x.html {
            root   html;
        }
    }
}

反向代理配置

需要理解 location 匹配请求的作用:把 nginx 接收到的请求字符串,比如 qinyangx.top/api/hello,对除了虚拟主机名称以外的字符串,比如/api/hello,进行匹配处理。

案例一

server {
    listen       80;
    server_name  qingyangx.top;

    # 匹配所有qingyangx.top域名(server_name)过来的请求,并代理到www.jd.com
    location / {
        root   html;
        index  index.html index.htm;
        proxy_pass  https://www.jd.com;
    }
}  

案例二

server {
    listen       80;
    server_name  qinyangx.top;

    location /hello {
        proxy_pass  www.google.com;
    }

    location ~ /hello2 {
        proxy_pass  http://www.github.com/;
    }
}

测试

新建配置文件

在/etc/nginx/sites-enabled 目录下创建新的配置文件:

sudo vim my-site

# 把如下配置写入
server {
    listen       80;
    server_name  qinyangx.top;

    location /hello {
        # 修改proxy_pass为完整路径
        proxy_pass  www.google.com;
    }

    # ~ 表示正则匹配(区分大小写)
    location ~ /hello2 {
        proxy_pass  http://www.github.com/;
    }
}
重启 nginx 配置
sudo nginx -s reload
检查当前配置
nginx -T
域名访问(结果展示)

proxy_pass1

proxy_pass2

成功!!!

location 配置匹配优先级

server {
    listen 80;
    server_name example.com;

    # 1. 精确匹配(最高优先级)
    location = /hello {
        return 200 'Exact match';
    }

    # 2. 前缀匹配(带 ^~ 修饰符)
    location ^~ /hello {
        return 200 'Prefix match with ^~';
    }

    # 3. 正则匹配(区分大小写)
    location ~ /hello[0-9] {
        return 200 'Case-sensitive regex match';
    }

    # 4. 正则匹配(不区分大小写)
    location ~* /HELLO {
        return 200 'Case-insensitive regex match';
    }

    # 5. 普通前缀匹配(最低优先级)
    location /hello {
        return 200 'Prefix match';
    }

    # 6. 默认匹配
    location / {
        return 200 'Default match';
    }
}

nginx 查看日志

Nginx 通常有两个主要日志文件: 访问日志:记录所有请求 错误日志:记录错误信息 默认位置通常在 /var/log/nginx/ 目录下:

/var/log/nginx/access.log  # 访问日志
/var/log/nginx/error.log   # 错误日志

实时查看日志

# 实时查看访问日志
tail -f /var/log/nginx/access.log

# 实时查看错误日志
tail -f /var/log/nginx/error.log

查看特定时间段的日志

# 查看过去5分钟的访问日志
awk -v d1="$(date --date="-5 min" "+%d/%b/%Y:%H:%M")" -v d2="$(date "+%d/%b/%Y:%H:%M")" '$0 > d1 && $0 < d2 || $0 ~ d2' /var/log/nginx/access.log

# 查看今天的错误日志
grep "$(date +"%Y/%m/%d")" /var/log/nginx/error.log

统计日志信息

# 统计访问量最多的IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 10

# 统计最常访问的URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 10

# 统计HTTP状态码
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

总结

开始随便找了一篇博客实践,结果发现很多地方不能理解,所以自己记录一下,在设置 Nginx 过程中想要了解和遇到的问题。