并发环境下 怎么解决并发问题银行存款问题

主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件。而上帝在努力创造出更大更傻的傻瓜。目前为止,上帝是赢的。个人网站:。个人QQ群:、
CSDN &《程序员》编辑/记者,我的邮箱
全栈攻城狮不知道是怎么炼成的
人生得意须尽欢,莫使金樽空对月。
声明:本文内容来自于TOP100Summit旗下技术沙龙品牌into100沙龙第17期:,如需转载请联系主办方msup进行授权。
嘉宾:刘国强,云智慧技术中心副总裁。拥有超过18年的IT行业研发、IT管理、服务器和桌面虚拟架构、数据库和云计算、企业级方案的经验。历任CA大中华区CTO、售前技术总监。Citrix中国区首席专家顾问,虚拟化系统工程师。
责编:钱曙光,关注架构和算法领域,寻求报道或者投稿请发邮件,另有「CSDN 高级架构师群」,内有诸多知名互联网公司的大牛架构师,欢迎架构师加微信qshuguang2008申请入群,备注姓名+公司+职位。
互联网时代的倒逼现在我们处于一个互联网的时代。现在所有的日常的衣食住行都依赖于软件,大家可以想想,从出门到工作到日常购物,你基本上不用出门:你可以订快餐给你送上门;买东西可以通过京东给你送上门;你要买东西,比如说买玩具在网上买,第二天就送到了;我订机票也是通过网络来定;我去旅游也是通过网上来订。这个时候软件应用度越来越高,软件的价值也越来越大。在这样的情况下,我们的企业包括我们的从业人员如何应对呢?这是一些简单的数字分享。移动支付,我昨天专门查了一下,5108亿这是2015年第二季度的数字。那么软件的可靠性、可用性、性能就变得非常重要。在这样的大背景之下,其实软件的发布速度是快的令人惊讶,我们做了一个调查。94%的应用程序发布的速度前所未有的快。大家简单来看,以我们自己为例,我们的产品是SaaS产品,我们的产品每周都会发布新的版本。在这样的情况下,我们做商业化,基本上互联网产品是按周去发布的,其他的App也是,更新速度非常快。在这样的情况下,因为你的版本更新速度非常快,用户是不是就可以容忍你的系统崩溃呢?是不是你的应用速度很慢,用户也会体谅你也觉得你挺好?其实用户对软件的要求没有降低,这就要求我们必须得快还不能提供差的服务。如果说你的应用程序延迟超过3秒,25%的用户就会离你而去。大家可以想想你平时写的程序是不是超过3秒,如果说超过的话大家最好想办法进行修改。高并发关键点在这样的大背景下如何做到高并发?其实我总结了一下,高并发的关键点在哪里?平时我们都做压力测试,各位有很多做高并发的经验,这种压力测试的关键点很多是以内部测试为主,在试验里去压测。但是有几个问题没有注意到:
你是不是真实的生产环境,是否测试到应用外网带宽;
是否测试到CDN,CDN有没有发挥作用;
不知道防火墙是不是配置得当;
负载均衡器是不是配置合理;
不要在「温室」里做压测大家觉得这些事情压力测试都可以做到,其实未必,现在的压测更多是在一个「温室」的环境,是一个「温室」的高并发。一开始我叫「实验室」高并发,我觉得「实验室」这个词不足以引起重视,因此我用了「温室」这个词。大家知道温室的花朵出了温室很可能就活不下来了,压力测试也是如此,如果说你的测试是在温室的话,你出事的概率就非常高。那么在温室和真实环境到底有什么差异?左边是真实的情况,我们希望做以下几个方面。
真实、准确有弹性。你要确保你的用户是真实发起的用户;
网络是用户真正的网络;
能不能准确定位问题;
线上性能实时检测;
随时随地发起;
这就是我们不要做「温室」的高并发。其实我们做高并发我们建议做到几点:
速度。你必须要考虑到你的速度,要能很快的去做,而不是说我要去申请,要预算,找领导去批复,可能是用了三个月。我们希望可以做到随时随地,或者是三个小时,或者是一天就可以发起。这是速度。
规模。你可以想像一下,你是300万并发可能需要上千台的服务器,这个服务器是自己购买还是怎么做。现在比较好的是可以利用云资源。
高性价比。如果说你的成本非常高,公司可能就不会做了,领导会有非常大的顾虑。如果说你可以做到速度、规模和高性价比,那么你就成功了。
如何设计压测方案1. 做并发要找到合适的交易,你不要去编写程序,最好的方法是直接录制交易。比如说我们最近做的一个案例。用户就用手机端,用户操作一遍,后我们把它录下来。录下来之后我把它变成数据,这样就变得很简单,你只需要录制就可以,不需要自己写程序。2. 定义测试任务,我什么时候发起,我发起的策略是什么?比如说我刚刚发起是300并发,什么时候加到500,什么时候加到1000,什么时候加到2000或者是3000。因此你要设置压力曲线,你要做一个压力曲线设置,在什么时间点上加,能不能加到你想要的高度。我们不希望写一个脚本写了三五天时间,这个效率就太低了。最好是操作一遍录下来,然后准备数据,准备数据是需要时间的,这个要看你准备的时间。3. 选择你的压测点。以前做法效率是很低的,那么能不能做到我就选阿里的,从华北、华东、华南三个地方发起。4. 压力测试之后,随时随地查看。我们建议的做法是什么呢?压测同时直接看当时的曲线数据情况。你实时加压,实时看数据情况。看你发的多少数据,接收了多少数据,有多少的请求发起,你的数据库的状态如何,有没有错误,错误率是多少等等这些都要在你实时监测的页面可以看到,进行实时的数据分析。5. 需要实时的监控大屏,尤其是电商的大促,不仅是监控交易量,你还要关注交易量背后资源的消耗量。这个实时监控的大屏大家看几个数字:1)总事务数;2)每分钟的事务数;3)成功/失败的事务数;4)错误的事务数;5)发送/接收的流量;6)当时的虚拟用户数。业务系统拓扑接下来是业务系统拓扑。我们一方面希望看到高并发,另一方面发起高并发之后我们应用程序内部的架构情况。大家可以想像一下。现在用java写,或者是用JS写,都是要用程序写,写出来之后,你一般看到的是使用资源的消耗量,那么你能不能知道你现在系统的整体的动态的应用拓扑架构。你要看到动态架构的实时生成,我们压测的同时,业务系统的拓扑可以呈现出来。业务系统的拓扑我们在图上用各种颜色标注这个机器或者是系统的负载是什么样的。绿色的代表他上面的所有业务请求都在500毫秒以内,这个机器的负载是可以的。如果说是黄色的,这个机器的负载在500到2000毫秒之间。而如果说是红色的,则是大于2秒的。接下来我们看一下应用请求概览,这是一个手机银行的例子。我们看到他正常的是多少,缓慢的是多少,非常慢的是多少。我们看到缓慢的事务分析。这个图有三个维度:第一个维度是底下的时间,整个高并发发起的时间点,比如说早上8点到中午12点。最左边是响应时间,最右边是并发的次数。这个请求次数是多少,响应时间多少,在什么时间点发起。你也知道在高并发起来的时候会不会有突然的发起下降。你通过黄色和绿色的柱状图可以看到每一个请求的时间点。我同时会列出每一个缓慢请求的拓扑图。告诉你,你现在压侧的每一个请求的情况,比如说可能是5秒,在这个5秒的时间里,到底这个请求是怎么走的,我会把拓扑图画出来。我们可以看到系统后端事务的追踪。同时我们可以发起深入代码级的问题诊断。如果说你的速度非常慢,我们会提供代码级的性能优化参考。这是应用请求拓扑。代码的详细诊断。我们可以看到整个代码的详情,到每一个请求的参数,他的SQL语句。前端有高并发,后端有应用数据的抓取。这是数据库的,如果说你有大量的数据库,如何进行所有数据库的SQL分析,应用的SQL响应时间我们会在这里列出。同时如果一般做压力测试的,如果系统出现崩溃或者是异常,大多数人是看日志,及时也可以从另外一个角度去看到底有没有错误信息,你在高并发过程当中,所有应用程序内部有没有出错,有多少次,什么样的错误,我们会把这些错误记录下来,你可以查看你的错误列表。后面同时还有一个异常的列表。大家写程序的人都知道,你有一个请求,后面可能会有异常处理。那么这个异常是什么在什么时候,什么时间点发生的,可以通过程序来发起抓取。后台主机的性能也是一样的,包括主机的列表,监控、服务的列表。然后是JVM性能分析报告你可以看到JVM线程,JVM内存使用统计,包括GC垃圾回收统计。真实压测案例看300VU-3000VU我前面讲了两个部分。接下来我们举一个案例,一个测试场景。这个测试场景我们是从300并发开始,基本上每隔5分钟左右加一次,加到500,加到1000最后是加到3000并发。我们看到左边是用户数,上面是用户所有请求平均响应时间,随着虚拟用户数增加,响应时间会增加。到3000并发的时候变成了427毫秒,服务器处理能力一直没有太大变化,带宽也变化不大;到两三千并发的时候有一些错误。简单来看,服务器的处理能力不够了,他就能处理这么多,你增加的再多,只是增加了响应的时间。这是我们的一个总体的结论。那么我们详细分析一下这个测试场景下我们分析的问题。我们分析下来,首先是响应时间过长的请求,我们看到响应时间过长的超过了3秒。第二个结论是什么呢?我们发现在这个请求过程当中有一些重复请求。就是一模一样的事情重复了两次,我们看到这当中有两次,我们用红色标注出来。有一个是四次,这是消耗的带宽,拉长了你的响应时间,影响了性能。我们把所有的事务列了出来,这是每一个事务的响应时间,我们做了两个端,一个是IOS,一个是安卓,我们模拟两种App同时做起并发。我们可以看到300、500、、3000一直到4000的并发情况。第一个是打开App,你会发现时间逐步增加,从毫秒。第二个是登陆系统,我们可以看到从2000毫秒一直到13秒,这个差异是非常大的。我们再看一看分指标的解读。在300并发的情况下,当时我们在执行到两分钟的时候截了一张图。错误数为0,然后是消耗带宽的情况,服务器处理能力每分钟2400笔。我们再看一下300并发的平均时间,我们是从北京和广州两个地方发起的。我们看到北京和广州稍微有一些差异,一个绿色,一个蓝色,北京的响应时间比较长,广州的响应时间比较短。我们看到虚拟用户数和平均相应时间的关系。第三个是和错误的关系,和带宽的关系。我们再看300并发的情况下,我所有的交易请求的情况。这当中我标了一个数字,就是90%,我压到300并发,90%的情况下,交易时间响应是多少。简单来看打开IOS的时间这里面是2s,在90%的时间,在300并发的情况下,打开时间是2s。我们再看一下500并发,500并发的时候,服务器的处理能力没有太大的变化,就是每秒2400笔,变化不大,出现了错误,我们看到总共发的请求带宽消耗。这张图可以看到300和500并发的关系,先看最左边的图,蓝色和绿色就是300和500并发下两个地方的差异。再看并发数的响应时间对应关系,你会发现在300并发的时候,响应时间是非常快的,但是到500的时候,突然响应时间就上去了,机器的负载响应的比较慢。我们看到响应时间500并发的时候达到3秒左右了,刚刚是2秒。带宽上有所增加,但是没有太大的本质上的变化。而在1000并发的时候,有发生了巨大的变化,错误数达到了15个,服务器的处理能力还是2400笔左右,没有太大变化。我测过几个不同的案例,有的用户是带宽不够,有的用户是机器的负载不够,有的用户是负载均衡器不行,他经常是一个机器响应,其他的机器没有响应。我们发现从300到500到1000,响应时间不断地增加。这表明要么是程序算法有问题,要么是服务器负载出现了状况。我们来看1000并发,从300到500到1000响应时间突然就上去了,变化很大。这是1000并发下到了5秒,刚刚是2秒、3秒,现在是5秒,带宽和刚刚没有太大变化。再看2000并发的情况。响应时间发生变化,错误数达到20个,服务器处理能力还是每秒2400笔左右,平均请求响应时间达到了250毫秒。我们看到响应时间增加,错误数增加。到2000并发时响应时间达到了6秒,带宽为30M,稍微增加了一些。到3000并发时,我们发现服务器处理能力变化不大,带宽消耗基本上还是在30M左右,带宽变化不大。响应时间变成7秒,所以你会发现,响应时间不断地增加。我们看到、3000并发时带宽都是30M,错误数达到了20个。压测后的分析简单来说这是一个场景,我简单分析一下这个场景发现的问题:
在混合场景当中出现了重复和多余的请求。有一些请求,用户一看这个请求不应该发生的,不应该有这样的请求在这个时候发生,这个请求是多余和重复的;
随着用户数增加,平均响应时间增加,服务器的负载没有增加,等待时间增加;
当时我们只是进行了一个普通的监控,看了CPU和内存的情况,当时没有做服务器里面细致的检控,我们建议应该有更多的后端代码的监控;
服务器配置有问题,要验证一下负载均衡器是不是有合理的转化。另外我们也建议做常态化测试,就是定期的,每个月或者是每周做一个常规的测试,而不是很长时间做一次。
我们发现活动首页有问题,缓存比较少,这是一个问题。
这是我给大家分享的内容。我简单汇总一下:第一、高并发不要做温室的发起;第二、在发起同时要看到当时代码的情况,SQL的执行情况;第三、整个压测的过程和解决问题的方法论。编辑推荐:架构技术实践系列文章(部分):如何在高并发环境下设计出无锁的数据库操作_百度知道
如何在高并发环境下设计出无锁的数据库操作
提问者采纳
所以必须启动一个线程去更新缓存。 最后,原理就是启动一个线程:public TableCache{  private HashMap&lt。那数据库操作怎么办,首先判断一级缓存:private static final ExecutorService EXECUTOR = Executors,所以直接操作二级缓存;即可保证无锁又全局唯一自增。有点像CPU了对不,我稍微改下数据库架构。当发生数据库变动?增加缓存,没有写操作,那么这个行为是不需要加锁的. 并发中如何无锁,得到了旧的数据,采用类似的思路?使用private final static AtomicLong _seq = new AtomicLong(0),但是可以被并发。但是”大循环“却不能直接操作这个缓存进行修改.execute(new LatencyProcessor(logs)),如何保证无锁呢,然后一个个顺序执行,必然整个处理都会放慢。这个架构就保证了内存数据的绝对准确。这样保证了“大循环”中不涉及到IO操作。 问题再次出现, Object&gt。  }}OK。结合这2个特点,必然会存在一个根据时间排序。至于写,保证了在并发的环境下能够准确的操作缓存,需要插库的数据可能很多,修正后删除一级缓存,分2种情况:如果我们的游戏只有个大循环还容易解决。但是实际上的游戏环境是并发和“大循环”并存的。我使用这个技巧、更新操作;();&#47. 既然我们要对操作排序, Object&gt,我们可以删除一些无效操作,把操作提交给一个Queue一个在线2k的游戏,性能强大,即上文的2种环境,去实现我们任意的业务逻辑。一旦并发转成单线程,把操作交给线程处理,直接从内存读取,我们原来的系统就有了2个环境?一级缓存只能被”大循环“修改。但是又有个问题出现了。2. 并发与“大循环”如何共处。采用了异步,如果只有读操作,任何并发都会变成了单线程操作,每秒钟并发都吓死人,那么就用“异步”,就被其他请求再次获取。”大循环“环境是我们使用Disruptor开辟出来的单线程无锁环境、”大循环“同时获取,消除锁,任务压入Queue。1,无论在哪个环境下读取数据; caches = new ConcurrentHashMap&lt,再加一层缓存;String。这个思路很简单。传统的hibernate直接插库基本上是不可行的。例如,必然会存在着锁,取最后一次,看起来很漂亮。如果用java的concurrentCollection类去做,作为时间序列;class LatencyProcessor implements Runnable{  public void run()  {     &#47,然后交给异步修正二级缓存,在缓存的上层。一个很简单的思路. 既然我们的数据库操作已经被异步处理,而且速度非常快,并发的时候。 2; 这里可以任意的去修改内存数据;String, 或者比较普通的ARPG服务端都是这个设计,原来的就自然成为”二级缓存“,通过对表,把并发转化成为单线程,没有问题。 在这个设计模式下,然后单独跑一个Thread去一个个获取插库?我们知道,那么某个时间,首先我们把变动数据存储在一级缓存,因为里面提供了完美的同步无锁,例如。所以在单线程中的任何操作绝对不能涉及到IO处理。Java的Disruptor就是一个很好的例子,非常有可能缓存还没有被更新,“大循环”架构,所以是不需要锁的,必然会快:并发环境 + ”大循环“环境并发环境就是我们传统的有锁环境:1)并发环境下的数据库变动,还有一些小技巧提升性能、操作类型的排序.js,跑一个Queue,必然会发现在缓存这块上要出现锁。这样,性能低下,线程轮训读取这个Queue。原本的缓存层。而且重要的是.newSingleThreadExecutor(),成为”一级缓存“,没有再判断二级缓存,我们是允许有锁的存在。 4。现在的node。那么无论我们怎么设计;}这个结构是必然的了。2)”大循环“环境下数据库变动。 3. 如何保证并发环境下缓存数据的唯一正确?我们知道如果在“大循环”中要避免锁操作、主键,只要出现Delete,例如。这样。在高速存取的过程中. ”大循环“环境 中如何提升处理性能。 1;EXECUTOR,前面所有操作无效。我就一步步推导出一个无锁的数据库操作:a)同一个表同一个主键的多次UPdate,那么其中一个线程一旦出现性能问题。b)同一个表同一个主键:我们有了一个高效的无锁空间
网络工程师
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁并发环境下GIS开发_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
并发环境下GIS开发
上传于||文档简介
&&并​发​环​境​下​G​I​S​开​发​框​架​设​计​等
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
下载文档到电脑,查找使用更方便
还剩29页未读,继续阅读
你可能喜欢【图文】数据库并发控制软件设计案例_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
数据库并发控制软件设计案例
上传于||暂无简介
大小:808.00KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢如何在高并发环境下设计出无锁的数据库操作_百度知道
如何在高并发环境下设计出无锁的数据库操作
提问者采纳
前面所有操作无效。b)同一个表同一个主键. 并发与“大循环”如何共处;即可保证无锁又全局唯一自增。但是”大循环“却不能直接操作这个缓存进行修改,在缓存的上层,即上文的2种环境;EXECUTOR。一个很简单的思路?使用private final static AtomicLong _seq = new AtomicLong(0),那么就用“异步”:public TableCache{  private HashMap caches = new ConcurrentHashMap()。这样保证了“大循环”中不涉及到IO操作,把操作提交给一个Queue,首先我们把变动数据存储在一级缓存,跑一个Queue。2)”大循环“环境下数据库变动,消除锁,没有写操作。 2一个在线2k的游戏,采用类似的思路。如果用java的concurrentCollection类去做。那么无论我们怎么设计,任何并发都会变成了单线程操作。但是实际上的游戏环境是并发和“大循环”并存的,我们原来的系统就有了2个环境。这个架构就保证了内存数据的绝对准确. 如何保证并发环境下缓存数据的唯一正确,如何保证无锁呢,非常有可能缓存还没有被更新. 并发中如何无锁。那数据库操作怎么办,性能低下,只要出现Delete. 既然我们的数据库操作已经被异步处理,把操作交给线程处理,并发的时候,然后交给异步修正二级缓存,保证了在并发的环境下能够准确的操作缓存?增加缓存,如果只有读操作,任务压入Q 这里可以任意的去修改内存数据。例如、”大循环“同时获取:如果我们的游戏只有个大循环还容易解决,分2种情况. 既然我们要对操作排序。在高速存取的过程中。所以在单线程中的任何操作绝对不能涉及到IO处理,“大循环”架构,没有问题,那么某个时间,没有再判断二级缓存。一旦并发转成单线程。这个思路很简单;class LatencyProcessor implements Runnable{  public void run()  {     &#47,线程轮训读取这个Queue。有点像CPU了对不,例如。至于写?我们知道。但是又有个问题出现了。传统的hibernate直接插库基本上是不可行的,原来的就自然成为”二级缓存“,通过对表。 在这个设计模式下,就被其他请求再次获取,看起来很漂亮,例如,我们是允许有锁的存在,而且速度非常快,所以是不需要锁的,需要插库的数据可能很多。当发生数据库变动。这样,我稍微改下数据库架构,作为时间序列,首先判断一级缓存。 问题再次出现。 4。现在的node. ”大循环“环境 中如何提升处理性能,因为里面提供了完美的同步无锁:并发环境 + ”大循环“环境并发环境就是我们传统的有锁环境.js.execute(new LatencyProcessor(logs)),我们可以删除一些无效操作,修正后删除一级缓存;&#47:private static final ExecutorService EXECUTOR = Executors, 或者比较普通的ARPG服务端都是这个设计。1,成为”一级缓存“,取最后一次,所以必须启动一个线程去更新缓存;}这个结构是必然的了。我使用这个技巧,必然会存在着锁。这样、操作类型的排序。”大循环“环境是我们使用Disruptor开辟出来的单线程无锁环境。我就一步步推导出一个无锁的数据库操作。而且重要的是,原理就是启动一个线程,还有一些小技巧提升性能,必然整个处理都会放慢,所以直接操作二级缓存.newSingleThreadExecutor(),必然会存在一个根据时间排序?一级缓存只能被”大循环“修改,直接从内存读取,再加一层缓存,必然会快,去实现我们任意的业务逻辑。 1,然后单独跑一个Thread去一个个获取插库,必然会发现在缓存这块上要出现锁,每秒钟并发都吓死人,得到了旧的数据,然后一个个顺序执行、更新操作:1)并发环境下的数据库变动。采用了异步。2,把并发转化成为单线程、主键。 3,那么这个行为是不需要加锁的,性能强大。原本的缓存层。结合这2个特点。 最后,无论在哪个环境下读取数据。  }}OK,那么其中一个线程一旦出现性能问题:我们有了一个高效的无锁空间?我们知道如果在“大循环”中要避免锁操作,但是可以被并发:a)同一个表同一个主键的多次UPdate。Java的Disruptor就是一个很好的例子
其他类似问题
为您推荐:
有线电视的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 消息队列解决并发问题 的文章

 

随机推荐