作者:张华 发表于:2015-11-13
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明
(http://blog.csdn.net/quqi99 )
- 四层的负载均衡,就是通过发布三层的IP地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,对需要处理的流量进行NAT处理,转发至后台服务器,并记录下这个TCP或者UDP的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。所以四层的负载均衡器更像是一个NAT路由器。
- 七层的负载均衡,就是在四层的基础上,再考虑应用层的特征,比如同一个Web服务器的负载均衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。负载均衡如果要真正理解七层应用层的内容,只能先代理最终的服务器和客户端建立三次握手连接后,才可能接受到客户端发送的真正应用层内容的报文,所以七层的负载均衡更像是代理服务器。
随着TCP越来越复杂,很多应用程序在UDP之上自已处理连接状态、数据序列等来自行控制复制度,比较典型的就是DTLS协议(SSL的UDP版本)以及OpenVPN。但UDP一般是来一个请求服务完了就结束了,它能做到你TCP一样维护一个连接池来利用多CPU的处理能力吗?
一个套接字由相关五元组构成(协议、本地地址、本地端口、远程地址、远程端口),不能破坏五元组的唯一性。
- SO_REUSEADDR仅仅表示可以客户端socket可以重用本地地址、本地端口,整个相关五元组还是唯一确定的。在对于UDP无连接状态没有办法通过“将新的连接匹配保存下来的已有的五元组连接”来判断是否五元组唯一。于是它就是简单地基于目标IP与目标端口查找UDP socket链表结构,找到第一个就返回。SO_REUSEADDR只是重用本地IP与端口,所以你可以在在一个进程或者多个线程里绑定相同的远程IP与端口的UDP连接,但只有最后一个(或者其他固定位置,依算法而定)UDP连接可以接收到数据。
- SO_REUSEPORT, 于是,从Linux3.9内核开始有了SO_REUSEPORT这个socket选项,它支持多个客户端套接字(多个进程或者线程)绑定到同一端口, 这样每一个线程拥有了自己的服务器套接字,从而在服务器套入字上没有了锁的竞争提升了性能。它的算法在查找UDP socket链表结构时,不仅使用了目标IP与端口,也使用了源IP与端口,这样就会找到多个,最后再通过Hash选择一个,这样实现了内核层面的负载均衡。这样在服务端创建多个udp socket并绑定相同的IP和端口,不同源IP与端口的客户端socket会自动负载到不同的服务端socket上去。这样,想利用多CPU的话,可以预先创建多个进程,每一个进程分配一个UDP socket来处理数据的收发(代码实现可以在主进程中预先fork多个进程,每一个进程只处理一个UDP socket)。如果有一个UDP socket死掉的话,就会改变socket链表的位置,所以办法是使用CLOEXEC参数保证UDP不被关闭。
Haproxy目前不支持上述的UDP方式在每一个进程上启动一个UDP socket来给客户端作负载均衡。corosync支持使用udpu方式作各节点间的心跳检查,但前提是配置host列表。
参考:
1, http://kb.cnblogs.com/page/188170/
2, http://blog.csdn.net/dog250/article/details/17061277
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-09-29 19:27:18