前言

近期通读了《nginx: a practical guide to high performance》,为了有更好的体验和为了后续的实验安排,本次设计并实验了nginx的反向代理/负载均衡功能。

As you’ll learn in this book, nginx is all of these things, but at the very core it’s an HTTP router, a living, breathing part of the web stack that gives developers the flexibility to build and deploy web apps easier than ever before.

正如你在本书中所了解到的,以上对nginx的认识都对。但它的核心是一个HTTP消息路由器,是Web堆栈中活生生的一部分,为开发人员提供了灵活性。nginx使他们比以往任何时候都更容易构建和部署Web应用程序。

nginx基本操作

  1. 添加环境变量,保证在任何目录下都能启动nginx.exe,方便实验进行。
  2. 启动nginx
start nginx
  1. 退出nginx
nginx -s quit
  1. 重载nginx(修改配置文件后重新打开)
nginx -s reload
  1. 使用指定配置文件打开
nginx -c conf/nginx.conf

nginx配置

空配置文件

配置文件为空时nginx仍然可以启动,配置为默认值.

默认配置显式表现如下:

user nobody nogroup;
worker_processes 1;

events {
    worker_connections 512;
}

http {
    server {
        listen *:80;
        server_name "";
        root /usr/share/nginx/html;
    }
}
  • 第一行规定了Unix用户和组
  • worker_process规定了运行的进程数量,通常与CPU核心数量相同。可以设置为auto,nginx可以自动检测逻辑CPU核心数。例如Intel的CPU使用超线程一个core当两个用。
  • events context中的worker_connections规定了每个工作进程可以同时打开的最多连接数,默认为512
  • listen指令 默认监听80端口
  • root规定了URI映射到本地文件系统的根目录

反向代理

The reverse proxy terminates the request and forwards it to the ruby app.

反向代理终止代理请求并将其转发给ruby应用程序。

This is the exact same concept as Load Balancing a Chapter 4— a Load Balancer is reverse proxy!

这(反向代理)和负载均衡概念相同,负载均衡就是一个反向代理。

实验思路

实验思路是在本地搭建反向代理,修改hosts文件将目标域名解析为本机地址;nginx捕获并终止指向目标域名的流量;nginx自身重新连接到目标域名,将http消息转发出去。

实验步骤
  1. 测试目标网址连通性,并查看未进行实验情况下目标网站反馈的http消息特征

可以看到,该网站域名解析出来是IPv6地址,并且http响应消息的响应头部显示出了各种特征。

  1. 修改hosts文件

此时使用浏览器测试,已经无法访问目标网站,修改成功。

(不过为什么Xshell访问显示响应消息302呢?浏览器此时是显示无法响应数据的)

  1. 配置nginx反向代理并启动
worker_processes  1;

events {
    worker_connections  1024;
}

http {     
    server {
        listen *:80;         
        server_name www.sina.com.cn;         
        root /usr/share/nginx/html;

        location / {
            proxy_pass http://www.baidu.com;
        }     
    } 
}

将所有指向目标网址的流量拦截,发送给百度。而启动nginx反向代理后测试结果如下:

image-20221218165120812

测试目标网址和百度的响应:根据E-Tag和Last-Modified首部、以及目标网址的正常响应,可以判断上图中的两个HTTP响应消息是内容是几乎相同的。

除了server首部有不同:访问目标网址的server标识为nginx/1.20.2,百度的服务器标识为bfe/1.0.8.18。

这是由于直接访问百度是百度的服务器发出响应;通过反向代理访问百度,消息响应到了nginx,server首部被修改成了nginx。

至此,本地反向代理测试成功。

负载均衡

The reverse proxy terminates the request and forwards it to the ruby app.

反向代理终止代理请求并将其转发给ruby应用程序。

This is the exact same concept as Load Balancing a Chapter 4— a Load Balancer is reverse proxy!

这(反向代理)和负载均衡概念相同,负载均衡就是一个反向代理。

The only difference in the case of load balancing is that typically a load balancer is communicating upstream to another nginx or web server, located on a different physical machine, while the reverse proxy is often talking to a service on the same
machine.

(反向代理)和负载均衡的唯一区别是,通常情况下,负载均衡器的upstream是与另外一台物理机上的nginx服务器或者web服务器进行通信;而反向代理通常是与本机的服务进行通信。

实验思路
  1. 实验一,监听本地的不同端口,将80端口和8080端口接收的消息发送到不同网站
  2. 实验二,监听本地的相同端口,但将流量轮流发送到不同网站,包括百度和example网站
实验一 分发不同端口的流量到不同网站
  1. 修改配置,同时监听80端口和8080端口。将80端口流量发送到百度,8080端口流量发送到example
worker_processes  1;

events {
    worker_connections  1024;
}


http {     
    server {
        listen *:80; 
        server_name www.sina.com.cn;

        location / {
            proxy_pass http://www.baidu.com;
        } 
    } 
    server {
        listen *:8080; 
        server_name www.sina.com.cn;

        location / {
            proxy_pass http://www.example.com;
        } 
    } 
}

nginx通过listen和server_name这两个指令来确定,将请求消息交给哪个server来处理。因此此处写了两个server context

  1. 测试结果

发送到80端口的结果与反向代理中的测试结果相同,流量发送给了百度。

发送到8080端口的流量也与预计相符,确实发送给了example网站

实验二 分发同一端口的流量到不同网站

暂未实验成功,返回403错误,配置文件如下

worker_processes  1;

events {
    worker_connections  1024;
}

http {     
    upstream backend {
        server www.example.com;
        server www.baidu.com;
    }

    server {
        listen *:80; 
        server_name 127.0.0.1;
        root html;

        location / {
            proxy_pass http://backend;
        }    
    } 
}
一些错误
  • 有些网站开启了HSTS,例如哔哩哔哩网站。用该网站进行HTTP消息的测试得到的响应一直是301
  • 没有关闭本地的其它占用端口的反向代理,干扰实验

参考书目

9781491924778-us

最后修改:2022 年 12 月 18 日
如果觉得我的文章对你有用,请随意赞赏