Nginx反向代理的负载均衡配置

Nginx 负载均衡详解

在互联网应用中,随着网站访问量的不断攀升,服务器的服务模式也需要进行相应升级。诸如分离数据库服务器、将图片作为单独服务等操作,这些都属于简单的数据负载均衡,其目的是将压力分散到不同机器上。而来自 Web 前端的压力同样不容忽视,如何将同一个域名的访问请求分散到两台或更多机器上呢?Nginx 自身就能实现这一功能,只需进行简单的配置即可。

Nginx 不仅是强大的 Web 服务器,还可以作为反向代理服务器。此外,它能够依据调度规则实现动态、静态页面的分离,并且支持按照轮询、IP 哈希、URL 哈希、权重等多种方式对后端服务器进行负载均衡,同时还具备后端服务器健康检查的功能。

Nginx 负载均衡基础知识

Nginx 的upstream目前支持下面几种请求分配方式:

轮询(默认):每个请求按照时间顺序依次分配到不同的后端服务器,当后端服务器出现故障(down 掉)时,Nginx 能够自动将其剔除。

weight:通过指定轮询几率,weight值与访问比率成正比,适用于后端服务器性能不均衡的场景。

ip_hash:每个请求依据访问 IP 的哈希结果进行分配,如此一来,每个访客将固定访问某一个后端服务器,能够有效解决 session 问题。

fair(第三方):按照后端服务器的响应时间分配请求,响应时间短的服务器优先接收请求。

url_hash(第三方)

Nginx 负载均衡配置

在 Nginx 的http段进行如下配置,即可实现针对不同域名的负载均衡:

bash 复制代码
http {
    upstream www.linuxidc.com {
        server 1.0.1.50:8080;
        server 1.0.1.51:8080;
    }

    upstream blog.linuxidc.com {
        server 1.0.1.50:8080;
        server 1.0.1.51:8080;
    }

    server {
        listen 80;
        server_name www.xxx.com;

        location / {
            proxy_pass http://www.linuxidc.com;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

    server {
        listen 80;
        server_name blog.xxx.com wode.xxx.com;

        location / {
            proxy_pass http://www.xxx.com;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

注意事项

3.1 多台机器间 session 共享问题

配置负载均衡相对容易,但其中最关键的问题是如何实现多台服务器之间的 session 共享,以下是几种常见的解决方法(部分内容来源于网络,第四种方法未经实践验证):

  1. 不使用 session,换用 cookie:将 session 替换为 cookie 可以避开 session 的一些弊端。在早期的
    J2EE 书籍中也提到,在集群系统中不宜使用 session,否则可能引发问题。如果系统不太复杂,可优先考虑去掉
    session;若改动难度较大,则可尝试其他方法。
  2. 应用服务器自行实现共享:以 PHP 为例,可以使用数据库或 memcached 来保存 session,从而在 PHP 层面构建一个
    session 集群。这种方式能够确保 session 的稳定性,即便某个节点出现故障,session 也不会丢失,适用于对
    session 稳定性要求较高但请求量不大的场景。不过,其效率相对较低,不太适合对效率要求严苛的场合。
  3. ip_hash:Nginx 中的ip_hash技术能够将来自某个 IP 的请求定向到同一台后端服务器,这样该 IP
    下的客户端与后端服务器就能建立稳定的 session。在upstream配置中定义ip_hash的方式如下:
bash 复制代码
upstream backend {
    server 127.0.0.1:8080;
    server 127.0.0.1:9090;
    ip_hash;
}

ip_hash原理简单易懂,但由于仅依据 IP 地址来分配后端服务器,存在一定局限性,在以下情况下不适用:

  • Nginx 不是最前端的服务器:ip_hash要求 Nginx 必须是最前端的服务器,否则 Nginx 无法获取正确的客户端
    IP,也就无法基于 IP 进行哈希计算。例如,当使用 Squid 作为最前端服务器时,Nginx 获取到的 IP 地址仅是 Squid
    服务器的 IP,以此进行分流会导致请求错乱。
  • Nginx 的后端还有其它方式的负载均衡:如果 Nginx
    后端还存在其他负载均衡方式,将请求再次分流,那么某个客户端的请求将无法始终定位到同一台 session 应用服务器上。因此,Nginx
    后端最好直接指向应用服务器,或者再搭建一个 Squid 后指向应用服务器。也可以使用location进行分流,将需要 session
    的请求通过ip_hash处理,其余请求通过其他后端处理。
  • upstream_hash:为解决ip_hash的部分问题,可以使用upstream_hash这个第三方模块。该模块通常用于url_hash,但也可用于实现
    session 共享。当前端是 Squid 时,Squid 会将客户端 IP 添加到x_forwarded_for这个 HTTP
    头中,通过upstream_hash可以利用该头部信息作为因子,将请求定向到指定后端。
    。在文档中默认使用$request_uri作为因子,可根据需求修改,例如:
bash 复制代码
hash $http_x_forwarded_for;

上述配置将使用x_forwarded_for头部信息作为哈希因子。在 Nginx 新版本中,还支持读取 cookie 值,可修改为:

nginx

hash $cookie_jsessionid;

如果在 PHP 中配置 session 为无 cookie 方式,可配合 Nginx 的userid_module模块由 Nginx 自动生成一个 cookie,另外,还可使用姚伟斌编写的upstream_jvm_route模块

3.2 后端服务器自动加上端口的问题

在典型的 Nginx + Apache 应用方案中,通常 Nginx 占用 80 端口,负责过滤静态请求,将动态请求代理(Proxy)到 Apache 的 8080 端口。反向代理的优势在于用户访问时始终使用 80 端口,不会察觉到后端服务器的差异。然而,有些应用会识别到 Apache 所在的端口是 8080,并在相关超链接中自动加上:8080,这将导致访问异常。解决该问题的一种方法是让 Apache 也运行在 80 端口上。在同一台服务器上同时运行 Nginx 和 Apache 两个 HTTPD 服务且都使用 80 端口,可通过以下配置避免冲突:

修改 Nginx 的配置文件nginx.conf,将:

bash 复制代码
server {
    listen 80;
    server_name www.linuxidc.com;
   ...
}

修改为:

bash 复制代码
server {
    listen 123.123.123.123:80; #指定Nginx只占用某个公网IP的80端口。
    #listen 123.123.123.124:80; #如果服务器中有多个IP,还可以指定多个。
    server_name www.linuxidc.com;
   ...
}

修改 Apache 的配置文件httpd.conf,将:

Listen 80

改为:

apache

Listen 127.0.0.1:80

完成上述配置修改后,保存文件并重启 Apache 服务即可生效。

相关推荐
大柏怎么被偷了1 分钟前
【Linux】文件系统
linux·运维·数据库
laoliu19961 小时前
Odoo 18企业版源码 包含 部署教程
运维·服务器
守城小轩2 小时前
基于Chrome140的Quora账号自动化(关键词浏览)——运行脚本(三)
运维·自动化·chrome devtools·指纹浏览器·浏览器开发
未来之窗软件服务2 小时前
幽冥大陆(五十五)ASR SetThreadInformation C语言识别到自动化软件
运维·自动化·asr·东方仙盟·操作系统级别错误
开开心心就好2 小时前
免费卸载工具,可清理残留批量管理启动项
linux·运维·服务器·windows·随机森林·pdf·1024程序员节
Lbwnb丶2 小时前
检测服务器是否是虚拟化,如KVM,VM等
linux·运维·服务器
老猿讲编程2 小时前
【车载信息安全系列4】基于Linux中UIO的HSE应用实现
linux·运维·服务器
鸡吃丸子2 小时前
初识Docker
运维·前端·docker·容器
wanhengidc3 小时前
巨椰 云手机 云游戏稳定运行
运维·服务器·arm开发·游戏·云计算