你管这破玩意儿叫负载均衡?( 二 )


这样的设计持续了很长一段时间 , 但是后来李大牛发现这样的设计其实还是有问题 , 不管是动态请求 , 还是静态资源(如js , css文件)请求都打到tomcat了 , 这样在流量大时会造成tomcat承受极大的压力 , 其实对于静态资源的处理tomcat不如Nginx , tomcat每次都要从磁盘加载文件比较影响性能 , 而Nginx有proxycache等功能可以极大提升对静态资源的处理能力 。
画外音:所谓的proxycache是指nginx从静态资源服务器上获取资源后会缓存在本地的内存+磁盘中 , 下次请求如果命中缓存就从Nginx本机的Cache中直接返回了
所以李大牛又作了如下优化:如果是动态请求 , 则经过gateway打到tomcat , 如果是Nginx , 则打到静态资源服务器上
你管这破玩意儿叫负载均衡?
文章图片
这就是我们所说的动静分离 , 将静态请求与动态请求分开 , 这样tomcat就可以专注于处理其擅长的动态请求 , 而静态资源由于利用到了Nginx的proxycache等功能 , 后端的处理能力又上了一个台阶 。
另外需要注意的是并不是所有的动态请求都需要经过网关 , 像我们的运营中心后台由于是内部员工使用的 , 所以它的鉴权与网关的api鉴权并不相同 , 所以我们直接部署了两台运营中心的server , 直接让Nginx将运营中心的请求打到了这两台server上 , 绕过了网关 。
你管这破玩意儿叫负载均衡?
文章图片
当然为了避免单点故障Nginx也需要部署至少两台机器 , 于是我们的架构变成了下面这样 , Nginx部署两台 , 以主备的形式存在 , 备Nginx会通过keepalived机制(发送心跳包)来及时感知到主Nginx的存活 , 发现宕机自己就顶上充当主Nginx的角色
你管这破玩意儿叫负载均衡?
文章图片
看起来这样的架构确实不错 , 但要注意的是Nginx是七层(即应用层)负载均衡器 , 这意味着如果它要转发流量首先得和client建立一个TCP连接 , 并且转发的时候也要与转发到的上游server建立一个TCP连接 , 而我们知道建立TCP连接其实是需要耗费内存(TCPSocket , 接收/发送缓存区等需要占用内存)的 , 客户端和上游服务器要发送数据都需要先发送暂存到到Nginx再经由另一端的TCP连接传给对方 。
你管这破玩意儿叫负载均衡?
文章图片
所以Nginx的负载能力受限于机器I/O , CPU内存等一系列配置 , 一旦连接很多(比如达到百万)的话 , Nginx抗负载能力就会急遽下降 。
经过分析可知Nginx的负载能力较差主要是因为它是七层负载均衡器必须要在上下游分别建立两个TCP所致 , 那么是否能设计一个类似路由器那样的只负载转发包但不需要建立连接的负载均衡器呢 , 这样由于不需要建立连接 , 只负责转发包 , 不需要维护额外的TCP连接 , 它的负载能力必然大大提升 , 于是四层负载均衡器LVS就诞生了 , 简单对比下两者的区别
你管这破玩意儿叫负载均衡?
文章图片
可以看到LVS只是单纯地转发包 , 不需要和上下游建立连接即可转发包 , 相比于Nginx它的抗负载能力强、性能高(能达到F5硬件的60%) , 对内存和cpu资源消耗比较低
那么四层负载均衡器是如何工作的呢
负载均衡设备在接收到第一个来自客户端的SYN请求时 , 即通过负载均衡算法选择一个最佳的服务器 , 并对报文中目标IP地址进行修改(改为后端服务器IP) , 直接转发给该服务器 。 TCP的连接建立 , 即三次握手是客户端和服务器直接建立的 , 负载均衡设备只是起到一个类似路由器的转发动作 。 在某些部署情况下 , 为保证服务器回包可以正确返回给负载均衡设备 , 在转发报文的同时可能还会对报文原来的源地址进行修改 。