高并发解决方案:
1)数据层
数据库集群和库表散列
分表分库
开启索引
开启缓存
表设计优化
Sql语句优化
缓存服务器(提高查询效率,减轻数据库压力)
搜索服务器(提高查询效率,减轻数据库压力)
图片服务器分离
2)项目层
采用面向服务分布式架构(分担服务器压力,提高并发能力)
采用并发访问较高的详情系统采用静态页面,HTML静态化 freemaker
使用页面缓存
用ActiveMQ使得业务进一步进行解耦,提高业务处理能力
使用分布式文件系统存储海量文件
3)应用层
Nginx服务器来做负载均衡
Lvs做二层负载
镜像
处理高并发常见的方法有哪些?
1、HTML静态化 freemaker
其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。但是对于大量内容并且频繁更新的网站,我们无法全部手动去挨个实现,于是出现了我们常见的信息发布系统CMS,像我们常访问的各个门户站点的新闻频道,甚至他们的其他频道,都是通过信息发布系统来管理和实现的,信息发布系统可以实现最简单的信息录入自动生成静态页面,还能具备频道管理、权限管理、自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的CMS是必不可少的。除了门户和信息发布类型的网站,对于交互性要求很高的社区类型网站来说,尽可能的静态化也是提高性能的必要手段,将社区内的帖子、文章进行实时的静态化,有更新的时候再重新静态化也是大量使用的策略,像Mop的大杂烩就是使用了这样的策略,网易社区等也是如此。同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实现,比如论坛中论坛的公用设置信息,这些信息目前的主流论坛都可以进行后台管理并且存储再数据库中,这些信息其实大量被前台程序调用,但是更新频率很小,可以考虑将这部分内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求。
2、图片服务器分离
大家知道,对于Web服务器来说,不管 是 Apache、IIS还是其他容器,图片是最消耗资源的,于是我们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服务器,甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力,并且可以保证系统不会因为图片问题而崩溃,在应用服务器和图片服务器 上,可以进行不同的配置优化,比如apache在配置ContentType的时候可以尽量少支持,尽可能少的LoadModule,保证更高的系统消耗和执行效率。
3、数据库集群和库表散列
大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快无法满足应用,于是我们需要使用数据库集群或者库表散列。在数据库集群方面,很多数据库都有自己的解决方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是类似的方案,您使用了什么样的DB,就参考相应的解决方案来实施即可。上面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用DB类型的限制,于是我们需要从应用程序的角度来考虑改善系统架构,库表散列是常用并且最有效的解决方案。我们在应用程序中安装业务和应用或者功能模块将数据库进行分离,不同的模块对应不同的数据库或者表,再按照一定的策略对某个页面或者功能进行更小的数据库散列,比如用户表,按照用户ID进行表散列,这样就能够低成本的提升系统的性能并且有很好的扩展性。sohu的论坛就是采用了这样的架 构,将论坛的用户、设置、帖子等信息进行数据库分离,然后对帖子、用户按照板块和ID进行散列数据库和表,最终可以在配置文件中进行简单的配置便能让系统随时增加一台低成本的数据库进来补充系统性能。
4、缓存
缓存一词搞技术的都接触过,很多地方用到缓存。网站架构和网站开发中的缓存也是非常重要。这里先讲述最基本的两种缓存。高级和分布式的缓存在后面讲述。 架构方面的缓存,对Apache比较熟悉的人都能知道Apache提供了自己的缓存模块,也可以使用外加的Squid模块进行缓存,这两种方式均可以有效的提高Apache的访问响应能力。 网站程序开发方面的缓存,Linux上提供的Memory Cache是常用的缓存接口,可以在web开发中使用,比如用Java开发的时候就可以调用MemoryCache对一些数据进行缓存和通讯共享,一些大型社区使用了这样的架构。另外,在使用web语言开发的时候,各种语言基本都有自己的缓存模块和方法,PHP有Pear的Cache模块,Java就更多了。
5、镜像
镜像是大型网站常采用的提高性能和数据安全性的方式,镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异,比如ChinaNet和EduNet之间的差异就促使了很多网站在教育网内搭建镜像站点,数据进行定时更新或者实时更新。在镜像的细节技术方面,这里不阐述太深,有很多专业的现成的解决架构和产品可选。也有廉价的通过软件实现的思路,比如Linux上的rsync等工具。
6、负载均衡
负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。 负载均衡技术发展了多年,有很多专业的服务提供商和产品可以选择。
高并发下电商网站的秒杀活动
秒杀实现思路
秒杀技术实现核心思想是运用缓存减少数据库瞬间的访问压力!读取商品详细信息时运用缓存,当用户点击抢购时减少redis中的库存数量,当库存数为0时或活动期结束时,同步到数据库。 产生的秒杀预订单也不会立刻写到数据库中,而是先写到缓存,当用户付款成功后再写入数据库。所有买家在同一时间网上抢购的一种销售方式。通俗一点讲就是网络商家为促销等目的组织的网上限时抢购活动。由于商品价格低廉,往往一上架就被抢购一空,有时只用一秒钟。
秒杀商品通常有两种限制:库存限制、时间限制。
需求:
商家提交秒杀商品申请,录入秒杀商品数据,主要包括:商品标题、原价、秒杀价、商品图片、介绍等信息
运营商审核秒杀申请
秒杀频道首页列出秒杀商品(进行中的)点击秒杀商品图片跳转到秒杀商品详细页。
商品详细页显示秒杀商品信息,点击立即抢购实现秒杀下单,下单时扣减库存。当库存为0或不在活动期范围内时无法秒杀。
秒杀下单成功,直接跳转到支付页面(微信扫码),支付成功,跳转到成功页,填写收货地址、电话、收件人等信息,完成订单。
当用户秒杀下单5分钟内未支付,取消预订单,调用微信支付的关闭订单接口,恢复库存。
秒杀架构设计理念
限流: 鉴于只有少部分用户能够秒杀成功,所以要限制大部分流量,只允许少部分流量进入服务后端。
削峰:对于秒杀系统瞬时会有大量用户涌入,所以在抢购一开始会有很高的瞬间峰值。高峰值流量是压垮系统很重要的原因,所以如何把瞬间的高流量变成一段时间平稳的流量也是设计秒杀系统很重要的思路。实现削峰的常用的方法有利用缓存和消息中间件等技术。
异步处理:秒杀系统是一个高并发系统,采用异步处理模式可以极大地提高系统并发量,其实异步处理就是削峰的一种实现方式。
内存缓存:秒杀系统最大的瓶颈一般都是数据库读写,由于数据库读写属于磁盘IO,性能很低,如果能够把部分数据或业务逻辑转移到内存缓存,效率会有极大地提升。
可拓展:当然如果我们想支持更多用户,更大的并发,最好就将系统设计成弹性可拓展的,如果流量来了,拓展机器就好了。像淘宝、京东等双十一活动时会增加大量机器应对交易高峰。
前端方案:浏览器端
页面静态化:将活动页面上的所有可以静态的元素全部静态化,并尽量减少动态元素。通过CDN来抗峰值。
禁止重复提交:用户提交之后按钮置灰,禁止重复提交
用户限流:在某一时间段内只允许用户提交一次请求,比如可以采取IP限流
后端方案:服务端控制器层(网关层)
限制uid(UserID)访问频率:我们上面拦截了浏览器访问的请求,但针对某些恶意攻击或其它插件,在服务端控制层需要针对同一个访问uid,限制访问频率。
服务层:上面只拦截了一部分访问请求,当秒杀的用户量很大时,即使每个用户只有一个请求,到服务层的请求数量还是很大。比如我们有100W用户同时抢100台手机,服务层并发请求压力至少为100W。
采用消息队列缓存请求:既然服务层知道库存只有100台手机,那完全没有必要把100W个请求都传递到数据库啊,那么可以先把这些请求都写到消息队列缓存一下,数据库层订阅消息减库存,减库存成功的请求返回秒杀成功,失败的返回秒杀结束。
利用缓存应对读请求:对类似于12306等购票业务,是典型的读多写少业务,大部分请求是查询请求,所以可以利用缓存分担数据库压力。
利用缓存应对写请求:缓存也是可以应对写请求的,比如我们就可以把数据库中的库存数据转移到Redis缓存中,所有减库存操作都在Redis中进行,然后再通过后台进程把Redis中的用户秒杀请求同步到数据库中。
数据库层:数据库层是最脆弱的一层,一般在应用设计时在上游就需要把请求拦截掉,数据库层只承担“能力范围内”的访问请求。所以,上面通过在服务层引入队列和缓存,让最底层的数据库高枕无忧。
使用Redis缓存实现秒杀:
Redis是一个分布式缓存系统,支持多种数据结构,我们可以利用Redis轻松实现一个强大的秒杀系统。我们可以采用Redis 最简单的key-value数据结构,用一个原子类型的变量值(AtomicInteger)作为key,把用户id作为value,库存数量便是原子变量的最大值。对于每个用户的秒杀,我们使用 RPUSH key value插入秒杀请求, 当插入的秒杀请求数达到上限时,停止所有后续插入。然后我们可以在台启动多个工作线程,使用 LPOP key 读取秒杀成功者的用户id,然后再操作数据库做最终的下订单减库存操作。当然,上面Redis也可以替换成消息中间件如ActiveMQ、RabbitMQ等,也可以将缓存和消息中间件 组合起来,缓存系统负责接收记录用户请求,消息中间件负责将缓存中的请求同步到数据库。
当商品库存数量不足时,如何保证不会超卖?当库存数量不足时,必须保证库存不能被减为负数,如果不加以控制,库存被减为小于等于0的数,那么这就叫做超卖。
那么如何防止超卖的现象发生呢?
场景一: 如果系统并发要求不是很高:那么此时库存就可以存储在数据库中,数据库中加锁控制库存的超卖现象。
场景二:系统的并发量很大:如果系统并发量很大,那么就不能再使用数据库来进行减库存操作了,因为数据库加锁操作本身是以损失数据库的性能来进行控制数据库数据的一致性的。但是当并发量很大的时候,将会导致数据库排队,发生阻塞。因此必须使用一个高效的nosql数据库服务器来进行减库存。此时可以使用redis服务器来存储库存,redis是一个内存版的数据库,查询效率相当的高,可以使用watch来监控减库存的操作,一旦发现库存被减为0,立马停止售卖操作。
做交易或是金融系统安全性需要从哪些方面考虑?没有用什么第三方可以框架?
ip黑白名单,访问日志明细记录,防止重复提交,访问频率控制,分布式锁,数据前后端校验,自动对账任务处理,互联网金融项目一般情况下,不建议自动重试,最好结合对账系统,人工进行处理,写好人工处理的接口就好。其他就是控制好数据的一致性了,这个最重要,其次还要保证接口的幂等性,不要重复处理订单。这些是最基本的安全控制了。像这类网站用户的输入数据一般都不会太多,一般敏感词过滤,广告之类的可以忽略,如果有的话还要控制这些。安全框架选shiro 了,在系统中分配好角色就好了,控制好用户的资源访问。其他的用springmvc 就够了。
讲一下高并发下的电商项目每台服务器的集群数量:
项目中一共15台项目服务,那么为了每一台高可用一主一备,但首页项目高并发设为四台服务器,则一共32台项目服务器,再加redis集群用了3台,为了每一台高可用一主一备一共6台,fastdfs一个trackerServer一个storageServer搭建集群一共6台,solr集群7台服务器,nginx为了高可用一主一备一共2台,mysql数据库集群3台!activemq消息中间件高可用2台;
共计:58台服务器!
介绍一下高并发的电商项目:
我最近的一个项目是一个电商项目,我主要负责的是后台管理和商品详情的模块,然后也会参与到购物车和订单模块。这个项目是以SpringBoot和mybatis为框架,应为springBoot相对于SSM来说 配置方面,还有操作方面简单很多。然后是采用zookeeper加dubbo分布式架构和RPC远程调用,因为他Dubbo实现了软负载均衡,其特点是成本低,但也会有缺点,就是负载能力会受服务器本身影响,然后为了解决软负载均衡的缺点,我们使用了Nginx进行负载均衡的轮询算法,但Nginx主要在我们项目还是实现反向代理,就是可以防止外网对内网服务器的恶性攻击、缓存以减少服务器的压力和访问安全控制。基础模块就有后台管理,商品详情,订单,支付,物流情况,库存服务。然后SpringBoot整合Thymeleaf模块技术开发项目商品详情模块,easyUI开发后台管理项目。至于我负责的两个模块呢,就是后台管理和商品详情,其中呢使用了sku和spu的数据表结构进行增删改查,spu就好比我们要买一台Mate20,但是我们没有选择它是什么配置,那么关于详细的配置就是sku了,就是我要买一台Mate20,黑色,内存是128G的。商品详情和商品列表模块使用Nginx实现集群,使用Redis解决应用服务器的cpu和内存压力,减少io的读操作,减轻io的压力,使用分布式锁防止Redis缓存击穿。其中Redis的作用我是觉得挺大的,因为他可以防止过多的用户去直接访问我们的数据库,当然,Redis也会在高并发的时候宕机,在使用Redis做缓存的时候,我们使用Redis持久化功能,防止Redis宕机后数据丢失,如果Redis宕机了,用户就会大量的去访问数据库,从而我们数据库也会崩溃吧。这个时候我们就用了一个分布式锁,用户需要获得一个锁才能访问我们的数据库,当然啦,并不只是只有一个锁,而是锁的数量是有限的,当一位用户查完了数据之后,锁就会释放,给下位用户,这也就是服务降降级。没有获得锁的用户,页面就一直刷新直到自己拿到锁为止。redis提供了持久化功能——RDB和AOF。通俗的讲就是将内存中的数据写入硬盘中。在实际应用中,用户如果要查询商品的话呢,首先回到Redis缓存里面找的,如果找不到,就会到数据库里面找,然后缓存到Redis中,那么下一次或者下一个用户需要查找这个数据就不必到数据库中查找了!然后我还参与了购物车和订单模块的开发。购物车模块里面呢,我先和您讲下他的业务逻辑吧。就像你逛网页淘宝一样,在没有登录的时候,把东西放入购物车,它是不会和你的账号里的商品合并的,这个时候,商品就会以cookie的形式,放到你的浏览器里面。这个时候如果你想购买这些商品的时候,你就要登录,这个时候就会使用到单点登录这一个技术。用户跳转到订单页面的时候,我们会用拦截器去进行判断用户是否已经登录。我们是用cookie中是否有token,如果没有token的话就跳转到登录页面,然后生成token,至于token的生成呢,我们是用本地的IP,用户的id,保存在map中,还有一个常量,这个我们通常会以项目名称来命名的。至于为什么要token呢,其实是因为cookie是不太安全的,它很容易被伪造,所以我们就需要token,然后有了token之后,我们用JWT这个盐值生成最后的token。并把它保存到cookie当中。下一次支付的时候我们也还会用到这个token,用一个加密算法再去运算验证一下就可以了!然后就是合并购物车了。这个的话我所知道的就是将客户端的cookie复印一份到缓存中进行修改然后送回客户端进行覆盖,再接着就是数据库的修改了。那这个如果登陆了的就直接从数据库中取得数据跳到订单系统了。然后订单模块里面,简单来说就是从购物车中勾选的商品迁移到订单里面。但是呢订单模块其实是会联系到另外两个模块的,就是库存和支付。如果你点击了提交订单,商品就会在购物车里移除。然后我们提交订单避免他反复的提交同一个订单,就会通过交易码防止订单重复提交。我们会吧tradecode放在缓存里面,以用户id为key商品的交易为value在Redis里面保存这个交易码。到最后选好收货地址,留言之后,提交订单了,就会用自己的tradecode和在Redis里面通过用户的id去获取tradecode进行对比,如果能跳转到支付页面,那么缓存中的交易码就会删除掉。到最后就是支付功能,这一步的话我是不太清楚其中的技术点了,只知道这个模块调用了支付宝的接口和用了消息队列,异步通知。
高并发下的一些优化:
数据层面的优化:
从数据库层面做优化,比如:索引,缓存,集群,读写分离,主从复制,分表,分库。
从数据库设计层面的优化:比如减少表关联,加入冗余字段
从缓存方面优化:比如redis实现数据缓存,减轻数据库压力
从搜索上进行优化:比如查找索引库
项目层面的优化:
采用面向服务的分布式架构:分担服务器压力 ,提高项目并发量。 比如dubbox+zookeeper分布式架构
采用分布式文件系统实现海量文件存储:如采用fastdfs实现海量图片存储,提高文件的访问速度。
采用mq使用服务进一步解藕:同步索引库,同步静态资源,短信发送
服务器层面的优化:
集群思想的使用:tomcat,zookeeper,redis,mysql等
Tomcat异步通信的使用,tomcat连接池配置
高可用解决方案:
通常企业级应用系统(特别是政府部门和大企业的应用系统)一般会采用安规的软硬件设备,如IOE(IBM的小型机、Oracle数据、EMC存储设备)系列。而一般互联网公司更多地采用PC级服务器(x86),开源的数据库(MySQL)和操作系统(Linux)组建廉价且高容错(硬件故障是常态)的应用集群。
目的:保证服务器硬件故障服务依然可用,数据依然保存并能够被访问。
主要的手段?
数据和服务的①冗余备份以及②失效转移:
对于服务而言,一旦某个服务器宕机,就将服务切换到其他可用的服务器上;
对于数据而言,如果某个磁盘损坏,就从备份的磁盘(事先就做好了数据的同步复制)读取数据。
高可用的服务
①分级管理:核心应用和服务具有更高的优先级,比如用户及时付款比能否评价商品更重要;
②超时设置:设置服务调用的超时时间,一旦超时,通信框架抛出异常,应用程序则根据服务调度策略选择重试or请求转移到其他服务器上
③异步调用:通过消息队列等异步方式完成,避免一个服务失败导致整个应用请求失败的情况。不是所有服务都可以异步调用,对于获取用户信息这类调用,采用异步方式会延长响应时间,得不偿失。对于那些必须确认服务调用成功后才能继续进行下一步的操作的应用也不适合异步调用。
④服务降级:网站访问高峰期间,为了保证核心应用的正常运行,需要对服务降级。
降级有两种手段:
拒绝服务,拒绝较低优先级的应用的调用,减少服务调用并发数,确保核心应用的正常运行;
关闭功能,关闭部分不重要的服务,或者服务内部关闭部分不重要的功能,以节约系统开销,为核心应用服务让出资源;
⑤幂等性设计:保证服务重复调用和调用一次产生的结果相同;
高可用的数据
保证数据高可用的主要手段有两种:一是数据备份,二是失效转移机制;
①数据备份:又分为冷备份和热备份,冷备份是定期复制,不能保证数据可用性。热备份又分为异步热备和同步热备,异步热备是指多份数据副本的写入操作异步完成,而同步方式则是指多份数据副本的写入操作同时完成。关系数据库的热备机制就是通常所说的主从同步机制,实践中通常使用读写分离的方法来访问Master和Slave数据库,也就是说写操作只访问Master库,读操作均访问Slave库。
②失效转移:若数据服务器集群中任何一台服务器宕机,那么应用程序针对这台服务器的所有读写操作都
要重新路由到其他服务器,保证数据访问不会失败。
网站运行监控
”不允许没有监控的系统上线“
(1)监控数据采集
①用户行为日志收集:服务器端的日志收集和客户端的日志收集;目前许多网站逐步开发基于实时计算框架Storm的日志统计与分析工具;
②服务器性能监控:收集服务器性能指标,如系统Load、内存占用、磁盘IO等,及时判断,防患于未然;
③运行数据报告:采集并报告,汇总后统一显示,应用程序需要在代码中处理运行数据采集的逻辑;
(2)监控管理
①系统报警:配置报警阀值和值守人员联系方式,系统发生报警时,即使工程师在千里之外,也可以被及时通知;
②失效转移:监控系统在发现故障时,主动通知应用进行失效转移;
③自动优雅降级:为了应付网站访问高峰,主动关闭部分功能,释放部分系统资源,保证核心应用服务的正
常运行;—>网站柔性架构的理想状态
其他手段:
主从切换:很好理解,当其中一台机器的服务宕机后,对于服务调用者来说,能够迅速的切换到其他可用服务,从服务升级为主服务,这种切换速度应当控制在秒级别(几秒钟)。当宕机的服务恢复之后,自动变为从服务,主从服务角色切换。主从切换一定是要付出代价的,所以当主服务恢复之后,也就不再替换现有的主服务。
负载均衡:当服务的请求量比较高的时候,一台服务不能满足需求,这时候需要多台机器提供同样的服务,将所有请求分发到不同机器上。高可用架构中应该具有丰富的负载均衡策略和易调节负载的方式。甚至可以自动化智能调节,例如由于机器性能的原因,响应时间可能不一样,这时候可以向性能差的机器少一点分发量,保证各个机器响应时间的均衡。
易横向扩展:当用户量越来越多,已有服务不能承载更多的用户的时候,便需要对服务进行扩展,扩展的方式最好是不触动原有服务,对于服务的调用者是透明的。
负载均衡:
什么是负载均衡?
当一台服务器的性能达到极限时,我们可以使用服务器集群来提高网站的整体性能。那么,在服务器集群中,需要有一台服务器充当调度者的角色,用户的所有请求都会首先由它接收,调度者再根据每台服务器的负载情况将请求分配给某一台后端服务器去处理。
简单介绍5种负载均衡:
(1)HTTP重定向负载均衡。
这种负载均衡方案的优点是比较简单;
缺点是浏览器需要每次请求两次服务器才能拿完成一次访问,性能较差。
(2)DNS域名解析负载均衡
优点是将负载均衡工作交给DNS,省略掉了网络管理的麻烦;
缺点就是DNS可能缓存A记录,不受网站控制。
(3)反向代理负载均衡。
优点是部署简单;
缺点是反向代理服务器是所有请求和响应的中转站,其性能可能会成为瓶颈。
(4)IP负载均衡。
优点:IP负载均衡在内核进程完成数据分发,较反向代理均衡有更好的处理性能。
缺点:负载均衡的网卡带宽成为系统的瓶颈。
(5)数据链路层负载均衡。
避免负载均衡服务器网卡带宽成为瓶颈,是目前大型网站所使用的最广的一种负载均衡手段。
详情介绍5种负载均衡:
(1)HTTP重定向负载均衡。
原理:当用户向服务器发起请求时,请求首先被集群调度者截获;调度者根据某种分配策略,选择一台服务器,并将选中的服务器的IP地址封装在HTTP响应消息头部的Location字段中,并将响应消息的状态码设为302,最后将这个响应消息返回给浏览器。当浏览器收到响应消息后,解析Location字段,并向该URL发起请求,然后指定的服务器处理该用户的请求,最后将结果返回给用户。
优点:比较简单
缺点:调度服务器只在客户端第一次向网站发起请求的时候起作用。当调度服务器向浏览器返回响应信息后,客户端此后的操作都基于新的URL进行的(也就是后端服务器),此后浏览器就不会与调度服务器产生关系,浏览器需要每次请求两次服务器才能拿完成一次访问,性能较差。而且调度服务器在调度时,无法知道当前用户将会对服务器造成多大的压力,只不过是把请求次数平均分配给每台服务器罢了,浏览器会与后端服务器直接交互。
(2)DNS域名解析负载均衡
原理:为了方便用户记忆,我们使用域名来访问网站。通过域名访问网站之前,首先需要将域名解析成IP地址,这个工作是由DNS域名服务器完成的。我们提交的请求不会直接发送给想要访问的网站,而是首先发给域名服务器,它会帮我们把域名解析成IP地址并返回给我们。我们收到IP之后才会向该IP发起请求。一个域名指向多个IP地址,每次进行域名解析时,DNS只要选一个IP返回给用户,就能够实现服务器集群的负载均衡。
优点:配置简单,将负载均衡工作交给DNS,省略掉了网络管理的麻烦;
缺点:集群调度权交给了DNS服务器,从而我们没办法随心所欲地控制调度者,没办法定制调度策略,没办法了解每台服务器的负载情况,只不过把所有请求平均分配给后端服务器罢了。某一台后端服务器发生故障时,即使我们立即将该服务器从域名解析中去除,但由于DNS服务器会有缓存,该IP仍然会在DNS中保留一段时间,那么就会导致一部分用户无法正常访问网站。不过动态DNS能够让我们通过程序动态修改DNS服务器中的域名解析。从而当我们的监控程序发现某台服务器挂了之后,能立即通知DNS将其删掉。
调度策略:一般DNS提供商会提供一些调度策略供我们选择,如随机分配、轮询、根据请求者的地域分配离他最近的服务器。
随机分配策略:当调度服务器收到用户请求后,可以随机决定使用哪台后端服务器,然后将该服务器的IP封装在HTTP响应消息
的Location属性中,返回给浏览器即可。
轮询策略(RR) :调度服务器需要维护一个值,用于记录上次分配的后端服务器的IP。那么当新的请求到来时,调度者将请求依
次分配给下一台服务器。
(3)反向代理负载均衡。
原理:反向代理服务器是一个位于实际服务器之前的服务器,所有向我们网站发来的请求都首先要经过反向代理服务器,服务器根据用户的请求要么直接将结果返回给用户,要么将请求交给后端服务器处理,再返回给用户。反向代理服务器就可以充当服务器集群的调度者,它可以根据当前后端服务器的负载情况,将请求转发给一台合适的服务器,并将处理结果返回给用户。
优点:
部署简单
隐藏后端服务器:与HTTP重定向相比,反向代理能够隐藏后端服务器,所有浏览器都不会与后端服务器直接交互,从而能够确保调度者的控制权,提升集群的整体性能。
故障转移 :与DNS负载均衡相比,反向代理能够更快速地移除故障结点。当监控程序发现某一后端服务器出现故障时,能够及时通知反向代理服务器,并立即将其删除。
合理分配任务 :HTTP重定向和DNS负载均衡都无法实现真正意义上的负载均衡,也就是调度服务器无法根据后端服务器的实际负载情况分配任务。但反向代理服务器支持手动设定每台后端服务器的权重。我们可以根据服务器的配置设置不同的权重,权重的不同会导致被调度者选中的概率的不同。
缺点:
调度者压力过大 :由于所有的请求都先由反向代理服务器处理,那么当请求量超过调度服务器的最大负载时,调度服务器的吞吐率降低会直接降低集群的整体性能。
制约扩展 :当后端服务器也无法满足巨大的吞吐量时,就需要增加后端服务器的数量,可没办法无限量地增加,因为会受到调度服务器的最大吞吐量的制约。
粘滞会话:反向代理服务器会引起一个问题。若某台后端服务器处理了用户的请求,并保存了该用户的session或存储了缓存,那么当该用户再次发送请求时,无法保证该请求仍然由保存了其Session或缓存的服务器处理,若由其他服务器处理,先前的Session或缓存就找不到了。
解决办法:
可以修改反向代理服务器的任务分配策略,以用户IP作为标识较为合适。相同的用户IP会交由同一台后端服务器处理,从而就避免了粘滞会话的问题。
可以在Cookie中标注请求的服务器ID,当再次提交请求时,调度者将该请求分配给Cookie中标注的服务器处理即可。
(4)IP负载均衡。
通过NAT实现负载均衡:响应报文一般比较大,每一次都需要NAT转换的话,大流量的时候,会导致调度器成为一个瓶颈。
通过直接路由实现负载均衡
VS/TUN 实现虚拟服务器
优点:IP负载均衡在内核进程完成数据分发,较反向代理均衡有更好的处理性能。
缺点:负载均衡的网卡带宽成为系统的瓶颈,场景:某个服务器跑的应用非高峰期间都能达到500M以
上,晚高峰一般能够超过1G,主流服务器的网卡都是千兆的,超过1G的流量明显会导致丢包的问题,此时又不
能停止业务对网卡进行更换。
(5)数据链路层负载均衡。
对于linux系统来说,数据链路层的解决方案就是实现多个网卡绑定联合提供服务,把多张网卡捆绑做成一个逻辑网卡。避免负载均衡服务器网卡带宽成为瓶颈,是目前大型网站所使用的最广的一种负载均衡手段。linux bonding的七种模式,mod=0~6:平衡抡循环策略,主-备份策略,平衡策略,广播策略,动态链接聚合,适配器传输负载均衡,适配器适应性负载均衡
————————————————
版权声明:本文为CSDN博主「晒车党」的原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45542824/article/details/99822372