﻿<?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-云-随笔分类-企业架构</title><link>http://www.blogjava.net/matuobasyouca/category/51266.html</link><description>敏捷、分布式、ALM过程自动化、企业应用架构</description><language>zh-cn</language><lastBuildDate>Tue, 22 May 2012 02:32:08 GMT</lastBuildDate><pubDate>Tue, 22 May 2012 02:32:08 GMT</pubDate><ttl>60</ttl><item><title>我们的用户体验真的这么差？</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/05/22/378752.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Mon, 21 May 2012 21:02:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/05/22/378752.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/378752.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/05/22/378752.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/378752.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/378752.html</trackback:ping><description><![CDATA[<p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">公司里有同事时常抱怨，项目的用户体验太差，常常挨领导的骂。大家都认为是在用户体验的设计方面，公司人员的能力和经验都不足引起的。发牢骚的时候也会说，如果公司能够请得起&#8220;淘宝&#8221;的</span>UI<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">设计师，咱们的系统肯定会更上一层楼。我之前也一直认为如此，即我们的设计是影响项目体验的重要原因。最近被领导调动去协助一个项目，产生了一些不一样的体会。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">项目背景，一个新的产品，小型项目，纯开发人员</span>3-4<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">人，</span>2<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">名熟练开发人员，</span>1<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">名新手，偶尔会有协助人员。没有技术经理，项目经理身负多个项目，对项目进度关心不足，部门经理会协助进行工作和进度管理。可以看到管理还是比较混乱。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">由于项目进度太慢，领导要求从我这边调一个熟练人员协助开发。我也基本了解他们的项目状况，为了不让我的人进去抓瞎，我就和他一起去了解项目情况。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">项目状况比较糟糕，介入项目时已经开发了一段时间，保留的文档只有两份，一副数据库说明，一份非常粗略的需求说明，而且还与开发进度不同步，就是没有维护。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">我了解了一下项目目前的难度，开发人员和我反映一个是人员熟练程度的问题，二是需求变更的问题。我整体了解了一下项目目前的需求和设计，以及进度。就挑了一个模块询问他们的变更情况，这个模块是一个关键词匹配功能。结果是领导看了他们的页面之后，嫌信息量太少，就要求提供一些更细化的数据展示。开发人员问我有什么意见，我就简单讲了一下页面大概怎么构建。其中有一个点，是用于变更数据范围，即查询的表变更，我一开始觉得使用下拉框就可以，产生了一些意见。有人建议分为不同子模块，或者</span>tab<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">页，或者分为多块并列展示。我想了想，就给他们讲了我认为几种方案的优点缺点及适用范围。</span></p>  <p>&nbsp;</p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">1.<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">多块并行展示：</span></p>  <p style="margin-left:21.0pt"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">多个不同范围的数据在同一页面中分为不同区域以相同形式展示。原因是由于多块数据之间有一定的关联因果关系，或值得对比。适用范围：如购物网站中的多个物品比较。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">2.<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Tab<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">页：</span></p>  <p style="margin-left:21.0pt"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">同一个页面的多个</span>tab<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">页，表示多个</span>tab<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">页中的数据可能在一定的领域概念之下有一定的关联，但关联度不强。因为</span>tab<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">页更重要的是强调一个同步工作的状态，即</span>A tab<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">页查看一定信息，会打开</span>B tab<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">页查看其他信息，中途还会切回</span>A tab<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">页。适用范围：如邮箱中，收件箱和草稿箱。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">3.<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">下拉框</span></p>  <p style="margin-left:21.0pt"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">下拉框作为查询条件的一部分，常用于有着常规或固定的可选择内容中（如性别，月份），更多是以过滤的形态出现，即下拉框更适合针对某表的某个字段过滤，如果针对的是数据范围或是对用户需要直观了解的重要业务条件则不太合适。适用范围：如在考试成绩中使用下拉框过滤&#8220;男女&#8221;或&#8220;及格不及格&#8221;。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">4.<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">单选框</span></p>  <p style="margin-left:21.0pt"><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">单选框与下拉框的作用范围相似，但是不同之处在于将被选项全部展示，目的在于能够让用户清楚的了解当前数据显示的实际范围或条件，以及备选的其他范围或条件。更适用于选项与实际业务及当前展示数据关系重要，不同选项可能会引发用户的不同行为。适用范围：如银行系统显示了当前用户下绑定多个帐号时，使用单选框。</span></p>  <p style="margin-left:21.0pt">&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">经过上述讨论，我们仔细分析了这个模块中用户的实际需求，以及可能后续操作，最终选择的单选框的方案。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">目前还没有后续，但是我想我们基于用户真是需求的挖掘和后续操作的认真分析，会让我们在与领导进行需求讨论的时候有更加充分合理的依据。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">回来之后我又看了看淘宝的搜索页面，比如就搜索&#8220;鞋子&#8221;来讲，将品牌这栏设置为单选和下拉将是完全不同的效果，而确定方案的理由则是对于用户的需求和实际行为的深入研究。这个应该是需求分析和调研的结果。将搜索条件以</span>tag<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的形式标注于页面上，并且可以直接点击</span>X<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">按钮进行删除，我觉得更加可以倾向为用户体验。满足并充分考虑了用户实际需求的是好的需求分析，能够简化并引导用户行为的是好的用户体验。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">当我们面临的系统感觉非常难用的时候，往往这时候并非是用户体验差，我们应该检讨的是我们对用户需求有没有好好挖掘，做出来的是不是用户想要、用户能用的系统。</span></p><img src ="http://www.blogjava.net/matuobasyouca/aggbug/378752.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/matuobasyouca/" target="_blank">一酌散千忧</a> 2012-05-22 05:02 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/05/22/378752.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Zookeeper的学习总结</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/05/15/378164.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Tue, 15 May 2012 03:02:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/05/15/378164.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/378164.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/05/15/378164.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/378164.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/378164.html</trackback:ping><description><![CDATA[<div><div><h3><span style="mso-spacerun:'yes'; font-weight:bold; font-size:16.0000pt; font-family:'宋体'; ">Zookeeper的核心概念：</span></h3><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">ZNode</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">Znode就是核心结构，Zookeeper服务中是由大量的Znode构成。Znode一般是由客户端建立和修改，作为信息或标志的载体，甚至本身就是标志。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">Znode可以设置为持久（PERSISTENT）或临时（EPHEMERAL），区别在于临时的节点若断开连接后就自动删除。建立节点时可选择是否使用序列号命名（SEQUENTIAL），若启用则会自动在节点名后加入唯一序列编号。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">Session</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">作为客户端和Zookeeper服务之间交互的凭证。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">Watch</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">当客户端对节点信息进行查询操作之后，可以选择是否设置一个Watch。其作用就是当本次查询的数据在服务器端发生变化之后，会对设置Watch的客户端发送通知。一次发送之后，就将删除该Watch，以后的变更或不再设置Watch则不会通知。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">ACLs</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">节点的权限限制使用ACL，如增删改查操作。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "></p><h3><span style="mso-spacerun:'yes'; font-weight:bold; font-size:16.0000pt; font-family:'宋体'; ">Zookeeper的服务器安装：</span></h3><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">1、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">下载对应版本号的tar.gz文件</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">2、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">使用&nbsp;</span><span style="color: #000000; font-style: normal; font-size: 10.5pt; font-family: Arial; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; background-position: initial initial; background-repeat: initial initial; ">tar&nbsp;xzvf&nbsp;zookeeper-3.4.2.tar.gz&nbsp;-C&nbsp;./</span><span style="color: #000000; font-style: normal; font-size: 10.5pt; font-family: 宋体; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; background-position: initial initial; background-repeat: initial initial; ">&nbsp;解压</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">3、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">设置，将conf/zoo.example.cfg复制到conf/zoo.cfg或者手动建立一个新的。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">4、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">启动Zookeeper服务：bin/zkServer.sh&nbsp;start</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">5、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">启动客户端连接：bin/zkCli.sh&nbsp;-server&nbsp;127.0.0.1:2181（此处在本机，且使用了默认端口，且在Java环境中）</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">6、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">使用命令：ls、get、set等。</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">7、</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">关闭Zookeeper服务：bin/zkServer.sh&nbsp;stop</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><h3><span style="mso-spacerun:'yes'; font-weight:bold; font-size:16.0000pt; font-family:'宋体'; ">Zookeeper代码编写：</span></h3><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">代码编写部分比较简单，因为暴露的接口很少，主要复杂在于项目如何使用节点以及节点信息。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">启动Zookeeper服务之后，客户端代码进行节点的增删，Watch的设置，内容的改查等。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">此处建议查看官方的《Programming&nbsp;with&nbsp;ZooKeeper&nbsp;-&nbsp;A&nbsp;basic&nbsp;tutorial》部分，当中举了两个例子来模拟分布式系统的应用。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">代码基本没有问题，唯一需要注意的就是：若之间按照原版进行调试时，有可能在调用</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><font class="Apple-style-span" face="宋体"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">&nbsp;Stat&nbsp;s&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;zk.exists(root,&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">);</span></div></font></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">这句代码时会出现一个异常，当中包括&#8220;KeeperErrorCode&nbsp;=&nbsp;ConnectionLoss&nbsp;for&#8221;。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">这个问题引起的原因可以看一下代码</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><font class="Apple-style-span" face="宋体"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Starting&nbsp;ZK:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zk&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;ZooKeeper(address,&nbsp;</span><span style="color: #000000; ">3000</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mutex&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Integer(</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Finished&nbsp;starting&nbsp;ZK:&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;zk);</span></div></font></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">最后一行有打印出Zookeeper目前的信息，若未修改的原代码，此处的State应当是CONECTING。连接中的时候去验证是否存在节点会报错。解决的方法也很简单，就是等到Zookeeper客户端以及完全连接上服务器，State为CONECTED之后再进行其他操作。给出代码示例：</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; text-align:justify; "><font class="Apple-style-span" face="宋体"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;使用了倒数计数，只需要计数一次</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;CountDownLatch&nbsp;connectedSignal&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;CountDownLatch(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);&nbsp;<br />SyncPrimitive(String&nbsp;address)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(zk&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">try</span><span style="color: #000000; ">&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Starting&nbsp;ZK:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zk&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;ZooKeeper(address,&nbsp;</span><span style="color: #000000; ">3000</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mutex&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Integer(</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connectedSignal.await();&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;等待连接完成</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Finished&nbsp;starting&nbsp;ZK:&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;zk);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000FF; ">catch</span><span style="color: #000000; ">&nbsp;(IOException&nbsp;e)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(e.toString());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zk&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000FF; ">catch</span><span style="color: #000000; ">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">else&nbsp;mutex&nbsp;=&nbsp;new&nbsp;Integer(-1);</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">}<br /></span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;process(WatchedEvent&nbsp;event)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;此处设立在Watch中会在状态变化后触发事件</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(event.getState()&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;KeeperState.SyncConnected)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connectedSignal.countDown();</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;倒数-1</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; ">&nbsp;(mutex)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">System.out.println("Process:&nbsp;"&nbsp;+&nbsp;event.getType());</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mutex.notify();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div></font></p><p style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">这样就可以正确运行代码了。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><h3><span style="mso-spacerun:'yes'; font-weight:bold; font-size:16.0000pt; font-family:'宋体'; ">Zookeeper的应用场景及方式：</span></h3><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">此处是为引用，原地址为（</span><a href="http://rdc.taobao.com/team/jm/archives/1232"><span style="mso-spacerun:'yes'; color:#0000ff; text-decoration:underline ;font-size:10.5000pt; font-family:'Times New Roman'; ">http://rdc.taobao.com/team/jm/archives/1232</span></a>&nbsp;<span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">）</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">ZooKeeper是一个高可用的分布式数据管理与系统协调框架。基于对Paxos算法的实现，使该框架保证了分布式环境中数据的强一致性，也正是基于这样的特性，使得zookeeper能够应用于很多场景。网上对zk的使用场景也有不少介绍，本文将结合作者身边的项目例子，系统的对zk的使用场景进行归类介绍。&nbsp;值得注意的是，zk并不是生来就为这些场景设计，都是后来众多开发者根据框架的特性，摸索出来的典型使用方法。因此，也非常欢迎你分享你在ZK使用上的奇技淫巧。</span></p><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p><table style="border-collapse:collapse; margin-left:5.4000pt; padding:0.0000pt 0.0000pt 0.0000pt 0.0000pt ; "><tbody><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:0.7500pt solid #cccccc; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">场景类别</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:0.7500pt solid #cccccc; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">典型场景描述（ZK特性，使用方法）</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:0.7500pt solid #cccccc; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">应用中的具体使用</span></p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">数据发布与订阅</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">发布与订阅即所谓的配置管理，顾名思义就是将数据发布到zk节点上，供订阅者动态获取数据，实现配置信息的集中式管理和动态更新。例如全局的配置信息，地址列表等就非常适合使用。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">1.&nbsp;索引信息和集群中机器节点状态存放在zk的一些指定节点，供各个客户端订阅使用。2.&nbsp;系统日志（经过处理后的）存储，这些日志通常2-3天后被清除。&nbsp;</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">3.&nbsp;应用中用到的一些配置信息集中管理，在应用启动的时候主动来获取一次，并且在节点上注册一个Watcher，以后每次配置有更新，实时通知到应用，获取最新配置信息。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">4.&nbsp;业务逻辑中需要用到的一些全局变量，比如一些消息中间件的消息队列通常有个offset，这个offset存放在zk上，这样集群中每个发送者都能知道当前的发送进度。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">5.&nbsp;系统中有些信息需要动态获取，并且还会存在人工手动去修改这个信息。以前通常是暴露出接口，例如JMX接口，有了zk后，只要将这些信息存放到zk节点上即可。</span></p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">Name&nbsp;Service</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">这个主要是作为分布式命名服务，通过调用zk的create&nbsp;node&nbsp;api，能够很容易创建一个全局唯一的path，这个path就可以作为一个名称。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; ">&nbsp;</p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">分布通知/协调</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">ZooKeeper中特有watcher注册与异步通知机制，能够很好的实现分布式环境下不同系统之间的通知与协调，实现对数据变更的实时处理。使用方法通常是不同系统都对ZK上同一个znode进行注册，监听znode的变化（包括znode本身内容及子节点的），其中一个系统update了znode，那么另一个系统能够收到通知，并作出相应处理。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">1.&nbsp;另一种心跳检测机制：检测系统和被检测系统之间并不直接关联起来，而是通过zk上某个节点关联，大大减少系统耦合。2.&nbsp;另一种系统调度模式：某系统有控制台和推送系统两部分组成，控制台的职责是控制推送系统进行相应的推送工作。管理人员在控制台作的一些操作，实际上是修改了ZK上某些节点的状态，而zk就把这些变化通知给他们注册Watcher的客户端，即推送系统，于是，作出相应的推送任务。&nbsp;</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">3.&nbsp;另一种工作汇报模式：一些类似于任务分发系统，子任务启动后，到zk来注册一个临时节点，并且定时将自己的进度进行汇报（将进度写回这个临时节点），这样任务管理者就能够实时知道任务进度。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">总之，使用zookeeper来进行分布式通知和协调能够大大降低系统之间的耦合。</span></p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">分布式锁</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">分布式锁，这个主要得益于ZooKeeper为我们保证了数据的强一致性，即用户只要完全相信每时每刻，zk集群中任意节点（一个zk&nbsp;server）上的相同znode的数据是一定是相同的。锁服务可以分为两类，</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">一个是保持独占，另一个是控制时序。</span>&nbsp;</p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">所谓保持独占，就是所有试图来获取这个锁的客户端，最终只有一个可以成功获得这把锁。通常的做法是把zk上的一个znode看作是一把锁，通过create&nbsp;znode的方式来实现。所有客户端都去创建&nbsp;/distribute_lock&nbsp;节点，最终成功创建的那个客户端也即拥有了这把锁。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">控制时序，就是所有视图来获取这个锁的客户端，最终都是会被安排执行，只是有个全局时序了。做法和上面基本类似，只是这里&nbsp;/distribute_lock&nbsp;已经预先存在，客户端在它下面创建临时有序节点（这个可以通过节点的属性控制：CreateMode.EPHEMERAL_SEQUENTIAL来指定）。Zk的父节点（/distribute_lock）维持一份sequence,保证子节点创建的时序性，从而也形成了每个客户端的全局时序。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; ">&nbsp;</p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">集群管理</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">1.&nbsp;</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">集群机器</span><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">监控：这通常用于那种对集群中机器状态，机器在线率有较高要求的场景，能够快速对集群中机器变化作出响应。这样的场景中，往往有一个监控系统，实时检测集群机器是否存活。过去的做法通常是：监控系统通过某种手段（比如ping）定时检测每个机器，或者每个机器自己定时向监控系统汇报&#8220;我还活着&#8221;。&nbsp;这种做法可行，但是存在两个比较明显的问题：1.&nbsp;集群中机器有变动的时候，牵连修改的东西比较多。2.&nbsp;有一定的延时。&nbsp;</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">利用ZooKeeper有两个特性，就可以实时另一种集群机器存活性监控系统：a.&nbsp;客户端在节点&nbsp;x&nbsp;上注册一个Watcher，那么如果&nbsp;x&nbsp;的子节点变化了，会通知该客户端。b.&nbsp;创建EPHEMERAL类型的节点，一旦客户端和服务器的会话结束或过期，那么该节点就会消失。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">例如，监控系统在&nbsp;/clusterServers&nbsp;节点上注册一个Watcher，以后每动态加机器，那么就往&nbsp;/clusterServers&nbsp;下创建一个&nbsp;EPHEMERAL类型的节点：/clusterServers/{hostname}.&nbsp;这样，监控系统就能够实时知道机器的增减情况，至于后续处理就是监控系统的业务了。</span><span style="color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">2.&nbsp;</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">Master选举则是zookeeper中最为经典的使用场景了。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">在分布式环境中，相同的业务应用分布在不同的机器上，有些业务逻辑（例如一些耗时的计算，网络I/O处理），往往只需要让整个集群中的某一台机器进行执行，其余机器可以共享这个结果，这样可以大大减少重复劳动，提高性能，于是这个master选举便是这种场景下的碰到的主要问题。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">利用ZooKeeper的强一致性，能够保证在分布式高并发情况下节点创建的全局唯一性，即：同时有多个客户端请求创建&nbsp;/currentMaster&nbsp;节点，最终一定只有一个客户端请求能够创建成功。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">利用这个特性，就能很轻易的在分布式环境中进行集群选取了。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">另外，这种场景演化一下，就是动态Master选举。这就要用到&nbsp;EPHEMERAL_SEQUENTIAL类型节点的特性了。</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">上文中提到，所有客户端创建请求，最终只有一个能够创建成功。在这里稍微变化下，就是允许所有请求都能够创建成功，但是得有个创建顺序，于是所有的请求最终在ZK上创建结果的一种可能情况是这样：&nbsp;/currentMaster/{sessionId}-1&nbsp;,&nbsp;/currentMaster/{sessionId}-2&nbsp;,&nbsp;/currentMaster/{sessionId}-3&nbsp;&#8230;..&nbsp;每次选取序列号最小的那个机器作为Master，如果这个机器挂了，由于他创建的节点会马上小时，那么之后最小的那个机器就是Master了。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">1.&nbsp;在搜索系统中，如果集群中每个机器都生成一份全量索引，不仅耗时，而且不能保证彼此之间索引数据一致。因此让集群中的Master来进行全量索引的生成，然后同步到集群中其它机器。2.&nbsp;另外，Master选举的容灾措施是，可以随时进行手动指定master，就是说应用在zk在无法获取master信息时，可以通过比如http方式，向一个地方获取master。</span></p></td></tr><tr><td width="57" valign="top" style="width:42.8500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:0.7500pt solid #cccccc; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">分布式队列</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">队列方面，我目前感觉有两种，</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">一种是常规的先进先出队列，另一种是要等到队列成员聚齐之后的才统一按序执行</span><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">。对于第二种先进先出队列，和分布式锁服务中的控制时序场景基本原理一致，这里不再赘述。&nbsp;</span></p><p style="margin-bottom:13.5000pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; line-height:13.5000pt; background:#ffffff; "><span style="mso-spacerun:'yes'; color:#333333; font-size:9.5000pt; font-family:'Tahoma'; background:#ffffff; ">第二种队列其实是在FIFO队列的基础上作了一个增强。通常可以在&nbsp;/queue&nbsp;这个znode下预先建立一个/queue/num&nbsp;节点，并且赋值为n（或者直接给/queue赋值n），表示队列大小，之后每次有队列成员加入后，就判断下是否已经到达队列大小，决定是否可以开始执行了。这种用法的典型场景是，分布式环境中，一个大任务Task&nbsp;A，需要在很多子任务完成（或条件就绪）情况下才能进行。这个时候，凡是其中一个子任务完成（就绪），那么就去&nbsp;/taskList&nbsp;下建立自己的临时时序节点（CreateMode.EPHEMERAL_SEQUENTIAL），当&nbsp;/taskList&nbsp;发现自己下面的子节点满足指定个数，就可以进行下一步按序进行处理了。</span></p></td><td width="259" valign="top" style="width:194.7500pt; padding:2.2500pt 7.5000pt 2.2500pt 7.5000pt ; border-left:none; ; ; border-right:0.7500pt solid #cccccc; border-top:none; ; border-bottom:0.7500pt solid #cccccc; background:#ffffff; "><p style="margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; text-align:left; vertical-align:; background:#ffffff; ">&nbsp;</p></td></tr></tbody></table><p style="margin-bottom:0pt; margin-top:0pt; text-align:justify; "></p></div></div><img src ="http://www.blogjava.net/matuobasyouca/aggbug/378164.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/matuobasyouca/" target="_blank">一酌散千忧</a> 2012-05-15 11:02 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/05/15/378164.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>maven自动化测试环境搭建</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/04/05/373359.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Thu, 05 Apr 2012 03:26:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/04/05/373359.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/373359.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/04/05/373359.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/373359.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/373359.html</trackback:ping><description><![CDATA[<p><span style="font-family: 宋体; ">环境背景：</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">我作为项目经理和技术架构管理人员负责公司一条生产线。讨论之后，首席架构师希望我们能够实施</span>TDD<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。在实施</span>TDD<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的过程中，设计实施过程的整体思路就是：单元测试用例文档</span> - <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">实施单元测试</span> - <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">实施业务代码</span> &#8211; <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">修改业务代码逻辑。实施人员需要参与每个环节，按照规范编写单元测试用例文档。单元测试我们按照模块（模块与人员基本没有重合）划分包（</span>suite<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">），保证实施起来不会产生干扰。。技术架构决定采用：</span>maven<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，</span>junit<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，</span>svn<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">。</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">技术背景：</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">技术架构设计上，我们封装了</span>dao<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">层的实现，所以实施人员基本无需涉及</span>dao<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">层的开发。服务层我们采用了</span>JAX-RS<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的服务规范，对外开发服务接口。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在测试覆盖率方面，我们基本不要求对</span>dao<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">层的单元测试，但要求在服务层的单元测试达到</span>100%<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。由于服务层是</span>Restful WS<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的模式，所以我们采用了模拟</span>HTTP<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">请求的方式在测试服务层。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">由于需要模拟</span>HTTP<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的请求，所以我们在单元测试中采用了</span>jetty<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">作为内嵌服务器，单元测试开始时同一启动，完成后关闭。</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">实施过程：</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">开发过程中，实际实施的时候发现一个问题，对于测试数据的管理问题。即测试当中需要一定的数据环境来验证业务逻辑。这个数据环境如何建立？</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">方案一，使用</span>dbunit<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">和</span>hsqldb<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。在测试启动时重建数据环境。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">否决，原因：</span></p>  <p>1.<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">与实际运行环境差异较大。</span></p>  <p>2.<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">反复重建数据环境，效率上有缺失。</span></p>  <p>3.<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">技术架构增加，学习和维护曲线较大。</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">讨论后决定使用</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">方案二，独立出一套测试数据库，完整数据环境。考虑到增删改与查询的冲突，制定默认规则，如</span>id<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">在</span>20<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">之内的不允许进行任何改动。以尽量隔离增删改的影响。</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">针对方案二，有一个较大的问题，如何在开发过程中自由的切换数据库配置呢？由于我们还是用了</span>Hudson<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">作为</span>CI<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">服务器，还要考虑到打包的过程。整体考虑之后，有两个步骤需要注意：</span></p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;">一、<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">开发过程。开发过程中，我们将配置直接指向测试数据库。</span></p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;">二、<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">打包过程。使用了</span>maven<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，存在单元测试配置与最终产品配置的冲突。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">所以最终问题的焦点集中在打包过程的</span>maven<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">配置方案。</span></p>  <p>&nbsp;</p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">搜索之后比较好的资料有</span></p>  <p>MAVEN:<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">如何为开发和生产环境建立不同的配置文件</span> --<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">我的简洁方案</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（</span><a href="http://www.blogjava.net/scud/archive/2010/10/27/336326.html">http://www.blogjava.net/scud/archive/2010/10/27/336326.html</a><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这篇博客是介绍在</span>maven <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">中使用</span>mvn package -P test <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">这样的自定义</span>profile<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">来实现的。这样是可行的，但是在</span>Hudson<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">中无法实现一条命令切换两套配置。</span></p>  <p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">于是继续寻找，最终在</span>maven<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的官方网站找到《</span>Building For Different Environments with Maven 2<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">》（</span><a href="http://maven.apache.org/guides/mini/guide-building-for-different-environments.html">http://maven.apache.org/guides/mini/guide-building-for-different-environments.html</a><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）看完文章之后发现，实际</span>maven<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">提供了一个非常好的插件</span>maven-antrun-plugin<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">，以实现某些</span>ant<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的功能。此处还需要了解的知识就是</span>maven<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的构建生命周期标准（</span>http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）。基于上述两个知识点，我们制定出如下方案，<strong>在项目中建立测试配置目录及产品配置目录，在</strong></span><strong>maven</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的</span>package</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">阶段开始前，都使用测试配置，运行集成测试，完成在</span>package</strong><strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">阶段前将产品配置覆盖至打包文件夹内，然后进行打包</span></strong><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。思路就是这样，下面贴出</span>pom<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">文件的关键部分。</span></p>  <p>&nbsp;</p>  <p>&nbsp;</p>  <p>POM.xml</p>  <p>&lt;!&#8212;profile <span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">节点定义覆盖文件的方式内容</span> --&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;profiles&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;profile&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;id&gt;product&lt;/id&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;build&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;plugins&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;plugin&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;artifactId&gt;maven-antrun-plugin&lt;/artifactId&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;executions&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;execution&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;id&gt;pre_product&lt;/id&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;phase&gt;prepare-package&lt;/phase&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;goals&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;goal&gt;run&lt;/goal&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/goals&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;configuration&gt;</p>  <p>&lt;!&#8212;<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">此处与</span>ant<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的任务相似</span> --&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tasks&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;delete file="${project.build.outputDirectory}/spring/dataSourceContext.xml" /&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;delete file="${project.build.outputDirectory}/log4j.properties" /&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;copy file="src/product/assembly/log4j.properties" tofile="${project.build.outputDirectory}/log4j.properties" /&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;copy file="src/product/assembly/spring/dataSourceContext.xml" tofile="${project.build.outputDirectory}/spring/dataSourceContext.xml" /&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/tasks&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/configuration&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/execution&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/executions&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/plugin&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/plugins&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/build&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/profile&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/profiles&gt;</p>  <p>&nbsp;</p>  <p>&lt;!&#8212;<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">构建过程</span> --&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;build&gt;</p>  <p style="text-indent:21.0pt">&lt;!&#8212;<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">指定资源目录</span> --&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;resources&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;resource&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;directory&gt;src/test/resources&lt;/directory&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;includes&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;include&gt;**/*&lt;/include&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/includes&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/resource&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;resource&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;directory&gt;src/test/assembly&lt;/directory&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;includes&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;include&gt;**/*&lt;/include&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/includes&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/resource&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/resources&gt;</p>  <p>&nbsp;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;finalName&gt;po&lt;/finalName&gt;</p>  <p>&nbsp;</p>  <p style="margin-left:21.0pt;text-indent:21.0pt">&lt;!&#8212;<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">指定集成测试配置</span> --&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;plugins&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;plugin&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;version&gt;2.4.3&lt;/version&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;configuration&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;junitArtifactName&gt;junit:junit&lt;/junitArtifactName&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;forkMode&gt;once&lt;/forkMode&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/configuration&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;executions&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;execution&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;id&gt;default-test&lt;/id&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;phase&gt;integration-test&lt;/phase&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;goals&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;goal&gt;test&lt;/goal&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/goals&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;configuration&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;skip&gt;false&lt;/skip&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;includes&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;include&gt;**/*TestSuitex.java&lt;/include&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/includes&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/configuration&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/execution&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/executions&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/plugin&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/plugins&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/build&gt;</p><img src ="http://www.blogjava.net/matuobasyouca/aggbug/373359.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/matuobasyouca/" target="_blank">一酌散千忧</a> 2012-04-05 11:26 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/04/05/373359.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>企业技术体系架构建设</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/03/29/372996.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Thu, 29 Mar 2012 08:27:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/03/29/372996.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/372996.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/03/29/372996.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/372996.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/372996.html</trackback:ping><description><![CDATA[<div style="text-align: center;"></div>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;">软件企业的技术体系架构包括对软件产品本身及生产过程、软件生产环境及生产者的管理和支持，此架构应当基于下列五项基础建设之上：</span></p>  <p align="left" style="margin-left:42.0pt;text-align:left; text-indent:-21.0pt;"><span style="font-size:12.0pt;font-family:Wingdings;">l</span> <span style="font-size:12.0pt;font-family:宋体;">开发技术架构</span></p>  <p align="left" style="margin-left:42.0pt;text-align:left; text-indent:-21.0pt;"><span style="font-size:12.0pt;font-family:Wingdings;">l</span> <span style="font-size:12.0pt;font-family:宋体;">开发环境架构</span></p>  <p align="left" style="margin-left:42.0pt;text-align:left; text-indent:-21.0pt;"><span style="font-size:12.0pt;font-family:Wingdings;">l</span> <span style="font-size:12.0pt;font-family:宋体;">过程管理架构</span></p>  <p align="left" style="margin-left:42.0pt;text-align:left; text-indent:-21.0pt;"><span style="font-size:12.0pt;font-family:Wingdings;">l</span> <span style="font-size:12.0pt;font-family:宋体;">企业产品架构</span></p>  <p align="left" style="margin-left:42.0pt;text-align:left; text-indent:-21.0pt;"><span style="font-size:12.0pt;font-family:Wingdings;">l</span> <span style="font-size:12.0pt;font-family:宋体;">企业人件架构</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;">下面详细介绍各项架构的内容及特点。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;">&nbsp;</p>  <p align="left" style="text-align:left;">&nbsp;</p>  <p align="left" style="text-align:left;"><strong><span style="font-size:14.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;;">开发技术架构</span></strong><strong></strong></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">开发技术架构作为一个软件企业的基石，包括可复用的架构组件、公用的基础代码库等。开发技术框架应当在一个良好的过程管理之下，严格的质量管理与实用性检查，并且鼓励普通技术人员的参与。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">1.</span><span style="font-size:12.0pt;font-family:宋体;">建立技术架构仓库标准体系与维护模式。建议使用MAVEN作为所有开发技术（包括架构预研与实际项目开发）的基础项目管理工具，实施严格的质量管理和持续集成。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">2.</span><span style="font-size:12.0pt;font-family:宋体;">选拔组建高素质的架构师队伍，并且鼓励技术人员参与到技术架构仓库的构建和维护。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">3.</span><span style="font-size:12.0pt;font-family:宋体;">加强技术架构实用性与适用性的检查与改造。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">4.</span><span style="font-size:12.0pt;font-family:宋体;">架构运营模式的考察，技术架构的改进与预研。技术架构的预研模式比较复杂，多个部门中多个项目可能都会要求进行多个同类框架的考察、比较、环境搭建等工作，若集中在独立架构组可能压力较大。可以考虑架构组内部划分为多个技术领域，如企业基础应用架构、消息中间件、动态化组件、分布式集群等。以技术部门的实施领域作为导向，进行技术架构的预研。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">5.</span><span style="font-size:12.0pt;font-family:宋体;">开放知识系统的构建（内部wiki，个人博客，视频分享）</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">根据企业行业背景，需要关注的技术领域包括：企业应用、ESB/SOA、大型分布式架构（在线/离线），自然语言处理。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;">&nbsp;</p>  <p align="left" style="text-align:left;"><strong><span style="font-size:14.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;;">开发环境架构</span></strong><strong></strong></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">包含IDE，编译环境，远程支持，通讯支持与其他大量功能性支持软件，并可以根据不同的工作角色制定不同的环境，以便排除干扰，更加快速有效的进入工作状态。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">项目的关键问题是沟通，个性化的工具妨碍&#8212;&#8212;而不是促进沟通。开发和维护公共的通用编程/项目管理工具有很多的好处。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">1.</span><span style="font-size:12.0pt;font-family:宋体;">建立具有鲜明特色与强大实用性的自有开发环境，展示一个软件龙头企业在企业技术沉淀中的深厚功力和规范性。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">2.</span><span style="font-size:12.0pt;font-family:宋体;">建立行政流程以规范和约束开发环境管理。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">3.</span><span style="font-size:12.0pt;font-family:宋体;">划分相关职能以保持对开发环境的维护</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">4.</span><span style="font-size:12.0pt;font-family:宋体;">建立多种培训机制以促进新员工能够迅速投入工作。如固定新员工开发环境熟悉培训机制，建立企业讲解&amp;培训视频库，小组内互助&amp;沟通。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;">&nbsp;</p>  <p align="left" style="text-align:left;"><strong><span style="font-size:14.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;;">过程管理架构</span></strong><strong></strong></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">1.</span><span style="font-size:12.0pt;font-family:宋体;">过程方法</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">对多家企业软件生命周期中使用的过程方法进行调查了解到，大部分优秀的软件企业对于过程方法十分重视，且存在针对不同项目合理运用不同的过程方法。项目经理对于过程方法的理解与运用常常关系到项目的成败。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">目前核心的管理模型/过程方法主要分为三大类：CMMI，RUP，敏捷。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">CMMI</span><span style="font-size:12.0pt;font-family:宋体;">作为软件质量体系的标准，软件企业必须具备的资质，具有文档齐全，流程规范等优势，对于大型核心项目有较大优势，其劣势在于灵活度不足，无法很好的满足日益变化的需求。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">RUP</span><span style="font-size:12.0pt;font-family:宋体;">由Rational公司（被IBM收购，目前是IBM 软件集团旗下之第五大软件品牌）提出，采用迭代开发模式，四个阶段，九大核心工作流，明确的角色划分与文档规划，可裁剪配置的开发过程。目前被大量的软件厂商作为最核心的过程方法使用。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">敏捷（Agile）为了满足队伍小型化和需求快速变化而产生的目前最流行的过程方法。XP（Extreme Programming）通过简单的四个核心价值（沟通（Communication）、简单（Simplicity）、反馈（Feedback）和勇气（Courage））与十二条最佳实践从研发的角度提出了最简单直接的开发方式。XP的形态特殊，从编程的角度描述方法与原则，加入了SCRUM之后，加强了从行政体制方面的支持，从而形成了完整的敏捷开发的过程方法体系。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;">&nbsp;</p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">过程方法一定不是万金油，针对不同的企业特点，甚至不同项目，都有必要对过程方法进行合理的裁剪与整合。对于目前公司的情况，大型核心项目可以使用CMMI，这些往往决定了企业的战略方向，稳健的过程方法最为合适。大部分中小型项目均可采用 RUP+敏捷 的过程方法，即遵守RUP的核心阶段和工作流，但是迭代周期和开发的基本原则根据敏捷，并挑战整合部分敏捷方法中的最佳实践。这样的策略用于面对市场需求的快速变化，同时也能很好的保障企业在软件生产中的产品价值保存和技术经验积累。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;">&nbsp;</p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">2.</span><span style="font-size:12.0pt;font-family:宋体;">过程方法自动化支持</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">针对不同的过程方法，往往有若干的软件产品用以快速自动化的实施。如实施CMMI时所使用到的DEVSUITE产品。完整体系的支持产品往往在应用于某套固定方法有着良好的效果，但容易存在流程生硬，无法与开发环境更好结合形成了信息孤岛，改进困难等缺点。一套优秀的过程方法支持软件，需要和开发环境（如IDE等）良好结合，并且易于调整以应对过程方法的变化，同时没有复杂冗余的过多细节流程以便容易被开发人员学习和掌握。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">产品涉及方面：项目计划、项目需求管理、软件配置管理、自动集成、自动产品发布、代码审核、代码质量管理等。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;">&nbsp;</p>  <p align="left" style="text-align:left;text-indent:24.0pt;">&nbsp;</p>  <p align="left" style="text-align:left;"><strong><span style="font-size:14.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;;">企业产品架构</span></strong><strong></strong></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">1.</span><span style="font-size:12.0pt;font-family:宋体;">产品/产品需求流程补充，产品立项时的立项报告中应当包含市场、竞争对手、对手产品、风险等分析。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">2.</span><span style="font-size:12.0pt;font-family:宋体;">领域模型与概念，在特定的行业中可以即使关注领域专家的动态，以便构建正确的领域模型，确定产品的发展方向和形态的正确性。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">3.</span><span style="font-size:12.0pt;font-family:宋体;">对于特定产品的领域概念及相关技术发展需要深入了解，如舆情分析系统，需要进行了一定的市场调查，跟进了当前领域专家的报告，参考国内外多项相关项目的设计理念和原则。对于目前市场状况、未来的方向、目前的技术实力等要有比较清晰的概念</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size:12.0pt;font-family:宋体;">4.</span><span style="font-size:12.0pt;font-family:宋体;">坚持以市场为导向的原则，在商务部门与研发部门之间搭建积极的沟通桥梁，研发部门的计划根据实际市场需求进行调整。产品的发布配合市场的要求，达到利益最大化。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;">&nbsp;</p>  <p align="left" style="text-align:left;text-indent:24.0pt;">&nbsp;</p>  <p align="left" style="text-align:left;"><strong><span style="font-size:14.0pt;font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;;">企业人件架构</span></strong><strong></strong></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">企业自身环境除了常见的软件（Software），硬件（Hardware）以为，还应当加入人件（Peopleware）。之前的种种，如过程方法、技术架构积累、知识分享等均是为了将整个企业构建成为一部精密的机器，无论缺少什么重要零件均可以快速修复，但是人员流失所造成的损失是巨大的。目前公司有着良好的软硬件环境，技术部门作为发动机，若在针对技术性员工有特别的规划和关心，必然能够增强在整个市场中的竞争力，对企业自身的发展也是有良好的推进作用。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">公司可以按照职位和员工自身的情况规划发展路线，明确技术目标。开发进化角色基本按照软考标准，程序员-高级程序员-软件设计师-系统分析师-系统架构师，程序员-高级程序员-项目经理。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">在技术部门内部，可以定期组织交流心得、新技术等。（在SCRUM中实际上有一些比较好的行政手段可以借鉴参考）</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">由于软件技术部门的特殊性，一些应用于生产线的行政制度可能能够讨论出更好的实施方案，避免员工单方面的错误认识引发消极的工作态度。</span></p>  <p align="left" style="text-align:left;text-indent:24.0pt;"><span style="font-size: 12.0pt;font-family:宋体;">由于有一定经验，而且公司技术架构建设的需要，能够很好的协助企业进行技术架构全方面的介绍和培训。而且我自身也很希望参与到企业文化的建设工作中去，鼓励技术人员之间的技术交流与沟通。</span></p>  <p>&nbsp;</p><img src ="http://www.blogjava.net/matuobasyouca/aggbug/372996.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/matuobasyouca/" target="_blank">一酌散千忧</a> 2012-03-29 16:27 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/03/29/372996.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>