论负载均衡技术在Web系统中的应用

467 阅读8分钟

说明:这是我在备考软考高级时写的练习论文,仅供参考。如有不当之处欢迎指正及讨论

题目

负载均衡技术是提升Web系统性能的重要方法。利用负载均衡技术,可将负载(工作任务)进行平衡、分摊到多个操作单元上执行,从而协同完成工作任务,达到提升Web系统性能的目的 。

请围绕“负载均衡技术在Web系统中的应用”论题,依次从以下三个方面进行论述。

1.概要叙述你参与管理和开发的软件项目,以及你在其中所承担的主要工作。

2.详细阐述常见的三种负载均衡算法,说明算法的基本原理。

3.详细说明你所参与的软件开发项目中,如何基于负载均衡算法实现Web应用系统的负载均衡。

摘要

我所在的单位是国内一家车联网科技企业,公司是国内外多家车个的供应商,作为单位的技术骨干之一,我从2019年1月开始主持了我司为某德系知名品牌国企提供的车联网平台的开发。随着物联网技术,4G网络的发展,为了进一步提高汽车的网联化,智能化,我司推出了车联网服务平台,并成功取得了多家国内外车企的订单。我司车联网平台集成了智慧加油, 无感停车,在线音乐,在线电台,智能导航,车队等多项车联网服务。这些车联网服务大多数以web应用接口的方式提供给车载终端及手机端使用。

项目中使用了Nginx作为负载均衡中间件,它支持常见的负载均衡算法:轮询算法,随机算法和最小连接算法。项目开始时使用的是基本的轮询算法,后来发现偶尔会出现个别节点负载比其它节点都要高的情况,后来改用了最小连接算法,解决了这个问题。经过一段时间的运行发现,最小连接算法的负载均衡能够有效的让节点间负载相对平均,运行效果良好。

正文

我所在的单位是一家创业公司,致力于让车更智能,让车主和乘客出行更舒心。我司在车联网的多个应用领域都有服务提供,主要的服务包括:1)智慧加油:车主加油不下车,支持车内支付,手机开发票。2)无感停车:开通服务后,车主离开停车场时,自动扣除停车费,无需等待,直接离场。3)在线音乐:车主可以在车上连网听音乐。除此之外,还集成了在线电台,智慧充电,汽车保险等服务。基于这些服务的基础上,我司在2018年底顺利获得了某德系知名品牌车企的车联网服务供应商资格。2019年1月,我作为公司的技术骨干,开始主持车联网项目的需求分析,架构设计和部分的开发工作。

车联网项目以服务端提供API接口,通过HTTPS协议与车载终端及手机端通讯,集成支付,加油,停车,在线音乐等第三方服务,为车主提供车联网服务。提供的API接口主要是Restful风格的JSON格式的接口。设计接入车辆为1000万辆,因为接入车辆较多,服务的可用性要求需要达到99.95%,年故障时间不得超过4.38小时。为了保证服务的可用性和性能的要求,项目采用了负载均衡技术。

常见的负载均衡算法包括:轮询算法,随机算法和最小连接算法。1)轮询算法是指对用户请求按先后次序,依次分配到不同的服务器上处理。这种算法的优点是实现简单,能实现绝对的均衡;缺点是无法保证任务的合理性,不能根据服务器的真实负载来分配任务,可能导致集群中个别服务器节点负载过高。2)随机算法是指对用户请求随机的分配到某个服务器上处理。这种算法实的优点是现简单,也能实现总体上的请求分配平均;缺点和轮询算法类似无法保证任务的合理性,不能根据服务器的真实负载来分配任务。3)最小连接算法是指对用户请求,总是分配到连接数最小的服务器上处理。这种算法的优点是能够保证任务的合理性,让多个服务节点的负载比较均衡;缺点是实现相对复杂,比轮询算法和随机算法复杂,需要维护各服务器节点的状态,对连接数进行统计和排序。

车联网项目通过nginx负载均衡接入,nginx后面是tomcat作为web服务器,tomacat连接MySQL数据和redis缓存。nginx和tomcat这间通过http协议进行通讯,在nginx服务器上启用HTTPS的支持,确保服务器和终端之间的安全传输。一开始,项目采用的时默认的负载均衡策略,即:轮询算法。在对项目接口进行压力测试时,我们发现三个被测服务器,其中有一台比另外两台的负载明显要高,经过分析日志发现,负载较高的服务上的请求平均处理时间要比其它两台服务器要长,连接数也比另外两台服务器要多。然后我尝试修改了负载均衡的算法,改为最小连接算法,再进行压力测试,就发现三台被测试的服务器的负载相差不多了。

项目过程中我们还遇到一个问题,一个流程在本地测试是正常的,但是部署到测试环境后,就很容易出现问题。原因是流程里一共有两个步骤的请求,这两个步骤的请求必须都在同一个服务器节点上。比如说:用户先使用语音说:“查询上海今天的天气”,服务器返回了今天 上海的天气信息。这个时候用户接着说:“明天呢”,这个时候用户的期望是“明天上海的天气”,这个上下文状态是保存在tomcat服务器上,这么一来就要求,同一个终端的请求,应该被分配到同一个服务器上。为了解决这个问题,我使用了基于客户端IP的哈希策略,对用户过来的请求,取客户端IP,计算一个哈希值,然后把这个哈希值对65535取模,把客户端为成65535份。每一份对应一个服务器IP地址。确保同一个IP每次都被分配到相同的服务器上。

服务器的配置不一定都是一样的,为了让高配置的服务器多处理请求,低配置的服务器少处理请求,项目中引入了权重的概念。给每个服务器分配一个权重。比如:服务器1的权重是5,服务器2的权重是3,那就是说同等负载的情况下服务器1可以处理5个请求,服务器2处理3个请求。通过权重的配置实现能者多劳,相对均衡。也就是配置高的服务器可以让其处理更多的用户请求,相对的配置低的服务器处理相对较少的用户请求,保证性能。

为了保证服务的可用性,项目引入了健康检查机制,如果某个服务器节点最近10个请求都无法正常返回数据,则标记它为异常节点。对于异常节点,在接下来的一异常时间段内(比如:3分钟)不会再提供服务。异常时间段后,会再次尝试接入该节点,如果此时节点能正常返回数据,刚标记其为正常的节点。否则继续保持为异常节点,直到下一个异常时间段结束。举个例子:节点A在某一个时刻连续10次无响应,这个时候nginx就把节点A标记为异常节点,在接下来的3分钟内,不会把请求分配给节点A,直到3分钟后,再分配请求到节点A,如果此时节点正常的响应了请求,那么nginx就把节点A标识为正常节点,节点A可以继续提供服务;如果此时节点未能正常响应,那么节点A继续被 标记为异常节点,进入下一轮3分钟的等待。健康检查机制能够有效的自动去除无效节点,而当节点恢复后,又能正常的让其继续提供服务。

总的来说,基于权重的最小连接算法是比较优秀的负载均衡算法,但上项目中因为需要保证同一个客户,两次请求需要保持在同一服务器,使得我们需要加上客户端IP哈希的算法,这样一来就无法保证负载均衡。后续可以考虑把web应用服务器都保持为无状态的,相关的状态信息都保存在redis中。以优化负载均衡的效果。