﻿<?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/</link><description>敏捷、分布式、ALM过程自动化、企业应用架构</description><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 10:39:41 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 10:39:41 GMT</pubDate><ttl>60</ttl><item><title>近期HADOOP（1.0.3）实施心得与总结</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/08/08/385087.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Wed, 08 Aug 2012 12:21:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/08/08/385087.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/385087.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/08/08/385087.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/385087.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/385087.html</trackback:ping><description><![CDATA[<div>
<div>
<p style="margin-bottom:0pt; margin-top:0pt; "><span class="Apple-style-span" style="font-family: 宋体; ">Hadoop实施已经有快一个月了，对Hadoop的概念理解、使用，Linux与shell脚本，甚至mysql都有了更多的理解。<br /><br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">项目背景</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">：用于互联网信息收集后的关键词匹配与内容提取。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">主要系统架构分为互联网爬虫、分析、业务应用三块：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; text-align:center; "><img width="341" height="399" src="http://www.blogjava.net/images/blogjava_net/matuobasyouca/52361/r_%e5%9b%be%e7%89%872.jpg" alt="" /></p>
<p style="margin-bottom:0pt; margin-top:0pt; text-align:center; "><span style="mso-spacerun:'yes'; font-size:9.0000pt; font-family:'宋体'; ">简单架构描述</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">由于我在当中的角色主要负责分析架构的搭建，所以其他两块都画得简单，下面也不会过多的描述。<br /><br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">Hadoop理解</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">：提到Hadoop都想到的是云、分布式计算，在一段时间的实施之后有了一些具体的理解。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">Hadoop的优势：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">针对</span><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">性能指标</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">，当业务数据量总量或增速上升到一定级别，依靠关系型数据库一定无法支持。对于非关系型数据库，包括Nosql和Solr一类存储方式，稍显复杂，对于机器集群性能要求偏高（相对于文件系统）。从</span><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">数据使用模式</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">上来讲，目前海量数据的常常是不包含复杂逻辑的简单统计整理（比如上述系统中的关键词匹配）。这时候文件系统的优势反而比较明显（结构简单，逻辑简单）。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">如上述系统的应用场景是怎么样的呢，在一个强大的爬虫系统之下，每个小时的数据增量在G到10G的级别，需要搜索所有的文件，获取关键字的匹配，并且对匹配内容进行摘要。很类似我们windows里面的搜索功能，需要解决的就是如何在这样增幅的文件系统之下，如何满足业务系统的需求。<br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">对</span><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">分析系统有什么要求</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">呢？</span></p>
<p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">能够建立集群，分布式的保存数据文件内容（统一控制，可配置）。</span></p>
<p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">有一定的保护机制，保证数据或节点丢失不会影响系统使用。</span></p>
<p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">如果有一个任务脚本执行框架机制就好了（用于并行计算）。</span></p>
<p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">能够进行节点间的数据均衡。</span></p>
<p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">能够简单的查看所有的状态与日志（web客户端）<br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">可能主要是这些了。若自己实现，确实是个复杂而庞大的工程，现在我们有了Hadoop。<br /><br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">系统物理架构：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">我们使用了一台服务器，利用虚拟化，安装了7套64x位的CentOS。一个Namenode，6个Datanode，复制数设置为3。每个系统分配到一个cpu，2G内存，Datanode挂载了500G的存储空间。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">理想的Hadoop的搭建环境，参照《Best&nbsp;Practices&nbsp;for&nbsp;Selecting&nbsp;Apache&nbsp;Hadoop&nbsp;Hardware》（http://hortonworks.com/blog/best-practices-for-selecting-apache-hadoop-hardware/）一文，以及一些其他的文章。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">CPU：最好是双CPU，8核左右。不用太高了。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">内存：推荐48G，但是4G应该就可以运行Hadoop了。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">硬盘：7200转的SATA硬盘即可，Hadoop很占空间，所以尽量加。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">网络：内部的数据交换要求非常高，内网最好是千兆网卡，带宽为1GB。<br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">理想与现实，有钱与没钱，呵呵。<br /><br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">系统软件架构：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">Hadoop：版本使用的是1.0.3，再下来就是2了，为了尽量简化应用，所以不考虑2的新特性。对Hadoop没有做太多的设置，基本基于默认。70为Namenode，71-76为Datanode。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">JDK：1.6.0_33&nbsp;（64x）<br /><br /><br /></span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-weight:bold; font-size:10.5000pt; font-family:'宋体'; ">系统实施过程：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">HDFS部分：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">爬虫抓取数据，整理后存放在50文件服务器，70以外部挂载的形式读取。网页文件比较小，假如直接写入Hadoop对Namenode负载过大，所以入库前合并，将每小时网页整合成为一个文件写入HDFS，由于区分类别，所以每小时基本写入10个文件左右，总量在5-8G，耗时在40-50分钟。（这个过程中，由于爬虫的IO过于频繁，导致文件读取困难，所以做了定时任务，每小时启动一次，将需要处理的文件先拷贝到临时区域，合并入库之后再删除。此处应该是受到单核cpu的限制，所有操作均是串行，包括拷贝（cp）和合并入库（java），所以Namenode严重建议配置稍高。）</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">此处没有太多问题。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">MapReduce部分：</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">写入完成后，进行分析工作，MapReduce。此处的工作过程为：数据库定时生成关键词列表文件。Job执行时会读取列表文件，匹配指定范围内的HDFS文件（过去一小时），匹配出对应的表达式与HTML，Map过程结束。在Reduce阶段，会将Map的所有数据入数据库（Mysql）。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">此处出现过一些问题，记录下来。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">1.&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">Reduce阶段需要加载Mysql的第三方驱动包。我在三个环境测试过（公司、家里、发布环境），使用&nbsp;-libjars&nbsp;一定可以，有的地方不需要也可以。不明确，怀疑与HADOOP_HOME环境变量有关。</span></p>
<p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">2.&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">MR过程中使用log4j打印日志，在Hadoop临时目录（如果你没有配置dfs.name.dir，dfs.data.dir,mapred.local.dir.mapred.system.dir等目录，这些都会在hadoop.tmp.dir当中，我就偷懒都没配置）mapred文件夹中查看一下。</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:'宋体'; ">整个过程实际上还是比较简单的，基本编码量就在Job的部分，但是一个Java文件就够了。在目前初级阶段应该还是比较好用的。现在还没有测试Job的执行效率。完成后会继续记录下来。有什么问题可以提出。我想到什么也会在本文继续更新。</span></p>
</div>
</div><img src ="http://www.blogjava.net/matuobasyouca/aggbug/385087.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-08-08 20:21 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/08/08/385087.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hadoop完整分布式配置方式(Fully distributed mode)</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/07/04/382150.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Tue, 03 Jul 2012 23:38:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/07/04/382150.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/382150.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/07/04/382150.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/382150.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/382150.html</trackback:ping><description><![CDATA[<div><p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; "></span></p><p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">硬件资源：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">三台</span><span style="font-family: Verdana; ">CentOS5.6</span><span style="font-family: 宋体; ">虚拟机（</span><span style="font-family: Verdana; ">Vmware</span><span style="font-family: 宋体; ">）</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">本机</span><span style="font-family: Verdana; "> windows7 64x</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">基本资源配置：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">三台虚拟机均是克隆自同一个镜像</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">已经安装了</span><span style="font-family: Verdana; ">Java</span><span style="font-family: 宋体; ">环境（</span><span style="font-family: Verdana; ">jdk1.6.0_25</span><span style="font-family: 宋体; ">）</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">Hadoop</span><span style="font-family: 宋体; ">路径在</span><span style="font-family: Verdana; ">/usr/hadoop/hadoop-0.20.205.0</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><strong><span style="font-family: 宋体; ">操作步骤：</span></strong><strong></strong></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">1</span><span style="font-family: 宋体; ">、机器名称规范</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">ip</span><span style="font-family: 宋体; ">分别为</span><span style="font-family: Verdana; ">128</span><span style="font-family: 宋体; ">、</span><span style="font-family: Verdana; ">129</span><span style="font-family: 宋体; ">、</span><span style="font-family: Verdana; ">130</span><span style="font-family: 宋体; ">，将</span><span style="font-family: Verdana; ">128</span><span style="font-family: 宋体; ">设置为</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">，其他设置为</span><span style="font-family: Verdana; ">slave</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">修改</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">/etc/sysconfig/network</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">/etc/hosts</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">两处配置，名称分别为</span><span style="font-family: Verdana; ">hadoop-master\hadoop-slave01\hadoop-slave02</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体;color:red;">注意</span><span style="font-family: 宋体; ">：此处名称最好不用使用下划线，有可能引发</span><span style="font-family: Verdana; ">namenode</span><span style="font-family: 宋体; ">的启动异常。</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">2</span><span style="font-family: 宋体; ">、修改</span><span style="font-family: Verdana; ">Hadoop</span><span style="font-family: 宋体; ">配置</span>&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">在</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">节点的</span><span style="font-family: Verdana; ">conf</span><span style="font-family: 宋体; ">中修改</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">和</span><span style="font-family: Verdana; ">slave</span><span style="font-family: 宋体; ">文件，分别为机器的</span><span style="font-family: Verdana; ">ip</span><span style="font-family: 宋体; ">地址</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">修改</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">节点的</span><span style="font-family: Verdana; ">conf</span><span style="font-family: 宋体; ">中：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">core-site.xml</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;name&gt;fs.default.name&lt;/name&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;value&gt;hdfs://ip-master:9000&lt;/value&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;/property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">mapred-site.xml</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;name&gt;mapred.job.tracker&lt;/name&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;value&gt;master:9001&lt;/value&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;/property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">hdfs-site.xm</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;name&gt;dfs.replication&lt;/name&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;value&gt;2&lt;/value&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">&lt;/property&gt;</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">注意此处的端口号均为默认。</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">3</span><span style="font-family: 宋体; ">、建立</span><span style="font-family: Verdana; ">m-s</span><span style="font-family: 宋体; ">之间的</span><span style="font-family: Verdana; ">ssh</span><span style="font-family: 宋体; ">连接</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">首先</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">与</span><span style="font-family: Verdana; ">slave</span><span style="font-family: 宋体; ">机器都需要进行</span><span style="font-family: Verdana; ">ssh</span><span style="font-family: 宋体; ">信任文件生成，执行如下命令：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">$ ssh-keygen -t rsa</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">中间需要输入的地方直接回车，接受缺省值即可</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">由于使用</span><span style="font-family: Verdana; ">root</span><span style="font-family: 宋体; ">用户登录，所以密钥文件生成在</span><span style="font-family: Verdana; "> /root/.ssh/</span><span style="font-family: 宋体; ">文件夹下，存有一对密钥</span><span style="font-family: Verdana; ">id_dsa</span><span style="font-family: 宋体; ">和</span><span style="font-family: Verdana; ">id_dsa.pub</span><span style="font-family: 宋体; ">。</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">此处</span><span style="font-family: Verdana; ">id_dsa</span><span style="font-family: 宋体; ">（私钥）必须为其他用户不可读，所以文件属性应当是</span><span style="font-family: Verdana; ">600</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">在</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">机器执行：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">将</span><span style="font-family: Verdana; ">id_dsa.pub</span><span style="font-family: 宋体; ">（公钥）复制为</span><span style="font-family: Verdana; "> authorized_keys</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">$ cp id_dsa.pub authorized_keys</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">如果是多台机器需要</span><span style="font-family: Verdana; ">,</span><span style="font-family: 宋体; ">无密码登陆</span><span style="font-family: Verdana; ">,</span><span style="font-family: 宋体; ">则各自机器产生公钥追加到</span><span style="font-family: Verdana; ">authorized_keys</span><span style="font-family: 宋体; ">即可</span><span style="font-family: Verdana; ">.</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">使用</span><span style="font-family: Verdana; ">scp</span><span style="font-family: 宋体; ">协议覆盖</span><span style="font-family: Verdana; ">slave</span><span style="font-family: 宋体; ">端的密钥文件夹，使得</span><span style="font-family: Verdana; ">slave</span><span style="font-family: 宋体; ">机器信任来自</span><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">的连接</span><span style="font-family: Verdana; ">:</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">$ scp /root/.ssh/* ip-slave:/root/.ssh</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">4</span><span style="font-family: 宋体; ">、启动服务</span>&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">建议将</span><span style="font-family: Verdana; ">$HADOOP_HOME/bin</span><span style="font-family: 宋体; ">下的所有文件给与执行权限：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">$ chmod 777 bin</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">master</span><span style="font-family: 宋体; ">作为</span><span style="font-family: Verdana; ">namenod</span><span style="font-family: 宋体; ">需要执行如下脚本：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">$HADOOP_HOME/bin/hadoop namenode &#8211;format</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">完成后执行</span><span style="font-family: Verdana; "> $HADOOP_HOME/bin/start-all.sh</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">5</span><span style="font-family: 宋体; ">、问题检查</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: 宋体; ">在</span><span style="font-family: Verdana; ">Hadoop</span><span style="font-family: 宋体; ">根目录下的</span><span style="font-family: Verdana; ">logs</span><span style="font-family: 宋体; ">文件中，检查各个服务日志的启动情况</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">6</span><span style="font-family: 宋体; ">、其他情况说明：</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">Q: $HADOOP_HOME is deprecated</span></p>  <p align="left" style="margin-bottom:12.0pt;text-align:left; line-height:15.75pt;"><span style="font-family: Verdana; ">A: </span><span style="font-family: 宋体; ">基本不会产生任何影响。由于脚本启动时设置了该环境变量，就会提示用户原有环境变量失效。可以取消环境变量设置，或者直接去</span><span style="font-family: Verdana; ">bin/hadoop</span><span style="font-family: 宋体; ">中找到这句话，去掉即可</span></p>  <p align="left" style="margin-bottom:12.0pt;text-align:left; line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">Q: </span><span style="font-family: 宋体; ">无效的选项</span><span style="font-family: Verdana; "> -jvm / Unrecognized option: -jvm</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;"><span style="font-family: Verdana; ">A: </span><span style="font-family: 宋体; ">在使用</span><span style="font-family: Verdana; ">root</span><span style="font-family: 宋体; ">用户登录时</span><span style="font-family: Verdana; "> bin/hadoop </span><span style="font-family: 宋体; ">脚本就会进行判断，加上</span><span style="font-family: Verdana; ">-jvm</span><span style="font-family: 宋体; ">参数。此处是为了进入</span><span style="font-family: Verdana; ">jsvc</span><span style="font-family: 宋体; ">（</span><span style="font-family: Verdana; ">http://commons.apache.org/daemon/jsvc.html</span><span style="font-family: 宋体; ">），此处并不确定是否</span><span style="font-family: Verdana; ">bug</span><span style="font-family: 宋体; ">，也不再进行详细的追溯，解决方法就是进入</span><span style="font-family: Verdana; "> bin/hadoop </span><span style="font-family: 宋体; ">脚本中</span> <span style="font-family: 宋体; ">找到</span><span style="font-family: Verdana; "> jvm </span><span style="font-family: 宋体; ">参数并去掉。</span></p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p align="left" style="text-align:left;line-height:15.75pt;">&nbsp;</p>  <p>&nbsp;</p><p>&nbsp;</p></div><div></div><img src ="http://www.blogjava.net/matuobasyouca/aggbug/382150.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-07-04 07:38 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/07/04/382150.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><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>MongoDB, Java 与对象关系映射</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/05/09/377698.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Wed, 09 May 2012 05:46:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/05/09/377698.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/377698.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/05/09/377698.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/377698.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/377698.html</trackback:ping><description><![CDATA[<div>  <h2><span style="font-size:14.5pt;font-family:Arial;color:black;letter-spacing:-.75pt">MongoDB</span><span><span style="font-size:14.5pt;color:black;letter-spacing:-.75pt">介绍</span></span><span></span></h2>  <p><span>当今<span>NoSQL领域中有很多有力的竞争者通过多种方式来处理海量数据问题。其中重要的解决方案之一就是MongoDB。MongoDB是面向文档的弱结构化存储方案，使用JSON格式来展现、查询和修改数据。</span></span></p>  <p><span><span>MongoDB文档相当完备，扩展规模与安装一样简单。它提供冗余、切片、索引以及map/reduce等概念支持。MongoDB的开源社区非常大且非常活跃。MongoDB在很多大型产品中被实际运用，如：Disney, Craigslist, Foursquare, Github 和SourceForge。MongoDB是一个开源项目，由</span></span><a href="http://www.10gen.com/"><span><span style="color:#0B59B2">10gen.com</span></span></a><span>建立并维护，该公司由<span>DoubleClick的前任执行人员创立。同时，10gen也提供了极好的商业支持与参与建设。</span></span></p>  <h2><span><span><span style="font-size:14.5pt; font-family:Arial;color:black;letter-spacing:-.75pt">MongoDB </span></span></span><span><span style="font-size:14.5pt;color:black;letter-spacing:-.75pt">与</span></span><span><span><span style="font-size:14.5pt;font-family:Arial;color:black;letter-spacing: -.75pt"> NoSQL: </span></span></span><span><span><span style="font-size:14.5pt;color:black; letter-spacing:-.75pt">缺陷与优势</span></span></span><span></span></h2>  <p><span><span>MongoDB作为一个可用NoSQL方案具有很多优势。我刚开始接触NoSQL数据库了解了一系列基于Java的方案，并且花了大量的时间来弄懂什么是列家族，Hadoop与HBase的关系，ZooKeeper到底是什么。当我终于全部清楚之后，发现Cassandra与HBase确实是对于NoSQL领域非常可靠、可信赖的解决方案。但与其他的解决方案相比，MongoDB让我在能够开始写代码之前，不用理解那么多的概念。</span></span></p>  <p><span>与其他软件相似，<span>MongoDB也存在缺陷。经过一段时间使用MongoDB，我列举经历过并需要注意的一些事情，我成为&#8220;Gotchas&#8221;：</span></span></p>  <ul type="disc"><li style="      text-align:left;"><span><span style="font-family:宋体;">不要按照关系型数据库来思考。这很明显，MongoDB</span></span><span><span style="font-family:宋体;">使得构建和执行复杂查询变得非常容易。当实际使用的时候，你会主要关注于效率问题（像我一样）。</span></span></li><li style="      text-align:left;"><span><span>MongoDB</span></span><span><span style="font-family:宋体;">的索引是二进制的树。如果你不是很熟悉B-tree</span></span><span><span style="font-family:宋体;">，可能需要了解一下。这些都涉及到构建符合提供查询条件需求的建立索引的方式。</span></span></li><li style="      text-align:left;"><span><span style="font-family:宋体;">小心的设计索引结构。这涉及到上面提到的B-tree</span></span><span><span style="font-family:宋体;">。刚开始我的索引包含文档中的很多字段，以防我会使用到他们。不要犯同样的错误。我有一个很小集合的索引（大约1</span></span><span><span style="font-family:宋体;">千万记录）增长到超过17GB</span></span><span><span style="font-family:宋体;">的空间，比集合本身还大。你应该不会想要索引一个包含成百上千个实体的列表字段。</span></span></li><li style="      text-align:left;"><span><span>MongoDB</span></span><span><span style="font-family:宋体;">采用了非常有意思的方式来实现NoSQL</span></span><span><span style="font-family:宋体;">：采用BSON</span></span><span><span style="font-family:宋体;">作为存储，JSON</span></span><span><span style="font-family:宋体;">作为展示，JavaScript</span></span><span><span style="font-family:宋体;">用于管理和Map/Reduce</span></span><span><span style="font-family:宋体;">。因此也引起了一些小问题比如</span></span><a href="https://jira.mongodb.org/browse/SERVER-1672"><span><span><span style="font-family:      宋体;color:#0B59B2">这个</span></span></span></a><span> </span><span><span style="font-family:宋体;">（破坏了Number</span></span><span><span style="font-family:宋体;">和Long</span></span><span><span style="font-family:宋体;">的相等操作），在MongoDB</span></span><span><span style="font-family:宋体;">逐渐流行之后，可能会不断的展示出来。</span></span></li></ul>  <p><span>&nbsp;</span></p>  <h2><span><span><span style="font-size:14.5pt; font-family:Arial;color:black;letter-spacing:-.75pt">MongoDB, </span></span></span><span><span style="font-size:14.5pt;color:black;letter-spacing:-.75pt">命令行与驱动</span></span><span></span></h2>  <p><span><span>MongoDB基本是使用JavaScript客户端命令行程序来进行复杂任务管理的，如数据整合和简单信息处理，编程都是完全使用JavaScript语言来的。本文中，我们会展示命令行的使用示例。现在有大量的MongoDB客户端产品提供，并且由MongoDB社区来支持驱动。通常每种编程语言都有驱动，并且所有流行的语言都有包括，一些不那么流行的也包含在内。这篇文章展示了使用MongoDB的Java驱动，并使用一个ORM库（MJORM）与之进行比较。</span></span></p>  <h2><span><span><span style="font-size:14.5pt;color:black; letter-spacing:-.75pt">介绍</span></span></span><span><span><span style="font-size:14.5pt; font-family:Arial;color:black;letter-spacing:-.75pt"> MJORM: MongoDB</span></span></span><span><span style="font-size:14.5pt;color:black;letter-spacing:-.75pt">的</span></span><span><span><span style="font-size:14.5pt;font-family:Arial;color:black;letter-spacing: -.75pt">ORM</span></span></span><span><span><span style="font-size:14.5pt;color:black; letter-spacing:-.75pt">方案</span></span></span><span></span></h2>  <p><span>在解决的众多有意思的问题中，最近<span>NoSQL数据存储在开发者中主要的问题趋势就是对象关系映射。对象关系映射就是将传统中保存在关系型数据库中的持久化数据映射为在应用程序中使用的对象。这使得编程语言使用起来更加流畅和自然。</span></span></p>  <p><span><span>MongoDB面向文档的架构使得它非常适合对象关系映射，因为文档本身就是以对象形式存储的。可惜没有太多的MongoDB的Java对象关系映射库，但是还是有一些，如</span></span><a href="http://code.google.com/p/morphia/"><span><span><span style="color:#0B59B2">morphia-(A type-safe Java library for MongoDB)</span></span></span></a><span>，<span>&nbsp;</span></span><a href="http://www.springsource.org/spring-data/mongodb"><span><span style="color:#0B59B2">spring-data</span></span></a><span><span>(SpringData项目的MongoDB实现)</span></span><span></span></p>  <p><span>这些<span>ORM库大量使用了注解，因为一些原因对我不适合，其中最重要的就是这些被注解的对象在多个项目中的兼容性问题。这让我开始了mongo-Java-orm 或者 "MJORM" (发音 me-yorm)项目，一个MongoDB的Java对象关系映射项目。MJORM是在MIT许可之下，并且在发布在了</span></span><a href="http://code.google.com/p/mongo-Java-orm/"><span><span><span style="color:#0B59B2">google code project</span></span></span></a><span>。项目采用<span>maven构建，并且maven构件仓库托管于google code版本控制服务器。MJORM的最新可用发布版本为0.15，已经由一些项目使用与生产环境中。</span></span></p>  <h2><span><span><span style="font-size:14.5pt;color:black; letter-spacing:-.75pt">开始使用</span></span></span><span><span><span style="font-size:14.5pt; font-family:Arial;color:black;letter-spacing:-.75pt">ORM</span></span></span></h2>  <h3><span><span><span style="font-size:11.5pt;line-height:173%;font-family:宋体;letter-spacing: -.75pt">加入</span></span></span><span><span><span style="font-size:11.5pt; line-height:173%;font-family:Arial;letter-spacing:-.75pt">MJORM </span></span></span><span><span><span style="font-size:11.5pt;line-height:173%;font-family:宋体;letter-spacing: -.75pt">库</span></span></span><span></span></h3>  <p><span><span>Maven的使用者首先应当在pom.xml中加入MJORM的maven仓库，使得MJORM构件可用。</span></span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&lt;repository&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;id&gt;mjorm-webdav-maven-repo&lt;/id&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;mjorm maven repository&lt;/name&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url&gt;http://mongo-Java-orm.googlecode.com/svn/maven/repo/&lt;/url&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;layout&gt;default&lt;/layout&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&lt;/repository&gt;</span></span></span></pre></div>  <p><span>然后加入依赖<span>:</span></span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&lt;dependency&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupId&gt;com.googlecode&lt;/groupId&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;artifactId&gt;mongo-Java-orm&lt;/artifactId&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;version&gt;0.15&lt;/version&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&lt;/dependency&gt;</span></span></span></pre></div>  <p><span>这样就可以在应用中引入<span>MJORM代码。假如没有使用maven，则你需要手动下载MJORM的pom.xml中列举的所有依赖。</span></span></p>  <h3><span><span><span style="font-size:11.5pt;line-height:173%;font-family:宋体;letter-spacing: -.75pt">建立</span></span></span><span><span><span style="font-size:11.5pt; line-height:173%;font-family:Arial;letter-spacing:-.75pt"> POJOs</span></span></span></h3>  <p><span>依赖已经导入，可以开始编码了。我们从<span>POJO开始:</span></span><span></span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span>&nbsp;</span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">class Author {</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String firstName;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String lastName;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ... setters and getters ...</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">}</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span>&nbsp;</span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">class Book {</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String id;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String isbn;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String title;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String description;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Author author;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ... setters and getters ...</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">}</span></span></span></pre></div>  <p><span>我们在这个对象模型中的描述是，作者有<span>ID、姓和名，书有ID、ISNB、标题、描述和作者。</span></span></p>  <p><span>你可能注意到书的<span>id属性是一个字符串，这是为了适应MongoDB的对象ID类型。MongoDB的ID是一个12字节的二进制值显示为一个十六进制的字符串。MongoDB要求集合中的每个文档都必须有一个唯一id，但不要求一定要是ObjectId。目前MJORM只支持ObjectId，并且显示为字符串。</span></span></p>  <p><span>你也可能注意到了<span>Author没有id字段。这是因为Book是它的父文档，因此不需要有id。记住，MongoDB只要求集合中的文档在根级别的id。</span></span></p>  <h3><span><span><span style="font-size:11.5pt;line-height:173%;font-family:宋体;letter-spacing: -.75pt">创建</span></span></span><span><span><span style="font-size:11.5pt; line-height:173%;font-family:Arial;letter-spacing:-.75pt">XML</span></span></span><span><span><span style="font-size:11.5pt;line-height:173%;font-family:宋体;letter-spacing: -.75pt">映射文件</span></span></span><span></span></h3>  <p><span>下一个步骤就是建立<span>XML映射文件，MJORM能够将MongoDB文档转换为对象。我们为每个文档创建一个对象作为示范，无论将所有的映射放在一个XML文件中还是分开都是可以的。</span></span></p>  <p><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">Author.mjorm.xml</span></code>:</span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&lt;?xml version="1.0"?&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&lt;descriptors&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;object class="Author"&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="firstName" /&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="lastName" /&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/object&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&lt;/descriptors&gt;</span></span></span></pre></div>  <p><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">Book.mjorm.xml</span></code>:</span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&lt;?xml version="1.0"?&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&lt;descriptors&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;object class="Book"&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="id" id="true" auto="true" /&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="isbn" /&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="title" /&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="description" /&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="author" /&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/object&gt;</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&lt;/descriptors&gt;</span></span></span></pre></div>  <p><span>&nbsp;</span></p>  <p><span>这些映射文件能够很好的自解释。</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">descriptors</span></code>&nbsp;元素是根元素，必须包含在每个映射文件中。在它下面是</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">object</span></code>元素定义了文档与之对应的类。</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">Object</span></code></span><span><code><span style="font-size:9.0pt;Courier New&quot;;Courier New&quot;;Courier New&quot;">包含的</span></code></span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">property</span></code>&nbsp;元素主要用于描述<span>POJO中的属性以及这些属性如何与MongoDB中的文档想对应。</span></span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">property</span></code>&nbsp;元素至少必须包含一个</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">name</span></code>&nbsp;属性，这个元素就是POJO和MongoDB的文档中的属性名称。</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">column</span></code>&nbsp;属性则是可选的，用于特定一个在MongoDB文档中的可选属性名称。</span></p>  <p><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">property</span></code>&nbsp;元素当中的<span>id属性应该是对象的唯一识别。一个对象只能有一个</span></span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">property</span></code>&nbsp;元素包含<span>id属性。</span></span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">auto</span></code>&nbsp;的设置会使得MJORM在持久化时为该属性自动生成一个值。</span></p>  <p><span>可以在<span>google code的MJORM项目主页中查看XML映射文件的更多细节描述。</span></span></p>  <h3><span><span><span style="font-size:11.5pt;line-height:173%;font-family:宋体;letter-spacing: -.75pt">整合</span></span></span><span><span><span style="font-size:11.5pt; line-height:173%;font-family:Arial;letter-spacing:-.75pt">POJO</span></span></span><span><span><span style="font-size:11.5pt;line-height:173%;font-family:宋体;letter-spacing: -.75pt">与</span></span></span><span><span><span style="font-size:11.5pt; line-height:173%;font-family:Arial;letter-spacing:-.75pt">XML</span></span></span></h3>  <p><span>我们创建了数据模型以及映射文件，使得<span>MJORM可以从MongoDB序列号以及反序列号POJO。我们可以进行一些有意思的事情了，首先打开MongoDB的链接：</span></span><span></span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">Mongo mongo = new Mongo(</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new MongoURI("mongodb://localhost/mjormIsFun")); // 10gen driver</span></span></span></pre></div>  <p><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">Mongo</span></code>&nbsp;对象是由10gen编写的Java驱动提供的。示例中连接了一个本地的MongoDB实例中的mjormIsFun数据库。接下来我们创建MJORM </span><span><span><code><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;">ObjectMapper </span></code>。目前</span></span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">ObjectMapper </span></code>在MJORM中的唯一实现就是</span><span><span><code><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;">XmlDescriptorObjectMapper</span></code>，使用XML结构描述信息。可能之后会增加对注解或其他结构定义的支持。</span></span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">XmlDescriptorObjectMapper objectMapper = new XmlDescriptorObjectMapper();</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">mapper.addXmlObjectDescriptor(new File("Book.mjorm.xml"));</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">mapper.addXmlObjectDescriptor(new File("Author.mjorm.xml"));</span></span></span></pre></div>  <p><span>建立好了</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">XmlDescriptorObjectMapper</span></code>&nbsp;并且加入了映射文件。接下来建立由MJORM提供的</span><span><span><code><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;">MongoDao</span></code>&nbsp;对象的实例。</span></span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">DB db = mongo.getDB("mjormIsFun"); // 10gen driver</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">MongoDao dao = new MongoDaoImpl(db, objectMapper);</span></span></span></pre></div>  <p><span>首先我们要获得<span>10gen驱动提供的DB对象实例。然后使用DB和</span></span><span><span><code><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;">ObjectMapper</span></code>&nbsp;建立</span></span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">MongoDao</span></code>&nbsp;。我们准备开始持久化数据，建立一个</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">Book</span></code>&nbsp;然后保存到MongoDB中。</span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">Book book = new Book();</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">book.setIsbn("1594743061");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">book.setTitle("MongoDB is fun");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">book.setDescription("...");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span>&nbsp;</span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">book = dao.createObject("books", book);</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">System.out.println(book.getId()); // 4f96309f762dd76ece5a9595</span></span></span></pre></div>  <p><span>首先建立</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">Book</span></code>&nbsp;对象并且填值，然后调用</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">MongoDao</span></code>&nbsp;的</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;"> createObject</span></code>&nbsp;方法，将</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">Book</span></code>&nbsp;对象传入"</span><span><span><code><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;">books</span></code>" 的集合中。MJORM会按照之前的xml映射文件将</span></span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">Book</span></code>&nbsp;转换为</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">DBObject</span></code>&nbsp;(这是10gen的Java驱动使用的基本类型)，并保存一个新的文档进"</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">books</span></code>" 集合。MJORM返回Book对象时，id属性会被填充。请注意，MongoDB默认是不需要在使用前建立数据库或集合的，系统会在需要时自动创建，这可能会造成某些困扰。在MongoDB的命令行中查看Book对象大概如下：</span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&gt; db.books.find({_id:ObjectId("4f96309f762dd76ece5a9595")}).pretty()</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">{</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "_id":&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectId("4f96309f762dd76ece5a9595"),</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "isbn":&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "1594743061",</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "title":&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "MongoDB is fun",</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "description":&nbsp;"..."</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">}</span></span></span></pre></div>  <p><span>&nbsp;</span></p>  <p><span>我们来看看假如不用<span>MJORM而直接使用10gen的Java驱动，如何使用</span></span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">createObject</span></code>&nbsp;方法：</span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">Book book = new Book();</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">book.setIsbn("1594743061");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">book.setTitle("MongoDB is fun");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">book.setDescription("...");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span>&nbsp;</span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">DBObject bookObj = BasicDBObjectBuilder.start()</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add("isbn", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; book.getIsbn())</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add("title",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; book.getTitle())</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add("description",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; book.getDescription())</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .get();</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span>&nbsp;</span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">// 'db' is our DB object from earlier</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">DBCollection col = db.getCollection("books");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">col.insert(bookObj);</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span>&nbsp;</span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">ObjectId id = ObjectId.class.cast(bookObj.get("_id"));</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">System.out.println(id.toStringMongod()); // 4f96309f762dd76ece5a9595</span></span></span></pre></div>  <p><span>&nbsp;</span></p>  <p><span>下面进行对象的查询<span>:</span></span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">Book book = dao.readObject("books", "4f96309f762dd76ece5a9595", Book.class);</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">System.out.println(book.getTitle()); // "MongoDB is fun"</span></span></span></pre></div>  <p><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">readObject</span></code>&nbsp;方法根据给定文档的id从指定的集合中读取文档，转换为对象（再次使用映射文件）并返回。</span></p>  <p><span>敏锐的读者会注意到<span>Book还没有指定Author，仍然保存了。这归咎于MongoDB的结构不敏感的特性。我们不能要求集合中的文档包含所有属性（id属性是必须的），所有在MongoDB中没有Author的Book是可以的。我们现在为Book添加一个Author并且更新一下：</span></span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">Author author = new Author();</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">author.setFirstName("Brian");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">author.setLastName("Dilley");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span>&nbsp;</span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">book.setAuthor(author);</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span>&nbsp;</span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">dao.updateObject("books", "4f96309f762dd76ece5a9595", book);</span></span></span></pre></div>  <p><span>现在<span>Book就包含了Author，并且在MongoDB中持久化了。现在在命令行查看了Book：</span></span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&gt; db.books.find({_id:ObjectId("4f96309f762dd76ece5a9595")}).pretty()</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">{</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "_id":&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectId("4f96309f762dd76ece5a9595"),</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "isbn":&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "1594743061",</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "title":&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "MongoDB is fun",</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "description":&nbsp;"..."</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "author": {</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "firstName": "Brian",</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "lastName": "Dilley"</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">}</span></span></span></pre></div>  <p><span>可以看到持久化的<span>Book中已经包含了author。不使用MJORM来操作一遍：</span></span></p>  <div style="border:solid #EFEFEF 1.5pt;padding: 0cm 0cm 4.0pt 0cm;background:#FAFAFA"><pre style="line-height:11.25pt; background:#FAFAFA;border:none;padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">Author author = new Author();</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">author.setFirstName("Brian");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">author.setLastName("Dilley");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span>&nbsp;</span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">book.setAuthor(author);</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span>&nbsp;</span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">DBObject bookObj = BasicDBObjectBuilder.start()</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add("isbn", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; book.getIsbn())</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add("title",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; book.getTitle())</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add("description",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; book.getDescription())</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .push("author")</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add("firstName", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; author.getFirstName())</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add("lastName",  author.getLastName())</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .pop()</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .get();</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span>&nbsp;</span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">DBCollection col = db.getCollection("books");</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span><span><span style="font-size:9.0pt; font-family:&quot;Courier New&quot;;color:#222222">col.update(new BasicDBObject("_id", bookObj.get("_id")), bookObj);</span></span></span></pre><pre style="line-height:11.25pt;background:#FAFAFA;border:none; padding:0cm;"><span>&nbsp;</span></pre></div>  <p><span>&nbsp;</span></p>  <p><span>对于</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">MongoDao</span></code>&nbsp;方法的深入讨论已经超出了本文的范围。对于将MJORM有兴趣用于实际项目中的用户强烈建议了解一下MJORM项目提供的相关文档，或者</span><span><code><span style="font-size:9.0pt;font-family:&quot;Courier New&quot;">MongoDao</span></code>&nbsp;接口提供的相关用法。</span></p>  <h2><span><span><span style="font-size:14.5pt;color:black; letter-spacing:-.75pt">总结</span></span></span><span></span></h2>  <p><span>希望这篇文章对<span>MongoDB和MJORM的亮点有所展示。MongDB是一个优秀的呃NoSQL数据存储，有着大量优秀的特性，会是NoSQL市场中长期竞争者。若你会在一个Java项目中使用MongoDB，希望你也能够考虑使用MJORM作为你的ORM框架。十分欢迎大家提交特性需求、错误异常报告、文档和源码修正。</span></span></p>  <p style="line-height:12.0pt;background:white"><span>&nbsp;</span></p>  <h2><span><span style="font-size:14.5pt;color:black;letter-spacing:-.75pt">作者</span></span><span><span><span style="font-size:14.5pt;font-family:Arial;color:black;letter-spacing: -.75pt"> Bio</span></span></span></h2>  <p style="line-height:12.0pt;background:white"><span><span><strong><span style="font-size:10.0pt; font-family:Tahoma;color:black">Brian Dilley</span></strong></span></span><span><span>&nbsp;</span></span><span><span><span style="font-size:10.0pt;color:black">是一个经验丰富的高级工程师以及项目领导，在</span></span></span><span><span><span style="font-size:10.0pt;font-family:Tahoma;color:black">Java/Java EE /Spring Framework/Linux</span></span></span><span><span style="font-size:10.0pt;color:black">内部结构理解和管理有着超过</span></span><span><span style="font-size:10.0pt;font-family:Tahoma;color:black">13</span></span><span><span style="font-size:10.0pt;color:black">年的经验。</span></span><span><span style="font-size:10.0pt;font-family:Tahoma;color:black">Brian</span></span><span><span style="font-size:10.0pt;color:black">对于创业公司有很多经验，推向市场，构建</span></span><span><span style="font-size:10.0pt;font-family:Tahoma;color:black">/</span></span><span><span style="font-size:10.0pt;color:black">维护产品等。他是</span></span><span><span style="font-size:10.0pt;font-family:Tahoma;color:black">Iaas</span></span><span><span style="font-size:10.0pt;color:black">、</span></span><span><span style="font-size:10.0pt;font-family:Tahoma;color:black">cloud</span></span><span><span style="font-size:10.0pt;color:black">、</span></span><span><span style="font-size:10.0pt;font-family:Tahoma;color:black">PHP</span></span><span><span style="font-size:10.0pt;color:black">和</span></span><span><span style="font-size:10.0pt;font-family:Tahoma;color:black">Linux</span></span><span><span style="font-size:10.0pt;color:black">的专家，熟悉产品的采购、安装及配置定义，以及公司的软硬件架构包括负载均衡、数据库、微博等。可以</span></span><span><span style="font-size:10.0pt;font-family:Tahoma;color:black">follow Brian</span></span><span><span style="font-size:10.0pt;color:black">的</span></span><span><span>&nbsp;</span></span><a href="https://twitter.com/#%21/dilleybrian"><span><span><span style="font-size:10.0pt; font-family:Tahoma;color:#0B59B2">Twitter</span></span></span></a><span> </span><span><span style="font-size:10.0pt;color:black">。</span></span><span></span></p>  </div><img src ="http://www.blogjava.net/matuobasyouca/aggbug/377698.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-09 13:46 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/05/09/377698.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据集成的演化：从EII到Big Data</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/04/19/375213.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Wed, 18 Apr 2012 23:15:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/04/19/375213.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/375213.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/04/19/375213.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/375213.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/375213.html</trackback:ping><description><![CDATA[<p><span style="font-size: 10pt; font-family: 宋体; ">&#8220;企业信息集成（</span><span style="font-size: 10pt; font-family: Times, serif; ">EII</span><span style="font-size: 10pt; font-family: 宋体; ">）：实用方式&#8221;于</span><span style="font-size: 10pt; font-family: Times, serif; ">2005</span><span style="font-size: 10pt; font-family: 宋体; ">年发布，描述了一套集成不同数据源的方法论，利用了当时的先进技术，如面向服务架构（</span><span style="font-size: 10pt; font-family: Times, serif; ">SOA</span><span style="font-size: 10pt; font-family: 宋体; ">）、</span><span style="font-size: 10pt; font-family: Times, serif; ">Web Services</span><span style="font-size: 10pt; font-family: 宋体; ">、</span><span style="font-size: 10pt; font-family: Times, serif; ">XML</span><span style="font-size: 10pt; font-family: 宋体; ">、资源描述架构（</span><span style="font-size: 10pt; font-family: Times, serif; ">RDF</span><span style="font-size: 10pt; font-family: 宋体; ">）、基于</span><span style="font-size: 10pt; font-family: Times, serif; ">XML</span><span style="font-size: 10pt; font-family: 宋体; ">的元数据格式以及数据提取、转换和加载（</span><span style="font-size: 10pt; font-family: Times, serif; ">ETL</span><span style="font-size: 10pt; font-family: 宋体; ">）。</span><span style="font-size: 10pt; font-family: Times, serif; ">EII</span><span style="font-size: 10pt; font-family: 宋体; ">能够基本为关系型数据元素提供统一视角，但在性能效率上缺乏能够替代数据仓库和多维数据库的能力。五年之后技术已经得到了显著提升，不仅在于对于分散数据的操作，还有简化了单一容器下不同数据的整合，以及对数据深入挖掘的能力。</span></p>
<p><span style="font-size:10.0pt;font-family:宋体;">转变了数据管理方式的技术正是虚拟化。低成本存储、云计算、</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">NoSQL</span><span style="font-size: 10.0pt;font-family:宋体;">数据库以及</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Hadoop</span><span style="font-size: 10.0pt;font-family:宋体;">。当我们提起虚拟化时，已经远远超出为一台物理机器提供一套软件实例这一概念。时至今日，我们可以虚拟化服务器、存储以及网络。所有这些虚拟化意味着我们不再被这些物理条件所限制，能够迅速构建物理环境以支持我们特定时刻的特定需求。当面对</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Gb</span><span style="font-size: 10.0pt;font-family:宋体;">、</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Tb</span><span style="font-size: 10.0pt;font-family:宋体;">、</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Pb</span><span style="font-size: 10.0pt;font-family:宋体;">等级数据量的处理需求时，我们基本能摆脱结构化的数据仓库。我们不在需要仅仅为了发掘业务的某一方面而建立一个特殊的环境了。</span></p>
<p><span style="font-size:10.0pt;font-family:宋体;">低成本存储在业务的数据存储方面节省了开支。高昂的存储成本会使得企业寻找在限定规模的数据之上进行关键业务分析的方案，这样使得如何选择最重要的数据变得十分关键，而且还限制了系统能够处理的数据的质量。</span></p>
<p><span style="font-size:10.0pt;font-family:宋体;">负面影响便是业务最终可能面临很少的选择，因为没有足够的历史数据提供从而识别一个有效关键模式。或者因为高昂的投入使得业务被停止，而使用常规惯例来识别模式。</span></p>
<p><span style="font-size:10.0pt;font-family:宋体;">云计算为那些需要通过海量数据源在合理时间范围内产生结果的需求提供了一个可用的方式。海量数据处理需要两点：弹性存储，</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">CPU</span><span style="font-size: 10.0pt;font-family:宋体;">。高速网络很有帮助，但是待会我们会看到在发掘软件在处理海量数据时，它并非是系统的瓶颈。弹性存储意味着企业不会在期望操作的数据规模或类型上受到限制，降低了使用数据仓库无法获取最佳结果的风险。更多的</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">CPU</span><span style="font-size: 10.0pt;font-family:宋体;">使得结果能够在期望的时间范围内更快的被交付。</span></p>
<p><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">NoSQL</span><span style="font-size: 10.0pt;font-family:宋体;">提供了海量数据的支持，但与传统的关系型数据库没有关联。而且大部分</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">NoSQL</span><span style="font-size: 10.0pt;font-family:宋体;">数据库是开源的，无须支付购买证书等费用。</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">NoSQL</span><span style="font-size: 10.0pt;font-family:宋体;">对于表结构有着惊人的灵活性，无须随着系统的改进而不断修改完善定义。</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">NoSQL</span><span style="font-size: 10.0pt;font-family:宋体;">可以支持不同数据源的合并查看，从而成为</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">EII</span><span style="font-size: 10.0pt;font-family:宋体;">之后另一个备选方案，这或许是</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">NoSQL</span><span style="font-size: 10.0pt;font-family:宋体;">最重要的方面了。</span></p>
<p><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">NoSQL</span><span style="font-size: 10.0pt;font-family:宋体;">内置了数据冗余与分布式数据存储机制。海量数据的最大问题之一就是磁盘读写，</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">NoSQL</span><span style="font-size: 10.0pt;font-family:宋体;">通过将数据分布至一系列节点来缓解这个问题。当一个查询请求发出时，这些节点能够并行查询自身节点，而不是仅仅依靠一块磁盘，一个磁盘阵列或一条网络连接等，数据查询能够在节省了读写开支之后变得更加迅速。</span></p>
<p><span style="font-size:10.0pt;font-family:宋体;">最终，我们来讨论</span><span style="font-size:10.0pt;font-family: &quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Hadoop</span><span style="font-size:10.0pt;font-family:宋体;">，集合了上述所有技术力量与一身的用于检测和分析数据的框架。有些人可能认为</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Hadoop</span><span style="font-size: 10.0pt;font-family:宋体;">是一项</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">NoSQL</span><span style="font-size: 10.0pt;font-family:宋体;">技术，实际上</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Hadoop</span><span style="font-size: 10.0pt;font-family:宋体;">是一个分布组件的</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">java</span><span style="font-size: 10.0pt;font-family:宋体;">框架，用于分解&#8220;吃大象&#8221;（此处也双关</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Hadoop</span><span style="font-size: 10.0pt;font-family:宋体;">是以创立者的儿子给自己的一个大象玩具起的名字）的工作&#8212;&#8212;每次一口。</span></p>
<p><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Hadoop</span><span style="font-size: 10.0pt;font-family:宋体;">自身实际上与待处理数据是各自独立的。它将大型查询任务分解为小的并行查询任务，然后收集结果，并整合出答案返回给用户。</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Hadoop</span><span style="font-size: 10.0pt;font-family:宋体;">相对于</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">NoSQL</span><span style="font-size: 10.0pt;font-family:宋体;">来说是一个并行查询框架，通过云计算驱动节点，运行在低成本存储及虚拟化技术之上。</span></p>
<p><strong><span style="font-size:16.0pt;font-family: &quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Kicking</span></strong><strong><span style="font-size:16.0pt;font-family:宋体;">的知识回顾</span></strong><strong></strong></p>
<p><span style="font-size:10.0pt;font-family:宋体;">当</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">EII</span><span style="font-size:10.0pt;font-family:宋体;">第一次作为最佳实践出现于</span><span style="font-size:10.0pt;font-family: &quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">2003-2004</span><span style="font-size:10.0pt;font-family:宋体;">年，关键要素就是无需再移动数据了。当时大部分的数据中心仍然运行于低速网络中，有限的空间用于复制数据。之后，</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">EII</span><span style="font-size: 10.0pt;font-family:宋体;">成为了当时可用技术和问题域中最优秀的解决方案。</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">EII</span><span style="font-size: 10.0pt;font-family:宋体;">的某些方面的优秀即使在海量数据中也是很显著的。</span></p>
<p><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">EII</span><span style="font-size: 10.0pt;font-family:宋体;">的优点之一就是将处理过程转移到数据所在地。海量数据方案的关键架构要素之一就是将处理过程转移到数据所在地，而不是转移数据。</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">EII</span><span style="font-size: 10.0pt;font-family:宋体;">中的一个重要原则就是使用数据归属地的查询功能。这项实践就是构建靠近数据源网络的</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Web Service</span><span style="font-size:10.0pt;font-family:宋体;">，能够建立起通用查询接口，但只针对本地数据库进行查询。我们通过开放的基于</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Web</span><span style="font-size: 10.0pt;font-family:宋体;">的接口解决了数据的专有格式的问题，从而使得多个数据子集能够迅速的整合并以统一模式展示。</span></p>
<p><span style="font-size:10.0pt;font-family:宋体;">有了低成本存储和</span><span style="font-size:10.0pt;font-family: &quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">10G</span><span style="font-size:10.0pt;font-family:宋体;">网络之后，我们就不必那么担心数据冗余与数据迁移，但还是有其他问题存在的，数据仓库无法确保数据的原始性便是其中之一。在</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">EII</span><span style="font-size: 10.0pt;font-family:宋体;">中，我们将从原始数据源获取数据视为&#8220;黄金准则&#8221;，这样就能够保证信息未被修改过，且是准确的。</span></p>
<p><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Big Data</span><span style="font-size:10.0pt;font-family:宋体;">要求数据必须转移到新的物理位置，这样可信任度又成为了问题。</span><span style="font-size: 10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">EII</span><span style="font-size:10.0pt;font-family:宋体;">的那些获取基线数据的最佳实践仍然是相关而且重要的。实际上，那些为</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">EII</span><span style="font-size: 10.0pt;font-family:宋体;">设计开发的</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Web Services</span><span style="font-size:10.0pt;font-family:宋体;">接口最终在</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Big Data</span><span style="font-size:10.0pt;font-family:宋体;">的启用中扮演主要角色。</span></p>
<p><span style="font-size:10.0pt;font-family:宋体;">当然，讨论数据管理不能不涉及到安全问题。</span><span style="font-size:10.0pt; font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">EII</span><span style="font-size:10.0pt;font-family:宋体;">在安全领域中还是超过了</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Big Data</span><span style="font-size:10.0pt;font-family:宋体;">。技术上来说，</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Big Data</span><span style="font-size:10.0pt;font-family:宋体;">在数据集成方面更加高效与敏捷，但是大部分缺少了固有的安全性，因为在设计上会加大处理的难度。所以，可能要由源系统来担任起数据访问安全方面的责任。因为</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">EII</span><span style="font-size: 10.0pt;font-family:宋体;">直接在源系统中查询数据，所以必须要求有适当的授权，否则查询就将失败。</span></p>
<p><span style="font-size:10.0pt;font-family:宋体;">上述关于安全讨论描述的是内在的安全控制情况。将访问权限控制列表集成进数据库是非常合理的，这将确保安全能够作为查询的一部分进行维护。然后，一旦能够直接查询</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">NoSQL</span><span style="font-size: 10.0pt;font-family:宋体;">数据源，就意味着能够自由的访问你所有的数据。</span></p>
<p><strong><span style="font-size:16.0pt;font-family:宋体;">总结</span></strong><strong></strong></p>
<p><span style="font-size:10.0pt;font-family:宋体;">引用老的</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Virginia Slims</span><span style="font-size:10.0pt;font-family:宋体;">的广告中的台词：&#8220;我们已经历很长的路途了，宝贝儿！&#8221;文中讨论到的技术的发展已经对</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">21</span><span style="font-size: 10.0pt;font-family:宋体;">世纪第二个</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">10</span><span style="font-size: 10.0pt;font-family:宋体;">年中的的数据解决方案产生了巨大的影响。商业化与小型化扫除了一些思想体系上的障碍，使得架构师能够专注于问题本身，而不是寻找一些实用及可实现的问题解决方案。构建</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">10000</span><span style="font-size: 10.0pt;font-family:宋体;">个节点的处理引擎，能够在数秒内处理</span><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">Pb</span><span style="font-size: 10.0pt;font-family:宋体;">级别的数据量，却只消耗每小时几便士，这就是数据处理的美好前景。</span></p>
<p><span style="font-size:10.0pt;font-family:宋体;">有了这些新工具，我们就要重新考虑如何推进数据管理。为何数据无法被很好地被维护整合，并且需要花费数万美元。数据管理几乎是每个大中型企业的心病。数据管理曾经在存储、管理、访问、整合以及查询上花费巨大，但是今后不再会是这样了。</span></p>
<p><strong><span style="font-size:16.0pt;font-family:宋体;">关于作者</span></strong><strong></strong></p>
<p><strong><span style="font-size:10.0pt; font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">JP Morgenthal</span></strong> <span style="font-size: 10pt; font-family: 宋体; ">是在</span><span style="font-size: 10pt; font-family: Times, serif; ">IT</span><span style="font-size: 10pt; font-family: 宋体; ">策略与云计算方面的世界级专家之一。他在企业复杂问题域的解决方案实施上有着</span><span style="font-size: 10pt; font-family: Times, serif; ">25</span><span style="font-size: 10pt; font-family: 宋体; ">年的经验。</span><strong><span style="font-size:10.0pt;font-family:&quot;Times&quot;,&quot;serif&quot;;Times New Roman&quot;">JP Morgenthal</span></strong><span style="font-size: 10pt; font-family: 宋体; ">以其在技术方面的深度和广度，有利的支持他在企业问题域中的敏感度。他在集成、软件开发和云计算是一位让人尊敬的作者，同时也是</span><span style="font-size: 10pt; font-family: Times, serif; ">InfoQ</span><span style="font-size: 10pt; font-family: 宋体; ">在引领云计算方面的编辑，并且参与了&#8220;云计算：评估风险&#8221;项目。</span>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-family:&quot;MS Mincho&quot;;">原文</span><span style="font-family:宋体;">链</span><span style="font-family:&quot;MS Mincho&quot;;">接：</span>http://www.infoq.com/articles/DataIntegrationFromEIItoBigData</p><img src ="http://www.blogjava.net/matuobasyouca/aggbug/375213.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-19 07:15 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/04/19/375213.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/06/373470.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Fri, 06 Apr 2012 06:48:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/04/06/373470.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/373470.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/04/06/373470.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/373470.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/373470.html</trackback:ping><description><![CDATA[<p><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">项目经理（</span>Project manager<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）是项目的支柱与核心，维基百科的定义：项目经理是项目管理方面的专家，负责项目的策划、执行和结束，即整个生命周期过程。项目经理手中的&#8220;干将莫邪&#8221;便是软件开发过程方法（</span>software development process/software development life cycle (SDLC)<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">），可能采取的有</span>RUP<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">（</span>Rational Unified Process<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>RUP<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的话，主要分为四大阶段，先启（</span>Inception<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）、精华（</span>Elaboration<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）、构建（</span>Construction<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）、交付（</span>Transition<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）迭代的开发方式，而</span>Scrum<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的核心概念则是</span>Sprint<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">。</span></p>  <p>&nbsp;</p>  <p>Maven<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<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">官方介绍《</span>What is maven<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>Objectives<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）（</span><a href="http://maven.apache.org/what-is-maven.html">http://maven.apache.org/what-is-maven.html</a><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: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><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: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><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: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><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: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><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: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><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>Maven<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">影响最为深刻的就是它的构建系统，几乎贯穿了整个实施阶段。作为对比我们参考一下</span>RUP<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的</span>Construction<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">阶段，以及</span>Scrum<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的单个</span>Sprint<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">过程。</span></p>  <p>&nbsp;</p>  <p>RUP<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的</span>Construction<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 style="margin-left:21.0pt;text-indent:-21.0pt;"><span style="font-size: 9.0pt;font-family:Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;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-size: 9.0pt;font-family:Wingdings;color:red">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;; color:red">实用性与质量兼具。</span></p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;"><span style="font-size: 9.0pt;font-family:Wingdings;color:red">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;; color:red">尽快发布可用版本。</span></p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;"><span style="font-size: 9.0pt;font-family:Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;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-size: 9.0pt;font-family:Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;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-size: 9.0pt;font-family:Wingdings;color:red">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;; color:red">检查项目发布的所有资源是否已经准备完全。</span></p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;"><span style="font-size: 9.0pt;font-family:Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;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>Scrum<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">与</span>XP<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">》一书中，介绍了作者实施</span>Scrum<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的过程。在一个</span>Sprint<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">中，不是只有</span>Sprint backlog<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">、</span>burn down chat<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-size: 9.0pt;font-family:Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">简单设计（</span><span style="font-size:9.0pt">Simple Design</span><span style="font-size: 9.0pt;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-size: 9.0pt;font-family:Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">结对编程（</span><span style="font-size:9.0pt">Pair Programming</span><span style="font-size:9.0pt;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-size: 9.0pt;font-family:Wingdings;color:red">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;; color:red">测试驱动（</span><span style="font-size:9.0pt;color:red">Test-Driven Development</span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;color:red">）</span></p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;"><span style="font-size: 9.0pt;font-family:Wingdings;color:red">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;; color:red">小规模发布（</span><span style="font-size:9.0pt;color:red">Small Releases</span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;color:red">）</span></p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;"><span style="font-size: 9.0pt;font-family:Wingdings;color:red">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;; color:red">持续集成（</span><span style="font-size:9.0pt;color:red">Continuous Integration</span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;color:red">）</span></p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;"><span style="font-size: 9.0pt;font-family:Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">集体拥有代码（</span><span style="font-size:9.0pt">Collective Code Ownership</span><span style="font-size:9.0pt;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-size: 9.0pt;font-family:Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">编码标准（</span><span style="font-size:9.0pt">Coding Standard</span><span style="font-size:9.0pt;font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）</span></p>  <p>&nbsp;</p>  <p>Maven<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: Wingdings; color:red">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="color:red">validate</span></strong><span style="color:red"> &#8211; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;color:red">验证项目正确性及依赖有效性</span></p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>compile</strong> &#8211; <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: Wingdings; color:red">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="color:red">test</span></strong><span style="color:red"> &#8211; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;color:red">使用合适的单元测试框架对编译后的源码进行测试，测试代码不会被打包或发布</span></p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>package</strong> &#8211;<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">将编译后的代码以规定格式打包，如</span>Jar</p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings; color:red">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="color:red">integration-test</span></strong><span style="color:red"> &#8211; </span><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;;color:red">将打包后的代码放置于环境中进行集成测试</span></p>  <p style="margin-left:21.0pt;text-indent:-21.0pt;"><span style="font-family: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>verify</strong> &#8211; <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: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>install</strong> &#8211; <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: Wingdings;">l<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong>deploy</strong> &#8211; <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>validate<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">可以项目所有依赖有效，</span>test<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>intergration-test<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>1.&lt;dependency&gt; - <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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;dependency&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupId&gt;junit&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; &lt;artifactId&gt;junit&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; &lt;version&gt;4.8.1&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; &lt;scope&gt;test&lt;/scope&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/dependency&gt;</p>  <p>&nbsp;</p>  <p>2. &lt;repository&gt; - <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>Jboss<span style="font-family: 宋体;Times New Roman&quot;;Times New Roman&quot;">等，如下是公司内建的</span>Nexus<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">资源库。</span></p>  <p style="margin-left:21.0pt;text-indent:21.0pt">&lt;repository&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;Suntang's Maven Repository&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;name&gt;Suntang Nexus Repository&lt;/name&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url&gt;http://10.10.10.33:8081/nexus/content/groups/public&lt;/url&gt;</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/repository&gt;</p>  <p>3. &lt;profile&gt; - <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://blog.csdn.net/turkeyzhou/article/details/4894657">http://blog.csdn.net/turkeyzhou/article/details/4894657</a><span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">）</span></p>  <p style="margin-left:42.0pt;">&lt;profile&gt;</p>  <p style="margin-left:63.0pt;">&nbsp;&lt;activation&gt;</p>  <p style="margin-left:84.0pt;">&lt;file&gt;</p>  <p style="margin-left:105.0pt;">&lt;missing&gt;target/generated-sources/axistools/wsdl2java/org/apache/maven&lt;/missing&gt;</p>  <p style="margin-left:84.0pt;">&lt;/file&gt;</p>  <p style="margin-left:63.0pt;">&lt;/activation&gt;</p>  <p style="margin-left:42.0pt;">&nbsp;&lt;/profile&gt;</p>  <p>4.&lt;build&gt; - <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://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference">http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference</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></p>  <p>&nbsp;</p>  <p>&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;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/main/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/main/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; &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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/build&gt;</p>  <p>&nbsp;</p>  <p>4.&lt; plugin &gt; - <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><a href="http://maven.apache.org/plugins/index.html">http://maven.apache.org/plugins/index.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>TestSuitex.java<span style="font-family:宋体;Times New Roman&quot;;Times New Roman&quot;">的测试类</span></p>  <p>&nbsp;</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;</p><img src ="http://www.blogjava.net/matuobasyouca/aggbug/373470.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-06 14:48 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/04/06/373470.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>Nosql企业之道</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/04/04/373338.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Wed, 04 Apr 2012 13:41:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/04/04/373338.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/373338.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/04/04/373338.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/373338.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/373338.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Nosql企业之道  http://www.infoq.com/articles/nosql-in-the-enterprise    &nbsp;  介绍  作为一个企业架构师的好处，就是我一直在找一些新的有希望的概念或想法，能够帮助我的企业用户处理不同垂直行业之间的问题。甚至在NoSQL这个词被杜撰（错误的杜撰？此处作者认为NoSQL这个词并不恰当，后面会提到）出来之前，因为上述的原因我曾持续...&nbsp;&nbsp;<a href='http://www.blogjava.net/matuobasyouca/archive/2012/04/04/373338.html'>阅读全文</a><img src ="http://www.blogjava.net/matuobasyouca/aggbug/373338.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-04 21:41 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/04/04/373338.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hadoop in action 实践(伪分布式)</title><link>http://www.blogjava.net/matuobasyouca/archive/2012/04/01/373194.html</link><dc:creator>一酌散千忧</dc:creator><author>一酌散千忧</author><pubDate>Sun, 01 Apr 2012 07:00:00 GMT</pubDate><guid>http://www.blogjava.net/matuobasyouca/archive/2012/04/01/373194.html</guid><wfw:comment>http://www.blogjava.net/matuobasyouca/comments/373194.html</wfw:comment><comments>http://www.blogjava.net/matuobasyouca/archive/2012/04/01/373194.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/matuobasyouca/comments/commentRss/373194.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/matuobasyouca/services/trackbacks/373194.html</trackback:ping><description><![CDATA[<div>《Hadoop in action》<span style="font-family: 宋体; ">由</span>Manning<span style="font-family: 宋体; ">出版，磕磕绊绊总算是看完了。书的内容就不做介绍，主要讲一下实践的过程。并且在实践过程中参考的书籍的部分也会简单介绍。<br /><br /></span><span style="font-family: 宋体; color: red; ">灰色背景部分为一些介绍，或过程中出现问题的描述，可以直接忽略。</span><span style="font-family: 宋体; "><br /><br /></span></div><p><span style="font-family: 宋体; ">由于公司的业务需要，要在网络收集网页之后对网页进行结构化的解析，这个结构化过程希望能够基于</span>HDFS<span style="font-family: 宋体; ">并且使用</span>MR<span style="font-family: 宋体; ">算法实现。</span></p><p><span style="font-family: 宋体; ">我虚拟了一个需求，针对</span><a href="http://hadoop.apache.org/common/releases.html">http://hadoop.apache.org/common/releases.html</a>&nbsp;<span style="font-family: 宋体; ">页面，假设已经下载了页面并入库。要求最终体现的数据是</span>&nbsp;<span style="font-family: 宋体; ">&#8220;版本号</span>+<span style="font-family: 宋体; ">完整链接（即</span>a<span style="font-family: 宋体; ">标签全部内容）&#8221;</span>&nbsp;<span style="font-family: 宋体; ">的结构。</span></p><p>&nbsp;</p><p><span style="font-family: 宋体; ">伪分布式环境搭建在虚拟机上，操作系统是</span>centos5.5<span style="font-family: 宋体; ">，</span>hadoop<span style="font-family: 宋体; ">的版本是</span>1.0.0.</p><p>&nbsp;</p><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">插入书中的一些环境搭建的介绍</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">书中的</span><span style="background-color: #c0c0c0; ">2.1</span><span style="font-family: 宋体; background-color: #c0c0c0; ">节中介绍了每个进程的作用。</span><span style="background-color: #c0c0c0; ">2.2</span><span style="font-family: 宋体; background-color: #c0c0c0; ">节中的</span><span style="background-color: #c0c0c0; ">ssh</span><span style="font-family: 宋体; background-color: #c0c0c0; ">设置也比较重要，否则好像会一直提示你输入密码。</span><span style="background-color: #c0c0c0; ">2.3.2</span><span style="font-family: 宋体; background-color: #c0c0c0; ">节介绍了伪分布式的配置方式，对</span><span style="background-color: #c0c0c0; ">core-site.xml</span><span style="font-family: 宋体; background-color: #c0c0c0; ">，</span><span style="background-color: #c0c0c0; ">mapred-site.xml</span><span style="font-family: 宋体; background-color: #c0c0c0; ">，</span><span style="background-color: #c0c0c0; ">hdfs-site.xml</span><span style="font-family: 宋体; background-color: #c0c0c0; ">进行配置之后，需要对</span><span style="background-color: #c0c0c0; ">namenode</span><span style="font-family: 宋体; background-color: #c0c0c0; ">节点进行格式化。</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">bin/hadoop namenode &#8211;format</span></p></blockquote></blockquote><p>&nbsp;</p><p>hadoop<span style="font-family: 宋体; ">的根目录为</span>/usr/local/hadoop-1.0.0<span style="font-family: 宋体; ">，直接启动</span>start-all.sh</p><p>&nbsp;</p><p>[root@localhost hadoop-1.0.0]# ./bin/start-all.sh</p><p>&nbsp;</p><p><span style="font-family: 宋体; ">启动成功后使用</span>jps<span style="font-family: 宋体; ">命令<br /></span></p><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">jdk</span><span style="font-family: 宋体; background-color: #c0c0c0; ">小工具</span><span style="background-color: #c0c0c0; ">jps</span><span style="font-family: 宋体; background-color: #c0c0c0; ">介绍</span>&nbsp;</p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">jps(Java Virtual Machine Process Status Tool)</span><span style="font-family: 宋体; background-color: #c0c0c0; ">是</span><span style="background-color: #c0c0c0; ">JDK 1.5</span><span style="font-family: 宋体; background-color: #c0c0c0; ">提供的一个显示当前所有</span><span style="background-color: #c0c0c0; ">java</span><span style="font-family: 宋体; background-color: #c0c0c0; ">进程</span><span style="background-color: #c0c0c0; ">pid</span><span style="font-family: 宋体; background-color: #c0c0c0; ">的命令，简单实用，非常适合在</span><span style="background-color: #c0c0c0; ">linux/unix</span><span style="font-family: 宋体; background-color: #c0c0c0; ">平台上简单察看当前</span><span style="background-color: #c0c0c0; ">java</span><span style="font-family: 宋体; background-color: #c0c0c0; ">进程的一些简单情况。</span><span style="background-color: #c0c0c0; ">&nbsp;jps</span><span style="font-family: 宋体; background-color: #c0c0c0; ">存放在</span><span style="background-color: #c0c0c0; ">JAVA_HOME/bin/jps</span></p></blockquote></blockquote><p>&nbsp;</p><p>[root@localhost hadoop-1.0.0]# jps</p><p>5694 SecondaryNameNode</p><p>5461 NameNode</p><p>5578 DataNode</p><p>6027 Jps</p><p>5784 JobTracker</p><p>5905 TaskTracker</p><p><span style="font-family: 宋体; ">这几个进程是非常重要的。很多时候出现意外就是因为某项服务未启动或异常。可以看到上面的命令上打印出日志位置。出现异常后可以在日志中查看详细的堆栈信息。</span></p><p>&nbsp;</p><p><span style="font-family: 宋体; ">至此，</span>hadoop<span style="font-family: 宋体; ">已经启动，环境已经准备就绪。</span></p><p>&nbsp;</p><p><span style="font-family: 宋体; ">下面准备我们的测试数据，将目标页面的</span>html<span style="font-family: 宋体; ">保存为</span>news.txt<span style="font-family: 宋体; ">，伪分布式也同样支持</span>hdfs<span style="font-family: 宋体; ">，所以我们使用</span>&nbsp;fs &#8211;put&nbsp;<span style="font-family: 宋体; ">将</span>news.txt<span style="font-family: 宋体; ">存入</span>hdfs<span style="font-family: 宋体; ">中。</span></p><p>[root@localhost hadoop-1.0.0]# ./bin/hadoop fs -put /mnt/hgfs/shared/news.txt /user/root</p><p>[root@localhost hadoop-1.0.0]# ./bin/hadoop fs -lsr /userdrwxr-xr-x&nbsp; &nbsp;- root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 2012-04-01 11:22 /user/root</p><p>-rw-r--r--&nbsp;&nbsp; 1 root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3935 2012-04-01 11:22 /user/root/news.txt</p><p>&nbsp;</p><p><span style="font-family: 宋体; ">实现的代码在</span>eclipse<span style="font-family: 宋体; ">中使用</span>maven<span style="font-family: 宋体; ">打包，上传至虚拟机。</span></p><p><span style="font-family: 宋体; ">文件名</span>com.suntang.analyse.hadoop-0.0.1.jar<span style="font-family: 宋体; ">。<br />使用hadoop的中的jar命令调用该jar文件。<br /></span></p><p><br class="Apple-interchange-newline" />[root@localhost hadoop-1.0.0]# ./bin/hadoop jar com.suntang.analyse.hadoop-0.0.1.jar com.suntang.analyse.hadoop.AnalyseJob /user/root/news.txt output_root_test</p><p>12/04/01 14:40:04 INFO input.FileInputFormat: Total input paths to process : 1</p><p>12/04/01 14:40:05 INFO mapred.JobClient: Running job: job_201204011420_0001</p><p>12/04/01 14:40:06 INFO mapred.JobClient:&nbsp; map 0% reduce 0%</p><p>12/04/01 14:40:19 INFO mapred.JobClient:&nbsp; map 100% reduce 0%</p><p>12/04/01 14:40:31 INFO mapred.JobClient:&nbsp; map 100% reduce 100%</p><p>12/04/01 14:40:37 INFO mapred.JobClient: Job complete: job_201204011420_0001</p><p>&#8230;</p><p>&nbsp;</p><p>&nbsp;</p><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">此处注意我犯的一个错误：</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">[root@localhost hadoop-1.0.0]# ./bin/hadoop jar com.suntang.analyse.hadoop-0.0.1.jar AnalyseJob -libjars hadoop-core-1.0.0.jar /user/root/news.txt output_root_test</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">Exception in thread "main" java.lang.ClassNotFoundException: AnalyseJob</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">提示找不到类，因为我忘了写完整类名，命令应该改为</span></p><span style="background-color: #c0c0c0; ">./bin/hadoop jar com.suntang.analyse.hadoop-0.0.1.jar com.suntang.analyse.hadoop.AnalyseJob -libjars hadoop-core-1.0.0.jar /user/root/news.txt output_root_test&nbsp;</span><span style="font-family: 宋体; background-color: #c0c0c0; ">即可。</span></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p>&nbsp;</p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">此处运行可能出现另外一个错误。在命令行中出现</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">12/04/01 14:01:38 INFO mapred.JobClient: Task Id : attempt_201204011356_0001_m_000001_0, Status : FAILED</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">java.lang.Throwable: Child Error</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:271)</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="background-color: #c0c0c0; ">Caused by: java.io.IOException: Creation of symlink from /mnt/hgfs/shared/hadoop-1.0.0/libexec/../logs/userlogs/job_201204011356_0001/attempt_201204011356_0001_m_000001_0 to&nbsp;</span><span style="font-family: 宋体; background-color: #c0c0c0; ">。。。</span></p></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family: 宋体; background-color: #c0c0c0; ">就不打全了，重点在与</span></p><span style="background-color: #c0c0c0; ">Creation of symlink</span><span style="font-family: 宋体; background-color: #c0c0c0; ">，看详细日志中</span><span style="background-color: #c0c0c0; ">hadoop-root-tasktracker-localhost.localdomain.log</span><span style="font-family: 宋体; background-color: #c0c0c0; ">中提示</span><span style="background-color: #c0c0c0; ">org.apache.hadoop.fs.FileUtil: Command 'ln -s ....': Operation not supported</span><span style="font-family: 宋体; background-color: #c0c0c0; ">，即</span><span style="background-color: #c0c0c0; ">ln</span><span style="font-family: 宋体; background-color: #c0c0c0; ">操作不支持。</span><span style="background-color: #c0c0c0; ">google</span><span style="font-family: 宋体; background-color: #c0c0c0; ">可知这个是由于</span><span style="background-color: #c0c0c0; ">vm</span><span style="font-family: 宋体; background-color: #c0c0c0; ">中的共享区域的问题，解决方法就是将</span><span style="background-color: #c0c0c0; ">hadoop</span><span style="font-family: 宋体; background-color: #c0c0c0; ">完全转移至</span><span style="background-color: #c0c0c0; ">linux</span><span style="font-family: 宋体; background-color: #c0c0c0; ">目录中。本例中从</span><span style="background-color: #c0c0c0; ">/mnt/hgfs/shared/hadoop-1.0.0</span><span style="font-family: 宋体; background-color: #c0c0c0; ">转移至</span><span style="background-color: #c0c0c0; ">/usr/local/hadoop-1.0.0</span><span style="font-family: 宋体; background-color: #c0c0c0; ">。</span></blockquote></blockquote><p>&nbsp;</p><p><span style="font-family: 宋体; ">执行完成后可在</span>hdfs<span style="font-family: 宋体; ">中查看结果，查看目录结构为</span></p><p>-rw-r--r--&nbsp;&nbsp; 1 root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 2012-04-01 14:40 /user/root/output_root_test/_SUCCESS</p><p>drwxr-xr-x&nbsp;&nbsp; - root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 2012-04-01 14:40 /user/root/output_root_test/_logs</p><p>drwxr-xr-x&nbsp;&nbsp; - root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 2012-04-01 14:40 /user/root/output_root_test/_logs/history</p><p>-rw-r--r--&nbsp;&nbsp; 1 root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13634 2012-04-01 14:40 /user/root/output_root_test/_logs/history/job_201204011420_0001_1333262405103_root_ccAnalyseJob</p><p>-rw-r--r--&nbsp;&nbsp; 1 root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 20478 2012-04-01 14:40 /user/root/output_root_test/_logs/history/job_201204011420_0001_conf.xml</p><p>-rw-r--r--&nbsp;&nbsp; 1 root supergroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3580 2012-04-01 14:40 /user/root/output_root_test/part-r-00000</p><p>&nbsp;</p><p>/user/root/output_root_test/part-r-00000<span style="font-family: 宋体; ">即为最终结果文件。</span></p><p>&nbsp;</p><p>&nbsp;=======================================================================</p><p><span style="font-family: 宋体; ">附加</span>AnalyseJob<span style="font-family: 宋体; ">代码</span></p><p>package com.suntang.analyse.hadoop;</p><p>&nbsp;</p><p>import java.io.IOException;</p><p>&nbsp;</p><p>import org.apache.hadoop.conf.Configuration;</p><p>import org.apache.hadoop.conf.Configured;</p><p>import org.apache.hadoop.fs.Path;</p><p>import org.apache.hadoop.io.LongWritable;</p><p>import org.apache.hadoop.io.Text;</p><p>import org.apache.hadoop.mapreduce.Job;</p><p>import org.apache.hadoop.mapreduce.Mapper;</p><p>import org.apache.hadoop.mapreduce.Reducer;</p><p>import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;</p><p>import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;</p><p>import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;</p><p>import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;</p><p>import org.apache.hadoop.util.Tool;</p><p>import org.apache.hadoop.util.ToolRunner;</p><p>&nbsp;</p><p>public class AnalyseJob extends Configured implements Tool {</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static class MapClass extends Mapper&lt;LongWritable, Text, Text, Text&gt; {</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Override</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected void map(LongWritable key, Text value, Context context)</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; throws IOException, InterruptedException {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // TODO Auto-generated method stub</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // super.map(key, value, context);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (value.toString().matches("&lt;a[^&gt;]*&gt;.*?release.*?&lt;/a&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; context.write(</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; new Text(value.toString().substring(</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; value.toString().indexOf("release") + 8,</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; value.toString().indexOf("available") - 1)),</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; value);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static class ReduceClass extends Reducer&lt;Text, Text, Text, Text&gt; {</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Override</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected void reduce(Text arg0, Iterable&lt;Text&gt; arg1, Context arg2)</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; throws IOException, InterruptedException {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // TODO Auto-generated method stub</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // super.reduce(arg0, arg1, arg2);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arg2.write(arg0, arg1.iterator().next());</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int run(String[] args) throws Exception {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Configuration conf = getConf();</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Job job = new Job(conf, "myAnalyseJob");</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setJarByClass(getClass());</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Path in = new Path(args[0]);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Path out = new Path(args[1]);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileInputFormat.setInputPaths(job, in);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileOutputFormat.setOutputPath(job, out);</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setMapperClass(MapClass.class);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setReducerClass(ReduceClass.class);</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setInputFormatClass(TextInputFormat.class);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setOutputFormatClass(TextOutputFormat.class);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setOutputKeyClass(Text.class);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job.setOutputValueClass(Text.class);</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(job.waitForCompletion(true) ? 0 : 1);</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int res = ToolRunner.run(new Configuration(), new AnalyseJob(), args);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(res);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>}</p><img src ="http://www.blogjava.net/matuobasyouca/aggbug/373194.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-01 15:00 <a href="http://www.blogjava.net/matuobasyouca/archive/2012/04/01/373194.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>