HAProxy网络问题

本文关键字:问题 网络 HAProxy | 更新日期: 2023-09-27 18:19:41

我正在构建一个.NET应用程序,该应用程序需要向第三方发送web服务消息。身份验证将通过相互SSL身份验证完成。第三方表示,他们使用HAProxy负载均衡器进行SSL终止。

当我发送一条消息时,第一条消息成功(HTTP 200),所有后续消息失败(HTTP 503-服务不可用),直到其中之一;A.我等待了一段时间——大约5分钟,然后再次发送B.重新启动我的客户端应用程序并再次发送在A或B之后,第一条消息工作,所有后续消息失败,依此类推…

我尝试过用几个应用程序发送消息——Fiddler、我的应用程序和另一个mock,我总是得到同样的行为。当我们从不同的位置/操作系统运行客户端时,也会发生同样的情况。

该客户端构建在.NET 4.5上,并依赖于HttpClient框架。根据这个类的文档"{…}每个HttpClient实例都使用自己的连接池,将其请求与其他HttpClient实例执行的请求隔离开来

https://msdn.microsoft.com/en-us/library/system.net.http.httpclient%28v=vs.110%29.aspx.

我正在为每个请求创建一个新实例。当我运行Wireshark跟踪时,我看到每条消息都有一个来自我端的新端口,并且有一个TCP握手,所以我认为它确实在为每条消息创建一个新的连接。。。

我的问题是,当我重置客户端应用程序进程时,服务器如何恢复自身。如果在每种情况下都是新的无状态TCP连接,服务器如何知道消息来自同一进程?

提前感谢,抢劫

附言:这是第一条和第二条消息的HTTP请求/响应示例;

第一条消息

POST https://xxxxxx/xxxxxxx HTTP/1.1
Host: xxxxxxxxxx:9001
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Content-Type: text/xml; charset=utf-8
Content-Length: 547
Keep-Alive: false
<?xml version="1.0" encoding="utf-8"?>
{.....}


HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: application/xml
Content-Length: 891
Date: Thu, 29 Oct 2015 09:02:35 GMT
Connection: close
<?xml version="1.0" encoding="UTF-8" ?>
{...}

第二条消息

POST https://xxxxxx/xxxxxxx HTTP/1.1
Host: xxxxxxxxxx:9001
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Content-Type: text/xml; charset=utf-8
Content-Length: 547
Keep-Alive: false

<?xml version="1.0" encoding="utf-8"?>
{.....}

HTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html
<html><body><h1>503 Service Unavailable</h1>
No server is available to handle this request.
</body></html>

HAProxy网络问题

如果我对多个请求使用相同的HttpClient实例,症状是相同的(1x 200/ok,多个503/服务不可用)。

最后,第三方删除了一个haproxy断言,即每个调用都会显示身份验证证书。这解决了问题。

这很奇怪,因为我的客户端代码为每个请求创建了一个新的HttpClient,并为每个新的HttpClient附加了一个客户端证书。

    private void btnSend_Click(object sender, EventArgs e)
    {
        using (this.client = new HttpClient(this.InitialiseHandler()))
        {
            this.SetupRequest();
            this.SendRequest();
            this.RenderResponse();
        }
    }
    private WebRequestHandler InitialiseHandler()
    {
        var handler = new WebRequestHandler
        {
            ClientCertificateOptions = ClientCertificateOption.Manual,
            UseProxy = false,
        };
        var clientCert = this.GetClientCertificate();
        handler.ClientCertificates.Add(clientCert);
        handler.ServerCertificateValidationCallback += this.ValidationCallback;
        return handler;
    }

在使其工作之前,第一个请求生成了以下几个数据包(通过Wireshark的PCAP);

     1. Me --> Them    TCP     [SYN]
     2. Them --> Me    TCP     [SYN, ACK]
     3. Me --> Them    TCP     [ACK]
     4. Me --> Them    TCP     [PSH, ACK]  ... Len=130
     5. Them --> Me    TCP     [ACK]       ... Len=1460

第二个和随后的(失败的请求)生成了以下几个数据包;

     1. Me --> Them    TCP     [SYN]
     2. Them --> Me    TCP     [SYN, ACK]
     3. Me --> Them    TCP     [ACK]
     4. Me --> Them    TCP     [PSH, ACK]  ... Len=1426
     5. Them --> Me    TCP     [PSH, ACK]  ... Len=113
     6. Them --> Me    TCP     [PSH, ACK]  ... Len=272
     7-9 {...} [PSH, ACK] back and forward
     10. Me --> Them   TCP     [FIN, ACK]
     11. Them --> Me   TCP     [FIN, ACK]
     12. Me --> Them   TCP     [ACK]
     13. Them --> Me   TCP     [RST]

我看不懂第四个数据包里的数据,好像是密码。我不明白为什么第一个和第二个请求的长度相差这么大。

随着HAProxy配置的更改,初始请求生成的数据包数量与以前相同。随后的请求偏离了上面在第6个数据包上显示的示例;

      6. Me --> Them    TCP     [PSH, ACK]  ... Len=256
      7. Them --> Me    TCP     [ACK]
      {...}