Linux环境下Nginx及负载均衡

Nginx 简介

Nginx 是一个高性能的 HTTP 和反向代理 Web 服务器,同时也提供了 IMAP/POP3/SMTP 服务。

前向代理作为客户端的代理,服务端只知道代理的 IP 地址而不知道客户端的 IP 地址。

Linux环境下Nginx及负载均衡

Nginx 安装

推荐使用 LNMP 一键安装包,Ubuntu/CentOS 等各平台都有提供,省去自己配置的过程。

Linux环境下Nginx及负载均衡

如果需要单独安装 Nginx,可以去找各平台的安装包名称。以 Ubuntu Desktop 19.04 为例,单独安装 Nginx 的命令如下:

sudo apt install nginx

Linux环境下Nginx及负载均衡

Nginx 安装后默认启动,打开浏览器输入 http://127.0.0.1 检查是否安装成功。

Linux环境下Nginx及负载均衡

练习 1

使用 tail -f /path/to/nginx/log/access.log 实时监控文件变化,再分别本地访问 127.0.01 和远程访问服务器 IP 地址,比较两次访问的日志有什么不同?

Tips: Ubuntu Server 版默认没有桌面,通过 SSH 连接到服务器

  1. 打开新终端,通过 SSH 连接到服务器,再使用 curl 127.0.0.1 命令返回页面源文件
  2. 打开客户端浏览器,输入服务器 IP 地址
  3. 比较上面两步对应的操作日志有什么区别

刚才在 Ubuntu 默认的火狐浏览器打开 127.0.0.1 时的访问日志如图。

Linux环境下Nginx及负载均衡

接下来换一台电脑访问 192.168.23.129。

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

首先可以看到,UA 是不一样的,这是因为我用了不同的浏览器,当然,访问时间等也是不一样的。

最关键的一点,第一次访问的 IP 是 127.0.0.1,是环回地址,而后一次访问的 IP 是 192.168.23.1,这个是我 Windows 10 的 IP 地址。

最后看一点实战的内容——我的博客的访问日志:

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

从中可以看到类似的日志记录,不仅记录了访问者的 IP、UA,还记录了访问资源 URL 以及一些附加的信息。

同样的,还有错误日志,例如看一下 gitlab.error.log

Linux环境下Nginx及负载均衡

有了这些日志,管理员就方便排查问题了。

Nginx 默认配置

配置文件:/etc/nginx/nginx.conf(如果是 LNMP 安装的,则可能在 /usr/local/nginx/conf/nginx.conf)。

可以用 less 查看配置文件,配置文件默认的环境是全局环境,即一个 main{},后面会定义用户、工作进程等,以及 HTTP 服务、邮件服务。

Linux环境下Nginx及负载均衡

下面主要讲一下 HTTP 配置文件。

Linux环境下Nginx及负载均衡

首先在 HTTP{} 会有一些全局的配置,包括访问日志、连接超时等信息,随后会给出一个或多个 server 表示多个虚拟主机。

来看一下实战的配置文件。

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

用户和用户组都是 www,配置了错误日志的访问路径,工作模式是 epoll、IO 多路复用,单个进程的最大连接数是 51200。

Linux环境下Nginx及负载均衡

配置了 fastcgi 相关信息。

Nginx 作为 HTTP 服务器的配置

Nginx 默认的静态资源文件夹为 /var/www/html(不同的安装包可能有不同的默认路径,例如可能为 /usr/local/nginx/www/html/default 或者其他目录,也可以自己指定)。

在默认目录下,新建一个叫做 jxtxzzw.html 的文件,随便写一点东西。

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

然后在 nginx.conf 的 HTTP 结点中新增一个虚拟服务器,并 sudo nginx -s reload 重新加载。

Linux环境下Nginx及负载均衡

如图,在 80 端口监听,当用户访问的服务器是 jxtxzzwtest.com 的时候,就定位到 /var/www/html/ 下,并当用户没有指定访问的路径的时候,默认访问 jxtxzzw.html

为了模拟域名解析的过程,修改 /etc/hosts 文件,增加 jxtxzzwtest.com 的 IP 为 127.0.0.1

Linux环境下Nginx及负载均衡

修改之后打开浏览器访问 jxtxzzwtest.com,可以看到刚才的页面。

Linux环境下Nginx及负载均衡

如何不购买新的二级域名和服务器,利用该服务器和已有的域名再做一个个人主页呢?

这就可以添加一个新的虚拟服务器。

重复上面的步骤,只是注意添加虚拟服务器的时候取一个新的 server_name,例如 new.jxtxzzwtest.com,至于 location 写什么,就看个人主页放在了哪个文件夹下面了。这些都可以根据自己需要修改。

server {
    listen 80;
    server_name new.jxtxzzwtest.com;
    location / {
        index a_new_page.html;
        root /home/jxtxzzw/web/;
    }
}

随后,在 hosts 模拟 DNS 解析,添加 127.0.0.1 new.jxtxzzwtest.com 之后就可以在浏览器访问 new.jxtxzzwtest.com 来看到个人主页了。

练习 2

  1. 在配置文件 nginx.conf 的 http 节点内新增一个虚拟服务器,新建 /var/www/EXAMPLE.com 文件夹,该文件夹下新建 index.html 文件写入文字,重加载配置 sudo nginx -s reload (注:将本页中的 EXAMPLE 替换成自己的名字拼音)
  2. 浏览器输入 IP 地址,检查是否生成 /var/log/nginx/EXAMPLE.access.log 文件,同时检查 /var/log/nginx/access.log 文件是否有变化
  3. 修改自己客户端电脑上的 hosts 文件,添加两行解析到服务器 IP 地址
  4. 浏览器输入 www.EXAMPLE.com,检查是否生成 /var/log/nginx/EXAMPLE.access.log,同时监测 /var/log/nginx/access.log 和 /var/log/nginx/EXAMPLE.access.log 文件的变化
server {
    listen 80;
    server_name www.zzw.com;
    access_log /var/log/nginx/zzw.access.log;
    location / {
        index index.html;
        root /var/www/html/zzw.com/;
    }
}

Linux环境下Nginx及负载均衡

输入 IP 地址,不论是本机访问 127.0.0.1 还是另一台电脑访问 192.168.23.129,发现都只访问了 Nginx 默认的安装成功页面,没有进入 zzw.com。

显然的,只有 access.log 会有变化,记录了本次访问信息。

Linux环境下Nginx及负载均衡

而在添加了 hosts 以后,访问 www.zzw.com 就会看到刚才输入的信息。

Linux环境下Nginx及负载均衡

需要注意的是,在配置文件中只定义了 www.zzw.com,没有定义 zzw.com,所以,在访问 zzw.com 的时候还是会跳转到 Nginx 安装成功的那个页面。

解决这个办法可以在 server_name 后面增加一个别名。

server_name www.zzw.com zzw.com;

看到 zzw.access.log 和 access.log 都有了新的记录。

来看一些实战的内容。

Linux环境下Nginx及负载均衡

我的博客,监听了 80 端口,同时处理 www.jxtxzzw.comjxtxzzw.com 两个服务器名字,并对 80 端口的请求全部转发到 443 端口。

443 端口配置了一些关于 SSL 相关的信息,并且导入了 PHP 相关的配置。

Linux环境下Nginx及负载均衡

同时,还有一个 gitlab.jxtxzzw.com 的虚拟主机,这个配置文件将在下面详述。

负载均衡简介

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

负载均衡转发算法:

  • 轮询(Round Robin):为第一个请求选择列表中的第一个服务器,然后按顺序向下移动列表直到结尾,然后循环
  • 最小连接(Least Connection):优先选择连接数最少的服务器,在普遍会话较长的情况下推荐使用
  • 散列(Hash):根据请求源的 IP 的散列来选择要转发的服务器,这种方式可以一定程度上保证特定用户能链接到相同的服务器

负载均衡算法:

  • round:每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器宕机,能自动删除
  • weight:指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况
  • fiar(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配
  • ip_hash:每个请求按访问 IP 的散列结果分配,每个访客固定访问一个后端服务器,可以解决 session 的问题
  • url_hash(第三方):每个请求按 URL 的散列结果分配,不同访客访问相同的服务器

Linux环境下Nginx及负载均衡

预备 Web 服务器环境:

  1. 配置两台 Apache(httpd) 作为 Web 服务器,例如可以使用 XAMPP
  2. XAMPP 的访问日志在 /opt/lampp/logs/access.log
  3. 一台 Ubuntu Desktop 的虚拟机,192.168.23.129,作为 Nginx 服务器
  4. 一台 Ubuntu Desktop 的虚拟机,192.168.23.128,作为第 1 台 XAMPP 服务器
  5. 一台 Ubuntu Server 的虚拟机,192.168.23.130,作为第 2 台 XAMPP 服务器
  6. 一台 Windows 的物理机,192.168.23.1,用来访问

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

在 nginx.conf 的 http 节点下添加以下代码后重新加载配置

upstream first {
    server 192.168.23.128;
    server 192.168.23.130;
}

server {
    listen 80;
    server_name load.jxtxzzwtest.com;
    location / {
        proxy_pass http://first;
    }
}

修改电脑的 host 文件,添加一个域名解析

192.168.23.129 load.jxtxzzwtest.com

Linux环境下Nginx及负载均衡

浏览器访问 load.jxtxzzwtest.com,发现打开了 XAMPP 的一个界面,说明代理成功了。

但是到底访问的是哪一个 XAMPP 呢?可以看一下日志。

在此之前,刷新几次,看看日志会不会访问了不同的页面。

日志的观察结果,可以看到 128 的那台服务器上收到了若干次来自 129 的转发请求,而 130 的那台服务器上也收到了若干请求,但是观察时间可以看到,两台服务器上接受的请求是先后交替的,这意味着符合轮询算法的期望结果。

更加直观的方法,是可以修改其中一个 Apache 服务器的主页显示。

Linux环境下Nginx及负载均衡

简单粗暴的方法,删掉了 128 那台服务器的 index.html。

然后刷新页面的效果就是交替出现 XAMPP 的 dashboard 和 Directory Listing。

Linux环境下Nginx及负载均衡

刷新以后变成下面这个页面,两个页面在每次刷新后交替显示。

Linux环境下Nginx及负载均衡

如果没有交替显示,有可能是浏览器做了缓存,强制刷新一下就好了。

练习 3

  1. 在 nginx.conf 的 http 节点下新增 upstream second 方案,将 server 节点下的 proxy_pass 设为 second 后重加载配置,其中 IP 地址要换成自己服务器的地址,浏览器访问域名,监测 Nginx 服务器的 /var/log/nginx/access.log 和两台 Web 服务器的 /opt/lampp/logs/access.log 发现有什么规律

    upstream second {
        server 192.168.1.102:80;
        server 192.168.1.103 weight=3;
    }
  2. 新增 upstream third 方案,重复上述实验

    upstream third {
        ip_hash;
        server 192.168.1.102;
        server 192.168.1.103;
    }

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

访问日志可以看出,交替比例变为 3:1。

需要特别说明的是,浏览器可能存在缓存,所以一定要去看日志。

换成 hash 以后,我只能刷出 Index of /dashboard 这个页面,不论刷新多少次,而查看访问日志也确实发现我被转发到了 130 这个服务器上。

换一台设备,可能(如果正好 hash 计算结果不同)就会被转发到 128 的服务器上。也可能还是访问的 130 的服务器。

再来看一些关于 Nginx 代理的实战的例子。

第一个例子是 HTTPS 反向代理到 Docker,具体的配置过程可以看我的另一篇文章《Nginx代理HTTPS到Docker指定端口》,这里只简要的给出与反向代理、负载均衡相关的代码。

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

第二个例子是 GitLab。

如果不想用 GitLab 自带的 Nginx 服务,而想要把 GitLab 作为一个虚拟主机统一在已有的 LNMP 服务中一起管理,可以用到反向代理。

由于 GitLab 默认的是在 socket 中通信,所以有点不太一样。

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

Linux环境下Nginx及负载均衡

这两张截图省略了 GitLab 中与 SSL 配置相关的代码。

练习 4

  1. 利用 XAMPP,搭建一个能访问数据库的动态网站,并通过负载均衡服务器访问
  2. 比较 Nginx 服务器和 Apache 服务器的异同

第一个练习,比较简单,基本上只要复现本文内容即可,唯一的区别在于需要把本文中简陋的 HTML 代码复杂化,加上与数据库通信的部分,例如,访问数据库并列出所有学生的姓名……

由于《MySQL备份与主备配置》已经配置了双主结构,所以,在一个 PHP 页面中加入增删改查的功能,并把页面复制到另一台服务器上就可以了,访问会通过负载均衡,数据库的访问会通过双主备份,保证了数据的一致。

代码就不贴了。

第二个练习,简单说一下。

Nginx 相对于 Apache 的优势:

  • Apache 是同步多进程模型,一个连接对应一个进程,Nginx 是异步的,多个连接(万级别)可以对应一个进程
  • Nginx 的抗并发能力强很多,对资源需求更少
  • Nginx 支持反向代理
  • Nginx 支持 7 层负载均衡

Apache 相对 Nginx 的优点:

  • Rewrite,比 Nginx 的 Rewrite 强大
  • 模块超多,基本想到的都可以找到

一般来说,需要性能的 Web 服务,用 Nginx,如果不需要性能只求稳定,那就 Apache 吧。总之,就是看自己需求的。

但是从个人使用经历来看,我会推荐 Nginx 作为 Web 服务器的首选。如果你是新手,什么都没接触过,不妨先试试 Nginx?

上一篇:MySQL备份与主备配置


下一篇:Go基础--goroutine和channel