第四周作业
一个典型的大型互联网应用系统使用了哪些技术方案和手段,主要解决什么问题?请列举描述。
负载均衡
常见的负载均衡有F5、LVS、Nginx
LVS
LVS 是内核的4层负载均衡
有NAT、DR模式,最常用的是DR模式
成本低
数十万级别负载均衡
F5
F5是硬件的4层负载均衡
硬件版本的LVS,价格较高,性能好
数十万 - 数百万级别负载均衡
Nginx
Nginx是软件的7层负载均衡
成本低
数万级别负载均衡
总结
F5与LVS都属于4层负载均衡,与通讯协议没有关系,不灵活,实际上是假4层负载均衡,只是通过4层的功能查看到是否是需要转发的流量,例如只转发80端口,其他端口的数据包丢弃,无法看到数据包里的内容和请求的URL等。
Nginx本身可以定制化很多功能(可以结合lua脚本语言实现),它可以针对http应用本身来做分流策略,比如针对域名、目录结构等。
每秒并发量在2-3万左右可以选择Nginx(官方宣称是可以抗住5w,实际在2-3w)
每秒并发量在3万以上选择LVS(具体没有经过测试)
解决了什么问题
平常使用java开发的程序会部署在 tomcat/jetty/undertow 的 servlet容器/web服务器 上,
这些容器可以承受的并发数远远小于LVS,Nginx,F5,所以流量的入口一般我们使用负载均衡接住流量后分发web服务器上。一般分发的算法有,加权、轮询、随机、最小连接数等。
缓存
CDN(内容分发网络)
将用户上传的图片/视频等静态资源上传到CDN节点上,用户请求时通过DNS负载均衡技术找到用户所在位置最近的CDN节点并响应请求。
解决了什么问题
因请求图片/视频等静态资源占用服务器资源,影响动态请求响应速度。
降低带宽成本,CDN流量还是很便宜的,如果买服务器带宽还是很贵的(阿里云是这样)
有哪些限制
CDN上的资源都是公开访问的,面对一些比较私密的静态内容并不适合使用CDN。
MemCache/Redis
缓存是把热点数据放在电脑的内存中,提供用户访问。一般我们在访问数据库的数据时,是从硬盘中读取数据,内存的访问速度是要比硬盘的访问速度快几十倍甚至几百倍。
官方宣称单机可以达到10w QPS。
解决了什么问题
大量的请求访问数据库,数据库的集群规模可能相应的会变的很大,服务器也会随时增多。缓存主要是为了缓解数据库的压力和更快的访问速度,用更低的成本解决大量请求的访问问题。
有哪些限制
Redis存储的数据有可能会丢失,并不能保证数据的完整性,不提供严谨的事务,本身定位就是缓存,不能当高性能数据库使用。
缓存穿透问题:
当用户访问一个并不存在的商品时。
例如访问商品ID为100000的商品时,缓存中并不存在,大量的请求就会直接落在数据库上,给数据库造成巨大的压力。
缓存雪崩问题:
当缓存集中式的失效后,大量的请求也会直接落在数据库上,给数据库造成巨大的压力。
例如商品类型为1的商品缓存失效了,大量的用户访问类型为1的商品。
缓存击穿问题:
当访问的一个数据失效时,大量的请求也会落在数据库上,给数据库造成巨大的压力。
例如 商品ID为10的商品缓存失效,而大量的用户查看这个商品。
本地缓存
直接在应用中,使用Map等集合类缓存热点数据。
解决了什么问题?
当用户请求量特别大时,用户当前线程首先需要从缓存连接池中获取一个缓存,然后发送网络请求到Redis服务器,这个过程相对与访问本地的Map还是要耗时的。
有哪些限制
缓存的数据量较大时会导致每个应用使用较多的内存。
消息队列
先进先出的数据结构,类似于Java中的Queue,一般消息队列中间件会提供更丰富的功能,提供数据的持久化,集群等功能。PS:有些消息中间件因为集群的原因,可能不会顺序消费数据。
解决了什么问题?
可以顶住并发写请求的压力:
当存在大量的写请求时,数据库写入速度与请求写的速度不匹配时,可以先写入到消息中间件,消息中间件的写入速度要比数据库的写入速度快很多。
支持数据回放:
数据写入到消息中间件后,会持久化到硬盘一段时间后再删除,具体与对应设置有关。即使数据被消费了但是还存在硬盘上。例如 我们的数据库出现了故障,但是 不影响我们的数据写入,数据库恢复时,消费者继续消费数据,存入到数据中。
解耦:
当A模块需要调用B模块时,A可以使用消息队列发送消息,B模块消费消息队列中的消息,B模块消费消息后执行某种操作。
例如:
当用户买某件商品下了订单按照一定规则,用户会得到积分,积分按照订单消费的金额或者特定商品来计算。
正常流程是:
订单模块:下订单 -》 保存订单 -》 计算积分(根据营销策略) -》 用户积分模块:增加用户账户积分
使用消息中间件的流程是:
订单模块:下订单 -》 保存订单 -》 发送用户下订单消息
营销模块:消费用户下订单消息 -》 计算积分(根据营销策略) -》用户积分模块:增加用户账户积分
营销策略会随着不同的节日变化,使用消息队列即使改变需求 也不需要修改订单模块,只需要修改营销模块,不使用消息队列则需要改变订单模块。
微服务
单体架构:代码打包到一个程序中,部署在一个集群上 或者 部署在一个服务器上,一个单体应用构成一个系统
微服务架构:将大的应用里面的一些模块拆分出来,将这些模块独立部署在一个集群上 或者 部署在一个服务器上,应用通过远程调用方式依赖这些独立的模块。
解决了什么问题?
编译、部署、发布困难 : 大的项目代码繁多,编译一次如果需要较长时间,那么改动一点代码就需要整体编译一次然后部署,编译浪费了大量的时间。
数据库连接耗尽 : 单体应用一般会使用一个数据库连接池,处理大量请求时,很可能会导致数据库连接不够用。例如: 商品订单在一个单体应用中,10个用户查询商品,10个用户下订单 就会使用20个数据库连接;如果分为商品服务,订单服务 它们都有单独的数据库,那么每个服务各使用10个数据库连接即可。
新增业务困难:开发新的应用需要在原有的庞大的复杂的单体应用上开发,不知从何下手。
级联故障:单体应用中,例如一个功能出现问题出现OOM或者其他问题,会影响到项目的其他功能。
分布式 数据库/缓存
将数据根据一定算法分别存储到不同的数据库服务节点上
解决了什么问题?
数据库/缓存 数据量过大所带来性能、存储容量问题。
数据一般会根据一定的算法将数据和该数据关联的数据存储到对应的节点上,读取的时候也会根据这个算法路由到对应的节点上。
常见的算法有
Hash算法 :
根据字段进行hash后的结果 映射到对应的服务器节点上。
优点:
数据分布均匀
缺点:
新增或者减少服务器是需要数据的全量迁移,全部的数据重新hash一次再分布到各个服务器上
一致性Hash算法 :
定义一个最大值,形成一个环,每个服务器上负责一部分的值。根据字段进行hash后的结果映射到对应的服务器上。
优点:
新增或者减少服务器节点时,只需要迁移部分数据即可。
缺点:
数据分布不均匀
数据段算法:
根据增量的数据分段,例如 每两天的数据存在不同的服务器上,今天明天存在01 ,后天大后天存在02。
评论