【Nginx】负载均衡

nginx · 浏览次数 : 0

小编点评

一、工作原理 Nginx的高性能主要归功于以下几个特点: 1. 事件驱动架构:Nginx采用事件驱动的非阻塞方式处理请求,利用操作系统提供的多路复用机制,通过异步非阻塞的方式处理大量并发请求,减少了线程切换和资源消耗,提高了并发处理能力和系统的稳定性。 2. 事件循环:Nginx的核心工作模式之一是事件循环。它通过单线程的方式处理事件,包括等待事件、处理事件和继续循环。在等待事件时,Nginx并不会像传统多线程模型那样阻塞等待,而是通过事件通知机制在有事件发生时再进行处理,这样可以充分利用CPU资源,提升系统的效率和性能。 3. 多进程:Nginx可以通过配置文件中的worker_processes选项来启动多个进程来处理请求。每个进程都有自己独立的事件循环和资源管理,进程之间没有共享状态,这种设计可以避免单点故障,提高系统的可靠性和稳定性。并且Nginx的多进程模型使得它能够更好地利用多核CPU,通过并行处理请求来提高整体的处理能力。 二、反向代理 反向代理是一种服务器配置,它允许客户端请求经过代理服务器,再由代理服务器将请求转发到实际的目标服务器。这种配置不仅隐藏了真实服务器的信息,还能提供安全性和负载均衡功能。 例如,在下面的反向代理配置中,通过正则表达式将/api/server/开头的映射到http://localhost:8080这个地址。 三、负载均衡 负载均衡是通过反向代理到不同的服务,保证服务的可用性。多用于在分布式系统中。例如某个系统分布在100个服务器上,当某几台服务器崩溃时,会代理到其他服务器,不会影响系统的运行。更好的实现横向扩展。 例如一个简单的get请求代码: ```python import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, Tornado!") def make_app(): return tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": app = make_app() app.listen(8888) print("Server running on http://localhost:8888") tornado.ioloop.IOLoop.current().start() ``` 具体的负载均衡算法包括: 1. 轮询:默认算法,直接基于事件循环。缺点是某些情况下的请求会导致负载很高。 2. 最少连接:会将请求分配给连接最少的服务,保证系统的整体性能。缺点是没有具体情况具体分析,没有考虑负载情况,不是请求越多负载越大。 3. IP哈希:通过客户端的IP地址的哈希值分配给特定的服务器。优点是避免了服务器的切换开销,保持了会话的一致性。缺点是同一个客户端的请求无法做到负载均衡。 4. 加权轮询:在轮询的基础上为每个服务器加上一个权重值,每个服务器的承受连接数量。优点是可以根据实际情况调整权重,实现更灵活的负载均衡。 5. 加权最小连接:在最小连接的算法基础上,加上权重值。需要根据连接数量和权重值来评估目标服务器。优点是可以根据服务器的负载情况实现更合理的负载均衡。

正文

一、工作原理

nginx的高性能主要是因为

1、事件驱动架构

Nginx采用事件驱动的非阻塞方式处理请求,主要利用了操作系统提供的多路复用机制,通过异步非阻塞的方式处理大量并发请求,减少了线程切换和资源消耗,提高了并发处理能力和系统的稳定性。

2、事件循环

事件循环机制是核心的工作模式之一。它通过单线程的方式处理事件,包括等待事件、处理事件和继续循环。在等待事件时,Nginx并不会像传统多线程模型那样阻塞等待,而是通过事件通知机制在有事件发生时再进行处理,这样可以充分利用CPU资源,提升系统的效率和性能。

3、多进程

Nginx可以通过配置文件中的worker_processes选项来启动多个进程来处理请求。每个进程都有自己独立的事件循环和资源管理,进程之间没有共享状态,这种设计可以避免单点故障,提高系统的可靠性和稳定性。并且Nginx的多进程模型使得它能够更好地利用多核CPU,通过并行处理请求来提高整体的处理能力。

二、反向代理

server {
    listen 80;  
    server_name example.com;  
    root /root/build/;#静态资源地址
    index index.html;    

    location /api/server/ {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For
    }
}

例如在这个例子中,设置了index目录和静态资源目录。并且设置了域名访问。很大了保证了服务器的安全性。在下面的反向代理配置中,通过正则表达式将/api/server/开头的映射到http://localhost:8080这个地址。

whiteboard_exported_image.png

三、负载均衡

负载均衡也就是通过反向代理到不同的服务,保证服务的可用性。多用于在分布式系统中。例如某个系统分布在100个服务器上,当某几台服务器崩溃时,会代理到其他服务器,不会影响系统的运行。更好的实现横向扩展。

例如一个简单的get请求代码

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, Tornado!") 

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888) 
    print("Server running on http://localhost:8888")
    tornado.ioloop.IOLoop.current().start()  

具体的负载均衡算法

1、轮询

nginx的均衡默认算法:直接基于事件循环。类似于排队,一个一个来,例如第一个请求分发给第一个服务,第二个就分发给第二个服务,以此类推。缺点:没有具体情况具体分析,某些情况下的请求会导致负载很高。

upstream tornado_servers {
    server 192.168.31.158:8888;
    server localhost:8888;
}

server {
    listen 80;
    server_name 192.168.62.132; 

    location / {
        proxy_pass http://tornado_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location /nginx_status {
    stub_status on;
    access_log off;
    allow 192.168.62.0/24;  # 允许访问的IP地址,根据需要调整
    deny all;         # 禁止其他IP地址访问
    }    
}

将上述访问运行在两个不同的服务器上,默认的轮询会每个服务器都请求一次,除非有一台掉线,否则nginx会均分请求。

下面行的localhost块b表示新的匹配规则,用于查看nginx当前的连接数和请求统计信息。

server accepts handled requests

Active connections: 1

表示当前活跃的连接数,即正在与Nginx服务器建立通信的客户端连接数量。

server accepts handled requests

accepts: 表示Nginx已经接受的连接总数。

handled: 表示Nginx已经处理的连接总数。

requests: 表示Nginx已经处理的请求总数。

Reading: 0 Writing: 1 Waiting: 0

Reading: 正在读取客户端请求的数量。

Writing: 正在向客户端发送响应的数量。

Waiting: 当前空闲的客户端连接数,等待处理请求

2、最少连接

会将请求分配给连接最少的服务,保证系统的整体性能。缺点是没有具体情况具体分析,没有考虑负载情况,不是请求越多负载越大。

upstream tornado_servers {
    least_conn;  # 使用最少连接数算法
    server 192.168.31.158:8888;
    server localhost:8888;
}

server {
    listen 80;
    server_name 192.168.62.132;  

    location / {
        proxy_pass http://tornado_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

least_conn字段表示使用最少连接算法。

3、IP哈希

通过客户端的IP地址的哈希值分配给特定的服务器,如果下一次请求的IP哈希值与之前一样,那么依然会请求到之前的服务器。如果不一样那么为新的服务器创建新的哈希值。这样避免了服务器的切换开销,保持了会话的一致性。但是这样的缺点是同一个客户端的请求无法做到负载均衡。

upstream tornado_servers {
    ip_hash;  # 使用IP哈希算法
    server 192.168.31.158:8888;
    server localhost:8888;
}

server {
    listen 80;
    server_name 192.168.62.132;  

    location / {
        proxy_pass http://tornado_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location /nginx_status {
    stub_status on;
    access_log off;
    allow 192.168.62.0/24;  # 允许访问的IP地址,根据需要调整
    deny all;         # 禁止其他IP地址访问
    }
}

4、加权轮询

在轮询的基础上为每个服务器加上一个权重值,每个服务器的承受连接数量。在轮询的情况下再次考虑权重值。例如两台服务器,服务器A、B的权重分别为5,3轮询流程为:

第一次请求:服务器A处理请求

第二次请求:服务器B处理请求

第三次请求:服务器A处理请求

第四次请求:服务器A处理请求

第五次请求:服务器A处理请求

第六次请求:服务器B处理请求

upstream tornado_servers {
    server 192.168.31.158:8888 weight=5;
    server localhost:8888 weight=3;
}

server {
    listen 80;
    server_name 192.168.62.132; 

    location / {
        proxy_pass http://tornado_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location /nginx_status {
    stub_status on;
    access_log off;
    allow 192.168.62.0/24;  # 允许访问的IP地址,根据需要调整
    deny all;         # 禁止其他IP地址访问
    }
}

5、加权最小连接

在最小连接的算法基础上,加上权重值。这时候需要根据连接数量和权重值来评估目标服务器。

例如服务器A、B、C。权重值分别为5、3、2。连接数分别为10、5、3.

计算加权连接数:

服务器A:10/5=2

服务器B:5/3=1.67

服务器C:3/2=1.5

那么根据加权连接数,最小加权连接数为1.5。那么会代理到服务器C

upstream tornado_servers {
    least_conn;  # 使用最少连接数算法
    server 192.168.31.158:8888 weight=5;
    server localhost:8888 weight=3;
}

server {
    listen 80;
    server_name 192.168.62.132; 

    location / {
        proxy_pass http://tornado_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location /nginx_status {
    stub_status on;
    access_log off;
    allow 192.168.62.0/24;  # 允许访问的IP地址,根据需要调整
    deny all;         # 禁止其他IP地址访问
    }
}

四、总结

反向代理就像是位于用户和真实服务器之间的一座桥梁,它接收用户的请求并将其转发到后端的多台服务器上。这种配置不仅隐藏了真实服务器的信息,还能提供安全性和负载均衡功能。负载均衡通过智能地分发请求到不同的服务器,确保每台服务器的负载相对平衡,从而提高整体性能和可靠性。这种结合能够有效地处理高并发请求,保证系统在压力下仍能保持稳定运行。

与【Nginx】负载均衡相似的内容:

【Nginx】负载均衡

Nginx作为负载均衡器,通过将请求分发到多个后端服务器,以提高性能、可靠性和扩展性。支持多种负载均衡算法,如轮询、最小连接数、IP哈希等,可以根据需求选择适合的算法。

[转帖]Nginx(四)负载均衡

一 nginx目录的说明 1 nginx/ 3 |-- client_body_temp 4 |-- conf #这是Nginx所有配置文件的目录,极其重要 5 | |-- fastcgi.conf 'fastcgi相关参数的配置文件' 6 | |-- fastcgi.conf.default #f

[转帖]Nginx负载均衡之ip_hash

原理: 通过哈希值和ip进行运算,得出一个哈希字符串,一个值。分发的时候进行判断请求之前是否和哈希绑定过。有的话则优先分配 匹配到对应哈希值的服务器上。 什么是ip_hash? ip_hash是根据用户请求过来的ip,然后映射成hash值,然后分配到一个特定的服务器里面;使用ip_hash这种负载均

[转帖]Nginx 负载均衡 和 健康检查

https://www.jianshu.com/p/fbb0a81604d9 简介 从 nginx 下载, 到模块安装 关于为什么不使用 ngx_http_upstream_module 测试过 ngx_http_upstream_module 这个模块, 在应用稳定的情况下做做负载均衡还可以. 但

Nginx的负载均衡策略

Nginx的负载均衡策略 共六种: 轮询、权重、ip_hash、least_conn、fair、url_hash 1、轮询(Round Robin)负载均衡策略:这是一种基本的负载均衡策略,将请求顺序转发给每个后端服务器,每个后端服务器依次处理请求,而轮询正是按照这样的方式平均地为每个后端服务器分配

Nginx负载配置

目录Nginx 负载均衡笔记1. 概述1.1 Nginx 简介1.2 负载均衡概述2. 四层负载均衡(传输层)2.1 工作原理2.2 特点2.3 优缺点优点缺点2.4 示例场景3. 七层负载均衡(应用层)3.1 工作原理3.2 特点3.3 优缺点优点缺点3.4 示例场景4. Nginx 调度算法4.

[转帖]解决Nginx负载均衡重复提交问题

https://www.qiansw.com/resolving-nginx-load-balancing-repeated-commit-problems.html 这篇文章的发布时间较早,其中的信息可能已经过时,阅读时请注意甄别。 Nginx [测试环境 Tengine version: Ten

[转帖]nginx如何实现负载均衡、限流、缓存、黑白名单和灰度发布

https://zhuanlan.zhihu.com/p/464491494 挺好的文章. nginx负载均衡配置 1.负载均衡配置 http { upstream real_server { server 192.168.1.100:8082 weight=1; #轮询服务器和访问权重 serve

[转帖]【官方文档】Nginx负载均衡学习笔记(三) TCP和UDP负载平衡官方参考文档

本章介绍如何使用NGINX Plus和NGINX开放源代理和负载平衡TCP和UDP流量。 目录 介绍先决条件配置反向代理配置TCP或UDP负载平衡被动健康监控 选择负载平衡方法配置会话持久性 主动健康监控 怎么运行的先决条件基本配置微调健康检查使用匹配配置块进行微调健康检查 TCP的微调健康检查UD

[转帖]记一次压测引起的nginx负载均衡性能调优

https://xiaorui.cc/archives/3495 这边有个性能要求极高的api要上线,这个服务端是golang http模块实现的。在上线之前我们理所当然的要做压力测试。起初是 “小白同学” 起头进行压力测试,但当我看到那压力测试的结果时,我也是逗乐了。 现象是,直接访问Golang