我编辑了我的问题,以便更多地关注问题。
编码以了解负载均衡的工作原理。 Debian 64位。
loadbalancer on 127.0.0.1:36001 后端在127.0.0.1:36000
卷曲调用loadbalancer(36001)。
我使用此代码创建了我的套接字socket code
我创建了一个非常天真的负载均衡器,一个服务器,我对负载均衡器有一个卷曲请求。 我的问题是我不明白如何在拼接时将客户端端口/ ip传递给后端到anwser直接卷曲。
curl localhost:36001 -d"致敬"
static int pool_of_conn[2],
pool_of_pipes[2][2];
int sentinel , efd;
struct epoll_event event;
struct epoll_event *events;
...
off64_t offset = 0;
pipe(pool_of_pipes[0]);
/* This splice works but sends the loadbalancer ip and port. How to put the client's here ? How to alter events[i].data.fd ? */
bytes = splice(events[i].data.fd, NULL, pool_of_pipes[0][1], NULL, 4096, SPLICE_F_MOVE);
if (bytes == 0)
break;
splice(pool_of_pipes[0][0], NULL, pool_of_conn[0], NULL, bytes, SPLICE_F_MOVE);
你能帮我吗?
答案 0 :(得分:0)
您的问题的根本问题是HTTP,通过TCP,这是一种面向连接的协议。因此,即使您可以使与后端的连接看起来来自客户端IP地址,也会在负载均衡器和后端之间建立TCP连接。因此,返回TCP数据包也使用该连接。以某种方式解决此问题,您需要HTTP为请求和回复使用不同的TCP连接,并且还要操纵本地IP路由以使后端回复仍然转到实际客户端。
如果您的目的是制作HTTP负载均衡器,那么最简单的解决方案可能就是应用程序协议(即HTTP)级别。您可以使用HTTP重定向或更复杂的内容,例如在转发之前将客户端请求包装在某些标头中。我确信现有的HTTP负载均衡器提供了大量的示例和想法。
也就是说,如果你想在TCP连接级别解决这个问题,对应用程序协议透明,这是可行的,但它需要相当多的额外代码。此外,后端回复仍然通过负载均衡器。我的建议是研究IP选项IP_TRANSPARENT。当连接到后端时,它将允许负载均衡器将客户端IP地址用作源。 (请注意,返回流量也会通过负载均衡器,因此您的splice()
会派上用场)
以下是关于IP_TRANSPARENT
Transparent proxying - how to pass socket to local server without modification?
以下是https://www.kernel.org/doc/Documentation/networking/tproxy.txt
的Linux内核文档