Archive for the 'Uncategorized' Category
mercurial的现状
Posted on June 23, 2008 - Filed Under Uncategorized
最初是从cyfdecyf的文章认识mercurial的,后来用netbeans开发rails,当时netbeans 6.0还没正式发布,我在用netbeans 6.0测试版,发现竟然有mercurial插件,而且更新相当频繁,于是也对mercurial颇有好感,到后来mercurial插件纳入netbeans正式发布包里面,之后netbeans宣布从cvs转到mercurial,这一切都很自然发生了.mercurial 1.0正式发布,而且有netbeans插件,还有TortoiseHg这个类似TortoiseSVN的windows工具,再加上指令并不多(十条指令左右,相比git的几十条指令),而且你还可以在dreamhost上搭建你的中央源,mercurail始终是新手和小项目的首选
Read More..>>mercurial&git的远程模式
Posted on June 23, 2008 - Filed Under Uncategorized
mercurail和git是一个很自由的版本管理软件,我们随时可以在自己的机器上任意一个目录启用版本管理,不需要任何服务器.但是,当我们需要跟别人协作的时候,应该怎么处理呢.我们可以N个人之间互相乱pull来push去,但是这样的网状结构并不方便管理,非常容易混乱,一般来说,我们会指定一个中央源,大家都把代码push到中央源.我认为它们的远程模式有如下几种:
1.U盘
最常见的情况就是我在家和公司都要使用同一份源代码,于是我就会把中央源定在U盘上,而家里和公司的电脑各有一份本地副本,代码提交到本地,然后push到U盘上.例如我会在U盘上建立一个sparkle_repo的目录,放少量代码和一些文档用git管理.也有不少人是这样用SVN的,不过经常会遇到盘符变化的问题.
优点是完全不需要网络,缺点也很明显,如果要跟朋友协作的话将会相当麻烦
2.网上邻居共享文件夹
很简单,在本地网络随便找一台机器共享一个完全读写的文件夹,然后把中央源放在上面,适合公司内部的简单使用.
优点是简单,缺点是,别人都能完全读写文件夹,干什么事情都可以了,包括删除整个目录.你当然可以进行权限认证,但是认证通过之后,一样可以做任何事情
3.ssh
功能丰富的ssh对于传送文件当然不在话下(我工作的时候都是用ssh而不是ftp传送文件),最适合有个人ssh主机的情况,例如拥有一个dreamhost的空间,你只要在ssh帐户下随便开一个目录就能作为中央源,但是如果你要跟朋友协作的话,你还是得告诉他你的ssh帐号,又或者你对机器有足够的控制权可以让两个ssh帐号访问到同一个目录.另外,ssh比网络邻居要好的地方是你可以控制能够通过ssh的指令,这样可以只允许mercurial/git的指令通过,防止有意或无意的删除目录
以上三种模式其实原理是一样的,就是通过一个大家都可以读写的目录进行协作
4.私有协议
mercurial&git都可以启动一个daemon server进行使用,mercurial启动的port是8000,其实是使用http协议的,而经常见到的git://xxxxx就是git的私有协议.由于要启动额外的daemon,你必须对机器有一定的控制权才行,例如你不能在dreamhost这样使用.
5.http模式
git只能通过http进行查看和pull,不能进行push操作,有点像viewcvs那样.这点来说,mercurial就比较厉害了,官方包里面提供了一个hgweb.cgi文件,通过配置这个cgi文件,我们可以在一个apache环境中提供push功能,也就是说我们可以在dreamhost上这样使用mercurial,非常棒(下一篇文章我将介绍怎么在dreamhost使用mercurial)
6.Don’t push to me, I will pull from you
是不是有点像IOC(Don’t call me, I will call you).我阅读到相关资料的时候,看见这样一种模式,简直有如脑袋哐当一声.我们太以中央式版本管理的思路来想分布式版本管理了,认为一定要有一个中央源,然后大家都push数据到中央,而且还要认证什么的.git提出的这种模式,就是没有中央源,但是有中央人,并不是大家push到中央,而是中央从大家那里pull,其他人只要用某种形式,例如共享文件夹,或者http等方法公开你的副本,然后发email什么的通知中央人到你的副本中pull.
例如我sparkle负责整个项目,然后我只从各个模块的主管的源那里pull数据,而各个模块的主管从他的手下coder pull数据(事实上使用git的大型项目都是分成多个级别的),我熟悉模块主管,所以我知道他们是可信的,至于他们的数据从哪里来的我不关心,而他们也对他们的手下coder信任,从他们那里pull数据,如此一级一级下去.这种处理模式,一来不需要认证的部分,二来中央的数据是可控的,就是我负责,而不是多个人push的模式那样,并不一定能确定是否正确,第三点,可以分级.
Mercurial之权限问题
Posted on June 9, 2008 - Filed Under Uncategorized
我多次跟朋友讨论分布式版本管理软件的时候,都提到一个固有的缺陷,就是权限认证问题.传统的中央式版本管理软件,例如SVN,可以很简单地在服务器上做登录验证,可以阻止非法用户获取文件,当然,你可以使用一些外部手段来进行读取限制,例如http basic认证,iptables等手段,但是这样只能针对整个Mercurial库进行控制,不能像SVN那样对某一个目录树进行限制,你可以把不同的模块使用独立的Mercurial库来保存,但是那会增加管理的复杂性,而且你很难实现权限组的概念.不过,分布式版本管理最常用的地方是开源领域,也因此SVN比较适合公司内部使用,一般情况你也不希望员工能方便地把源代码带回家.
上面提到的是权限问题,另外一个比较大的就是认证问题.回想一下我们使用SVN的流程,我用sparkle&password登录SVN,然后提交修改,别人就能在SVN上看到这次的修改是我提交的,因为只有我才拥有sparkle这个帐号的密码,别人就没有办法冒认我.而使用Mercurial的时候,我们根本不用登录(当然有些远程模式可以配置需要登录,但是并没有认证效果,我在迟点专门写一篇远程模式的文章),使用Mercurial的时候,我们一般会先设置我们的名字,例如Sparkle,但是,别人一样可以取这个名字,你根本没有办法证明/阻止别人冒认你.又比如说我一个朋友Nomad的提交让我一起commit到center,我先把Nomad的修改pull到我这里,然后我再push到一个大家认为的公共库center,也就是说我同时把写着是我的修改和Nomad的修改提交,我随时可以假冒Nomad.
当然,你也可以认为大家都是守法的,比如说团队成员是可控的,但是这始终是个问题.因为没有了中心,也就没有了认证的可能性.其实有一个办法可以解决,就是使用证书签名,在我的提交里面,我附带一份使用我的私钥对此修改的签名,大家就可以通过公钥去验证这的确是我签发的,就能证明我的身份.不过目前大家还是比较少用这种模式,因为使用成本也挺高的.
并发相关
Posted on March 26, 2008 - Filed Under Uncategorized
http://www.javaeye.com/post/498557
copy on write array list
ConcurrentHashMap
ReentrantLock
ReentrantReadWriteLock
CAS
我都有在用,JDK内置
一直都想写一些关于它们的文章,不过始终太松散,而且我是知道原理然后直接用API而已
我随便说一些
楼主的copy on write模式是可取的,JDK很早就引入copy on write array list来处理Listener部分,在写入非常非常少的情况下,copy on write其实是很好的。至于楼主的实现好不好就不知道了
ConcurrentHashMap用了多个锁来处理,里面有一个一个的bucket来隔离锁,默认就是16个bucket&锁。但是它也有缺点,就是不能保证数据绝对准确,例如他的size就是不准确的。但是它肯定是线程安全的
ReentrantLock是可以代替synchronized的东西,除了写起来比synchronized难稍稍。默认是non-fair模式,比synchronized快很多,如果改成fair就会下降到跟synchronized差不多
ReadWriteLock很简单,read不互斥,write互斥
CAS就是AtomicInteger之类的了,使用了CPU的交换指令,理论上比锁快,但是在高并发的环境一样会下降
你们还是看一下JDK源代码和JavaDoc好过了,你们的讨论本来就有答案的
Mercurial续
Posted on March 19, 2008 - Filed Under Uncategorized
上次谈到一些Mercurial的事情,后来因为忙别的事情没有继续写下去。中途跟cyfdecyf通过几次email讨论Mercurial。总体来说,我对Mercurial和分布式版本管理的理解还是比较松散的,比较难形成文章,但还是很希望把我所知道的写出来。
我对分布式版本管理的理解很简单。首先这里假设你有一般版本管理软件的概念(CVS或者SVN)。假设你在家里装了一个SVN服务器,你在家里编写的代码都提交上去。在公司也装了一个SVN,你在公司编写的代码也都提交上去。这里就有两个完全独立的SVN服务器了。分布式版本管理,就是这两个SVN服务器之间可以互相提交,其操作就像你提交上其中一台SVN那样,SVN之间互相提交就会将多个changeset同时提交。而且这两个SVN服务器没有主次之分,这样处理是很容易混乱的,实际上,我们会架设另一个SVN服务器,作为两个SVN的父,两个SVN向父提交changeset。这个行为仅仅是方便我们管理的一个比较好的参考做法,并没有强制。另外,当然SVN服务器是不支持互相提交的,于是我们需要一个分布式版本管理软件。
个人觉得,一台SVN就好像一台MySQL,我们只有一个数据库。而分布式版本管理就好像Master-Master MySQL集群。有经验的朋友就会知道,在集群中使用自增字段是不可取的,就像SVN的changeset id是自增的不能适应分布一样。做MySQL集群很经常会用UUID作为主键,分布式版本管理也使用了类似的机制来保证多个库之间的changeset有唯一的ID不会冲突。这个已经是比较细节的处理问题。这里暂时不打算细节研究具体的机制或者使用方法,先有一个大概的概念,看软件的refrence很快会上手的。
再待续
预告:
权限问题
Mercurial目前的情况
远程模式
在Dreamhost上使用Mercurial
Mercurial基本使用
给《程序员》写的MINA文章已经出刊了
Posted on February 26, 2008 - Filed Under Uncategorized
第一次给杂志写文章,没什么经验,行文一般般,呵呵。不过也是能顺利出刊。
对文章有任何意见和建议,或者讨论MINA,可以在这里留言
迟点我再写一些MINA的心得
架设你的CruiseControl
Posted on January 28, 2008 - Filed Under Uncategorized
说实在话,07年最大的感悟就是重新认识了TDD和持续集成的意义,这个下次有机会再说。这次要说的是部署一个持续集成服务器。
持续集成服务器的作用其实很简单,就是check out最新的代码,然后运行指定的script,然后把结果记录下来,还可以将结果(尤其是错误的结果)通过email等手段发给程序员。
事情倒是很简单,但是我们为什么要专门的软件呢,当然你也可以自己写bash script来做这些事情,做着做着你就会发现差不多实现一个CruiseControl出来了,呵呵,无谓重复发明轮子。
常用的持续集成服务器有CruiseControl、Luntbuild 和 Anthill等,相对来说CruiseControl比较老牌,支持度也比较好,不过实际使用的时候还是觉得不太好使(最近又发现了一个软件Hudson,Netbeans在使用)
下面是安装和配置过程,可能有一些细节不是很准确,因为已经是比较早之前安装的
从官方网站下载最新版的CruiseControl 2.7.1,我选用的是exe的版本,因为我的服务器是windows的,相对来说,exe版本有一些预设的参数,配置会简单些
运行安装程序,默认装在C:\Program Files\CruiseControl,可以不改动,而实际的项目文件可以放在其他盘上面的
安装成功之后运行cruisecontrol.bat,就能看到一个dos窗口运行,这个时候访问本机8080端口就可以看到一个示范项目
接下来修改配置文件
打开config.xml,可以看到示范例子的配置,把它都注释掉,不过其实我最后的配置也跟它差不多
直接贴我的配置吧,然后再来解释
<project name="xxx-xxx">
<listeners>
<currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
</listeners>
<bootstrappers>
[...]
优化你的Eclipse VM参数
Posted on January 26, 2008 - Filed Under Uncategorized
最近dzone在讨论eclipse的VM参数
引用了一篇2004年的帖子
Here are the best options that I’ve found so far for my 2-processor Windows machine running JDK5.0 and Eclipse3.1:
-vmargs -XX:+UseParallelGC
2004年就用两个CPU都颇奢侈了吧
我现在的机器是双核+2G内存,于是我修改了一下eclipse的VM参数
打开eclipse.ini
修改或加入如下内容
-vmargs
-Xmx512m
-XX:+UseParallelGC
我与Mercurial
Posted on January 25, 2008 - Filed Under Uncategorized
最初知道 Mercurial这个工具其实是因为去年6月份看了cyfdecyf的一篇blog分布式版本管理工具:git & mercurial(作者搬迁了blog,新地址是这里).然后断断续续有在使用,一直想把一些经验写出来.最近刚好遇到云风在研究分布式版本管理,还是动手把一些经验写下来吧
一直一来都是用CVS,然后是SVN来做版本管理,最初认识分布式版本管理,是一个叫SVK的工具,是一个台湾人的作品,本身基于SVN,令到SVN可以分布式工作.当时觉得安装非常麻烦就没有研究下去了,而且本身对这样的功能需求也不大.后来Linus因为不满现有版本管理软件的问题,自己花了两个星期写了一个分布式版本管理Git,现在Linux kernel等源代码已经完全工作在Git的管理之上了.但是Git本身非常晦涩难懂,而且只能在Linux下运行,我本身也主要用Windows来工作,因此也没有深入研究.
直至看到 cyfdecyf的文章,这篇文章有坚定我研究分布式版本管理的信心.集中式版本管理的缺陷, cyfdecyf和云风都有描述了一些例子,我认为那些例子都很典型.如果所有开发人员都在一个房间里面,集中式版本管理是最好的,最明显的例子就是公司的开发,大家都能直接访问到服务器,网络不会中断.这种情况下,使用分布式版本管理反而增加了复杂性.但是,如果开发人员不是在同一个房间,甚至在不同的国家.当然你也可以在Internet上假设一个SVN服务器.但是,开发人员不一定有网络,或者网络不一定很好.而每次提交,或者同步,都要花上好几分钟或者更长时间,这非常影响开发.又或者你只是私人的项目,而你有没有能力假设公开的SVN服务器.而且我只是一个人,为什么每次都要提交到外边的服务器.当然也可以在自己的机器上面架设一个SVN,但是如果你有两台以上的机器就会觉得很麻烦了.
所有的这些场景,其实你需要一个分布式版本管理.cyfdecyf的文章最后在选择Git的代替品,定了用Mercurial.那我也从Mercurial开始吧.不过Mercurial的中文资料非常少,我始终不理解分布式版本管理的原理.最后,非常搞笑的情况是,我其实是看了Git的一份中文资料才真正明白的,也推荐大家从Git的中文资料入手.
待续…
如何用Java进行3DES加密解密
Posted on January 5, 2008 - Filed Under Uncategorized
最近一个合作商提出使用3DES交换数据,本来他们有现成的代码,可惜只有.net版本,我们的服务器都是Linux,而且应用都是Java。于是对照他们提供的代码改了一个Java的版本出来,主要是不熟悉3DES,折腾了一天,终于搞定。
所谓3DES,就是把DES做三次,当然不是简单地DES DES DES就行了,中途有些特定的排列。这个我可不关心,呵呵,我的目的是使用它。
在网上搜索了一下3DES,找到很少资料。经过朋友介绍,找到GNU Crypto和Bouncy Castle两个Java扩充包,里面应该有3DES的实现吧。
从GNU Crypto入手,找到一个TripleDES的实现类,发现原来3DES还有一个名字叫DESede,在网上搜索TripleDES和DESede,呵呵,终于发现更多的资料了。
Java的安全API始终那么难用,先创建一个cipher看看算法在不在吧
Cipher cipher = Cipher.getInstance("DESede");
如果没有抛异常的话,就证明这个算法是有效的
突然想看看JDK有没有内置DESede,于是撇开Crypto,直接测试,发现可以正确运行。在jce.jar里面找到相关的类,JDK内置了。
于是直接用DES的代码来改&测试,最后代码变成这样
SecureRandom sr = new SecureRandom();
DESedeKeySpec dks = new DESedeKeySpec(PASSWORD_CRYPT_KEY.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey securekey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
return new String(Hex.encodeHex(cipher.doFinal(str.getBytes())));
需要留意的是,要使用DESede的Spec、Factory和Cipher才行
事情还没完结,合作商给过来的除了密钥之外,还有一个IV向量。搜索了一下,发现有一个IvParameterSpec类,于是代码变成这样
SecureRandom sr = new SecureRandom();
DESedeKeySpec dks = new DESedeKeySpec(PASSWORD_CRYPT_KEY.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey securekey = keyFactory.generateSecret(dks);
IvParameterSpec iv = new IvParameterSpec(PASSWORD_IV.getBytes());
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, securekey, iv, sr);
return new [...]