
置顶随笔
摘要: Application DeveloperIf you would like to...Inthis position you will be responsible for technical leadershipcontributing to the successful delivery of application developmentprojects. Your responsibil...
阅读全文
posted @
2008-11-03 09:36 taowen 阅读(448) |
评论 (1) |
编辑

2009年7月10日
主板:泰安 S4981
CPU:Operton 8350
内存:南亚 4G * 2
硬盘:Runcore 箭鱼四代 32G * 2
RAID卡:PERC 6/i
电源:台达 DPS-700mb
机箱:道和D416
posted @
2009-07-10 10:04 taowen 阅读(272) |
评论 (0) |
编辑

2008年11月11日
谈到敏捷,人们往往都非常高调地打探TDD与持续集成。同时很多实践,非常低调。比如,估算。学习TDD,你有很多具体例子可以学习。但是学习估算,却无从下手。在“搞砸”了几个项目之后,貌似我摸着了一些门道了。
估算的目的
在我看来,估算有两个截然不同的目的。第一个是报价,第二个是规划。为了报价,我们追求的是所有故事卡的总体的绝对大小。为了指导发布规划和在迭代开发中做调整,我们追求的是故事卡之间的相对大小的准确。但是无论,这两个目的都很难达到。
别说不靠谱
首先我想说,估算故事卡的绝对大小,然后拿去报价,TMD这就是扯——淡——。不过,谁让我们是小角色呢,领导让你做估算,你还能不做不成?想不想干了?所以,我们还得干。但是,还千万别不认真做。做得一塌糊涂的估算最后还是要我们一个一个故事卡地去码代码,最后倒霉的还不是我们这些小角色吗?所以,即使你觉得这追求估算绝对大小的事再不靠谱,你还得认认真真,仔仔细细地做好它。
你的痛苦我明了。敏捷从来不打算在项目开始的时候把故事卡写得能让我们读得懂的。如果一开始就把验收条件写得清清楚楚,再按上若干个手印,那就不叫敏捷了。所以,从一开始敏捷就是玩我们开发人员的,你得有这个心理准备。
一般,项目开始阶段的时候都有一个需求收集阶段。幸运的话,你也参与了这个阶段。然后,会有商务分析师写出一个高屋建瓴的故事卡列表来,非常非常的高屋建瓴。拿到这个故事卡列表之后,你干什么?
第一件事
第一件事情就是浏览整个列表,试图归纳一下商务分析师是按照什么思路去划分故事的。如果我们把整个项目看做一团泥:

那商务分析师写的Story,就是对它的第一次切分:

到我们写代码,把一个个故事卡变成一打一打的类的时候,是对它第二次切分:

所以,我们程序员和商务分析师做的事情,本质上是一脉相承的。商务分析师的职责就是把故事卡写到最小的程度,写到”外部可见”地最小程度。而外部不可见的部分,也就是类之间的协作等面向对象建模就由我们程序员来完成。所以,好的商务分析师写出来的故事,你非常舒服,拿来就可以写。但是,我们不在理想的世界种,不是吗?不可能给每个项目都配备最强的商务分析师。很多时候,你面对那故事列表会哭笑不得。体现出来的现象是,很复杂的一件事情,没有足够的故事来覆盖。而很简单,或者本质一样的事情,却写出了一堆故事来。所以这就需要你做两件事情。
第一件事情是查漏补缺,无论故事列表看上去是怎么完善,你自己要心里面对整个流程有一个数。然后去确认没有遗漏的故事。第二件事情是寻找重复,大概明白它们是怎么实现的,分析故事之间是不是从实现地角度看是重复的。
最糟糕的情况是商务分析师的切分角度完全错误,切分的时候没有把握住系统的变化点(真正是代码复杂度所在的地方)。对于整体不了解就开始估算是非常危险的。开发人员在这个时候一定要强硬,对于遗漏的故事一定要提出来,对于重复的故事一定要去掉,对于切分完全错误的故事列表一定要求她们返工。
不明白的时候,我们能做什么?
别指望在项目开始的时候,故事卡上会有很多字。让你估算,你算不出 。难不成你给你的项目经理说,不如你来?NO,NO WAY。这个时候你首先应该与商务分析师交谈,尽可能多的了解细节。但是我们在报价阶段,或者项目前期,商务分析师自己也不是很了解业务,而且我们也没有无限多的时间是去调查了解。所以,真实世界中,你必须在没有充足信息的情况下做出估算。这个时候,你有两个选择:
1、拒绝估算
有的时候,我们可以说不。荒谬的估算,害人害己。不要指望,一个“充分大”的估算可以把你罩住。把小的故事估算大了,只能让其他真正大的故事相对变得小。不要给10,或者8这样没有谱的数字。不要在你所有的估算值中随意地选一个非常大的值。因为你一旦选择了这个值,比如10,项目经理在做发布计划的时候就真的会当10来计划,这意味着5张2的故事卡,3张多3的故事卡。你要扪心自问,这真的有5张2的故事卡那么多吗?或者这够吗?10不是10,10代表你“不知道”。程序员可以说不。
2、做一些假设,把假设写下来,然后在假设的基础上做估算
这是迫不得已的做法,特别是你要报价的话。你必须要把你做的假设写下来。因为你会忘记,你会离开这个项目。你不希望你的同事实现这张故事卡的时候骂你对不对?那请你把你做的每个假设,比如不包括数据库,只有前台界面等等,写在你的估算的旁边。剩下的事情就是祈求你的项目经理和商务分析师会在做迭代开发的时候尊重你的假设。当假设变化的时候,让客户知道,我们做了额外的超出了估算范围的事情,你必须补偿我(。。。Ideally)
做加减法不要做乘除法
在具体做估算的时候,有两种风格。一个种是乘除法,一种是加减法
1、乘除法
选择一张所谓的一个点的故事卡。然后其他的故事卡去和这张一个点的卡做比较,得出它们的估算。如果需要两倍时间,那就是两个点。如果是三倍时间就是三个点。
2、加减法
选择一张中等尺寸的故事卡。然后其他的故事卡去和这张卡做比较,比它大的一点的,我们加一,比它大很多的,我们加二,比它小一点的,我们减一,比它小很多的,我们减二。
我个人觉得, 不要去用乘除法,只用加减法。因为人对于衡量两个物体的倍数,非常不擅长。即便把项目做完了,你也未必能准确估计两张故事卡的倍数。另外,写到好的故事,应该是大小相当的。如果故事的尺寸相差三倍是一个常态,那我觉得这是不正常的。理论上来说,最小的和最大的故事卡,应该在两倍大小左右。如果太大了,说明我们没有理解业务,或者切分方法有问题。特别是你要理解估算是要指导迭代开发的。你估算出一张卡是8个点,那要4张2个点的卡才与之相当。如果用乘除法,导致故事卡的尺寸往往相差很悬殊,在实际开发中真的会有那么悬殊的差距吗?个人推荐的估算值是2,3,4,5。一般取2或者3,大一点的4,大一点的带一些风险的5,如果更大的,那你就要考虑拆分故事了。
总结
估算应该算是敏捷的薄弱环节吧。而且也是成功敏捷项目中的关键环节。传统项目,预先设计,闭口合同等等很多东西,有一整套方法学来指导我们做估算。在这个方面,敏捷毫无疑问把担子都推卸到了具体去做的人身上。关于估算,还有很多东西值得我们去学习探讨。
posted @
2008-11-11 11:32 taowen 阅读(1899) |
评论 (10) |
编辑

2008年11月7日
以下是我个人的一些主观感受,没有任何客观数据支持。
————————
按实现方式来划分,从下面几个方面做一个比较
CPU效率:
软虚拟和硬件虚拟基本差不多,但是模拟的CPU速度最慢,而且不是慢一点半点。
内存效率:
大家都差不多,即便是QEMU这样的模拟器加上了KQEMU的加速,也能凑合。
内存占用:
硬虚拟的一大软肋。软虚拟可以轻松地在一台机器上安装十多个虚拟机,但是硬虚拟就很难做到。主要的障碍是硬虚拟上的操作系统彼此独立,而且主流的操作系统对内存消耗都是非常贪婪的(用尽最后一个比特)。
I/O效率:
硬虚拟的另一大软肋。在Guest操作系统上装特殊的驱动,然后通过虚拟的总线(Hyper-V的VMBus)把操作直接委托给Host来完成,速度有所提升。但是由于DMA的缘故,在AMD/Intel不推出硬件支持的情况下,没法有根本改观。
可管理型:
硬虚拟的弱项。控制Guest操作系统基本上都是靠在Guest操作系统上安装控制软件来完成的。在没有控制软件的帮助下,就是关闭操作系统之类的事情都无法完成,要强制关机。软虚拟在这个方面非常方便。
安全性:
软虚拟的大软肋。就是Unix的chroot,人称jail系统。但是越狱的事情时有发生。硬虚拟,特别是纯硬件的全虚拟,有很高的安全性,能够真正达到沙箱(sandbox)的效果。
通用性:
软虚拟机的大软肋。最明显的是Virtuozzo,这个windows下唯一的操作系统级别的虚拟化技术,它只支持Windows Server 2003 r2 sp2。硬虚拟在没有驱动加速的情况下,通用性一般是比较好的。但是如果需要驱动加速,仍然是要给每个不同平台写不同的驱动。
————————
按我用过的产品来分,大概列出它们的一些特色和适用的场合
Hyper-V
实现:硬件虚拟(对于Windows和Suse Linux支持驱动加速的半虚拟)
特色:对Windows支持好,将来支持会更好。管理型不错,微软有一套管理工具。
适用:负载不高的服务器,安全性敏感的场合,开发。
Virtual Server/PC
实现:硬件虚拟
特色:使用简单,和Windows集成好。性能差。
适用:开发,负载非常低的服务器
Vmware Workstation/GSX Server
实现:硬件虚拟
特色:使用简单,支持多平台。性能差。
适用:非Windows平台的开发,以及负载非常低的服务器
Virtual Box
实现:硬件虚拟
特色:另外一个Virtual PC或者Vmware Workstation
Vmware ESX Server
实现:硬件虚拟机+对主流平台的驱动加速+内存优化
特色:硬虚拟中的速度标杆,成熟
使用:负载中等的服务器
Xen
实现:同Vmware ESX Server
特色:速度也很快,有开源社区支持(不过Windows优化那部分没有开源。。。)
适用:负载中等的服务器
QEMU
实现:动态编译模拟器+KQEMU(内存加速)
特色:兼容性好,支持多CPU。
适用:玩具?
KVM
实现:硬件虚拟+Linux平台的驱动加速和内存优化+Windows平台的网卡加速
特色:后起之秀,有强大的社区和大公司支持。直接整合进Linux内核
适用:Linux平台上的开发与不重要的服务器
Virtuozzo
实现:操作系统虚拟化
特色:Windows下的唯一操作系统级别虚拟化产品(也有Linux版本OpenVZ)
适用:大规模的虚拟服务器部署,虚拟主机提供商
————————
做开发的:
Windows用Virtual PC,Linux用Vmware
做中低负载服务器:
Vmware ESX,Xen,KVM,Hyper-V
做高负载,高密度服务器:
Virtuozzo,OpenVZ,Linux系的chroot族产品,Solaris Zone
————————
状态管理
最后来关注一下虚拟机的一个非常重要的特性,状态管理。功能强弱排列:
静态磁盘状态
最弱,不支持Differencing。Xen?Virtuozzo?
动态磁盘状态
支持Differencing
静态内存状态
支持把内存状态存档和恢复,但是需要重启,所谓Snapshot。大部分虚拟机都支持到这(Virtual PC,Vmware Workstation。。。)
动态内存状态
动态记录内存状态和恢复。QEMU/KVM
全管理
包括网卡状态等都管理了。从而能够实现Live Migration(动态迁移)。Hyper-V 2.0的重要目标就是这个了。所以从角度来说,硬虚拟最成熟的还是Vmware ESX,其次是Xen。KVM也不能小视,短短时间连Live Migration都支持了。
posted @
2008-11-07 12:56 taowen 阅读(2189) |
评论 (4) |
编辑

2008年11月6日
上回我们是从硬件下手了。经历了一个从纯模拟,到半虚拟化,到全虚拟化,最终又半虚拟化的过程。但是,它们都是在同一个地方插了一脚:

现在,我们把目光往上移,从应用程序到硬件之间,还有一层,那就是操作系统。虚拟机的第二个流派就是OS-Level Virtualization(操作系统级别的虚拟化),Application Virtualization(应用程序虚拟化)。

说到硬件,作为应用程序开发人员的我们,都不怎么熟悉。实际上硬件也是提供了类似API一样的东西的,硬件流派的虚拟机实际上,就是通过模拟常见硬件的API来达到虚拟化的目的的。同样,在操作系统和应用程序之间也有一个API层。那么我们为什么不能虚拟化这个API呢?让应用程序调用我们的API,然后我们再调用真实操作系统的API。比如它访问c:\temp,我就把路径重定向到c:\virtualized\temp。
这方面,数Chroot历史最悠久。Chroot就是在某个文件夹下比如/home/wtao/root模拟出一个新的root来。在chroot之后执行的程序,它去访问root,实际上是/home/wtao/root不再是真正的root(/)了。由于Unix的Posix API是以文件路径为约定的,而且啥都是基于文件的(比如/proc就是所有的进程所在的目录)。虚拟的根目录,相当于虚拟的操作系统API。所以,从这个意义上来说,Chroot就是启动了一个虚拟机。基于Chroot的原理,有BSD的jail和Solaris的Zone等等。
Windows方面的OS Level虚拟机只有一个真正能用的实现,那就是Virtuozzo。它的原理我也不是很清楚。不过根据观察每个虚拟机都有一个自己的smss.exe。而这个是Windows的Session Manager,是第一个被启动的用户态进程。而每个虚拟机也有自己的驱动程序。在主机上也有一个特殊的文件系统(不启动就看不到里面的文件)。所以我推测Virtuozzo并不是一个纯粹的OS Level虚拟化,它应该是硬件流和软件流混血的产物。
大厂都是主要玩硬件流的,比如Vmware,微软。Linux社区由于内核开放,所以操作系统虚拟化比较成熟。一些小厂没法直接加入到那么高层次的竞争,最容易进入的就是Application Virtualization(应用程序虚拟化)这个领域了,相比前两者门槛最低。我个人理解应用程序虚拟化就是不完整版的操作系统虚拟化。很多Windows下的应用程序虚拟化的产品只虚拟化文件系统和注册表。实现起来相对容易,只需要应用我之前提到过的API Hooking技术修改几个ntdll导出的API就行了。

我得承认,在操作系统级别的实现上,我没有深入的研究,可能是错误的。不过对于应用程序虚拟化(Application Virtualization)我非常确信它是如何实现的。今天的软件流派就讲到这里。明天从速度,可管理性,安全等方面给这些实现方案给一个我个人的主观评价(没有数据支持的),并推荐一些产品,以及它们适用的场合。
posted @
2008-11-06 10:54 taowen 阅读(2181) |
评论 (6) |
编辑

2008年11月5日
80x86机器的虚拟化最近太火了,不但微软加入了战团,还有一堆Startup摇旗呐喊。那到底哪种虚拟机好呢?本文就尝试接着笔者的一些经验,做一些个人总结。
好是一个相对的概念。市面上的虚拟机不但表面上产自不同的公司,其核心实现技术也五花八门,适用的场合也千差万别。一方面你要知道虚拟化技术能给你带来什么,一方面你要知道你自己需要什么, 一方面还要知道要达到你的目标选用什么虚拟机,用什么虚拟化战略最适合你。这个过程就是选型的过程。希望读完本文之后,你对80x86的虚拟化技术和其发展现状能够有一个大概的了解。略去虚谈虚拟化技术的好处的文字,让我们直接来看虚拟机是怎么实现的,从而给市面上的虚拟机做一个分类。

如果我们重新实现一个虚拟机,有好几种选择。最直接的选择是用软件来模拟硬件。写一个简单的while循环就可以模拟一个cpu的工作了:
while (true) {
var instr = GetNextInstruction();
switch (instr) {
case xxx:
// do xxx
case HALT:
return;
}
}
这也是普通的游戏机模拟器的实现原理。再加上软件模拟的外设,比如主板,硬盘什么的。这类虚拟机叫Enumlator。

Emulator有一个最大的优势是独立于底层硬件。你可以在586上模拟出6502CPU来。这对于开发特殊硬件的软件的工程师特别有用。而由于模拟器的效率低下,最终也只能沦落为调试工具。为了改进性能,人们引入了编译来代替解释执行。著名的JIT(JVM也算是虚拟机啊)就是其中的一种,QEMU则是80x86领域的字节码编译的虚拟机实现。但是这更多地是一种运行时的优化技术,并没有根本改变其实现,也没有根本地改变执行效率。
根本地解决方案是,不用软件的循环去模拟CPU,而是直接使用宿主机的CPU来执行。而且内存也不用去模拟,也可以直接用宿主机的CPU来执行。这就是Virtualization技术。

内存是比较容易实现的,一般都是有一个映射表来做虚拟内存和实际内存地址的映射。这种内存虚拟化已经是广泛使用并且非常成熟的技术。AMD后来提出的虚拟化技术进一步把这种表映射在硬件层面上提供了加速。
问题的难点在于80x86的ring结构上。ring0到ring3,权限依次递减。实际使用中,Windows只利用了ring 0和ring 3两个级别。Guest OS需要运行在80x86的Ring 0级别上。但是Host OS自己已经是在80x86的Ring 0级别上了。虚拟机作为一个用户态的应用程序,只有ring3的特权,这个状态的CPU是不能满足Guest OS的需要的。这也是为什么80x86虚拟化技术难以实现的原因。所以,在最开始的时候,为了达到虚拟化的目的,Guest操作系统必须经过修改。最开始的时候Xen就是这么实现的,需要Guest OS是打过补丁之后的特定版本的Linux。显而易见,Windows的内核是无法被打补丁的。所以,Para-Virtualization只适合开放源代码或者厂商支持的操作系统。
但是随着硬件的进步。Intel提出了Vt-d技术,Amd提出了Pacifica技术。虽然名称不同,但是结果都是让ring0之上再多出了一层。从而使得虚拟机可以欺骗过Guest操作系统,让它认为自己就是运行在普通的CPU之上。所以Full-Virtualization就出现了。为了利用这些CPU的新技术,它们都有一个直接贴近硬件的驱动程序,并不是完全基于Host OS之上的。

人类的追求是无止尽的。在把全虚拟化的虚拟机用在实战中,特别是高负载的服务器场合之后,很快性能问题就暴露出来。CPU速度是没有问题的,非常快。问题集中在内存消耗和I/O操作速度与随之而来的CPU占用率的问题。
当一台机器能够安装多个虚拟机之后,人们就想装尽可能多的虚拟机,从而提高整体的资源利用率。但是由于内存的限制,使得这个单机负载的虚拟机数量很难提高,同时内存的利用率却并不高。假设每个虚拟机都分配了1G内存,内存利用率是60%,那就每台有400M的内存空闲。一台4G的机器装了4个虚拟机,就有1.6G的空闲内存。所以装5台虚拟机是一点问题都没有的。但是由于每个虚拟机都自己捏了一把富余的内存在手上以防万一,导致整体的利用率上不来。为了解决这个问题,大厂的虚拟机都有很多优化,比如Deflate,Ballooning之类的。而这些优化往往是在Guest操作系统上装一些特殊的驱动程序去控制Guest操作系统的内存分配(或者是Linux内核的直接支持)。
I/O速度和CPU占用率的问题是由软件模拟的外设,特别是硬盘和网卡照成的。解决方案自然也是尽可能的利用真实的硬件。通过给Guest OS上装优化的驱动程序就可以实现。不过要进一步提高性能,就卡在了DMA(Direct Memory Access,直接内存访问)技术上。DMA是一个I/O优化技术,它可以让CPU不参与I/O,而外设直接访问内存。由于内存地址是虚拟化的,而DMA是硬件控制的,又无法被修改从而知道虚拟化之后的地址。这个问题的解决,仍然依赖于Intel、AMD。相信将来会有支持硬件支持的虚拟I/O的CPU上市。不过从计划发布,到现在我们已经等了很久了。

这个时候,由于效率的原因Full-Virtualization又变成Para-Virtualization了。因为Driver也是对Guest OS的一种修改,不再是透明地虚拟化了。如果对应操作系统没有驱动,你就没法用(或者说没法利用优化之后的外设和内存)。而这个对于Windows来说,又是一个问题了。KVM至今都没有发布Windows的硬盘Virtio驱动,导致效率低下。
今天讲的是硬件流派,明天继续讲软件流派。未完待续……
posted @
2008-11-05 13:55 taowen 阅读(2678) |
评论 (9) |
编辑

2008年11月3日
摘要: 上一次提到了如何跨线程访问GUI。而这个需求往往是异步操作导致的。今天我们就来看看Jeffrey Richter写的AsyncEnumerator如何帮助我们处理异步问题。先来看看最简单的一段异步下载网页的代码:[代码]很简单不是吗?如果我们下载之后还要异步存储到本地的磁盘,这个时候就不是那么容易了:[代码]代码太长了,以至于我不得不折叠起来。这段代码还是有问题的,因为它没有处理异常情况,中途出个...
阅读全文
posted @
2008-11-03 22:11 taowen 阅读(1693) |
评论 (3) |
编辑
摘要: Application DeveloperIf you would like to...Inthis position you will be responsible for technical leadershipcontributing to the successful delivery of application developmentprojects. Your responsibil...
阅读全文
posted @
2008-11-03 09:36 taowen 阅读(448) |
评论 (1) |
编辑
摘要: 无论是WIN32还是Windows Form还是WPF还是Swing,都不支持GUI线程之外的线程直接访问其API。今天我们来回顾一下这个发展过程。一个普通的操作是怎么被封装封装再封装的。Win32在Windows SDK时代,我们都知道,界面就是一个大的WndProc控制的。[代码]如果我们需要另外一个线程去做一些耗时的IO操作,同时要回调回来更新的界面,这个时候要么自己定义一个回调队列,然后在...
阅读全文
posted @
2008-11-03 07:58 taowen 阅读(2067) |
评论 (4) |
编辑

2008年11月1日
摘要: 不是我变态,我也是被逼的。客户喜欢Word 2007里的Custom Task Pane,希望在侧边栏上放一些界面。但是他们刚刚从Word 97升级到2003,完全没有可能升级到更高的版本。我之前给他们做过一个DEMO,是用ActionsPane技术实现的。他们觉得挺好,就要这个。但是我不喜欢ActionsPane,所以只能自己想办法喽。为什么不喜欢ActionsPane?理由有很多:1、绑定到T...
阅读全文
posted @
2008-11-01 19:38 taowen 阅读(1632) |
评论 (3) |
编辑

2008年10月31日
摘要: 昨天提到了如何用Hook Ole32 提供的两个API来实现Hook Drag & Drop的过程。算是给EasyHook库做一个广告吧。今天给大家讲讲EasyHook的实现原理。API Hooking有两种,内核态级别的和用户态级别的。内核态级别的API Hooking也是很多病毒的实现原理,而且在微软不断强化其PatchGuard技术之后,已经越来越困难。做为建设四化的四有青年,我们还...
阅读全文
posted @
2008-10-31 23:08 taowen 阅读(2281) |
评论 (8) |
编辑