作者:deniz2502915157 | 来源:互联网 | 2023-06-05 19:31
这篇文章是因为在阿里云上做负载均衡的时候,遇到了一些问题,在找问题原因的时候,发现是因为没有注意当时创建的负载均衡是四层负载均衡器。问题表现形式在负载均衡后端的服务器访问一个正在使
这篇文章是因为在阿里云上做负载均衡的时候,遇到了一些问题,在找问题原因的时候,发现是因为没有注意当时创建的负载均衡是四层负载均衡器。
问题表现形式
在负载均衡后端的服务器访问一个正在使用此负载均衡的项目api的时候,偶尔访问的到,偶尔访问不到。
四层负载均衡
四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
以常见的TCP为例,负载均衡设备在接收到第一个来自客户端的SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器IP),直接转发给该服务器。
TCP的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。在某些部署情况下,为保证服务器的返回信息可以正确返回给负载均衡设备,,通常是需要把负载均衡器设置为后端服务器的默认网关,否则客户端的在建立链接的时候,会因为收不到返回的包,而表现出服务端拒绝了连接的样子。
七层负载均衡
七层负载均衡,也称为“内容交换”,也就是通过应用层协议,主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
以常见的http为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(三次握手)后,才可能接受到客户端发送的真正应用层内容的报文,然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立TCP连接。所以从这个技术原理上来看,七层负载均衡明显的对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。
原理总结
四层负载均衡:扮演路由器角色,只负责转发包,而不做其他处理。后端服务器需要把默认网关设置成负载均衡器,以使得返回的网络报文能正常的返回给客户端。
七层负载均衡:扮演的代理角色,客户端每次访问后端服务器,七层负载均衡器都需要分别与客户端和后端服务器分别建立一条连接。优点是使得可以按照应用层内容进行负载均衡,控制更加灵活。缺点是每次访问需要维护两条连接,性能会低于四层负载均衡。
问题剖析
看完了原理也就明白了,因为使用的是4层负载均衡器,假设负载均衡器N后面的服务器有A和B两台,当从A请求一个使用此负载均衡器的api的时候,如果请求被负载均衡器路由到了B服务器,这时候连接可以正常建立。
当请求被负载均衡器路由到了A服务器的时候,假设我们认为发送的包是Aclient(Ac),返回的包是Aserver(As)。Ac中的目的IP地址是负载均衡器N,原Ip地址是A,这个包经过负载均衡器的时候,被改成源Ip地址为A,目的Ip地址为A。当A接受到这个包以后,处理完毕发现源IP和目的IP都是自己,这个包就不会再发送到负载均衡器,而是自己处理了。
但是这里网络比较熟悉的朋友应该能知道,虽然数据也是给了A,但是因为没有经过负载均衡器,所以其IP地址没有改为负载均衡的IP(当然可能端口号也一样没变),A虽然收到了这个包,但是没有一个对应的socket,也就没有进程来处理这个连接(因为源和目的IP地址和端口号都一样才是一个socket)。这就导致在客户端这边显示是连接被拒绝,其实是因为发送给负载均衡器的syn包没有回复。报错印象中应该是
connect close by foreign host
解决方案
1.可以使用七层负载均衡代替4层负载均衡
2.可以使用内部路由方式,比如k8s提供了内部的访问service的地址。