网络代理

正向代理是位于用户设备和互联网之间的服务器。它代理的是客户端,是站在用户一方的。其真实客户端对于服务器不可见

反向代理是一种服务器,它接受客户端的请求,将请求转发给网络服务器,然后将结果返回给客户端,就像代理服务器处理了请求一样。反向代理代理的是服务器,是和网络服务器站在一方的。其真实服务器对于客户端不可见。这就是它叫“反向”的原因。

其实就好比租房子,中介就是客户的正向代理,二房东就是房东的反向代理。至于二者的作用可以看下图:

负载均衡(Load Balancing)

此处为全文转载。原文网址:https://learn.lianglianglee.com/%E4%B8%93%E6%A0%8F/%E4%BB%8E%200%20%E5%BC%80%E5%A7%8B%E5%AD%A6%E6%9E%B6%E6%9E%84/20%20%E9%AB%98%E6%80%A7%E8%83%BD%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%EF%BC%9A%E5%88%86%E7%B1%BB%E5%8F%8A%E6%9E%B6%E6%9E%84.md

单服务器无论如何优化,无论采用多好的硬件,总会有一个性能天花板,当单服务器的性能无法满足业务需求时,就需要设计高性能集群来提升系统整体的处理性能。

高性能集群的本质很简单,通过增加更多的服务器来提升系统整体的计算能力。由于计算本身存在一个特点:同样的输入数据和逻辑,无论在哪台服务器上执行,都应该得到相同的输出。因此高性能集群设计的复杂度主要体现在任务分配这部分,需要设计合理的任务分配策略,将计算任务分配到多台服务器上执行。

高性能集群的复杂性主要体现在需要增加一个任务分配器,以及为任务选择一个合适的任务分配算法。对于任务分配器,现在更流行的通用叫法是“负载均衡器”。但这个名称有一定的误导性,会让人潜意识里认为任务分配的目的是要保持各个计算单元的负载达到均衡状态。而实际上任务分配并不只是考虑计算单元的负载均衡,不同的任务分配算法目标是不一样的,有的基于负载考虑,有的基于性能(吞吐量、响应时间)考虑,有的基于业务考虑。考虑到“负载均衡”已经成为了事实上的标准术语,这里我也用“负载均衡”来代替“任务分配”,但请你时刻记住,负载均衡不只是为了计算单元的负载达到均衡状态

今天我先来讲讲负载均衡的分类及架构,下一期会讲负载均衡的算法。

负载均衡分类

常见的负载均衡系统包括3种:DNS负载均衡、硬件负载均衡和软件负载均衡。

DNS负载均衡

DNS是最简单也是最常见的负载均衡方式,一般用来实现地理级别的均衡。例如,北方的用户访问北京的机房,南方的用户访问深圳的机房。DNS负载均衡的本质是DNS解析同一个域名可以返回不同的IP地址。例如,同样是www.baidu.com,北方用户解析后获取的地址是61.135.165.224(这是北京机房的IP),南方用户解析后获取的地址是14.215.177.38(这是深圳机房的IP)。

下面是DNS负载均衡的简单示意图:

DNS负载均衡实现简单、成本低,但也存在粒度太粗、负载均衡算法少等缺点。仔细分析一下优缺点,其优点有:

  • 简单、成本低:负载均衡工作交给DNS服务器处理,无须自己开发或者维护负载均衡设备。
  • 就近访问,提升访问速度:DNS解析时可以根据请求来源IP,解析成距离用户最近的服务器地址,可以加快访问速度,改善性能。

缺点有:

  • 更新不及时:DNS缓存的时间比较长,修改DNS配置后,由于缓存的原因,还是有很多用户会继续访问修改前的IP,这样的访问会失败,达不到负载均衡的目的,并且也影响用户正常使用业务。
  • 扩展性差:DNS负载均衡的控制权在域名商那里,无法根据业务特点针对其做更多的定制化功能和扩展特性。
  • 分配策略比较简单:DNS负载均衡支持的算法少;不能区分服务器的差异(不能根据系统与服务的状态来判断负载);也无法感知后端服务器的状态。

针对DNS负载均衡的一些缺点,对于时延和故障敏感的业务,有一些公司自己实现了HTTP-DNS的功能,即使用HTTP协议实现一个私有的DNS系统。这样的方案和通用的DNS优缺点正好相反。

硬件负载均衡

硬件负载均衡是通过单独的硬件设备来实现负载均衡功能,这类设备和路由器、交换机类似,可以理解为一个用于负载均衡的基础网络设备。目前业界典型的硬件负载均衡设备有两款:F5和A10。这类设备性能强劲、功能强大,但价格都不便宜,一般只有“土豪”公司才会考虑使用此类设备。普通业务量级的公司一是负担不起,二是业务量没那么大,用这些设备也是浪费。

软件负载均衡

软件负载均衡通过负载均衡软件来实现负载均衡功能,常见的有Nginx和LVS,其中Nginx是软件的7层负载均衡,LVS是Linux内核的4层负载均衡。4层和7层的区别就在于协议灵活性,Nginx支持HTTP、E-mail协议;而LVS是4层负载均衡,和协议无关,几乎所有应用都可以做,例如,聊天、数据库等。

软件和硬件的最主要区别就在于性能,硬件负载均衡性能远远高于软件负载均衡性能。Nginx的性能是万级,一般的Linux服务器上装一个Nginx大概能到5万/秒;LVS的性能是十万级,据说可达到80万/秒;而F5性能是百万级,从200万/秒到800万/秒都有(数据来源网络,仅供参考,如需采用请根据实际业务场景进行性能测试)。当然,软件负载均衡的最大优势是便宜,一台普通的Linux服务器批发价大概就是1万元左右,相比F5的价格,那就是自行车和宝马的区别了。

除了使用开源的系统进行负载均衡,如果业务比较特殊,也可能基于开源系统进行定制(例如,Nginx插件),甚至进行自研。

下面是Nginx的负载均衡架构示意图:

软件负载均衡的优点:

  • 简单:无论是部署还是维护都比较简单。
  • 便宜:只要买个Linux服务器,装上软件即可。
  • 灵活:4层和7层负载均衡可以根据业务进行选择;也可以根据业务进行比较方便的扩展,例如,可以通过Nginx的插件来实现业务的定制化功能。

其实下面的缺点都是和硬件负载均衡相比的,并不是说软件负载均衡没法用。

  • 性能一般:一个Nginx大约能支撑5万并发。
  • 功能没有硬件负载均衡那么强大。
  • 一般不具备防火墙和防DDoS攻击等安全功能。

负载均衡典型架构

前面我们介绍了3种常见的负载均衡机制:DNS负载均衡、硬件负载均衡、软件负载均衡,每种方式都有一些优缺点,但并不意味着在实际应用中只能基于它们的优缺点进行非此即彼的选择,反而是基于它们的优缺点进行组合使用。具体来说,组合的基本原则为:DNS负载均衡用于实现地理级别的负载均衡;硬件负载均衡用于实现集群级别的负载均衡;软件负载均衡用于实现机器级别的负载均衡。

我以一个假想的实例来说明一下这种组合方式,如下图所示。

整个系统的负载均衡分为三层。

需要注意的是,上图只是一个示例,一般在大型业务场景下才会这样用,如果业务量没这么大,则没有必要严格照搬这套架构。例如,一个大学的论坛,完全可以不需要DNS负载均衡,也不需要F5设备,只需要用Nginx作为一个简单的负载均衡就足够了。

这里还有另一种分类的方式,即四层、七层负载均衡的分类,而这种评价和前面讲到的分类是完全两个维度的。我们在这里可以区分一下:

**四层负载均衡 (L4)**:

  • 工作在OSI模型的传输层(第4层)
  • 仅基于IP地址和TCP/UDP端口信息进行转发
  • 处理TCP/UDP协议,不解析应用层内容
  • 特点:处理速度快,资源消耗少,但功能较简单

**七层负载均衡 (L7)**:

  • 工作在OSI模型的应用层(第7层)
  • 能够解析HTTP/HTTPS等应用层协议内容
  • 可基于URL路径、Cookie、HTTP头等信息做出转发决策
  • 特点:功能丰富,可实现更精细的流量控制,但处理开销较大

软件负载均衡

  • 以软件形式部署在通用服务器上
  • 代表产品:Nginx、HAProxy、LVS
  • 优势:成本低、灵活性高、易于更新
  • 劣势:性能受限于服务器硬件,高并发场景可能成为瓶颈

硬件负载均衡

  • 专用硬件设备,有专门的ASIC芯片
  • 代表产品:F5 BIG-IP、Citrix ADC
  • 优势:性能强大,处理能力高,可靠性好
  • 劣势:成本高,扩展性受限,更新升级不便

两种分类维度的组合应用

这两种分类方式可以组合:

  • 硬件设备通常同时支持四层和七层负载均衡
  • 软件负载均衡解决方案中:
    • LVS主要是四层负载均衡
    • Nginx/HAProxy既支持四层也支持七层,但以七层为主要优势

选择时需考虑业务需求、预算、性能要求和技术团队能力等因素综合决定。

负载均衡算法

负载均衡将网络流量或一组任务以某种算法合理分配给各个处理节点,使得节点得到平等的使用,并及时可靠地返回结果给用户。其应用于各种硬件软件系统中,比如:

  1. 根据 IP 地址进行网络流量负载均衡。在服务进行维护时,可以方便将网络流量切换到临时节点或降级的服务上。
  2. 根据 HTTP 头信息或请求字段进行应用程序负载均衡,用户得到响应的时间更短,并且可以提供分层服务,也方便服务扩容时加入新的节点。
  3. CDN 根据流量的来源,将流量导入相邻地区的服务器,以获得更短的响应时间和更高的可用性。

下图显示了 6 种常见算法。

如果要记忆的话,可以分成静态算法和动态算法两个部分:

01 静态算法

  • 循环(Round Robin)

客户端请求按顺序发送到不同的服务实例。通常要求服务是无状态的。这种算法最简单,但是也无法处理某个节点变慢或者客户端操作有连续性的情况。

  • 粘性循环(Sticky Round Robin)

这是对循环算法的一种改进。如果 Alice 的第一个请求发送到服务 A,那么接下来的请求也会发送到服务 A。这种负载均衡可以确保一个用户的请求都发往同一个服务节点,适合客户端操作有连续性的情况。有时候该服务节点上会保存该用户的一些状态,避免去后端数据库查询。

  • 加权循环(Weighted Round Robin)

管理员可以指定每个服务的权重。权重高的服务会比其他服务处理更多请求。

  • 散列(IP/URL Hash)

该算法对传入请求的 IP 或 URL 应用哈希函数。根据哈希函数的结果将请求路由到相关服务。

02 动态算法

  • 最少连接(Least Connections)

新请求会发送到并发连接最少的服务节点。

  • 响应时间最少(Least Time)

新请求会发送到响应时间最快的服务节点。这样,某个服务节点变慢就不会阻塞后续请求处理了。