Skip to main content
 首页 » 编程设计

python之haproxy 背后扭曲的应用程序

2025年05月04日8TianFang

我有一个简单的扭曲应用程序,它提供“Hello World!”通过 HTTP 协议(protocol)。我正在尝试运行多个实例以利用所有处理器。

但我提到,单个扭曲的应用程序处理的请求甚至比 haproxy 背后的同一应用程序的 1、2 或 5 个实例要多得多。我不明白为什么会这样。

我运行 5000 个线程通过 JMeter 获取 /。当我在 127.0.0.1:9001 上运行它时,它会在 500 毫秒的时间内成功处理每个请求。当我在 127.0.0.1:8080 上运行它时,一些响应是 503 Service Unavailable 并且一些运行时间超过 500 毫秒。

这是我的配置文件:

global 
    maxconn 500000 
    user german 
 
defaults 
    mode http 
    retries 0 
    timeout connect 5000ms 
    timeout client 50000ms 
    timeout server 50000ms 
    balance roundrobin 
    # if something goes wrong with server, redistribute client to a working server 
    option redispatch 
 
listen http 127.0.0.1:8080 
    mode http 
    option httpchk GET / HTTP/1.1 
 
    server prototype-local 127.0.0.1:9001 maxconn 0 weight 1 maxqueue 0 cookie server01 check inter 5000 rise 1 fall 3 
 
    balance roundrobin 
 
    # to see ip's of clients 
    option forwardfor 
    option http-server-close 
    # disable or enable immediate session resource cleaning(useful for chat) 
    # option nolinger 
    # inserts cookie to each client requet to identify a process 
    cookie SWCOMMET insert indirect nocache 
    # will be enalbed as soon as main server with process crashed :nice fail resistance 
    option allbackups 

请您参考如下方法:

When I run it on 127.0.0.1:9001 it handles each request successfully in 500ms time

你在开玩笑吗?如果像“hello world”这样简单的应用程序在 500 毫秒内做出响应,那么肯定有什么地方出了问题。

你应该检查你的服务器没有交换(例如:由于内存泄漏),这可以解释如此长的响应时间以及为什么当你在链中添加 haproxy 时它会更糟,因为这两个进程都会受到影响。

您从 haproxy 获得 503 的事实意味着它丢失了无法响应健康检查的服务器。这符合巨大的响应时间 BTW。

也有可能由于任何原因,应用程序正在占用所有 CPU,如果它绑定(bind)到同一个 CPU,则会导致 haproxy 的高调度延迟。您应该监视 CPU 使用率并查看每个进程在哪个 CPU 上运行(为此使用“top”)。理想情况下,您应该将 haproxy 强制到一个特定的核心(使用任务集),并将您的应用程序强制到另一个核心。避免跨内核的线程迁移对于实现高负载至关重要,因此每个新实例都必须在专用内核上运行。

如果服务器占用大量内存,您应该使用 haproxy 的服务器 maxconn 参数来序列化请求(并删除 maxqueue)。

我在您的 haproxy 配置中看到的其他内容中,全局 maxconn 很大并且没有多大意义,因为您需要大约 9 GB 的 RAM 才能达到此限制。此外,您需要在默认部分设置一个 maxconn 值,因为前端的默认值为 2000,这可能低于您尝试的值。

您应该删除“maxconn 0”、“maxqueue 0”和“weight 1”,因为它们是默认的并且只会使配置的理解复杂化。