﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Terry.B.Li           彬-文章分类-设计模式</title><link>http://www.blogjava.net/libin2722/category/26101.html</link><description>虚其心，可解天下之问；专其心，可治天下之学；静其心，可悟天下之理；恒其心，可成天下之业。</description><language>zh-cn</language><lastBuildDate>Wed, 16 Feb 2011 14:30:02 GMT</lastBuildDate><pubDate>Wed, 16 Feb 2011 14:30:02 GMT</pubDate><ttl>60</ttl><item><title>串讲23种设计模式</title><link>http://www.blogjava.net/libin2722/articles/344406.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Wed, 16 Feb 2011 01:01:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/344406.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/344406.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/344406.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/344406.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/344406.html</trackback:ping><description><![CDATA[
		<div class="postbody">
				<p>零零碎碎地，学习过很多轮设计模式。总是学过就忘。后来就在google docs上做了一系列笔记，方便复习。最近把这些笔记搬家到blogjava上了，一边搬家，一边又复习一遍。学习设计模式有两个意义：</p>
				<p>一、学习设计模式最重要的是了解模式的应用场景。编程遇到特定场景的话，要有意识联想到设计模式，哪怕细节忘了也没关系，翻翻书就找到了。</p>
				<p>二、提高设计的思想。学习设计模式的时候，要体会模式精妙之处，当想明白大师思想和自己的差距的时候，差距就缩短了一点儿。</p>
				<p>有的模式平淡无奇，应用却广泛。有的模式设计精巧，应用场景却不易遇到。无论如何，要么掌握工具，要么学到思想，都是收获。</p>
				<p> </p>
				<p>最适合简单概括设计模式的是UML图，收集了一个非常好的资源，分享在我的sky drive网络硬盘上，包含23种设计模式的UML图</p>
				<p>
						<a title="http://cid-d8b11f9bf86fecfa.office.live.com/self.aspx/.Public/books/designpatternscard.pdf" href="http://cid-d8b11f9bf86fecfa.office.live.com/self.aspx/.Public/books/designpatternscard.pdf">http://cid-d8b11f9bf86fecfa.office.live.com/self.aspx/.Public/books/designpatternscard.pdf</a>
				</p>
				<p> </p>
				<p>设计模式可以分为三类：behavioural, structural, creational</p>
				<p>
						<strong>behavioural 11 种</strong>
				</p>
				<p>1. Memento（备忘录）</p>
				<p>精巧程度： 5星</p>
				<p>应用广泛：2星</p>
				<p>memento适合保存/恢复状态的场景。分为宽接口和窄接口。学习就要学窄接口！</p>
				<p>具体请见： <a title="http://www.blogjava.net/vcycyv/archive/2011/02/08/343949.html" href="../../vcycyv/archive/2011/02/08/343949.html">http://www.blogjava.net/vcycyv/archive/2011/02/08/343949.html</a></p>
				<p> </p>
				<p>2. Chain of Responsibility(责任链)</p>
				<p>精巧程度： 3星</p>
				<p>应用广泛： 3星</p>
				<p>适合用在"一系列handler”的场景下。分为纯和不纯两种，好像女孩儿也可以这么分？</p>
				<p>具体请见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/12/344167.html" href="../../vcycyv/archive/2011/02/12/344167.html">http://www.blogjava.net/vcycyv/archive/2011/02/12/344167.html</a>
				</p>
				<p> </p>
				<p>3. Observer（观察者）</p>
				<p>因为java里有Obserable和Observer， 所以通常在java里不会自己设计观察者模式。</p>
				<p> </p>
				<p>4. Command(命令模式)</p>
				<p>精巧程度：4星</p>
				<p>应用广泛：3星</p>
				<p>command模式用来解耦invoker和receiver. </p>
				<p>具体请见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/12/344168.html" href="../../vcycyv/archive/2011/02/12/344168.html">http://www.blogjava.net/vcycyv/archive/2011/02/12/344168.html</a>
				</p>
				<p> </p>
				<p>5. State(状态模式)</p>
				<p>精巧程度：4星</p>
				<p>应用广泛：3星</p>
				<p>OO编程如果出现多个相同的if…else条件，应该考虑用state模式重构。work flow的状态器也是基于State模式的。</p>
				<p>具体请见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/09/343998.html" href="../../vcycyv/archive/2011/02/09/343998.html">http://www.blogjava.net/vcycyv/archive/2011/02/09/343998.html</a>
				</p>
				<p> </p>
				<p>6. Interpreter</p>
				<p>精巧程度： N/A</p>
				<p>应用广泛： 1星</p>
				<p>据说只有搜索引擎才用得上这个模式，反正我每次学设计模式的时候，都把这个跳过去，就是不喜欢，抱歉。</p>
				<p> </p>
				<p>7. Strategy（策略模式）</p>
				<p>精巧程度： 2星</p>
				<p>应用广泛：4星</p>
				<p>用来封装不同算法。从uml图上看和state模式一样。 因为这个太简单了，所以没记笔记，这个忘不了。</p>
				<p> </p>
				<p>8. Iterator(迭代子)</p>
				<p>Java Collection都可以迭代，在java上不需要格外设计iterator。</p>
				<p> </p>
				<p>9. Template Method(模板方法)</p>
				<p>精巧程度：2星</p>
				<p>应用广泛：4星</p>
				<p>见名知义。太简单了，学过一遍就不会忘。但是这个应用非常广泛！</p>
				<p> </p>
				<p>10. Mediator(仲裁者)</p>
				<p>精巧程度：4星</p>
				<p>应用广泛：1星</p>
				<p>用来解耦多个peer。个人觉得这个模式多半会让mediator十分臃肿，mediator本身需要有很清晰的设计才能使用。应用场景恐怕也少。</p>
				<p>具体请见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/08/343951.html" href="../../vcycyv/archive/2011/02/08/343951.html">http://www.blogjava.net/vcycyv/archive/2011/02/08/343951.html</a>
				</p>
				<p> </p>
				<p>11. Visitor(访问者)</p>
				<p>精巧程度：5星</p>
				<p>应用广泛：2星</p>
				<p>collection里存一个类系的entry时，使用visitor模式可以避免instance of的使用。更重要的是方便扩展类系。</p>
				<p>具体请见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/13/344194.html" href="../../vcycyv/archive/2011/02/13/344194.html">http://www.blogjava.net/vcycyv/archive/2011/02/13/344194.html</a>
				</p>
				<p> </p>
				<p>
						<strong>Structure 7种</strong>
				</p>
				<p>12. adapter(适配器)</p>
				<p>精巧程度：2星</p>
				<p>应用广泛：1星</p>
				<p>个人觉得Adaptee由第三方提供的时候才可能用上这个模式。简单应用范围又窄，略</p>
				<p> </p>
				<p>13. Proxy(代理)</p>
				<p>精巧程度：2星</p>
				<p>应用广泛：5星</p>
				<p>aop是代理模式的一种发挥。Spring和Hibernate都大量使用proxy。可以引申学学JDK的dynamic proxy。模式简单，略。</p>
				<p> </p>
				<p>14. Bridge</p>
				<p>精巧程度： 5星</p>
				<p>应用广泛： 3星</p>
				<p>Bridge在技术上是strategy的进一步发挥，但侧重在实现与抽象的解耦。</p>
				<p>具体见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/08/343950.html" href="../../vcycyv/archive/2011/02/08/343950.html">http://www.blogjava.net/vcycyv/archive/2011/02/08/343950.html</a>
				</p>
				<p> </p>
				<p>15. Composite</p>
				<p>精巧程度： 4星</p>
				<p>应用广泛： 3星</p>
				<p>适用于树状结构。</p>
				<p>具体见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/13/344209.html" href="../../vcycyv/archive/2011/02/13/344209.html">http://www.blogjava.net/vcycyv/archive/2011/02/13/344209.html</a>
				</p>
				<p> </p>
				<p>16. Decorator(装饰)</p>
				<p>精巧程度： 5星</p>
				<p>应用广泛：3星</p>
				<p>在java I/O中广泛使用。为了解决“类爆炸”的问题。</p>
				<p>具体请见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/09/343997.html" href="../../vcycyv/archive/2011/02/09/343997.html">http://www.blogjava.net/vcycyv/archive/2011/02/09/343997.html</a>
				</p>
				<p> </p>
				<p>17. Facade(门面)</p>
				<p>连个UML图都没有，算神马模式？</p>
				<p> </p>
				<p>18. Flyweight</p>
				<p>精巧程度：5星</p>
				<p>应用广泛：2星</p>
				<p>分“单纯”“复合”两种，本身包含了工厂方法模式。一系列对象如果他们都有某部分属于特定集合，就让他们共享这个特定集合以节省资源。</p>
				<p>具体请见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/12/344169.html" href="../../vcycyv/archive/2011/02/12/344169.html">http://www.blogjava.net/vcycyv/archive/2011/02/12/344169.html</a>
				</p>
				<p> </p>
				<p>
						<strong>Creational 6 种</strong>
				</p>
				<p>19. Factory Method(工厂方法)</p>
				<p>精巧程度：3星</p>
				<p>应用广泛：4星</p>
				<p>两个变种，一个是根据参数创建对象，一个是factory类系对应产品类系。面向接口编程在创建模式的体现。</p>
				<p>具体请见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/13/344176.html" href="../../vcycyv/archive/2011/02/13/344176.html">http://www.blogjava.net/vcycyv/archive/2011/02/13/344176.html</a>
				</p>
				<p> </p>
				<p>20. Abstract Factory（抽象工厂）</p>
				<p>精巧程度：5星</p>
				<p>应用广泛：1星</p>
				<p>只有产品有两个类系的时候才用得上。</p>
				<p>具体请见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/15/344390.html" href="../../vcycyv/archive/2011/02/15/344390.html">http://www.blogjava.net/vcycyv/archive/2011/02/15/344390.html</a>
				</p>
				<p> </p>
				<p>21. Builder</p>
				<p>精巧程度： 5星</p>
				<p>应用广泛： 2星</p>
				<p>产品分部分，并且build的过程不定的时候考虑用这种模式。是模板模式的一种发挥</p>
				<p>具体请见：</p>
				<p>
						<a title="http://www.blogjava.net/vcycyv/archive/2011/02/09/343995.html" href="../../vcycyv/archive/2011/02/09/343995.html">http://www.blogjava.net/vcycyv/archive/2011/02/09/343995.html</a>
				</p>
				<p> </p>
				<p>22. Prototype(原型)</p>
				<p>java有cloneable的支持，所以通常不需要自己设计prototype. java用prototype的时候注意深复制浅复制的问题。prototype之外的一个选择是提供一个constructor接受本类型对象作为参数，这个方式更加实用！</p>
				<p> </p>
				<p>23. singleton(单态)</p>
				<p>古典的singleton分为懒汉，饿汉两种。JDK1.5之后可以用唯一entry 的enum作为singleton的实现。好处有两点，一是简单。二是不需要格外处理serializable的情况</p>
		</div>
<img src ="http://www.blogjava.net/libin2722/aggbug/344406.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2011-02-16 09:01 <a href="http://www.blogjava.net/libin2722/articles/344406.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)应用架构设计“防火”经验分享</title><link>http://www.blogjava.net/libin2722/articles/293768.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Thu, 03 Sep 2009 09:25:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/293768.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/293768.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/293768.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/293768.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/293768.html</trackback:ping><description><![CDATA[
		<p style="text-align: center;" class="MsoNormal" align="center">
				<span style="font-family: 宋体; font-size: 15pt;">应用架构设计“防火”经验分享</span>
		</p>
		<p style="background: white none repeat scroll 0% 0%; text-align: left; line-height: 150%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;" class="MsoNormal" align="left">
				<span style="line-height: 150%; color: black; font-size: 12pt;">Author : </span>
				<span style="line-height: 150%; font-family: 宋体; color: black; font-size: 12pt;">岑文初</span>
				<span style="line-height: 150%; color: black; font-size: 12pt;">(</span>
				<span style="line-height: 150%; font-family: 宋体; color: black; font-size: 12pt;">淘宝花名：放翁</span>
				<span style="line-height: 150%; color: black; font-size: 12pt;">)</span>
		</p>
		<p style="background: white none repeat scroll 0% 0%; text-align: left; line-height: 150%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;" class="MsoNormal" align="left">
				<span style="line-height: 150%; color: black; font-size: 12pt;">Email: </span>
				<span style="line-height: 150%; color: blue; font-size: 12pt;">
						<a href="mailto:fangweng@taobao.com">fangweng@taobao.com</a>
				</span>
		</p>
		<p style="background: white none repeat scroll 0% 0%; text-align: left; line-height: 150%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;" class="MsoNormal" align="left">
				<span style="line-height: 150%; color: black; font-size: 12pt;">Blog: </span>
				<span style="line-height: 150%; font-family: 宋体; color: black; font-size: 12pt;">
						<a href="http://blog.csdn.net/cenwenchu79">
								<span style="font-family: 'Calibri','sans-serif';">http://blog.csdn.net/cenwenchu79</span>
						</a>
				</span>
		</p>
		<p style="background: white none repeat scroll 0% 0%; text-align: left; line-height: 150%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;" class="MsoNormal" align="left">
				<span style="line-height: 150%; color: black; font-size: 12pt;">Date: 2009-08-26</span>
		</p>
		<p>         <span style="font-family: 宋体;">刚从阿软到淘宝不久，现在主要负责</span>TOP<span style="font-family: 宋体;">平台的技术框架设计，同时要肩负“救火”和“防火”的工作，也需要培养团队的同学能够有“防火”意识，减少“救火”次数，因此今天下午花了一点时间，也没于写任何的</span>PPT<span style="font-family: 宋体;">，就直接将自己想的起来的一些自己认为应用架构设计“防火”知识做了一下事例分享，这里也想记录下来给更多的同学分享一下，当然很多都是老生常谈的常识，但是有时候不经意就会忘记一些血的教训。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">资源是有限的</span>
				</strong>
		</p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">着火点：</span>
		</p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">系统设计的时候总是估摸不到会有大数据量从远端传输过来（例如处理</span>Http<span style="font-family: 宋体;">请求时，对于大附件内容的处理，全部装载到内存，结果资源耗尽。从搜索引擎或者</span>DB<span style="font-family: 宋体;">或者缓存里面拉数据，没有分页，结果内存被吃尽。</span>Socket<span style="font-family: 宋体;">无限建立连接，结果</span>linux<span style="font-family: 宋体;">的文件句柄被耗尽。）</span></p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">防火点：</span>
		</p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">对业务场景中资源的分配与申请需要做到上限控制，以及达到上限以后的逻辑处理（排队，丢弃，告警）。可以采取一些滑动窗口设计来将不需要过多处理的内容分段直接送入下一个处理管道中。</span>
		</p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">依赖是未知的</span>
				</strong>
		</p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">着火点：</span>
		</p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">事务中嵌入对于第三方系统的请求（例如在数据库操作时去发送邮件或者缓存获取内容，结果连接池资源被</span>Hold<span style="font-family: 宋体;">，导致系统不可用）。默认依赖系统会给出结果，如果出现异常就反复重试，结果对方被压垮，自己也牺牲。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">对于第三方系统的依赖能够异步的就采用异步方式，能够从主流程
中剥离的就剥离。同时设计好容错的机制，采用本地时效性缓存减少对对方的压力和依赖。最重要的就是注意系统间的死锁，申请了一套资源处理业务逻辑，结果由
于远端系统的不可用，导致本地资源的无法释放，最后击垮自己系统。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">线程安全与性能</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">对于线程不安全的对象处理一定要小心，否则业务出现异常的地方其实已经离设计出现问题的地方十万八千里，问题时常成为灵异问题，解决只有靠经验。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">首先对于自己设计的类和方法需要注释是否是线程安全的。同时明确类的使用场景，对线程安全及高性能作判断，因为采用线程安全的对象一定会有性能损耗。最近给同学写的一个</span>Http<span style="font-family: 宋体;">消息的</span>Lazy<span style="font-family: 宋体;">获取参数，就是线程不安全的类，但是这个类只会保存在</span>ThreadLocal<span style="font-family: 宋体;">中，因此不存在问题。很直观的一点判断是否线程安全，就看看你设计的类里面的成员变量在多线程操作时候是否会有并发问题，例如一个普通的</span>Map<span style="font-family: 宋体;">，多个线程操作就会导致结果的不可估量性。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">资源释放</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">正常逻辑都会将</span>IO<span style="font-family: 宋体;">流关闭，</span>Socket<span style="font-family: 宋体;">关闭，但是异常抛出时候，没有走到资源释放的流程中，产生了资源泄露问题。另外，资源中可能会有内嵌资源，当内部资源被外部的对象引用，则释放将不成功，内部资源依然会泄露。一些需要显式回收的资源（例如</span>ThreadLocal<span style="font-family: 宋体;">），如果不回收，那么下次线程被操作系统重用，则会出现莫名其妙的问题（</span>Java<span style="font-family: 宋体;">的线程创建和使用依赖于操作系统的实现）。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         Finally<span style="font-family: 宋体;">的处理。需要释放的资源要做深度检查。需要显式回收的资源要确保使用完毕以后被回收（异常情况也需要考虑）。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">创建与复用</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">在以前设计</span>Cache<span style="font-family: 宋体;">客户端的时候，有同学给我建议说我对于字节数组利用可以采取复用的方式，这样可以减少对象的申请。但是做了一下测试，这样的重复利用其实效果不像想象的那么好，甚至还不如直接创建。</span></p>
		<p style="text-indent: 20.25pt;" class="MsoNormal">
				<span style="font-family: 宋体;">防火点：</span>
		</p>
		<p style="text-indent: 20.25pt;" class="MsoNormal">Java<span style="font-family: 宋体;">的垃圾收集器已经在性能上有了很大的提高，同时对于对象的复用需要考虑对象复用前的初始化或者是内容重置，这些得成本及复杂度可能远远要高于复用带来的优势，因此需要根据具体的业务场景选择复用和创建。当然对于稀缺资源采用池的方式是最好的。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">字符串处理，日志级别的选择</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">这两个是小问题，但是会带来大麻烦。首先字符串的累加是老生常谈的问题，但是很多新手不以为然，当你是一个高速运转的系统时，你就会发现</span>1ms<span style="font-family: 宋体;">的延时在上千万次调用下回被无限放大，</span>10byte<span style="font-family: 宋体;">的申请，在上千万次的请求下会带来</span>GC<span style="font-family: 宋体;">多次的操作（带来的短暂处理停滞直接影响系统的可用性）。日志级别的随意性会导致线上环境日志迅速膨胀，出错难以查找，影响系统的效率。（</span>log4j<span style="font-family: 宋体;">优化的再好也是要写文件的，虽然是异步刷页）</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">谨慎处理字符串拼接，选择线程安全或者不安全的两个</span>StringBuilder<span style="font-family: 宋体;">和</span>StringBuffer<span style="font-family: 宋体;">。日志尽量区分清楚，</span>debug<span style="font-family: 宋体;">和</span>Info<span style="font-family: 宋体;">，前者纯粹调试，可以有海量信息，</span>Info<span style="font-family: 宋体;">一般用于系统或者模块的状况报告。</span>Warn<span style="font-family: 宋体;">通常不建议使用了。</span>Error<span style="font-family: 宋体;">就把你需要的关键信息都打出来。附带这里说一下对于日期对象的处理，在传输和保存的过程中，建议都还是采用</span>long<span style="font-family: 宋体;">型，可以很好的提高性能及满足国际化的需求。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">原子操作与并发控制</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">对于本地的对象操作通常情况下通过锁机制保证并发的一致性，当在设计一个对于资源访问控制的策略时，例如集群应用处理某人每天发送短信</span>1000<span style="font-family: 宋体;">条，这时候计数器保存在远端的集中式缓存中，采用</span>get<span style="font-family: 宋体;">和</span>put<span style="font-family: 宋体;">方式就会有并发问题，因为在应用获得到</span>999<span style="font-family: 宋体;">这个计数器值的时候，也许正有</span>10000<span style="font-family: 宋体;">个请求也获得了这个值，这样原有的控制就失效了。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">其实就是一个原子操作的支持，本地数据可以通过锁来达到原子操作，远程依赖就需要对方系统提供原子操作接口来实现高并发下的业务处理，例如</span>Memcached Cache<span style="font-family: 宋体;">提供的</span>incr <span style="font-family: 宋体;">和</span>decr<span style="font-family: 宋体;">。结合黑名单策略，计数器可以发挥很多用途，包括及时监控告警等。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">接口实现与松耦合</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点</span>:</p>
		<p>         <span style="font-family: 宋体;">没有接口提供，团队间合作困难，无法</span>Mock<span style="font-family: 宋体;">，相互之间进度影响很大。同时业务实现的修改直接影响业务调用方，使得双方耦合性很强，系统不稳定性被放大。</span></p>
		<p style="text-indent: 20.25pt;" class="MsoNormal">
				<span style="font-family: 宋体;">防火点：</span>
		</p>
		<p style="text-indent: 20.25pt;" class="MsoNormal">
				<span style="font-family: 宋体;">对外提供的服务，或者模块间交互的服务都需要接口化。框架性代码需要在模块载入时考虑是否需要接口化定义，以便在不同环境可以切换不同实现提供对特殊场景的支持，同时也可以将具体实现延后交给使用者实现，使得框架更加灵活。</span>Jdk<span style="font-family: 宋体;">对于</span>xml<span style="font-family: 宋体;">的解析就是最好的范例。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">灵活性和性能和可维护性的折中</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">最近看了一些同学的代码，看到大量的使用了反射，拦截器等。但是在线上环境运行过程中就发现对于一些拦截器的配置疏漏导致系统性能大幅度降低。对于几十个</span>spring<span style="font-family: 宋体;">文件，有谁能够很清楚和直观的了解到这些看似灵活和无侵入性的设计。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">对于业务逻辑不复杂，同时场景不多变的流程采用简单的实现，不要追求花哨的灵活性，带来的只会是可读性，可维护性，可用性的降低。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">要有分布式和并发的观念，但是不要本末倒置</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">有些同学在做设计的时候考虑的很清晰，但是就是没有考虑集群部署的情况，结果系统上线以后出现了无法集群部署的问题。并发情况的设计也一样，仅仅在满足业务需求以后，对于多用户并发操作的考虑缺失，导致系统流程错误。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">设计的时候需要适度考虑这些问题，但是是在满足现有业务逻辑的前提下，不要为了追求分布式而分布式。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">便利性的函数与性能的冲突</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">首先申明的是这点适用范围有限（高速运转的模块）。对于</span>String,Date<span style="font-family: 宋体;">等对象的便利性函数，例如正则匹配，分割，</span>Format<span style="font-family: 宋体;">等等其实都会有不少的性能损耗。例如你只是需要判断文件名最后的后缀是否满足需求，采用了正则匹配，结果发现性能在高速运转的情况下大大下降。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">高速运转的模块尽量采用原始方式或者半原始方式。例如上面说到的文件后缀，就用</span>string<span style="font-family: 宋体;">的</span>endwith<span style="font-family: 宋体;">来判断。对于一些字符串的替换，能够用字符串拼接就拼接。对于一些字节流的处理也可以自己根据需求来订制的写。总的一句话，能够满足的就用最低成本的方法。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">防止系统设计的完备性成为攻击或者压力的瓶颈</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">在很多设计的时候，对于一些系统设计讲究比较完美。例如对于对象的查询会分本地缓存，集中缓存，</span>DB<span style="font-family: 宋体;">三个阶段。当对方攻击采用不存在的资源名称时候，这种分阶段的设计反而会增加系统负荷。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">简化流程的分支和层次，对于消耗性资源的访问尽量减少或者没有（采用黑名单本地缓存或者集中缓存的方式），同时改</span>Pull<span style="font-family: 宋体;">为</span>Push<span style="font-family: 宋体;">方式，通过控制数据变更点来通知相关系统，而非轮询获取更新状态。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">多级缓存和异步缓解异构系统的瓶颈</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">有时候设计系统时，服务提供方向我们许诺说对方系统如何高效和健壮，但是当频繁访问产生网络风暴的时候，我们发现原来带宽和网络</span>IO<span style="font-family: 宋体;">本身都会成为瓶颈。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">对于第三方系统的依赖，要做到松耦合就要从流程的异步化来实现。同时通过缓存的使用来达到，系统的高效性和降低对于第三方系统的依赖程度。这样可以大大降低系统的瓶颈。</span>
		</p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">运行期白盒化，模块可重置</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">系统运行起来以后就无法在知道内部的状态，也无法对问题组件进行单独处理，造成线上环境的不可知性和无法部分修复。不得不停机重起和看日志。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">模块设计过程中考虑运行期可观测和可重置，提高系统的模块化程度及健壮性。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">站在用户角度设计接口，提升系统可用性</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">总是从自身业务体系和架构去考虑如何设计对外接口，但是发现最后用户使用的很别扭，同时由于需求不能直接被满足，会多次反复调用接口，导致自身系统的压力增大。例如对于一个状态的检查接口，是否提供一个状态变更通知接口就会极大降低轮询的压力</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">需要从客户角度考虑问题，设计接口，防止需求和实现脱节，导致系统压力增加。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">懒惰有时候是件好事</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点</span>:</p>
		<p>         <span style="font-family: 宋体;">业务流程中很多耗时的操作在流程编排方面没有考虑清楚，当耗时工作做完以后，发现不符合最基本的交验，这样就会导致系统无谓的增加了开销。对于需要申请的资源，考虑处理流程的阶段，阶段性申请要优于一次申请（不过需要注意死锁）。</span></p>
		<p>         <span style="font-family: 宋体;">防火点</span>:</p>
		<p>         <span style="font-family: 宋体;">流程编排需要合理性，尽量将耗时的工作放到合理的位置，同时做好基础的防攻击轻量前端屏障逻辑，提高系统的健壮性。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">主流程和副流程隔离</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         SIP<span style="font-family: 宋体;">早先的日志分析模块中有分析日志，备份，发邮件，更新系统缓存，操作数据库等多种操作，但是一股脑儿都被放到一个流程中，结果当邮件没有发成功导致整个流程的失败。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">把真正的主流程梳理出来，同时对于一些副流程可以考虑采用后台异步方式完成，提高系统稳定性。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">模块间接口交互，控制资源直接操作入口</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">对于数据库中的资源任何模块不区分范围都可以访问，最后导致数据结构变更困难，业务对象管理混乱，模块无法剥离独立。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">模块化设计的基本思想，模块间通过接口交互获得其他模块管辖的数据，接口方式屏蔽了对于后端实现及业务对象的依赖。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">学习份外的事情，配置决定成败</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">没有</span>SA<span style="font-family: 宋体;">就高不定环境，也无法了解操作系统的配置与</span>Web<span style="font-family: 宋体;">容器的配置对于应用的影响。没有</span>DBA<span style="font-family: 宋体;">就无法确定如何写</span>SQL<span style="font-family: 宋体;">避免一些简单的耗时查询。没有测试同学就无法作压力测试，无法了解当前系统性能。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">多学多问，多了解一些其他岗位的内容，才能够更加全面的掌握好架构设计。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">不要迷信</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">总是看到新技术如何有优点，但是看不到它的成熟度。总是听到很多经验之谈，但是从来没有真的比较过。结果就是别人说什么就是什么，系统地稳定性和可用性基于</span>Google<span style="font-family: 宋体;">出来的结果。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">需要听取各种意见和经验，同时用测试结果说明问题的结果，看代码说明结果背后的问题。这样才会走得更加踏实，学的更加实际。其实技术发展来说，真正的基础性内容还是有限的，而且各种技术都是触类旁通。分布式，不论是文件系统，</span>DB<span style="font-family: 宋体;">，缓存都会遇到分布式的共性问题（负载均摊，容错，数据复制，动态扩容等等），在结合一些文件系统，</span>DB<span style="font-family: 宋体;">，缓存的自身特质。因此扎扎实实学好基础，了解</span>Http<span style="font-family: 宋体;">协议，了解七层通信协议，了解文件系统设计，了解</span>MapReduce<span style="font-family: 宋体;">思路，了解结构化，半结构化（</span>bigmap<span style="font-family: 宋体;">），非结构化存储的要点，就会不会让自己迷失在技术宣传中。</span></p>
		<p>         <span style="font-family: 宋体;">明天晚上去北京参加系统架构师会议，到时候会和大家分享一下</span>TOP<span style="font-family: 宋体;">的一些商业和技术上的心得，准备得很仓促，但是个人觉得分享就在于自己将自己知道的说出来，时间不长，</span>45<span style="font-family: 宋体;">分钟，能讲的也不多，但是如果对于淘宝开放平台有兴趣的同学可以来听一下。这里也算是做个广告，不过不要期望过高，免得失望也大</span>^_^<span style="font-family: 宋体;">。五年没有来北京了，首都应该也变化不小了。</span></p>
<img src ="http://www.blogjava.net/libin2722/aggbug/293768.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2009-09-03 17:25 <a href="http://www.blogjava.net/libin2722/articles/293768.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>