2012年11月4日星期日

Xen虚拟化的NAT和Bridge网络模式的共存

这是几个月前在下厨房做的一次改动。当时Xen虚拟化配置的是NAT模式,所有虚拟机均在一个局域网之中,和Dom0不在同一个网段之内。由于新增了一台物理机,我们就需要将新增的物理机和所有的虚拟机配置在同一个网络之内,这样就算以后再新增物理机也不会有任何麻烦。

我翻遍了Debian的wiki以及网上的所有帖子都没有找到如何在不重启Xend的情况下切换网络模式。Xen 4.x的网络部分相比3.x貌似有比较大的改动,官方文档已经不再推荐使用Xen自带的脚本配置网络,而是鼓励网管们根据自身的实际情况自行配置。Xen自带的脚本对于Bridge模式的配置还是很简单易懂的。我看了一下,相比3.x并没有什么变化。那么我们就自己来配置网桥吧。

我们的Dom0有四块网卡,公网IP在eth0上。那我们就把网桥和eth1关联起来。Dom0和新物理机都在192.168.0.x网段,所有虚拟机都在10.x.x.x网段。首先我们在Dom0上创建一个bridge:
sudo brctl addbr xenbr1

然后把eth1添加到xenbr1之中:
sudo brctl addif xenbr1 eth1

配置xenbr1的IP:
sudo ifconfig xenbr1 192.168.0.99/24

xenbr1就配好了,基本就是把Xen的脚本自己手动做一遍。然后就是配置所有虚拟机。为每台虚拟机都新增一块网卡,IP固定在Dom0的网段之内,也就是192.168.0.x。这包括在vm.cfg里面,把vif这一行注释掉:
#vif = [ 'ip=10.1.1.3,mac=00:16:3E:12:03:99' ]

然后改成:
vif = [ 'ip=10.1.1.3,mac=00:16:3E:12:03:99',
        'ip=192.168.0.3,mac=00:16:3E:12:03:9A,script=vif-bridge,bridge=xenbr1' ]


mac地址可以随便编,只要开头是00:16:3E,而且所有的虚拟机都不重复就行。虚拟机硬盘上的/etc/network/interfaces也要加入这块新的网卡:
auto eth1
iface eth1 inet static
 address 192.168.0.153
 gateway 192.168.0.1
 netmask 255.255.255.0


OK,大功告成。重启该虚拟机,它就会通过eth1和Dom0处于同一网段(192.168.0.x)上了。当然,如果你要完全去掉NAT,还是需要修改Dom0上Xen的网络配置并重启Xend才行。

2012年9月27日星期四

Mercurial Internal

最近在图灵社区上翻译了一篇mercurial架构的文章,顺便看了一下mercurial的代码和内部实现:http://www.ituring.com.cn/article/details/11708

我还没看AOSA这本书的git这一章。虽然平时git用的比较多,但是对git的内部实现还是认识的很模糊,没法和mercurial进行对比。就mercurial本身而言,除了在分支的实现上不如git之外,其他都非常好。mercurial一开始只能clone,这对于大型项目来说很坑爹。比如Firefox,开始克隆代码库之后程序员就可以去泡杯咖啡了。为了解决这个问题,mercurial后来加上了branch命令,可以原地切换分支。但是mercurial为了保持对svn和cvs用户的友好性,设计上还是希望在每个changeset之内记录分支名,不像git那么奔放,分支名就是个指针。

Mercurial的另一个特别之处在于每个changeset除了有一个hashid之外还有一个整数版本号。 虽然分布式版本控制系统中的版本历史是非线性的,但是这个整数版本号在任何一个mercurial版本库中都是线性的,只是顺序可能不同。这个数字版本号不仅使得mercurial对svn用户更友好,而且对于mercurial的内部实现很重要,它是mercurial快速读取版本历史的关键。

从社区的角度来说,Github完胜Bitbucket。我不知道为啥,可能是因为git比mercurial性能更好?或者Github更友好?我用python最多,所以也更偏爱mercurial。

Mercurial项目也有自己的性格,比如类名都是小写,变量名的单词之间不要下划线而是直接连起来写(比如loaddoc或者disabledext这样的函数名)。mercurial的代码中的注释真的多啊,不过注释多也不见得一定就是好事。给mercurial提交patch也是要带测试的,但是mecurial现在的测试已经太多了,跑起来要好久。我跑了一遍需要十多分钟。于是大家约定新的patch不再接受新的测试文件,但测试还是要,只是要塞在已有的某个测试脚本之中。囧!另外,虽然有个bugzilla来记录bug,但是所有的patch都要发到邮件列表里,有机器人会扫描新邮件,并根据邮件中的某些字样自动的在相应的bug中添加reference或者修改bug的状态。哎,真是奇怪的工作流程。

2012年3月9日星期五

自己实现 Interview Zen


偶尔遇到了www.interviewzen.com这个网站,一开始我觉得太神奇了,而且太酷了,这真是面试的神器!随即我就开始思考它是怎么实现的。

我并没有第一时间查看它的源代码。在考虑了几个小时之后,我感觉它可能是通过记录

2012年3月2日星期五

计算机编程语言的掌握程度

在简历上,“精通”这两个字基本上起到的都是嘲讽和增加仇恨的效果。一旦你自称“精通”某一门技术或者编程语言,面试官如果不是直接在心里给你打一个不靠谱的标签,那就会努力的证明你是不靠谱的——“精通”这两个字一般都会引来最最困难的提问。所以我一直在想,到底应该怎么形容自己的掌握程度呢?某种技术我说不好。但今天偶尔的一次谈话让我觉得对一门计算机编程语言的掌握程度,是可以有以下四个层次的:

1、知道
在这个层次,你已经了解了这门语言的基本语法。虽然这很微不足道,但也足够你阅读这门语言的程序了。不同语言在语法层面还是有一些区别的,比如语言的类型是编译还是解释、强类型还是弱类型、代码段是用begin/end还是{}表示、声明一个函数是用function还是def等等。

2、熟悉
在这个层次,你已经学会使用了这门语言的基本类库。只有语法没有类库的语言是没有意义的,熟悉这些类库是正确运用语言的基础。熟练使用操作文件系统、socket、日志、并发等等的类库,知道什么时候该用链表什么时候该用哈希,你才能算“熟悉”了这门语言。

3、掌握
在这个层次,你已经使用这门语言写出了一些能够解决实际问题的程序了。在前面的层次,你的代码解决的可能都是一些toy problem,但是只有你的程序经受了实践和时间的考验,你才能够有机会去解决一些书本上永远不可能出现的问题,并且更加深入的了解这门语言的细节。

4、精通
在这个层次,你已经阅读了这门语言的源代码。你应该已经了解它的内部实现,并且有了恍然大悟的感觉。


用这个角度检视自己,我对于各种语言的认知程度又有几分呢?

A类:最接近于精通的
Python:感谢《Python源代码剖析》这本书,给了我一个很好的入门。不过一来这本书我也没看完,二来Python本身的代码也在快速变化着,完全理解Python的实现仍然是一个很艰难的任务。

B类:掌握
C语言: 把C语言列在这里有点勉强,因为我上大学之后就基本没有写过C的代码了,不过C给我的影响仍然是巨大的,它塑造了我对计算机和程序的认识。
Javascript:Javascript是我很喜欢的一门语言,更不必说在这个浏览器的时代,它简直就是世界的未来。Douglas Crockford的那本《Javascript: The good part》是每个js程序员都必读的一本书,而Coffeescript则可以看作是这本书的实现。

C类:熟悉
C++、Java: 把这两门重量级的语言放在这一类实在是让我脸红,不过面向对象程序设计的确仍然是我最弱的地方。类、继承、多态、虚函数、接口——这些都不是问题,我似乎只是不知道怎么把这些螺丝刀派上用场。
PHP:玩具语言。
VB:感谢这门语言陪我度过了紧张的高中时光。

D类:知道
这一类就多了,不一一列举。


显然,随着时间的推移,这些分类也总是在变化的。有的语言因为你不再使用而变得生疏,有些则越来越熟悉。门户之见最没有意义,最重要的是把它们运用在正确的地方。