转自:

本文如有不对之处,欢迎各位拍砖扶正。另源码在文章最下面,大家下载过后先还原一下nuget包,需要改一下redis的配置,rabbitmq的配置以及Ef的连接字符串。另外使用的是CodeFirst,先update-database生成数据库后再进行操作

高并发

高并发一直是网站上线后会遇到的一个严峻的考验,渡过了一切都好,渡不过就是宕机。

在电商时代如此发达的今天,高并发无此不在双十一 、618、双十二,还有雷猴王的某米手机抢购。首先我们要分析高并发究竟会给我们开发者带来什么样的挑战

大量的请求,如果仅仅只有一台服务器肯定是吃不消的,通常一些公司都是一台服务器上部署了很多个网站也充当了数据库服务器、redis服务器。如果要应用高并发没有足够的硬件支持是不行的。我们需要进行 分布式集群 以及 负载均衡

硬件支持有了过后,我们就需要下一步的分析

这时我们还需要提高网站的吞吐量,怎么提高呢?首先我们需要针对IO密集型异步化操作,抢单的页面不只是有抢单按钮,还有商品的介绍,图片,文字描述等。对于这些数据我们要进行缓存,一万个用户一万次请求都从数据库中取数据与只取一次剩下9999次从缓存中取效率自然是不一样的

上面说的都是为了解决一个  字,而并发才是我们真正需要准备的,假如两个用户同时请求,这时库存还有1,程序里先判断库存是不是1,现在都符合条件,然后进行生成订单等操作。就发生了资源共享的问题,明明只有一个订单,但是两个用户都完成了订单,那么这个商品应该给谁呢?

并发

假设现在是一个电商网站,今天要举办活动,有10个商品低价销售,但是会来抢购的人会特别多,最后只有十个人可以成功的买到商品

假设的逻辑,我们用户进行了请求,我们把他们的信息放到库里,但是只有前十个人是可以购买商品的,因为库存只有10个

也许我们可以用锁来解决并发的问题,但是锁无疑带来的是效率的低下,用户体验也极低。我们想要的是快速返回,但是后面那一堆的逻辑怎么办呢?我们可以使用RabbitMq队列,用户的请求到达了抢单接口,我们只向队列中丢一条数据后就立即返回

这时又来了一个问题,会有同一个用户多次进行请求的情况,如果像之前的逻辑,前10条信息有二条是属于一个人的呢,(这里假设每个人只可以购买一次)我们就需要进行判断了,同一个账户发送的多次请求,我们只认为第一次请求是有效的,剩下的都请都直接返回。因为是并发,我们又怎么做到第一次请求有效呢?这时我们可以使用Redis incr存储用户的标识,Redis是单线程的,不存在并发的问题。incr返回为1那么是第一次请求,为N则是第N请求那么它就是无效的。这是请求标识

请求标识我们可以在抢单接口就进行判断,也就是先拿用户的标识去Incr,返回为1则丢到队列,不为1则不丢到队列。

也可以在rabbitmq的消费端进行处理,从rabbitmq消息队列中拿到用户信息后,进行incr。再进行下一步操作

丢到了消息队列中,我们还需要去处理,consumer我们肯定是要有多个的,我们可以使用平分分发手动交付。在这里我们把用户的信息进行入库,当然入库后我们再向Redis中存入一条入库标识

上面都是在后端,客户端这里点击了抢单按钮后可以立即导向排队界面(是不是很熟悉,某米。。。)在这个界面进行轮询五秒一次,判断当前用户在库中的位置,如果是前十,那么就进行订单操作,不是。。。那就再等,看看会不会有其他用户放弃购买资格。

其实讲到这里,已经差不多了,成功的把并行变成了串行。剩下的就是业务处理,怎么做都可以。其实对于并发还可以有其它的处理方式,比如乐观锁也可以有效的控制并发,可以看我的相关文章,其中就有关于乐观锁的实现

.Net高并发解决思路的更多相关文章

  1. java高并发解决思路

    一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构.性能的要求都很简单,随着互联网业务的不断丰富,网站 ...

  2. .Net高并发解决思路(附源码)

    本文如有不对之处,欢迎各位拍砖扶正.另源码在文章最下面,大家下载过后先还原一下nuget包,需要改一下redis的配置,rabbitmq的配置以及Ef的连接字符串.另外使用的是CodeFirst,先u ...

  3. 每一个程序员都应该知道的高并发处理技巧、创业公司如何解决高并发问题、互联网高并发问题解决思路、caoz大神多年经验总结分享

    本文来源于caoz梦呓公众号高并发专辑,以图形化.松耦合的方式,对互联网高并发问题做了详细解读与分析,"技术在短期内被高估,而在长期中又被低估",而不同的场景和人员成本又导致了巨头 ...

  4. 关于php 高并发解决的一点思路

    涉及抢购.秒杀.抽奖.抢票等活动时,为了避免超卖,那么库存数量是有限的,但是如果同时下单人数超过了库存数量,就会导致商品超卖问题.那么我们怎么来解决这个问题呢,我的思路如下(伪代码): sql1:查询 ...

  5. SSM(Spring+SpringMVC+MyBatis)高并发优化思路

    SSM(Spring+SpringMVC+MyBatis)框架集由Spring.MyBatis两个开源框架整合而成(SpringMVC是Spring中的部分内容).常作为数据源较简单的web项目的框架 ...

  6. php 处理高并发的思路

    1.nginx 服务器,提高网站服务器并发性能 2.控制大文件的下载,减少CPU的消耗. 3.对于sql查询做缓存. 4.静态页面文件缓存. 5.CND缓存静态文件, 6.反向代理到多个服务器,用来分 ...

  7. SpringCloud应对高并发的思路

    一.Eureka的高可用性 Eureka下面的服务实例默认每隔30秒会发送一个HTTP心跳给Eureka,来告诉Eureka服务还活着,每个服务实例每隔30秒也会通过HTTP请求向Eureka获取服务 ...

  8. Nginx高并发配置思路(轻松应对1万并发量)

    测试机器为腾讯云服务器1核1G内存,swap分区2G,停用除SSH外的所有服务,仅保留nginx,优化思路主要包括两个层面:系统层面+nginx层面. 一.系统层面 1.调整同时打开文件数量 ulim ...

  9. Mysql的锁机制与PHP文件锁处理高并发简单思路

    以购买商品举例: ① 从数据库获取库存的数量. ② 检查一下库存的数量是否充足. ③ 库存的数量减去买家购买的数量(以每个用户购买一个为例). ④ 最后完成购买. 仅仅这几行逻辑代码在并发的情况下会出 ...

随机推荐

  1. linux出现Redirecting to /bin/systemctl start mysqld.service,解决方法

    上去就是一个命令     /bin/systemctl start httpd.service

  2. HttpClient两种调用方式

    一.参数字符串 /** * HttpClient请求接口 * @return 成功:音频字节 失败:null */ public static byte[] requestBaiduAudio(Str ...

  3. 3709: [PA2014]Bohater

    3709: [PA2014]Bohater 或者:Bohater 题解 好狠啊这个题 z 要开 long long ,可能算掉血回血的时候会爆 long long 吧 首先把能回血的怪打死(不然你后面 ...

  4. OpenStack 高性能虚拟机之大页内存

    目录 文章目录 目录 前文列表 虚拟存储器系统 页式虚拟存储器 大页内存 Linux 的大页内存 大页的实现原理 大页内存配置 透明巨型页 THP 大页面对内存的影响 Nova 虚拟机的大页内存设置 ...

  5. Python 安装 for Linux

    make后报错: Failed to build these modules:_multiprocessing   binascii           zlib 下载http://www.zlib. ...

  6. Python——GUI编程 利息计算器 作业9(python programming)

    import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class ...

  7. 安装好oracle11gR2之后在相应路径下却没有生成tnsnames.ora和listener.ora

    oracle安装帖子:https://blog.csdn.net/wjb123sw99/article/details/80780277 oracle安装过程中检查失败:需开启C盘共享,或者勾选忽略, ...

  8. JobHandle和依赖项

    要当您调用作业的Schedule方法时,它将返回JobHandle.您可以在代码中使用一个JobHandle作为其他作业的依赖项.如果作业取决于另一个作业的结果,您可以将第一个作业JobHandle作 ...

  9. python基础之元祖tuple

    元祖是只读列表,不可哈希,可循环查询,可切片*儿子不能改,孙子可更改--元祖里面单个元素不能更改---元祖内列表可更改增:tu1+tu2查:tu1[index] tu1[start_index:end ...

  10. "a++" 与 "++a" 的区别-演示

    两种表示方法经常容易混淆, 在这里将利用演示程序来揭示两者之间的区别, 演示代码如下 int main() { ; cout << "a=1 " << &q ...