一、关于高并发
高并发是指在同一个时间点,有很多用户同时访问URL地址,比如:淘宝的双11、双12,就会产生高并发。又如贴吧的爆吧,就是恶意的高并发请求,也就是DDOS攻击,再屌丝点的说法就像玩LOL被ADC暴击了一样,那伤害你懂的。
1
高并发会来带的后果
下面我进行实例分析,简单粗暴,动态分析,纯属本人经验分享,如有说错或者更好的建议,请留言,大家一起成长。
2
并发下的数据处理
通过表设计,如:记录表添加唯一约束,数据处理逻辑使用事物防止并发下的数据错乱问题。通过服务端锁进程防止包并发下的数据错乱问题。这里主要讲述的是在并发请求下的数据逻辑处理的接口,如何保证数据的一致性和完整性,这里的并发可能是大量用户发起的,也可能攻击者通过并发工具发起的并发请求。
例子1:通过表设计防止并发导致数据错乱
例子2:事务+通过更新锁,防止并发导致数据错乱;或者事物+Update的锁表机制
例子3:通过程序代码防止包并发下的数据错乱问题
3
访问量大的数据统计接口
4
高并发的下的服务器压力均衡,合理站点架设,DB部署
以下我所知道的:
服务器代理nginx,做服务器的均衡负载,把压力均衡到多台服务器;
部署集群MySQL数据库, Redis服务器,或者MongoDB服务器,把一些常用的查询数据,并且不会经常的变化的数据保存到其他NoSQL DB服务器中,来减少数据库服务器的压力,加快数据的响应速度;
数据缓存,Cache;
在高并发接口的设计中可以使用具有高并发能力的编程语言去开发,如:nodejs做web接口;
服务器部署,图片服务器分离,静态文件走CDN;
DBA数据库的优化查询条件,索引优化;
消息存储机制,将数据添加到信息队列中(redis list),然后再写工具去入库
脚本合理控制请求,如,防止用户重复点击导致的ajax多余的请求,等等。
5
并发测试神器推荐
Apache JMeter
Microsoft Web Application Stress Tool
Visual Studio 性能负载
二、关于高并发架构
为了让业务可以流畅地运行并且给用户一个好的交互体验,我们需要根据业务场景预估达到的并发量等因素,来设计适合自己业务场景的高并发处理方案。
在电商相关产品开发的这些年,我有幸遇到了并发下的各种坑,这一路摸爬滚打过来有着不少的血泪史lol更新完无法连接服务器,这里进行总结,作为自己的归档记录,同时分享给大家。
1
服务器架构
业务从发展的初期到逐渐成熟,服务器架构也是从相对单一到集群,再到分布式服务。
一个可以支持高并发的服务少不了好的服务器架构,需要有均衡负载,数据库需要主从集群,NoSQL缓存需要主从集群,静态文件需要上传CDN,这些都是能让业务程序流畅运行的强大后盾。
服务器这块多是需要运维人员来配合搭建,具体我就不多说了,点到为止。
大致需要用到的服务器架构如下:
服务器:
数据库:
NoSQL:
CDN:
2
并发测试
高并发相关的业务,需要进行并发的测试,通过大量的数据分析评估出整个架构可以支撑的并发量。
测试高并发可以使用第三方服务器或者自己测试服务器,利用测试工具进行并发请求测试,分析测试数据得到可以支撑并发数量的评估,这个可以作为一个预警参考,俗话说知己自彼百战不殆。
第三方服务:
并发测试工具:
3
实战方案
1)通用方案
日用户流量大,但是比较分散,偶尔会有用户高聚的情况;
场景:用户签到,用户中心,用户订单等。
服务器架构图:
说明:
场景中的这些业务基本是用户进入APP后会操作到的,除了活动日(618、双11等),这些业务的用户量都不会高聚集,同时这些业务相关的表都是大数据表,业务多是查询操作,所以我们需要减少用户直接命中DB的查询;优先查询缓存,如果缓存不存在,再进行DB查询,将查询结果缓存起来。
更新用户相关缓存需要分布式存储,比如使用用户ID进行hash分组,把用户分布到不同的缓存中,这样一个缓存集合的总量不会很大,不会影响查询效率。
方案如:
用户签到获取积分:
用户订单:
用户中心:
其他业务:
以上例子是一个相对简单的高并发架构,并发量不是很高的情况可以很好的支撑,但是随着业务的壮大,用户并发量增加,我们的架构也会进行不断的优化和演变,比如对业务进行服务化,每个服务有自己的并发架构,自己的均衡服务器,分布式数据库,NoSQL主从集群,如:用户服务、订单服务。
2)消息队列
秒杀、秒抢等活动业务,用户在瞬间涌入产生高并发请求。
场景:定时领取红包等。
服务器架构图:
说明:
方案如:
附加:通过消息队列可以做很多的服务。
如:定时短信发送服务,使用sset(sorted set),发送时间戳作为排序依据,短信数据队列根据时间升序,然后写个程序定时循环去读取sset队列中的第一条,当前时间是否超过发送时间,如果超过就进行短信发送。
3)一级缓存
高并发请求连接缓存服务器超出服务器能够接收的请求连接量,部分用户出现建立连接超时无法读取到数据的问题;
因此需要有个方案当高并发时候时候可以减少命中缓存服务器;
这时候就出现了一级缓存的方案,一级缓存就是使用站点服务器缓存去存储数据,注意只存储部分请求量大的数据,并且缓存的数据量要控制,不能过分的使用站点服务器的内存而影响了站点应用程序的正常运行,一级缓存需要设置秒单位的过期时间,具体时间根据业务场景设定,目的是当有高并发请求的时候可以让数据的获取命中到一级缓存,而不用连接缓存NoSQL数据服务器,减少NoSQL数据服务器的压力。
比如APP首屏商品数据接口,这些数据是公共的不会针对用户自定义,而且这些数据不会频繁的更新,像这种接口的请求量比较大就可以加入一级缓存;
服务器架构图:
合理地规范和使用NoSQL缓存数据库,根据业务拆分缓存数据库的集群,这样基本可以很好支持业务,一级缓存毕竟是使用站点服务器缓存所以还是要善用。
4)静态化数据
高并发请求数据不变化的情况下如果可以不请求自己的服务器获取数据那就可以减少服务器的资源压力。
对于更新频繁度不高,并且数据允许短时间内的延迟,可以通过数据静态化成JSON、XML、HTML等数据文件上传CDN,在拉取数据的时候优先到CDN拉取,如果没有获取到数据再从缓存,数据库中获取,当管理人员操作后台编辑数据再重新生成静态文件上传同步到CDN,这样在高并发的时候可以使数据的获取命中在CDN服务器上。
CDN节点同步有一定的延迟性,所以找一个靠谱的CDN服务器商也很重要。
5)其他方案
对于更新频繁度不高的数据,APP、PC浏览器,可以缓存数据到本地,然后每次请求接口的时候上传当前缓存数据的版本号,服务端接收到版本号判断版本号与最新数据版本号是否一致,如果不一样就进行最新数据的查询并返回最新数据和最新版本号,如果一样就返回状态码告知数据已经是最新。减少服务器压力:资源、带宽。
- END -
推荐阅读:
理解K8s的网络:pods、services、ingress
年轻时偷的懒lol更新完无法连接服务器,迟早是要还的。点亮
版权声明
本文仅代表作者观点。
本文系作者授权发表,未经许可,不得转载。
发表评论