`
cenwenchu
  • 浏览: 160851 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论
阅读更多
 

Author : 岑文初(淘宝花名:放翁)

Email: fangweng@taobao.com

Blog: http://blog.csdn.net/cenwenchu79

      这部分内容是我前个礼拜作内部分享的一部分,是挑了大家在日常中经常使用的生产者消费者模式作了一个细节问题的分析来讲述关于系统设计中的一些问题,其实在我前面的救火经验分享里面也有部分的介绍,不过那些比较抽象一点,需要有实际的工作经历的同学才会体会的到,而这里就具体的针对某一个特定场景作了分析.



1 生产者消费者模式

         生产者和消费者模式在我们日常生产的代码里面应该出现的很频繁,但是有一些细节足以导致这种模式漏洞百出,同时也会使得系统不稳定。在早期Java来实现这种生产者和消费者模式,通常就采用线程池,资源池加上消息通知(wait,notify)的方式来实现,现在的Jdk有原生线程池(ExecutorService)和阻塞式队列,那我就主要说说后者这种实现需要注意的一些问题。

消费者的依赖带来的系统不稳定性

       在我们现有系统中消费者往往会依赖于外部系统(文件系统,DB等等),或者内部处理会有比较长时间的消耗,那么对于整个模式来说就会出现在特定情况下队列暴涨(消费者被Hold住,同时控制了总消费者的数量),此时对于队列的压力直接会导致应用系统的不稳定,这时候通常就两种解决方式,一种就是加大消费者线程数(治标不治本),另一种就是将业务处理再细分,同时考虑优化。

         业务处理再细分,其实就是考虑对于消费者的角色是否应该还有分层。参看nio等设计思想,其实可以看到对于工作者角色和消息监听者角色的分割,可以提高对于消息的处理,增加吞吐量。简单来说就是消费者作的事情更少,功能更加单薄,目的就是将消费这个动作加速,而将具体的业务操作分配给后端的工作线程来做,同时考虑在分配的过程中作合并和其他的优化处理,批量处理消息提高效率。

         这么做的优点就在于避免“单点”资源池或者队列的不稳定性,任务在低并发下按常规即时处理,在高并发下批量优化处理。



2 生产者消费者模式

 

三个维度解决消费慢于生产的情况

当消费无论如何优化都慢于生产的情况,那么需要考虑在三个维度上去防止异常情况发生。

1. 控制生产者生产频度。

2. 对列或者资源池空间大小限制,同时制定满载的消息处理策略(出错丢弃,磁盘固化等等)

3. 工作者处理时长控制,超时丢弃任务。

资源是宝贵的

         这个在以前反复说过,但是实际操作过程中往往被很多同学忽视。

1.使用线程池一定要设置边界,不然连接池不断膨胀会立刻导致内存溢出。

2.队列需要设置大小,特别是在选择时用阻塞队列的时候需要仔细考虑,同时存储在队列的内容尽量是对象的标示,在性能允许的范畴下,由工作线程去获得具体的庞大的处理数据集。

3.超时时间无论如何需要设置,不然依赖的不稳定性随时可以击垮系统。

并行和串行相辅相成

         很怕很多同学动不动就起一个线程池,说是多线程效率高。其实是否选择多线程首先就是要考虑这个任务并行执行是否好于串行执行。

1. 是不是关键路径。有时候优化了半天其实到后续还会堵塞在流程的某一阶段,那么多线程的意义就不大了。

2. 会不会有资源竞争。有资源竞争问题不大,但是发现竞争带来的性能损失要远多于多线程带来的性能节省,那么就绝对不选择多线程。并行化计算的最大问题就是一个共享资源访问控制问题,解决这个问题就两种方式:a.共享资源,锁机制保证数据一致性。b.不共享资源,操作结果可合并。(Share nothing,也是MapReduce, Erlang等分布式计算的核心设计理念)

3. 简单的工作串行,复杂的工作多线程并行执行。这个其实回到上面将消费者在分成消息监听者和任务执行者两个角色。(消息监听如果处理得够快,那么采用单线程串行处理也可以接受,只要保证任何异常不会中止监听工作)

多线程,并行处理不是包治百病的良药,串行并行结合起来根据实际场景来合理使用,才会设计出简单高效的系统架构。(设计作复杂容易,作简单难,因此不要在意简单的设计图拿不出手,因为用户只在乎如何得到稳定,高效的服务)

容错策略的抉择

         上面有提到如果队列满了应该做一定的策略去保证业务的正常流转。但是对于容错策略的选择上,其实要考虑自己系统地特性。原则如下:

1.       业务需求优先。(任务是否可以丢,任务执行顺序是否有要求,任务的及时性)

2.       架构简单。

3.       不引入新的性能瓶颈和系统不稳定因素。

根据上面的几点,首先业务是否可以丢弃,如果可以丢弃,那么很简单,直接丢弃过载的任务请求(考虑异步记录一些日志备作查询和告警)。如果不可以丢弃,那么就考虑执行的顺序是否有要求,执行的即时性是否有要求,这将直接决定你数据恢复处理的策略。此时就会结合23两点来考量方案,有可能会引入持久化操作,同时还有恢复处理的顺序等等。但是一定要仔细判断是否因此会带来其他的性能瓶颈。总结起来一个结论,在业务容许的范围内,结构越简单越好。

后话:

         我记得我刚工作那阵子也和现在一些刚毕业不久的同学一样,如果觉得自己的设计很简单,发现出去讲讲都很没面子,一定要想一个很完备的方案,面面俱到,但其实就像我前面所说的,客户在乎的不是你如何实现,而是是否能够满足他的需求(业务上,稳定性,容错性)。

         会做出很复杂的设计但是从来不关心客户的想法的程序员仅仅只能算是一个学生。

         会考虑如何满足客户需求但是不会走在客户前面多为将来考虑的程序员是一个新手。

         会考虑如何满足客户,同时会为客户更进一步思考的程序员是一个合格的程序员。

         工作3年内还是一个新手不可怕,可怕的是工作了几年还是处于一个学生状态,如何把设计从简单做复杂,然后再从复杂作到简单,其实才考验一个人实际的工作能力,在合时的环境采用合适的方法,得出最简化方案是程序员应该追求的。引用我小时候读书老师常常灌输我的一句话:“书是先要读厚来,然后再读薄的。“

分享到:
评论

相关推荐

    Java面向对象程序设计杨晓燕面向对象基本原则和模式.pptx

    高层模块不应该依赖低层模块,抽象不应该依赖细节,使系统设计更为通用、更为稳定。面向抽象编程,这里的抽象主要指的是抽象类或接口。 第14页/共30页 Java面向对象程序设计杨晓燕面向对象基本原则和模式全文共30页...

    asp.net知识库

    第2章 并发操作的一致性问题 (2) Using sqlite with .NET Visual Studio 2005 中的新 DataSet 特性 MySQL 和 .Net2.0配合使用 与DotNet数据对象结合的自定义数据对象设计 (二) 数据集合与DataTable 与DotNet数据对象...

    本科毕业设计开题报告(飞翔的小鸟游戏的设计与实现V3)

    用java语言来设计一个游戏,不同于现在的大型网络游戏和手机游戏,也不同于其他的小型的单机控制程序,它对游戏编写者对java语言特点认知、语法运用、工作模式、面向对象的理解的把握都提出了更高的要求,特别是在...

    软件工程知识点

    其具有非常好的工作稳定性和安全保密性。但系统建设费用、运行费用比较高,灵活性不够好,结构不便于扩充。 (2)客户机/服务器结构 客户机/服务器结构依靠网络将计算任务分布到许多台不同的计算机上,但通过其中的...

    驱动精灵(可以备份驱动,也可以升级驱动)

    1、修正部分用户出现的E02错误,联网稳定性大幅提升。 2、修正NVIDIA GTX460识别错误,新增NVIDIA GF104、GF106、GF108系列显卡芯片支持。 3、为照顾不同用户需求,驱动精灵细分为三种版本:标准版、扩展版、升级版...

    discuz!6.1GBK 版本论坛系统

    【修正】各种以往版本中存在的已知问题,具体细节不再一一描述 操作系统要求 Discuz! 具备跨平台特性,可以运行于 Linux/FreeBSD/Unix 及微软 Windows 2000/2003 等各种操作系统环境下。我们已在软件中针对上述操作...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    (1)针对多窗口类浏览器模式问题,指出并分析了该问题存在的原因,利用Activity的运行机制,通过Fragment栈对主要模块的Webview进行管理,实现对不同模块之间切换的控制。 (2)针对跨域数据交互问题,指出并分析了...

    计算机二级公共基础知识

    算法一般具有4个基本特征:可行性、确定性、有穷性、拥有足够的情报。 (2)算法的基本运算和操作 算法的基本运算和操作包括:算术运算、逻辑运算、关系运算、数据传输。 (3)算法的3种基本控制结构 算法的3种基本...

    yershop开源网店系统 v3.8.2.zip

    让应用的扩展更加方便,基于MVC(Model-View-Controller,模型-视图-控制器)模式,并且均支持多层(multi-Layer)设计,全面采用命名空间方式定义和加载类库文件,有效的解决多个模块之间的冲突问题,并且实现了更加...

    飞蛙B2B2C商城电商系统 v2.1.8.zip

    封装了CURD和一些常用操作,在安装部署、数据查询、数据缓存、数据验证、模型处理、视图与布局、路由处理、SEO支持、大数据支持等方面表现稳定。 本次升级内容较多,细节就不做阐述,主要修复了阿里云服务器屏蔽25...

    网址网站导航整站源码

    .# 对在线升级功能进行了改进,提高兼容性和稳定性。 .# 对程序进行优化,后台运行效率明显加快; .# 修改地方服务子分类不可修改Bug; .# 修复修改网址信息后自动跳转会出现2000秒倒数的Bug; .# 修复天气自动判断...

    最新版114啦2010.9.23更新.rar

    .# 对在线升级功能进行了改进,提高兼容性和稳定性; .# 对程序进行优化,后台运行效率明显加快; .# 修改地方服务子分类不可修改Bug; .# 修复修改网址信息后自动跳转会出现2000秒倒数的Bug; .# 修复天气自动...

    java 面试题 总结

    抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性...

    超级有影响力霸气的Java面试题大全文档

    抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承:  继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确...

    MySQL 5.1参考手册

    1.4.3. MySQL稳定性 1.4.4. MySQL表最大能达到多少 1.4.5. 2000年兼容性 1.5. MaxDB数据库管理系统概述 1.5.1. 什么是MaxDB? 1.5.2. MaxDB的历史 1.5.3. MaxDB的特性 1.5.4. 许可和支持 1.5.5. MaxDB和MySQL...

    MySql 5.1 参考手册.chm

    1.4.3. MySQL稳定性 1.4.4. MySQL表最大能达到多少 1.4.5. 2000年兼容性 1.5. MaxDB数据库管理系统概述 1.5.1. 什么是MaxDB? 1.5.2. MaxDB的历史 1.5.3. MaxDB的特性 1.5.4. 许可和支持 1.5.5. MaxDB和MySQL之间的...

    史上超高压缩软件2009

    异常错误处理以及改善很多细节设定.(5)经过了大量测试,保证了压缩/解压的稳定性. 0.231 加入了解压时自定解压缩文件的路径.出现错误时立即停止程序而不继续压缩/解压. 优化内核程序使压缩/解压速度提高了4%.增加了...

    TCP/IP症状和原因

     路由触发活跃模式 1) 不一致的间隔2) 硬件问题3) 不稳定的链路  十、TCP/IP症状和行动计划  问题 行动计划  DNS工作不正常 1)配置DNS主机的配置和DNS服务器,可以使用nslookup校验DNS服务器的工作  ...

    PPP:PPP使用LCP设置和维护链路

     路由触发活跃模式 1) 不一致的间隔2) 硬件问题3) 不稳定的链路  十、TCP/IP症状和行动计划  问题 行动计划  DNS工作不正常 1)配置DNS主机的配置和DNS服务器,可以使用nslookup校验DNS服务器的工作  ...

    TinyShop网店系统 v1.0.2

    使用户商品筛选更加的高效,适合当下的各种促销,更能使系统在众多商城系统中居有优势,报表系统让数据更加的直观,订单系统处理更加简洁,让操作不再麻烦,良好的设计使系统的安全性、稳定性、易用性和实用性都得到...

Global site tag (gtag.js) - Google Analytics