XDH_LESSON15

互联网线上项目开发最大坑点-并发冲突处理(单线程之路)
有多个用户同时更新或删除数据的 Web 应用程序可能引入一个用户的修改覆盖另一个用户的修改的可能性。当设计这样的应用程序时,选择适当的并发控制技术很重要。

遇到内容比较多的情况下,我们会使用分页比如现在流行的要点击加载更新内容

如果是在移动端,我们采用的是上拉刷新和下拉刷新,比如手机微博

分页功能由来已久,我们现在来看下常见的分页有什么问题呢?

大家看下我展示的这个项目是用thinkPHP来编写的。很多流行的框架和开源项目都对分页做了支持,那么大家来看我演示一个案例。

看到的现在的第一页是最新的新闻,如果我点击下一页,相对来说是老一点的新闻。

这个时候我们来做一件事情,我们新打开一个浏览器窗口,刚刚的分页页面不要关闭,我们在后台里面再发布5篇新闻,

假设我们在后台发布新闻的同时,用户还在浏览第二页,当发布完毕以后,用户又点了下一页,我们观察到了奇特的现象

我们看到第3页和刚刚看到的第二页完全一样,原本用户点下一页希望看到再早一些的新闻,结果看到了一样的数据,是我们的分页程序出问题了吗?非也。

当我们再点下一页,程序又正常工作了。刚刚出现的奇怪的那一幕,其实就是由于并发产生的冲突。

在什么地方我们做了并发操作了呢?其实就是在一个用户浏览页面的同时,还有人在往数据库里面写入数据。你会发现thinkPHP这样的框架,还是PHPCMS这样的开源系统,他们都存在这样的bug。

并发产生的问题,往往难以捕捉,更难以重现,而我们准备的这个案例,算是并发案例冲突中相对容易重新的典型案例

我们如果调整一下刚刚操作的顺序,我们会得到一些其他的结果。

比如说:我们分页条目数是每页5条,在用户浏览某一页的时候,后台管理员发布了新的新闻,新闻的数量小于5条的情况下,我们点下一页,会看到有几条重复的新闻,也有更早的新闻

这样影响用户体验,但毕竟我们点一下一的页时候内容还是能接的上的,用户浏览某一页的时候,后台发布的新闻数量大于分页条目数(5条)

那么再点击下一页,其中会有若干条新闻被跳过去了,无论用户点多少次下一页,都看不到那些条目,这种产生的并发冲突后果是很严重的,而且普遍存在。

那么再点击下一页,其中会有若干条新闻被跳过去了,无论用户点多少次下一页,都看不到那些条目,这种产生的并发冲突后果是很严重的,而且普遍存在。

他具有很好的隐蔽性,在过去很多年几乎不被察觉

在大门户网站时代,网站编辑并不会频繁的发布新闻,而用户也很少守着新闻列表去逐篇阅读,然而在微博诞生以后,这种问题就暴露出来了。

由于社区类应用信息的产生室友用户产生的,不在是靠编辑在后台发布的,就好像微博,每时每分秒,都有很多用户分享心得内容

这样一来你在查看微博列表的同时,内容就已经更新 了 很多,而且很多人打发无聊的时间,很多人也会去逐一查看,不停的上划,把所有遗漏的条目全部看一遍

这是如果项目设计不合理,产生并发事故,就会对用户体验造成极大的影响。

抢购与秒杀抽奖等应用的时候,并发将导致更多的问题。通常比较容易出现的bug有实际商品的订单量大于库存量。

也就是说,商品实际销售量大于活动的商品数量,这样会导致公司的亏损。

有些公司为了解决这个问题,采用了一种思路,虽说4个人同时操作,但是交易成功的这次网络请求到达服务器的时间总会有个先后顺序

那么可以将订单支付成功之后的库存减一之后的值也随订单保存,如果这个值小于0,就证明有用户购买了产品,已经是卖完的,于是标记订单失败。

这样看上去避免公司造成额外的损失,但却会给用户带来极大的不满,是一种极差的用户体验。它并没有真正的解决我们的问题。

当然还有些公司解决方案也不高明,我们知道无论是数据库还是文件都可以给他加锁,在很早期的程序设计和软件开发里面,锁是解决并发问题的万能灵药。

无论是c++,或java,提到多进程或多线程的时候,往往也会提到锁这个字。那么作为最早期的通用解决方案,用到秒杀方案是否合适呢?

我们来看一下加锁后的工作流程:还是ABCD 4个用户同时秒杀,他们都去查询库存。当某一个用户,比如A的请求,优先到达时,我们就将数据表锁住,不让其他的数据库连接来动这张表,待用户A完成购买流程,将库存量减一后,把锁打开,其他的连接才可以再次操作这张表。

如此一来,可以保障一个用户查看库存以及库存减一这段时间内,不可能还有其他用户可以对表做出修改,这一并发冲突的问题就没有了。不过这样的做法真的合适吗?

要知道ABCD 4个用户都是在同一时间段去秒杀的,由于A用户在操作中锁表,导致其他用户只能等待,而且A完成整个业务需要消耗一段时间,只能等A完成以后其他用户才能操作

这样一来单位时间内的业务处理量会大幅降低,我们所看到的现象就是网站卡死,或者服务器宕机

关于并发性能如何设计,我们可能需要单独的一次或几次课来为大家讲解。不过锁这种很原始的并发冲突解决方案,我们可以看到他并不适合互联网项目。

之所以大家会有并发冲突的程序,是因为大部分程序员,思维模式都是线性的。

作为程序逻辑思维来讲,线性思维是没有错的,因为计算机执行指令的时候本身就是线性的。然而如果把业务也看做是线性的,就会产生问题了。

任何一个程序操作,他都会消耗一定的时间,即便你的CPU速度再快,也只是缩短了这个时间范围而已,..

如果只有一个用户操作,比如我们在后台发布文章,看自己发布的新闻,我们是无法感知并发带来的冲突的。这就对我们的程序员提出了更高的要求。

理论上来讲,所有跨越时间段的操作过程中如果涉及到数据修改就会有可能产生并发冲突,因此我们在设计程序的时候,要保障应用程序的质量,就需要去做并发冲突处理,只是实现业务需求与实现业务的同时做好质量需求,就是好程序员与坏程序员的差别。

那么分析了产生并发冲突的原因以后,就比较容易思考解决方案了。大体的思路有两种:一种是将并发操作变为单线操作,另一种是让所有跨越时间的段的操作不去更改数据。

我们现在来看一下分页,或者上拉或者下拉刷新的解决方法。我们刚刚提出的2种的解决思路,哪一种比较合适呢?对于发布数据和浏览数据,比如微博,我们有可能把这种并发操作变为单线操作吗?好像不太容易。

那么我们能够走得路就剩下第二条,也就是跨时间段的过程中不要改变数据,我们刚刚产生的bug到底是什么数据改变导致了bug。回顾下我们的代码实现的本质,就容易找到其中的缘由了。

通常我们在实现分页的时候,首页看到的是最新的数据,那么从数据库中取数据的sel语句是select * from news order by desc limt 0,10,这样取到最新的数据,如果点击下一页,查询语句不变,只是分页条目不在是第0-9,而是第10-19条,如果在这个过程中有新的数据插入,我们会发现有一个东西变了,就是原有数据在数据库的排序序号变了,如果我新发布一条数据,原来的第一条最新的新闻就会变成第二条,原来的第10条会变成第11条。这就是一个时间段内的操作过程中有数据发生了改变。

既然我们无法把这样的并发操作变成单线操作,我们可以选择不让数据发生改变,这样并发bug就可以得到很好的解决了。

需要了解详细解决方案的,我会把无bug程序实例分享给大家。课后可以联系赫赫要资料,或者是听我们的视屏直播课,陈老师有详细的解决。

跨时间段的让数据不改变不好走,那我们可以选择第一种思路,让并发操作变为单线操作,之前提到的加锁是解决方案之一,但是对用户体验不好性能很差,基本上无法再互联网项目中使用。如果不能加锁,那么常用的解决方案是什么?

我们可以用队列。如果我们将所有的用户请求进行排队,有一个服务来订阅这个队列,那么不管有多少用户访问,最终到服务器端,处理服务的就只有一个进程。这样就实现了一个由并发操作转换成单线操作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,248评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,681评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,443评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,475评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,458评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,185评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,451评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,112评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,609评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,083评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,163评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,803评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,357评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,357评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,590评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,636评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,925评论 2 344

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,527评论 25 707
  • 一辈子很短,所以要及时行乐,别委屈自己,别用所谓的道德绑架自己,开不开心只有自己知道,自私一点也没关系的 一辈子很...
    zZZ悦悦悦悦悦阅读 803评论 0 0
  • 我是这个社会的18线演员,我不想任何的姿态去挑衅这个世界,我更不敢与时间作对,我也不敢安排别人的生活,甚至是自己的...
    畅歌阅读 250评论 2 2
  • 叉子: 使用不锋利的叉子,增加进食难度。 小碟&小碗: 每个装的东西都不多。 勺子: 这种勺子,汤是喝不成了,其他...
    扶绫阅读 166评论 0 0
  • 家里面有这些人,爷爷,奶奶,爸爸,妈妈,哥哥,我。我曾经这样想过,如果以后爷爷去世了,我一定不怕他的鬼魂还是啥,如...
    一无所有则无所不能LLL阅读 304评论 1 1