简单理解下高并发:
高并发是指在同一个时间点,有很多用户同时的访问URL地址,比如:淘宝的双11,双12,就会产生高并发,如贴吧的爆吧,就是恶意的高并发请求,也就是DDOS攻击, 再屌丝点的说法就像玩撸啊撸被ADC暴击了一样,那伤害你懂得(如果你看懂了,这个说法说明是正在奔向人生巅峰的
屌丝
)。
高并发会来带的后果:
服务端:导致站点服务器/DB服务器资源被占满崩溃,可能产生不是理想中的重复杂乱的数据。 用户角度:尼玛,这么卡,老子来参加活动的,刷新了还是这样,垃圾网站,再也不来了。
我的经历:
在做公司产品网站的过程中,经常会有这样的需求,比如什么搞个活动专题,抽奖,签到,搞个积分竞拍 等等,如果没有考虑到高并发下的数据处理,那就Game Over了,很容易导致抽奖被多抽走,签到会发现一个用户有多条记录,签到一次获得了获得了多积分,等等,各种超出正常逻辑的现象,这就是做产品网站必须考虑的问题,因为这些都是面向大量用户的,而不是像做ERP管理系统,OA系统那样,只是面向员工。 下面我进行实例分析,简单粗暴,动态分析,纯属本人个人经验分享,
如有说错,或者有更好的建议或者意见的请留言,大家一起成长
。
需求点: 【签到功能】 一天一个用户只能签到一次, 签到成功后用户获取到一个积分 已知表: 用户表,包含积分字段 高并发意淫分析(属于开发前的猜测): 在高并发的情况下,会导致,一个用户签到记录会有多条,后者用户签到后不止加一个积分。 我的设计: 首先更具需求我会添加一张签到记录表, 重点来了 ,这张表需要把用户唯一标识字段(ID,Token)和签到日期字段添加为唯一约束,或者唯一 索引 ,这样就可以 防止并发的时候插入重复用户的签到记录。 然后再程序代码逻辑里,先执行签到数据的添加,添加成功后再进行积分的添加,这样就可以防止重复的添加积分了。 最后我还是建议所有的数据 操作 都写在一个sql事务里面, 这样在添加失败,或者编辑用户积分失败的时候可以回滚数据。
-------------------------------------------[我只是美丽的分割线]------------------------------------------- 如例子2(事务+通过更新锁 防止并发导致数据错乱 或者事物+Update的锁表机制) 需求点: 【抽奖功能】 抽奖一次消耗一个积分 抽奖中奖后编辑剩余奖品总数 剩余奖品总数为0,或者用户积分为0的时候无法进行抽奖 已知表 : 用户表,包含积分字段 &nbp; 奖品表,包含奖品剩余数量字段 高并发意淫分析(属于开发前的猜测): 在高并发的情况下,会导致用户参与抽奖的时候积分被扣除,而奖品实际上已经被抽完了 我的设计: 在事物里,通过WITH (UPDLOCK) 锁住商品表,或者Update 表的编辑时间字段,来把数据行锁住,然后进行商品数量的消耗,和用户积分的消耗,都完成后提交事物,失败就回滚。 这样就可以保证,只有可能存在一个 操作 在 操作 这件商品的数量,只有等到这个 操作 事物提交后,其他的 操作 这个商品行的事物才会继续执行。
-------------------------------------------[我只是美丽的分割线]------------------------------------------- 2,高并发的下的服务器压力均衡,合理站点架设,DB部署 以下我所知道的: 1,服务器代理nginx,做服务器的均衡负载,把压力均衡到多台服务器 2,部署redis服务器,或者mongodb服务器,把一些常用的查询数据,并且不会经常的变化的数据保存到其他nosql DB服务器中,来减少数据库服务器的压力,加快数据的响应速度。 3,前端JS脚本合理控制请求,如,防止用户重复点击导致的ajax多余的请求,等等。 4,在高并发接口的设计中可以使用具有高并发能力的编程语言去开发,如:nodejs 做 web接口 3,并发测试神器推荐: Apache JMeter Microsoft Web Application Stress Tool (如果还有更好的工具求推荐,简单易用)
1,高并发的数据处理:
通过表设计或者SQL语句来防止包并发下的数据错乱问题 通过程序代码防止包并发下的数据错乱问题 -------------------------------------------[我只是美丽的分割线]------------------------------------------- 如例子1(通过表设计防止并发导致数据错乱)需求点: 【签到功能】 一天一个用户只能签到一次, 签到成功后用户获取到一个积分 已知表: 用户表,包含积分字段 高并发意淫分析(属于开发前的猜测): 在高并发的情况下,会导致,一个用户签到记录会有多条,后者用户签到后不止加一个积分。 我的设计: 首先更具需求我会添加一张签到记录表, 重点来了 ,这张表需要把用户唯一标识字段(ID,Token)和签到日期字段添加为唯一约束,或者唯一 索引 ,这样就可以 防止并发的时候插入重复用户的签到记录。 然后再程序代码逻辑里,先执行签到数据的添加,添加成功后再进行积分的添加,这样就可以防止重复的添加积分了。 最后我还是建议所有的数据 操作 都写在一个sql事务里面, 这样在添加失败,或者编辑用户积分失败的时候可以回滚数据。
-------------------------------------------[我只是美丽的分割线]------------------------------------------- 如例子2(事务+通过更新锁 防止并发导致数据错乱 或者事物+Update的锁表机制) 需求点: 【抽奖功能】 抽奖一次消耗一个积分 抽奖中奖后编辑剩余奖品总数 剩余奖品总数为0,或者用户积分为0的时候无法进行抽奖 已知表 : 用户表,包含积分字段 &nbp; 奖品表,包含奖品剩余数量字段 高并发意淫分析(属于开发前的猜测): 在高并发的情况下,会导致用户参与抽奖的时候积分被扣除,而奖品实际上已经被抽完了 我的设计: 在事物里,通过WITH (UPDLOCK) 锁住商品表,或者Update 表的编辑时间字段,来把数据行锁住,然后进行商品数量的消耗,和用户积分的消耗,都完成后提交事物,失败就回滚。 这样就可以保证,只有可能存在一个 操作 在 操作 这件商品的数量,只有等到这个 操作 事物提交后,其他的 操作 这个商品行的事物才会继续执行。
-------------------------------------------[我只是美丽的分割线]-------------------------------------------
IT经典笑语录:打,打,打劫。一女黑夜遇抢劫,颤抖曰:“大哥,我是搞java的,两个月没发工资了,还刚被裁员,你看报道就知道了,真的没有钱… …” 劫匪听后竟然痛哭流涕,“妹子,同行,俺原来是做C++的,金融危机闹得做劫匪也 不踏实,你拿好工牌,后面那帮抢劫是做.NET的,你放心,我们绝不抢自己人。” “对了,边上那条路不要走,那边是搞PHP的… …”
如例子3(通过程序代码防止包并发下的数据错乱问题) 需求点: 【缓存数据到cache里】, 当缓存不存在的时候,从数据库中获取并保存在cache里,如果存在从cache里获取,每天10点必须更新一次,其他时间点缓存两个小时更新一次 到10点的时候,凡是打开页面的用户会自动刷新页面 问题点: 这里有个逻辑用户触发缓存的更新,用户刷新页面,当缓存存在的时候,会取到最后一次缓存更新时间,如果当前时间大于十点,并且最后缓存时间是10点前,则会从数据库中重新获取数据保存到cache中。 还有客户端页面会在10点时候用js发起页面的刷新,就是因为有这样的逻辑,导致10点的时候有很多并发请求同时过来,然后就会导致很多的sql查询 操作 ,理想的逻辑是,只有一个请求会去数据库获取,其他都是从缓存中获取数据。(因为这个sql查询很耗服务器性能,所以导致在10点的时候,突然间数据库服务器压力暴增) 解决问题: C#通过 (锁)lock,在从数据读取到缓存的那段代码前面加上锁,这样在并发的情况下只会有一个请求是从数据库里获取数据,其他都是从缓存中获取。-------------------------------------------[我只是美丽的分割线]------------------------------------------- 2,高并发的下的服务器压力均衡,合理站点架设,DB部署 以下我所知道的: 1,服务器代理nginx,做服务器的均衡负载,把压力均衡到多台服务器 2,部署redis服务器,或者mongodb服务器,把一些常用的查询数据,并且不会经常的变化的数据保存到其他nosql DB服务器中,来减少数据库服务器的压力,加快数据的响应速度。 3,前端JS脚本合理控制请求,如,防止用户重复点击导致的ajax多余的请求,等等。 4,在高并发接口的设计中可以使用具有高并发能力的编程语言去开发,如:nodejs 做 web接口 3,并发测试神器推荐: Apache JMeter Microsoft Web Application Stress Tool (如果还有更好的工具求推荐,简单易用)