星期五, 十月 22, 2004

目标:一个全方位的网络虚拟社区

发信人: walklooktalk (千红一窟), 信区: BuildingBBS
标 题: 我们做点什么?
发信站: The unknown SPACE (Sun May 14 12:29:13 2000), 站内信件


目标:一个全方位的网络虚拟社区。

这个想法在现在看来,也许已经不是很新鲜,但从我们的BBS
的基础来看,这是最现实的一个方向。
放眼海外的华人网站,目前并没有一个十分强劲的网络社区存在。
这也许是一个暂时的空缺,我们有这么好的基础,为什么不去尝试一下。
现在网站的潮流之一,就是“私人化”,要能留住用户,最好的办法
除了“留下用户自己的东西”还会是什么呢?这也是BBS为什么会吸引人
的地方所在,因为在这上面留有你的文章、你的网友...

所以,网站提供的服务的宗旨是“留下用户自己的东西”,基于这个想法,
我觉得可以提供如下服务,欢迎大家补充:
1.讨论组/精华区/文摘区
这是我们最大的资本,可以将BBS的讨论组移植过来。
另外,可以将这个概念丰富化,我觉得可以提供以下几种类型的讨论组:
公共讨论组:普通用户具有读、写的权限,其它权限版主定制;
俱乐部讨论组:成员具有读、写的权限,其它权限版主定制;
个人讨论组:版主任意定制;
如果在讨论组加上Email定阅的功能,就可以涵盖 mailing list 的功能。
2.邮件
3.chat/talk/message
chat/talk可以用applet来实现,message可能需要写一个ICQ一样的东西。
4.投票
5.个人主页/文件夹/相册
6.个人管理
与个人有关的一些定制,如好友、坏友名录、个人信息、个人参数等等。
7.系统管理
8.地址簿/Bookmarks
9.Calendar

欢迎大家补充,先把大目标定下来,然后分头细化,我可以负责“讨论组”
这一块,基本就是把原来BBS的东西完善化,所以有些经验。

Thanks.
--

我是一匹脱缰的野狗,狂奔于你荒芜的心上。

千山我一独行

※ 来源:.The unknown SPACE bbs.mit.edu.[FROM: 24.147.15.53]

发信人: andrews (旱鸭子~Torpedo in water!), 信区: BuildingBBS
标 题: Re: 我们做点什么?
发信站: The unknown SPACE (Sun May 14 12:55:30 2000), 站内信件


【 在 walklooktalk (千红一窟) 的大作中提到: 】
: 目标:一个全方位的网络虚拟社区。
这样的目标需要多大的硬件支持? 完全业余的工作
是否完成这个目标?

: 我觉得可以提供如下服务,欢迎大家补充:
: 1.讨论组/精华区/文摘区
: 这是我们最大的资本,可以将BBS的讨论组移植过来。
: 另外,可以将这个概念丰富化,我觉得可以提供以下几种类型的讨论组:
: 公共讨论组:普通用户具有读、写的权限,其它权限版主定制;
: 俱乐部讨论组:成员具有读、写的权限,其它权限版主定制;
: 个人讨论组:版主任意定制;
这个应该没有问题.
: 如果在讨论组加上Email定阅的功能,就可以涵盖 mailing list 的功能。
: 2.邮件
邮件的话, 不如只做邮件转发功能. 我想很多人不愿意把BBS上
的ID和现实中的身份联系起来, 做转发是比较有意义的. 反过来说,
是否有必要为大家提供邮箱? 我看意义不大.
: 3.chat/talk/message
: chat/talk可以用applet来实现,message可能需要写一个ICQ一样的东西。
telnet BBS系统的优势之一就是"集成". 聊天消息灌水都可以用
一个TELNET 界面完成. 如果做WWW界面这些东西还要分开, 很多用户
可能不好接受.此外WWW界面的消息等等缺乏实时性(每次都要刷新才
能看到新消息, 不甚方便)
: 4.投票
没有问题.
: 5.个人主页/文件夹/相册
这些东西会需要多大的系统负担?
: 6.个人管理
: 与个人有关的一些定制,如好友、坏友名录、个人信息、个人参数等等。
没有问题.
: 7.系统管理
: 8.地址簿/Bookmarks
: 9.Calendar
这些都没有问题.

: 欢迎大家补充,先把大目标定下来,然后分头细化,我可以负责“讨论组”
: 这一块,基本就是把原来BBS的东西完善化,所以有些经验。
: Thanks.
我对系统底层的东西更关心, 如何提高效率和稳定性?
比方FBBS使用UNIX文件系统作为底层, 不满1K的文件都当
1K来存. 可是一般版面上大多数文章实际内容都不到1K,
这样造成的浪费有多少?
再就是我以前提过的问题, 同样用户数量, 究竟是WWW
方式下系统资源耗得多还是TELNET下的多?


--
望远镜里烟雨迷蒙的远方, 两艘日本海上保安厅的巡逻艇正在驶近, 海豚直升机
低低悬停在其正前方, 正挡住去路.
"命令直升机最后一次警告, 钓鱼台是中国领土, 外国舰船不得驶入."
日本巡逻艇上火光一闪, 海豚直升机猛得一抖, 炸裂成一个鲜艳的火球.
"开火还击."
双100炮怒吼起来.

发信人: thrust (滚来滚去的西瓜虫), 信区: BuildingBBS
标 题: Re: 我们做点什么?
发信站: The unknown SPACE (Sun May 14 15:50:37 2000), 站内信件


【 在 andrews (旱鸭子~Torpedo in water!) 的大作中提到: 】
: 【 在 walklooktalk (千红一窟) 的大作中提到: 】
: 我对系统底层的东西更关心, 如何提高效率和稳定性?
: 比方FBBS使用UNIX文件系统作为底层, 不满1K的文件都当
: 1K来存. 可是一般版面上大多数文章实际内容都不到1K,
: 这样造成的浪费有多少?
应该说, 为了提高效率, 这种浪费是不可避免的.
: 再就是我以前提过的问题, 同样用户数量, 究竟是WWW
: 方式下系统资源耗得多还是TELNET下的多?
你这里的系统资源是指的什么?
如果对于网络资源, 当然是TELNET占得多. 用户每按一个键,
都要进行一次TCP的传送, 这当然是很浪费的. WWW在这上面具有优势.
对于系统资源(CPU/HD)来说, 我认为TELNET当然是有优势的, 因为每个用户自始
至终只需一个进程服务, 而且这个进程大部分时间处于空闲状态.
在WWW方式, 每看一条消息就需重判一次合法性,初始化状态上下文等等.
从内存上说, WWW也是有优势的, 用户数再多, 也只有那么些HTTPD在服务.


--
嘿嘿, 韦大人, 您猜对了, 又是我出卖您的!

发信人: walklooktalk (千红一窟), 信区: BuildingBBS
标 题: Re: 先做一下普及教育吧
发信站: The unknown SPACE (Mon May 15 11:30:22 2000), 站内信件


【 在 TAR (星--Flying......) 的大作中提到: 】
: 【 在 kyu (水海飘香-教父) 的大作中提到: 】
: : 2000年开工了,加入了,我美!!!!
: : 下面是我的一些看法:
: : 1,运行平台:Linux+Apache+Apache JServ+JDK+postgresql
: : 主要以Java servlet实现服务端的工作.(绝对好于CGI,简单于NSAPI)
: : 好处:可靠省钱,全free呀!,参与开发者也可方便的构造自己的开发环境
: : 坏处:抛弃原有的,可惜呀.
: : 2,设计上希望导入CORBA(Common Object Request Broker Architecture).
: : 这样可以增强系统的伸缩性,延缓系统的老化速度.
: : 3,希望站长对原有的系统做一个介绍,我一点也不清楚.
: 原来的telnet和www系统主要缺陷在哪里?

主要缺陷为:缺少可伸缩性,随着负载增大,很难通过有效的办法来负载均衡。
缺少可维护性,不好做进一步的开发。
缺少可靠性,需要修改的BUG很多,这些代码经过多人修改,可读性也很差。

: 是什么原因要完全另起炉灶,重新开发.
: : 4,希望站长罗列一下设计开发人员的必备知识,以便大家赶快学习.
: 这一点在目前应该是非常重要的,可能很多人还没有实际开发经验,
: 站长和有条件的网友能否共享一些开发所需要的技术资料?

还是那句话,请仔细阅读本版第1篇文章“项目规划书”。
第1步只是“需求分析”,我们没有特殊的技术背景要求,这也是目前成员
比较多的原因,随着项目的进展,大家的熟悉,再慢慢地进行分工。

--

我是一匹脱缰的野狗,狂奔于你荒芜的心上。

千山我一独行

发信人: ray (稀里呼噜), 信区: BuildingBBS
标 题: 建议--投票系统
发信站: The unknown SPACE (Sun May 28 18:04:17 2000), 站内信件


关于系统需求的部分,我个人是比较关心投票系统的部分

记得这个BBS最早的初中有建立/实习一个民主的意愿在里面。
那么一个完善的投票体系很重要。
原有的简单投票法颇有弊病。 比如多ID问题。后来站方好象是做了不少
改进的,3K是否可以介绍一下现在情况如何,是否要准备作些改进呢?
如果有改动的需要,我愿意试试这块。

ray

发信人: TAR (星--Flying......), 信区: BuildingBBS
标 题: 能否在原来的基础上进行大规模改进呢
发信站: The unknown SPACE (Sun May 28 20:56:38 2000), 站内信件

我觉着完全重新来可能工作量太大
而且以志愿开发,能否成功很难说
这里很多人对已有的BBS系统是比较了解的
能否对它进行全面的测试,找出影响性能的地方,
对关键部分彻底改写
修改系统的Bug,依次改进,提高可靠性
制定统一规范,将对原有的代码重新改写,保证可读性
......

--
--无聊中,虽然我应该努力工作

※ 来源:.The unknown SPACE bbs.mit.edu.[FROM: 130.161.67.116]

发信人: walklooktalk (千红一窟), 信区: BuildingBBS
标 题: 需求分析大纲
发信站: The unknown SPACE (Sat Jun 3 16:59:46 2000), 站内信件

首先非常抱歉,最近一段时间比较消沉。

关于本站的新站建设,肯定是以WWW为主的,这是大势所趋,
我想不用多争。

新站的规模,可以做大,也可以做小。
做大的话就是只要是个性化的服务,都可以提供,其实也就
相当于一个portal了。
做小的话就是把BBS的交互功能,如讨论组、聊天等,做精做好,
也不失为一种特色。

我本来的想法是做大,希望能够听听大家的意见,但这么多天下来,
好象有建设性的意见并不多。

那我就拟一个大纲,加括号的是可做可不做的,其余的是必须做的。
我也把这篇文章发给大家在BBS的邮件帐号里,你对哪几部分感兴趣,
请回信告知,也可以多人做同一部分的需求。到时候,拟出名单来
好将这个项目进行下去。

大纲如下,我只是凭个人经验拟的,如果有不同看法,或有增、删意见,
欢迎提出来讨论:
------------------------------------------------------
1.讨论组
2.精华区
3.文摘区
4.投票
5.邮件
6.talk
7.chat
8.message
9.系统管理
10.个人管理
(11.个人主页)
(12.个人文件夹)
(13.个人相册)
(14.地址簿)
(15.Bookmark)
(16.Calendar)
--

我是一匹脱缰的野狗,狂奔于你荒芜的心上。

千山我一独行

※ 修改:.walklooktalk 于 Jun 3 17:02:13 修改本文.[FROM: 24.147.15.53]
※ 来源:.The unknown SPACE bbs.mit.edu.[FROM: 24.147.15.53]

发信人: ColdIce (hot), 信区: BuildingBBS
标 题: 安全子系统需求分析(初稿)
发信站: The unknown SPACE (Mon Jun 5 21:16:44 2000), 站内信件

安全子系统需求分析(初稿)

1. 为使新系统做到既具高安全性同时又不失灵活性与可扩展性,我建议
把安全子系统(security sub-system)独立于各项具体服务(services),
如公共版面,私人版面,聊天,邮件,消息,各项系统或个人设定等等。

2. 认证(authentication)与授权(authorization)应当各自独立。认证
应当是把一个具体(操作期间???)(session)与某一特定用户(user)相映
射的动态过程,而授权则是把一个具体的服务与某一特定用户或用户群
及相应权限映射起来的静态过程。在提供服务时,系统通过session把
动态的认证与静态的授权联系起来以决定是否提供相应服务。

3. 认证与可监控性

3.1 我们应当对所有访问用户进行认证,以保证足够的可监控性,对一个
session, 必须记录其访问地址,即使通过proxy访问,必须记录用户名,
同时允许匿名登录。我们的最后结果应当是session=user=realIP,而与
所要求服务无关。
3.2 提供服务无关的IP保护,对给定的IP范围予以屏蔽,但系统管理员
在需要的时候能方便地查询。
3.3 认证过程以注册时提供的密码为唯一标识。在忘记密码时应该提供
某种方式在无须管理员干预的情况下重新获得,比如发给用户的注册
email。
3.4 为保证用户的密码不被窃听,可以提供加密方式的登录认证方式。
这项要求取决于系统负担。
3.5 必须防止机器人登录及灌水。所以有必要对访问客户段软件作一个
认证。(个人觉得java或java script可以搞定,设想过没做过二万五千里)
3.6 允许用户在系统范围内自定义session发呆时间,系统管理员可定义
系统许可范围。

4. 授权机制

4.1 用户应该被确定一个安全等级,比如0--99。用户可以被归于一个或
若干个安全组(group)。
4.2 授权机制可以以用户之安全等级界定,如>10许可读,<50不许可读写。 style="font-weight: bold;">发信人: thomas (00), 信区: BuildingBBS
标 题: Re: 建议--投票系统
发信站: The unknown SPACE (Thu Jun 8 04:15:03 2000) WWW-POST


关键是人员的认证呀。但是看看如buy.com这类的大站点
都因为自己coupon系统的问题而被我们乱用的。这个站
怕是仍然做不好这一点吧。

可以想到的就是如www方式投票时,可以限定一个ip只能
够投一票的等等。即使这样,误差难免,而且和网虫想
玩花样的精力有关。

【 在 ray (稀里呼噜) 的大作中提到: 】
:
: 关于系统需求的部分,我个人是比较关心投票系统的部分
:
: 记得这个BBS最早的初中有建立/实习一个民主的意愿在里面。
: 那么一个完善的投票体系很重要。
: 原有的简单投票法颇有弊病。 比如多ID问题。后来站方好象是做了不少
: 改进的,3K是否可以介绍一下现在情况如何,是否要准备作些改进呢?
: 如果有改动的需要,我愿意试试这块。
:
: ray
:
:

--
\=/, _-===-_-====-_-===-_-==========-_-====-_
| @___oo ( )
/\ /\ / (___,,,}_--= 落难的时候应该一个人慢慢走出困境 )
) /^\) ^\/ _) =__ 成功的时候应该不忘帮助过自己的人! )
) /^\/ _) (_ 年轻的时候最怕的就是因为过分执着 )
) _ / / _) ( 在意而伤害了别人。 )

※ 来源:.The unknown SPACE bbs.mit.edu.[FROM: ]

发信人: ColdIce (hot), 信区: BuildingBBS
标 题: 系统管理功能需求(草稿)
发信站: The unknown SPACE (Thu Jun 22 11:06:50 2000), 站内信件

想了这么久,没什么好想法,先写点再说吧,大家群策群力啊。

1. 有关安全认证的部份见前面的贴子。

2. 统计
2.1 系统必须记录足够的信息以作为统计基础
2.2 统计结果定期发表,并清除或压缩老记录。
2.3 统计项目可包括(不限于,欢迎增加)
A. 各版被使用受欢迎程度(人时,文章数),可以小时或天为单位
B. 系统用户登录数,系统负担大小,文章数,以小时或天为单位
C. 登录用户来源分布
D. 新增用户数,所有用户数,以天或月,年为单位
E. 用户点击模式??(保密)

3. 备份
3.1 系统提供方便的手段设置备份参数,如时间,数量等等
3.2 备份以各服务为单位,这样在需要的时候可以只回卷该服务
而不影响其他,也应当提供全系统恢复以备 不测。
3.3 各具体服务提供的类似删文的备份与此无关,但具体服务
提供的备份手段应当做到谁误删谁就可以恢复以减轻管理
员负担


4. 状态监控
4.1 系统提供状态监控功能,旨在使管理员可方便查看当前系统
资源分配状况,实时查出消耗资源过多的进程或用户,有利
于定位BUG或做坏事的用户
4.2 应当给出按CPU或MEM占有率排序的进程列表
4.3 应当给出当前已登录用户占用资源列表。

5. 日志
5.1 日志记录应当简洁明了又不忽略重要信息
5.2 对管理类操作应当都作出记录,以防止滥用职权的情况
5.3 用户的重要操作如登录退出发表文章发信等等,以防止
滥用本系统的情况,同时在一些纠纷中可充当证据
5.4 日志的查询和搜索必须方便易行。

--
西北望,射天狼

※ 来源:.The unknown SPACE bbs.mit.edu.[FROM: 137.132.61.102]

发信人: thomas (00), 信区: BuildingBBS
标 题: Photo Album, Address book, Calendar, and more(需求分析草案)
发信站: The unknown SPACE (Sun Jul 16 03:41:42 2000) WWW-POST


Photo Album
主要是参考了www.zing.com的制作,因为自己就是在用那个站点存贮
数字照片的。
1. 相册管理:一个用户应该有多本相册,因此有添加删除相册和相
片的操作;提供对相册内所有照片的游览;安全性角度,可以共享或
是私藏;相册属性还有背景、音乐、相册说明和在整个站点中的索引
设置。上载和下传图片则见下面两点。
2. 上载图片:除了通过网页选择文件之外,还应该提供小程序支持
任意多的图片同时选择上载。当然如果提供全部的FTP支持将会是更
好的。
3. 下传图片及其它:许多网上图片集站点只提供上载而没有下传。
那么用户就得自己保存所有上载的图片。从功能上讲是不够完善和方
便的。如果可以打包让用户下载自己制作好的图片集,或者我们帮助
用户制作成Kodak CD就更好了。还有制作照片服务。
4. 照片管理:提供一些基本的功能,这是可以参照如PhotoShop和gi
mp一类的程序的。有旋转、放大缩小、亮度调节、对比度调节和删除
(可以group删除)。调节好的相片如果能够允许用户再下载,显然功
能就比其它站点会更多些。最后是一个安全性问题,用户可以选择哪
些照片是可共用的,而哪些是自己有版权的---类似于BBS上发表的文
章啦。同样,站点也可以要求对相关的照片打上站点的标记,以保护
自己的权益,并进行宣传。
5. 索引:可以根据用户名、相册名、或是相片名来搜索所需要的图
片(集)。也可以根据分类来进行索引和搜索。
6. 其它:提供由站点上的照片制作贺卡,加上背景、音乐、相关文
字(有字体可选,特别是对中文来说),以及一些方便实现的动画---
包括给图片加上雪、雨等等;把自己的照片生成网上slide show,并
且允许用户把这个引到自己的其它主页上---可以扩大宣传。
唯一没有把握的还是网路流量问题,以上全部功能需要多大的带宽来
支持?这需要有经验的来把关了。
Address book
地址簿需要的就是存放他人的contact information:包括人名、地
址(邮件地址、各种电话BP机和电子邮件地址、主页)、工作单位和其
它信息(如生日,共同渡过的人生大事等等)。
所有的地址信息还能够组成不同的组,如大学好友、中学好友、工作
同仁等等,以便方便处理:比如把自己拍的照片制作成贺卡然后发送
给所有的大学好友等等。
另外可能是比较有用的就是提醒功能:在某人生日前一周,能够自动
发送电子邮件给自己,提醒开始准备礼物;或者是婚礼多少年纪念日
一周前,让自己开始准备。
提供从现有的比较流通的地址文件格式中转入地址信息,这应该包括
MS Outlook、MS Outlook Express和Netscape的相关产品的支持。
总体上地址簿是和其它,如free email、送贺卡和后面的日历组织活
动相结合的附助品。
Calendar
记录自己的工作和生活中能够安排的部分。每个事件都有时间、地点
、参与人(可以是地址簿中的一个组),及相关内容。
同样,我们需要提供电子邮件提醒功能,特别是能够提醒所有参与的
人。
更扩展的功能,可以有论坛或是chat room让参与的人在事前事中事
后直接交流;或者可以给每个事件加个memo文件什么的。
进一步的扩展就是加入project管理,把不同的事件能够串起来成为
项目的一部分。
其它
随便想到的几点:
ü 安全特性:发文章的用户可以选择隐去自己的ip地址
ü 真正的www论坛:www方式的文章按thread而不是如telnet那样以
发表顺序来组织,这样便于user选择参与什么样的讨论话题。没有必
要把www的BBS按telnet的思路做。
ü 精华区同样应该提供和版面一样的,按标题内容和作者名来查文
章;更重要的是能够从当前位置查所有的子目标下的文章。
ü www方式提供telnet方式。小托看到的是http://www.first.gmd.d
e/persons/leo/java/Telnet 的Java
Telnet。也是当年清华做成的telnet的出处,只是需要进行汉化。
ü BBS许可贴图是不错,但是是否能够把URL隐藏或者要显示的话,
控制长度。否则就会造成阅读的不便。
ü 提供中文转成中文图片服务---能够很快地扩大知名度,但是对服
务器要求比较高。

--
\=/, _-===-_-====-_-===-_-==========-_-====-_
| @___oo ( )
/\ /\ / (___,,,}_--= 落难的时候应该一个人慢慢走出困境 )
) /^\) ^\/ _) =__ 成功的时候应该不忘帮助过自己的人! )
) /^\/ _) (_ 年轻的时候最怕的就是因为过分执着 )
) _ / / _) ( 在意而伤害了别人。 )

※ 来源:.The unknown SPACE bbs.mit.edu.[FROM: ac8d2455.ipt.ao]

心目中的编程高手

  MIT BBS上说微软电话面试的一道题就是“Who do you think is the best coder, and why?”。我觉得挺有意思的,也来凑个热闹。排名不分先后。

  Bill Joy, 前任Sun的首席科学家,当年在Berkeley时主持开发了最早版本的BSD。他还是vi和csh的作者。当然,Csh Programming Considered Harmful 是另一个话题乐。据说他想看看自己能不能写个操作系统,就在三天里写了个自己的Unix, 也就是BSD的前身。当然是传说了,但足见他的功力。另一个传说是,1980年初的时候,DARPA让BBN在Berkley Unix里加上BBN开发的TCP/IP代码。但当时还是研究生的B伯伯怒了,拒绝把BBN TCP/IP加入BSD,因为他觉得BBN的TCP/IP写得不好。于是B伯伯出手了,端的是一箭封喉,很快就写出了高性能的伯克利版TCP/IP。当时 BBN和DARPA签了巨额合同开发TCP/IP Stack,谁知他们的代码还不如一个研究生的好。于是他们开会。只见当时B伯伯穿个T-shirt出现在会议室(当时穿T-shirt不象现在,还是相当散漫的哈)。只见BBN问:你怎么写出来的?而B伯伯答:简单,你读协议,然后编程就行了。最令偶晕倒的是,B伯伯硕士毕业后决定到工业界发展,于是就到了当时只有一间办公室的Sun, 然后他就把Sparc设计出来乐。。。象这种软硬通吃的牛人,想不佩服都不行的说。据Bill Joy的同事说,一般开会的时候B伯伯总是拿一堆杂志漫不经心地读。但往往在关键之处,B伯伯发言,直切要害,提出漂亮的构想,让同事们彻底崩溃。对了,他还是Java Spec和JINI的主要作者之一。

  John Carmack,ID Software的founder和Lead Programmer。上个月和一个搞图形的师兄聊天,他竟然不知道John Carmack, 也让偶大大地晕了一把。不过也许搞研究的和搞实战的多少有些隔吧。想必喜欢第一人称射击游戏的都知道J哥哥。90年代初只要能在PC上搞个小动画都能让人惊叹一番的时候,J哥哥就推出了石破天惊的Castle Wolfstein, 然后再接再励,doom, doomII, Quake...每次都把3-D技术推到极 限。J哥哥的简历上说自己的专长是"Exhaust 3-D technology",真是牛人之言不我欺的说。做J哥哥这样的人是很幸福的,因为各大图形卡厂家一有了新产品就要向他“进贡” ,不然如果他的游戏不支持哪种卡,哪种卡基本就会夭折乐。当初MS的Direct3D也得听取他的意见,修改了不少API。当然,J哥哥在结婚前十数年如一日地每天编程14小时以上,也是偶们凡人望尘莫及的。对了,J哥哥高中肆业(?),可以说是自学成才。不过呢,谁要用这个例子来为自己学习不好辩护,就大错特错了。那 Leonardo Da Vinci还是自学成才呢(人是私生子,不能上学)。普通人和天才还是有区别的。对了,其实偶们叫“达分奇”是相当不对的,因为Vinci是地名,而Da Vinci就是从Vinci来的人的意思。换句话说,Leonardo Da Vinci就是“从Vinci来的Leonardo”的意思。叫别人“Da Vinci”就不知所谓乐。嗯,扯远了,打住。

  David Cutler,VMS和Windows NT的首席设计师,去微软前号称硅谷最牛的kernel开发员。当初他和他的手下在微软一周内把一个具备基本功能的bootable kernel写出来,然后说:“who can't write an OS in a week?",也是牛气冲天的说。顺便说一句,D爷爷到NT3.5时,管理1500名开发员,自己还兼做设计和编程,不改coder本色啊。

  D 爷爷天生脾气火爆,和人争论时喜欢双手猛击桌子以壮声势。 日常交谈F-word不离口。他面试秘书时必问:"what do you think of the word 'fuck'?" ,让无数美女刹羽而归。终于有一天,一个同样火爆的女面对这个问题脱口而出:"That's my favorite word"。于是她被录取乐,为D爷爷工作到NT3.5发布。

  Don Knuth。高爷爷其实用不着偶多说。学编程的不知道他就好像学物理的不知道牛顿,学数学的不知道欧拉,学音乐的不知道莫扎特,学Delphi的不知到 Anders Hejlsberg,或者学Linux不知道Linus Torvalds一样,不可原谅啊。为了让文章完整,就再罗唆几句吧。高爷爷本科时就开始给行行色色的公司写各种稀奇古怪的编译器挣外快了。他卖给别人时收一两千美元,那些公司拿了code,加工一下卖出去就是上万上十万。不过也没见高爷爷不爽过,学者本色的说。想想那可是60年代初啊,高爷爷写编译器写多了,顺带就搞出了个Attribute Grammar和LR(k),大大地造福后人啊。至于高爷爷在CalTech的编程比赛(有Alan Kay得众多高高手参加)总是第一,写的Tex到86年就code freeze,还附带2^n美分奖励等等都是耳熟能详的,偶就不饶舌乐。

  顺便说一下,高老大爷是无可争议的写作高手。他给Concrete Mathematics 写的前言可谓字字铿锵,堪为前言的典范。他的技术文章也是一绝,文风细致,解释精当,而且没有学究气,不失轻快跳脱。记得几年前读Concrete Mathemathics,时不时开怀大笑,让老妈极其郁闷,觉得我nerdy到家,不可救药。其实呢,子非鱼,安知鱼之乐,更不知那完全是高爷爷的功劳。说到写作高手,不能不提Stephen A. Cook。他的文章当年就被我们的写作老师极力推荐,号称典雅文风的样本。库爷爷一头银发,身材颀长,总是面带谦和的微笑,颇有仙风道骨,正好和他的仙文相配的说。

  高爷爷其实还是开源运动的先驱。虽然他没有象Richard Stallman那样八方奔走,但他捐献了好多作品,都可以在网上看到,比如著名的Mathematical Writing,MMIXWare,The Tex Book等,更不用说足以让他流芳百世的Tex乐。

  Ken Thompson,C语言前身B语言的作者,Unix的发明人之一(另一个是Dennis M. Riche老大,被尊为DMR),Belle(一个厉害的国际象棋程序)的作者之一, 操作系统Plan 9的主要作者(另一个是大牛人Rob Pike, 前不久被google挖走了)。Ken爷爷也算是计算机历史上开天辟地的人物了。1969年还是计算机史前时代,普通人都认为只有大型机才能运行通用的操作系统,小型机只有高山仰止的份儿。至于用高级语言来写操作系统,更是笑谈。Ken爷爷自然不是池中物,于是他和DMR怒了,在1969年到1970间用汇编在PDP-7上写出了UNIX的第一个版本。他们并不知道,一场轰轰烈烈的UNIX传奇由此拉开了序幕。Ken爷爷在1971年又把Unix用C重写,于是C在随后20年成就了不知多少豪杰的梦想和光荣。

  Ken爷爷还有段佳话: 装了UNIX的PDP-11最早被安装在Bell Lab里供大家日常使用。很快大家就发现Ken爷爷总能进入他们的帐户,获得最高权限。Bell Lab里的科学家都心比天高,当然被搞得郁闷无比。于是有高手怒了,跳出来分析了UNIX代码,找到后门,修改代码,然后重新编译了整个UNIX。就在大家都以为“这个世界清净了”的时候,他们发现Ken爷爷还是轻而易举地拿到他们的帐户权限,百思不解后,只好继续郁闷。谁知道这一郁闷,就郁闷了14年,直到Ken爷爷道出个中缘由。原来,代码里的确有后门,但后门不在Unix代码里,而在编译Unix代码的C编译器里。每次C编译器编译UNIX的代码,就自动生成后门代码。而整个Bell Lab的人,都是用Ken爷爷的C编译器。

  (6)Rob Pike, AT&T Bell Lab前Member of Technical Staff ,现在google研究操作系统 。罗伯伯是Unix的先驱,是贝尔实验室最早和Ken Thompson以及Dennis M. Ritche开发 Unix的猛人,UTF-8的设计人。他还在美国名嘴David Letterman的晚间节目上露了一小脸,一脸憨厚地帮一胖子吹牛搞怪。让偶佩服不已的是,罗伯伯还是1980年奥运会射箭的银牌得主。他还是个颇为厉害的业余天文学家,设计的珈玛射线望远镜差点被NASA用在航天 飞机上。他还是两本经典,The Unix Programming Environment 和 The Practice of Programming 的作者之一。如果初学者想在编程方面精益求精,实在该好好读读这两本书。它们都有中文版的说。罗伯伯还写出了Unix下第一个基于位图的窗口系统,并且是著名 的blit 终端的作者。当然了,罗伯伯还是号称锐意革新的操作系统,Plan9,的主要作者。可惜的是,Plan9并没有引起多少人的注意。罗伯伯一怒之下,写出了振聋发聩的雄文 Systems Software Research is Irrelevant,痛斥当下系统开发的不思进取,固步自封 的弊病。虽然这篇文章是罗伯伯含忿出手,颇有偏激之词,但确实道出了系统开发的无奈:开发周期越来越长,代价越来越大,用户被统一到少数几个系统上,结果越来越多的活 动是测量和修补,而真正的革新越来越少。

  就在罗伯伯郁闷之极的时候,google登门求贤来乐。如果说现在还有一家大众公司在不遗余力地把系统开发推向极致的话,也就是google乐。随便看看google的成果就知道了。具 有超强容错和负载平衡能力的分布式文件系统GFS (现在能够用100,000台廉价PC搭起一个 巨型分布系统,并且高效便宜地进行管理的系统也不多哈),大规模机器学习系统(拼写检查,广告匹配,拼音搜寻。。。哪个都很牛的说),更不用说处理海量并行计算的各式 google服务了。Rob在System Software Research is Irrelevant里萧瑟地说现在没有人再关心系统研究的前沿成果了。想不到他错了,应为google关心。google网络了大批功成 总是试图吸取系统研究的最新成果。想必Rob Pike在google很幸福。愿他做出更棒的系统

★中国程序员基本素质★

程序员是一种技术工作,在IT的发展中有相当重要的地位,从底层硬件通讯协议的建立,到数据传输层的处理,到操作系统的建设,到数据库平台的建设,一直到应用层上各种数据营销平台的搭建,程序员在里面都扮演着举足轻重的角色并为IT事业的发展做出了巨大的贡献。

   中国有很多精于编码的人,但是中国软件行业,尤其是网络应用开发方面误区很大,很难形成有规模的软件开发力量和产品能力,不但比美国差距甚远,和印度相 比也是颇有不如。这些问题不是在于中国程序员的智商和工作努力状况,也不是在于国家和民间对开发的投入程度,而是很大程度上,有一些对技术,对程序开发, 对项目设计方面的思想误区,这些误区,导致了软件行业的产品化能力不足,缺乏规模化和大型复用系统研发能力,可以说,改变认识误区,是解决软件行业小作坊 模式和个体英雄模式所带来的局限性的重要工作。

  中国有很多小朋友,他们18,9岁或21,2岁,通过自学也写了不少代码,他们有的代 码写的很漂亮,一些技术细节相当出众,也很有钻研精神,但是他们被一些错误的认识和观点左右,缺乏对系统,对程序的整体理解能力,这些人,一个网上的朋友 说得很好,他们实际上只是一些Codingfans,压根没有资格称为程序员,但是据我所知,不少小网络公司的CTO就是这样的coding fans,拿着吓人的工资,做着吓人的项目,项目的结局通常也很吓人。

  程序员基本素质:

  作一个真正合格的程序员,或者说就是可以真正合格完成一些代码工作的程序员,应该具有的素质。

  1:团队精神和协作能力

   把它作为基本素质,并不是不重要,恰恰相反,这是程序员应该具备的最基本的,也是最重要的安身立命之本。把高水平程序员说成独行侠的都是在呓语,任何个 人的力量都是有限的,即便如linus这样的天才,也需要通过组成强大的团队来创造奇迹,那些遍布全球的为linux写核心的高手们,没有协作精神是不可 想象的。独行侠可以作一些赚钱的小软件发点小财,但是一旦进入一些大系统的研发团队,进入商业化和产品化的开发任务,缺乏这种素质的人就完全不合格了。

  2:文档习惯

   说高水平程序员从来不写文档的肯定是乳臭未干的毛孩子,良好的文档是正规研发流程中非常重要的环节,作为代码程序员,30%的工作时间写技术文档是很正 常的,而作为高级程序员和系统分析员,这个比例还要高很多。缺乏文档,一个软件系统就缺乏生命力,在未来的查错,升级以及模块的复用时就都会遇到极大的麻 烦。

  3:规范化,标准化的代码编写习惯

  作为一些外国知名软件公司的规矩,代码的变量命名,代码内注释格式,甚至 嵌套中行缩进的长度和函数间的空行数字都有明确规定,良好的编写习惯,不但有助于代码的移植和纠错,也有助于不同技术人员之间的协作。有些coding fans叫嚣高水平程序员写的代码旁人从来看不懂,这种叫嚣只能证明他们自己压根不配自称程序员。代码具有良好的可读性,是程序员基本的素质需求。再看看 整个linux的搭建,没有规范化和标准化的代码习惯,全球的研发协作是绝对不可想象的。

  4:需求理解能力

  程序 员需要理解一个模块的需求,很多小朋友写程序往往只关注一个功能需求,他们把性能指标全部归结到硬件,操作系统和开发环境上,而忽视了本身代码的性能考 虑,有人曾经放言说写一个广告交换程序很简单,这种人从来不知道在百万甚至千万数量级的访问情况下的性能指标是如何实现的,对于这样的程序员,你给他深蓝 那套系统,他也做不出太极链的并访能力。性能需求指标中,稳定性,并访支撑能力以及安全性都很重要,作为程序员需要评估该模块在系统运营中所处的环境,将 要受到的负荷压力以及各种潜在的危险和恶意攻击的可能性。就这一点,一个成熟的程序员至少需要2到3年的项目研发和跟踪经验才有可能有心得。

  5:复用性,模块化思维能力

  经常可以听到一些程序员有这样的抱怨,写了几年程序,变成了熟练工,每天都是重复写一些没有任何新意的代码,这其实是中国软件人才最大浪费的地方,一些重复性工作变成了熟练程序员的主要工作,而这些,其实是完全可以避免的。

   复用性设计,模块化思维就是要程序员在完成任何一个功能模块或函数的时候,要多想一些,不要局限在完成当前任务的简单思路上,想想看该模块是否可以脱离 这个系统存在,是否可以通过简单的修改参数的方式在其他系统和应用环境下直接引用,这样就能极大避免重复性的开发工作,如果一个软件研发单位和工作组能够 在每一次研发过程中都考虑到这些问题,那么程序员就不会在重复性的工作中耽误太多时间,就会有更多时间和精力投入到创新的代码工作中去。
一些好的程序模块代码,即便是70年代写成的,拿到现在放到一些系统里面作为功能模块都能适合的很好,而现在我看到的是,很多小公司软件一升级或改进就动辄全部代码重写,大部分重复性工作无谓的浪费了时间和精力。

  6:测试习惯

  作为一些商业化正规化的开发而言,专职的测试工程师是不可少的,但是并不是说有了专职的测试工程师程序员就可以不进行自测;软件研发作为一项工程而言,一个很重要的特点就是问题发现的越早,解决的代价就越低,程序员在每段代码,每个子模块完成后进行认真的测试,就可以尽量将一些潜在的问题最早的发现和解决,这样对整体系统建设的效率和可靠性就有了最大的保证。

  测试工作实际上需要考虑两方面,一方面是正常调用的测试,也就是看程序是否能在正常调用下完成基本功能,这是最基本的测试职责,可惜在很多公司这成了唯一的测试任务,实际上还差的远那;第二方面就是异常调用的测试,比如高压力负荷下的稳定性测试,用户潜在的异常输入情况下的测试,整体系统局部故障情况下该模块受影响状况的测试,频发的异常请求阻塞资源时的模块稳定测试等等。当然并不是程序员要对自己的每段代码都需要进行这种完整测试,但是程序员必须清醒认识自己的代码任务在整体项目中的地位和各种性能需求,有针对性的进行相关测试并尽早发现和解决问题,当然这需要上面提到的需求理解能力。

  7:学习和总结的能力

  程序员是人才很容易被淘汰,很容易落伍的职业,因为一种技术可能仅仅在三两年内具有领先性,程序员如果想安身立命,就必须不断跟进新的技术,学习新的技能。

  善于学习,对于任何职业而言,都是前进所必需的动力,对于程序员,这种要求就更加高了。但是学习也要找对目标,一些小codingfans们,他们也津津乐道于他们的学习能力,一会学会了asp,一会儿学会了php,一会儿学会了jsp,他们把这个作为炫耀的资本,盲目的追逐一些肤浅的,表面的东西和名词,做网络程序不懂通讯传输协议,做应用程序不懂中断向量处理,这样的技术人员,不管掌握了多少所谓的新语言,永远不会有质的提高。

  善于总结,也是学习能力的一种体现,每次完成一个研发任务,完成一段代码,都应当有目的的跟踪该程序的应用状况和用户反馈,随时总结,找到自己的不足,这样逐步提高,一个程序员才可能成长起来。

  一个不具备成长性的程序员,即便眼前看是个高手,建议也不要选用,因为他落伍的时候马上就到了。

  具备以上全部素质的人,应当说是够格的程序员了,请注意以上的各种素质都不是由IQ决定的,也不是大学某些课本里可以学习到的,需要的仅仅是程序员对自己工作的认识,是一种意识上的问题。

  那么作为高级程序员,以至于系统分析员,也就是对于一个程序项目的设计者而言,除了应该具备上述全部素质之外,还需要具备以下素质:

  第一,需求分析能力

  对于程序员而言,理解需求就可以完成合格的代码,但是对于研发项目的组织和管理者,他们不但要理解客户需求,更多时候还要自行制定一些需求,为什么这么说呢?

  一般而言,进行研发任务,也许是客户提出需求,也许是市场和营销部门提出的需求,这时候对于研发部门,他们看到的不是一个完整的需求,通常而言,该需求仅仅是一些功能上的要求,或者更正规些,可能获得一个完整的用户视图;但是这都不够,因为客户由于非技术因素多一些,他们可能很难提出完整和清晰,或者说专业性的性能需求,但是对于项目组织者和规划者,他必须能够清醒认识到这些需求的存在并在完成需求分析报告的时候适当的提出,同时要完整和清晰的体现在设计说明书里面,以便于程序员编码时不会失去这些准则。

  程序设计者必须正确理解用户需求所处的环境,并针对性做出需求的分析,举例而言,同样一个软件通过ASP租用方式发布和通过License方式发布,性能需求可能就是有区别的,前者强调的是更好的支撑能力和稳定性,而后者则可能更强调在各种平台下的普适性和安装使用的简捷性。

  第二,项目设计方法和流程处理能力

  程序设计者必须能够掌握不少于两到三种的项目设计方法(比如自顶至下的设计方法,比如快速原型法等等),并能够根据项目需求和资源搭配来选择合适的设计方法进行项目的整体设计。设计方法上选择不当,就会耽误研发周期,浪费研发资源,甚至影响研发效果。

  一个程序设计者还需要把很多功夫用在流程图的设计和处理上,他需要做数据流图以确立数据词典;他需要加工逻辑流图以形成整体的系统处理流程。一个流程有问题的系统,就算代码多漂亮,每个模块多精致,也不会成为一个好的系统。当然,做好流程分析并选择好项目设计方法,都需要在需求分析能力上具有足够的把握。

  第三,复用设计和模块化分解能力

  这个似乎又是老调重谈,前面基本素质上不是已经说明了这个问题吗?

  作为一个从事模块任务的程序员,他需要对他所面对的特定功能模块的复用性进行考虑,而作为一个系统分析人员,他要面对的问题复杂的多,需要对整体系统按照一种模块化的分析能力分解为很多可复用的功能模块和函数,并针对每一模块形成一个独立的设计需求。举个例子,好比是汽车生产,最早每辆汽车都是独立安装的,每个部件都是量身定做的,但是后来不一样了,机器化大生产了,一个汽车厂开始通过流水线来生产汽车,独立部件开始具有一定的复用性,在后来标准化成为大趋势,不同型号,品牌甚至不同厂商的汽车部件也可以进行方便的换装和升级,这时候,汽车生产的效率达到最大化。软件工程也是同样的道理,一个成熟的软件行业,在一些相关项目和系统中,不同的部件是可以随意换装的,比如微软的许多桌面软件,在很多操作模块(如打开文件,保存文件等等)都是复用的同一套功能模块,而这些接口又通过一些类库提供给了桌面应用程序开发者方便挂接,这就是复用化的模块设计明显的一个佐证。
将一个大型的,错综复杂的应用系统分解成一些相对独立的,具有高度复用性的,并能仅仅依靠几个参数完成数据联系的模块组合,是作为高级程序员和系统分析员一项最重要的工作,合适的项目设计方法,清晰的流程图,是实现这一目标的重要保证。

  第四,整体项目评估能力

  作为系统设计人员,必须能够从全局出发,对项目又整体的清醒认识,比如公司的资源配置是否合理和到位,比如工程进度安排是否能最大化体现效率又不至于无法按期完成。评估项目整体和各个模块的工作量,评估项目所需的资源,评估项目可能遇到的困难,都需要大量的经验积累,换言之,这是一种不断总结的累计才能达到的境界。在西方一些软件系统设计的带头人都是很年长的,比如4,50岁,甚至更老,他们在编码方面已经远远不如年轻人那样活络,但是就项目评估而言,他们几十年的经验积累就是最重要和宝贵的财富。中国缺这么一代程序员,主要还不是缺那种年纪的程序员,而是那种年纪的程序员基本上都是研究单位作出来的,都不是从专业的产品化软件研发作出来的,他们没有能积累那种产品化研发的经验,这也是没有办法的事情。
第五,团队组织管理能力

  完成一个项目工程,需要团队的齐心协力,作为项目设计者或研发的主管人,就应当有能力最大化发挥团队的整体力量,技术管理由于其专业性质,不大同于一般的人事管理,因为这里面设计了一些技术性的指标和因素。

  首先是工作的量化,没有量化就很难做到合适的绩效考核,而程序量化又不是简单的代码行数可以计算的,因此要求技术管理人员需要能真正评估一个模块的复杂性和工作量。

  其次是对团队协作模式的调整,一般而言,程序开发的协作通常分为小组进行,小组有主程序员方式的,也有民主方式的,根据程序员之间的能力水平差距,以及根据项目研发的需求,选择合适的组队方式,并能将责权和成员的工作任务紧密结合,这样才能最大发挥组队的效率。

  一个代码水平高的人,未必能成为一个合格的项目研发主管,这方面的能力欠缺往往是容易被忽视的。

  综上可以看到,作为一个主管研发的负责人,一个项目设计者,所需要具备的素质和能力并不是程序代码编写的能力,当然一般情况下,一个程序员通过不断的总结提高达到了这种素质的时候,他所具有的代码编写能力也已经相当不简单了,但是请注意这里面的因果关系,一个高水平的项目设计者通常已经是代码编写相当优秀的人了,但是并不是一个代码相当优秀的程序员就可以胜任项目设计的工作,这里面存在的也不是智商和课本的问题,还是在于一个程序员在积累经验,逐步提升的时候没有意识到应当思考哪方面的东西,没有有意识的就项目的组织和复用设计进行揣摩,没有经常性的文档习惯和总结习惯,不改变这些,我们的合格的项目设计者还是非常欠缺。

  最后补充一点东西,一个软件项目研发的设计流程是怎样的呢?以通常标准的设计方法为例。

  第一个步骤是市场调研,技术和市场要结合才能体现最大价值。

  第二个步骤是需求分析,这个阶段需要出三样东西,用户视图,数据词典和用户操作手册。用户视图是该软件用户(包括终端用户和管理用户)所能看到的页面样式,这里面包含了很多操作方面的流程和条件。数据词典是指明数据逻辑关系并加以整理的东东,完成了数据词典,数据库的设计就完成了一半多。用户操作手册是指明了操作流程的说明书。请注意,用户操作流程和用户视图是由需求决定的,因此应该在软件设计之前完成,完成这些,就为程序研发提供了约束和准绳,很遗憾太多公司都不是这样做的,因果颠倒,顺序不分,开发工作和实际需求往往因此产生隔阂脱节的现象。

  需求分析,除了以上工作,笔者以为作为项目设计者应当完整的做出项目的性能需求说明书,因为往往性能需求只有懂技术的人才可能理解,这就需要技术专家和需求方(客户或公司市场部门)能够有真正的沟通和了解。

  第三个步骤是概要设计,将系统功能模块初步划分,并给出合理的研发流程和资源要求。作为快速原型设计方法,完成概要设计就可以进入编码阶段了,通常采用这种方法是因为涉及的研发任务属于新领域,技术主管人员一上来无法给出明确的详细设计说明书,但是并不是说详细设计说明书不重要,事实上快速原型法在完成原型代码后,根据评测结果和经验教训的总结,还要重新进行详细设计的步骤。

  第四个步骤是详细设计,这是考验技术专家设计思维的重要关卡,详细设计说明书应当把具体的模块以最‘干净’的方式(黑箱结构)提供给编码者,使得系统整体模块化达到最大;一份好的详细设计说明书,可以使编码的复杂性减低到最低,实际上,严格的讲详细设计说明书应当把每个函数的每个参数的定义都精精细细的提供出来,从需求分析到概要设计到完成详细设计说明书,一个软件项目就应当说完成了一半了。换言之,一个大型软件系统在完成了一半的时候,其实还没有开始一行代码工作。那些把作软件的程序员简单理解为写代码的,就从根子上犯了错误了。

  第五个步骤是编码,在规范化的研发流程中,编码工作在整个项目流程里最多不会超过1/2,通常在1/3的时间,所谓磨刀不误砍柴功,设计过程完成的好,编码效率就会极大提高,编码时不同模块之间的进度协调和协作是最需要小心的,也许一个小模块的问题就可能影响了整体进度,让很多程序员因此被迫停下工作等待,这种问题在很多研发过程中都出现过。编码时的相互沟通和应急的解决手段都是相当重要的,对于程序员而言, bug永远存在,你必须永远面对这个问题,大名鼎鼎的微软,可曾有连续三个月不发补丁的时候吗?从来没有!

  第六个步骤是测试

  测试有很多种:按照测试执行方,可以分为内部测试和外部测试;按照测试范围,可以分为模块测试和整体联调;按照测试条件,可以分为正常操作情况测试和异常情况测试;按照测试的输入范围,可以分为全覆盖测试和抽样测试。以上都很好理解,不再解释。

  总之,测试同样是项目研发中一个相当重要的步骤,对于一个大型软件,3个月到1年的外部测试都是正常的,因为永远都会又不可预料的问题存在。完成测试后,完成验收并完成最后的一些帮助文档,整体项目才算告一段落,当然日后少不了升级,修补等等工作,只要不是想通过一锤子买卖骗钱,就要不停的跟踪软件的运营状况并持续修补升级,知道这个软件被彻底淘汰为止。

技术专题:大型应用系统的一些讨论

第一:作为OLTP应用(联机事物处理,区别于OLAP),响应速度和处理并访能力是系统整体性能评价的第一要旨。
作为带动性能提升的主要因素,占第一位的是系统的体系架构、第二位的是数据结构定义、第三位的才是选择怎样的语言和系统平台。当然,很多情况下在考虑体系结构的时候是有基于系统平台的考量,但是一般而言,系统体系结构并不是依存于某特定平台才能确定的。

作为高并访应用的OLTP而言,一般在涉及数据库操作和数据存储操作的时候,应当明确的关键问题是,数据库操作的触发和执行是不应当基于用户请求的,这也是三层体系结构的真谛所在。也就是说,如果一个用户请求就触发了一个数据库操作,不管你使用的是php,jsp,asp,cfm,fcg还是com组件或其他什么东东,严格讲都不是真正的三层体系,因为这时中间层实际上并不存在。即便使用了预编译,即便使用了数据连接池(Connect Pool),即使系统提供了足够的缓冲处理,都是不够的。

举个例子而言,如果你在一个页面上使用了计数器,最简单的方法是每次页面请求的时候,处理程序直接数据库中相关记录加1,不管使用什么语言,什么平台,或调用什么控件,亦或采用了数据库内部的存储过程处理(显然这样效率很高)。但是这还不够,比如类似于易数统计这样的系统,当它每天处理几百万至上千万请求的时候,任何数据库就都无法容忍这样的操作,因为对于update操作,数据库缓冲的存在基本是无用的。
那么取代的手段是怎样的,前台的API程序将来访请求的一些信息按照一个指定规范直接扔到指定缓冲区里面,这样API程序(请注意这里我不提CGI, CGI效率那么差,在这样的场合是不推荐的)的处理过程很简单,效率很高。后台的看守进程从缓冲区读取数据,通过指定管道(数据连接池,固定数据库连接进程维持常连接状态)和数据库进行数据更新操作,这样的好处有以下几点,第一是当并访瞬间高峰时,前台响应不会受很大影响,缓冲可能会造成溢出而损失数据,但是不会影响前台的展示,而且当缓冲合理分配时,这种压力也会减轻,而后台看守进程可以将任务负载均衡分布处理,一时处理不完的在系统负载减轻时可以继续处理,这样后台负载可以均担,减少因瞬态高峰造成系统崩溃的隐患;第二是当缓冲区数据存储合理安排时,后台可以作到批量处理,要知道数据库批量更新比一个一个单独更新的效率会高很多,这样从处理任务量上减轻系统负载!
针对以上补充一点说明,一般而言,针对良好的商业数据库而言,select操作比update操作的效率高一个数量级,因为前者可以充分利用缓冲,而后者不能,因此将update操作批量化和后台化是非常重要的!

第二:动态页面的静态化至关重要
很多人会对这个问题感到疑惑,因为提到动态页面,自然是能够根据不同条件动态显示的页面,这也是相对于静态主页的优势,为什么要退回去静态化?
其实静态化不等于就是静态主页,这也是基于效率和性能的考虑。还是用例子表达。
范例1:新闻系统
新闻的时效性是最重要的,为了减少维护和提高更新速度,现有的新闻系统很强调后台更新的即时展示。
我们现在要考虑一个问题,一个新闻系统的首页每天显示动辄几万至几百万次,而新闻每天的更新频率最多几十到几百次,也就是在新闻标题列表两次更新之间,有几千至几万人看到的是同样的东西,类似这样的东东,就要考虑静态化处理了。同样,对于每一条新闻而言,几百至几千人看到的是同样的东西,依然有这样的处理需求。类似这样的问题,作为新闻标题列表的页面和单一新闻页面,都应当是静态html发布,这样最符合效率原则,而后台的维护程序仅仅在更新和发布新闻的时候,对这种静态html以文本文件方式打开和操作,这样就不会影响时效性和维护的便捷性。新浪的新闻系统绝对是这样的,我还看到了很多免费共享软件,可惜没有这样处理的。
范例2:广告交换系统
广告交换系统和上述有一些区别,在于每个用户所看到的东西都是不同的,每次用户刷新也是不同的,这种情况下上述方式就无法解决。但是静态化的工作还是需要的。
实际上这里面有一个小窍门就是广告交换系统或类似系统(即便是商业广告投放系统)从需求定义而言并不需要100%严格的交换比例,甚至也不可能作到 100%严格的交换比例,这时候后台进程就应当对需要投放的广告内容定时进行预生成(比如间隔三分钟生成一次),并放入缓冲,前台的API程序在接受用户请求后,根据用户请求的参数和条件,在预生成的广告队列里面进行二次生成,并将这次投放的记录放到存放统计的缓冲(这是本文刚开始就提到的手段,后台对统计信息的处理同前文),前台程序虽然也进行了动态生成过程,但是由于数据来源是缓冲中的预生成信息,因此处理量小,处理效率高,而后台进程则将原本需要每次请求进行的类似操作集中一次进行,同样从架构上减少了系统处理的工作量。而作为代价,仅仅是投放过程中的交换显示比会由于三分钟预生成中的统计变化而显得不那么精确,但是当系统运营时间很长以后,这种不精确会逐步调整到可以完全忽略的地步。

第三:那种语言效率最高
这是一个最原始的问题,php+zend,fcg,jsp,IIS API都宣称自己非常之快,实际上他们都是采用了提前加载,预编译,驻留内存,缓冲分配等手段,使得处理请求响应的速度非常之快,但是这种速度仅仅是处理响应的速度,当系统需要对后台数据库,对后台文件,甚至对后台shell进行操作的时候,最快的毋庸质疑,还是C语言,而且是标准C语言,有一个事实必须提醒诸位,尽管高级语言层出不穷,但是从70年代到21世纪,世界上最值钱的程序员一直是标准C的程序员(当然还有更原始的汇编程序员)。其实一个大型系统,前台动态展示采用asp也好,cfm也好,fcg也好,jsp也好都是无关紧要的,关键是采用合适的架构并把烦琐的数据操作尽可能放到后台执行。
放到后台执行的准则是,将动态化过程中所有可以集中批量处理的,所有可以通过缓冲交换的,所有重复性的工作,所有与用户请求没有直接关联的,一概放到后台,以看守进程,或者定时程序进行。

第四:安全问题考虑。
当一个大的网上应用系统,如果有些程序,访问量不高,因此网站设计者认为效率无所谓,可以通过api直接对数据库进行烦琐操作,那么就危险了,实质上那种程序往往成为基于CGI的D.o.s攻击的靶子,(本人恰恰是这方面的专家:))。因为当有人通过伪装报文,瞬间大量请求这个处理效率不高,反应缓慢的程序的时候,系统资源就会大量被占用,很快就会因为系统资源过载而导致系统崩溃或拒绝服务。
请注意这种攻击是导致系统资源的过载而不是带宽,由于宽带网的接近,基于带宽的拒绝服务攻击将越来越困难,但是恰恰相反的是,基于系统资源的拒绝服务攻击将越来越容易,所以网站设计者,千万不可在任何一个地方掉以轻心,而烦琐操作后台化,对这样的攻击行为就有很好的抗击能力,这一点也是我这里再次要强调的。
再补充一句,进行这样的攻击非常容易,以至于一个完全不会写程序的人,只要懂得一些网络,就可以在很短时间掌握,并给大型站点带来严重打击。
第五:数据支持

本人罗里罗嗦这么半天,大家不知道是不是不耐烦,我有何德何能在此逞强?
www.isme.net是目前每天支撑接近 300万次广告链调用的免费广告交换系统,瞬间高峰每秒请求超过50次,每天流量12G以上。我在系统正常运行的过程中作过测试(系统已经有一定负载),通过apache的ab进行标准测试,对广告链投放程序,测试结果是在100个并访情况下,瞬间处理能力可达到每秒1300次广告链请求!如果不是合理分配内存缓冲和后台看守进程的预生成,如果每个请求程序都要到数据库跑一趟,这个数字是绝对不可能达到的。

任何人都可以在apache下面用ab对自己写的程序进行速度评测,看看你的程序能达到怎样的处理能力?

技术测试:你是oltp应用开发方面的高手吗?

这里是一篇技术测试的文章,希望所有那些自称的和被人吹捧的技术高手来看一看,做做我们的几个测试,看看你属于那种层次的高手?

以下测试是针对oltp开发而言的,对于做算法和桌面程序的,不是我这里要讨论的对象。

好了,第一个考题:你能否做一个统计系统,功能上和易数差不多,能够通过页面嵌入方式记录一个网站的显示次数,来访分析,时段分析,日期分析等等。怎么,这就被难住了,那你算哪门子高手?啊哈,这位说了,这些都easy,手到擒来,很好,很好,看来在实现功能上,你具有了高手的基本能力,不过且慢,如果你认为可以实现这些功能就能自称做个易数统计出来,未免也太小瞧了技术这碗饭的分量,实现这些功能,就中国而言,至少有6位数的程序员可以作到,而设计这么一套系统(仅从功能考虑),也至少有5位数的程序员可以作到,明白吗?你不过是这里面平平常常的一个而已了,要高兴还早呢。

第二个考题:呵呵,其实还是做这些功能,不过加个条件,我只给你一台PC Server(单/双PIII 733+512M Ecc内存+18G SCSI硬盘),你要支撑300万/天的请求调用。琢磨琢磨吧。
简简单单的一个cgi+数据库,那是肯定死翘翘了,怎么办?
第一,你要建立三层体系模型,后台数据库必须通过中间应用层和前台CGI分开。
第二,合理分配使用共享内存空间,并合理通过IPC信号量防止内存区的读写冲突和死锁。
第三,必要时改写web server原代码以获得效率最优化,比如改写apache server的http_log.c程序并重新编译。
如果你对建立这么一套系统的整体架构非常清楚,那么恭喜,你可以在一个比较不错的网络公司做一个CTO了,中国能够清晰搭建这样系统的人,不过4位数而已(当然,能够在这样系统里进行编码工作的,肯定还是有5位数以上的,毕竟左右都是c语言而已)。
知道为什么层出不穷那么多统计系统,虽然功能花哨,但是最后都撑不过易数,基本功不扎实,光靠功能花哨,那是没前途的。

在这个领域做的比较好的,好耶,网易,adsunion,腾讯,太极链等几家而已。
那些所谓广告交换没什么技术瓶颈的人,自己做一套大并访系统出来再说话。

第三个考题,还是这些功能,(我够贫的是吧)我要你一天能记录下3000万次浏览日志,不但要统计,还要完整记录,以供随时查验,当然主机环境提升一下,处理数据的主机用集群,但是核心数据库还是用一台电脑的,这次用sun的小型机,比如RS6000什么的;还有这次再加个条件,数据损失不能超过 0.01%。
这个已经不再象建立一个网站了,到象是大型电信的计费中心。你能胜任吗?
这时候要求对整体操作系统,对C语言,对数据库核心都必须有深入骨髓的理解,甚至于,对于数据的导入导出和一些日志的数据库记录,你已经不能再用sql去写了!要利用数据库产品的核心接口按照其数据存储格式直接进行文件或设备块的读写操作!对于一些负载非常大而性能要求又非常高的系统,甚至你需要建立一套独立的数据库体系和数据结构体系。这不是玩笑,因为我领教过这样的系统。
在中国,能搭建这样平台的高手,最多3位数而已。主要集中在电信计费领域,如亚信这样的企业。

第四个考题,这次每天的请求不是3000万了,而是3万万,我没说胡话,3万万!不过你的工作变了,我不要你再做后面的数据处理,我只让你做一个前端报文转发处理,这次我很苛刻,给你一台PII的PC服务器,256M Ecc内存,而数据损失要求则绝对不能超过0.0001%,你的工作很简单,对来往的请求进行简单识别并转发到合适的应用服务器处理。
你用web server转发?别开玩笑了!这时候,你已经别无选择,用汇编自己写一套报文处理程序,作为看守进程驻入内存并挂在接收报文的端口上,你对效率的理解,应当已经超出了对操作系统的认识,对编程语言的认识,而直接达到对CPU指令集的认识程度上,是的,你必须清楚自己的每一条汇编指令是不是已经达到最小的 CPU指令占用。必须能计算出分解和处理一条报文的流程需要多少CPU指令循环,是不是已经针对CPU的指令集达到了最大优化,当然,你还必须很熟悉 TCP/IP协议对每一种报文的格式定义和规范,不过这和汇编指令的效率优化而言,到不显得有多高深了。
我们经常说CISCO是硬件产品服务商,错了!他们的利润主要就来自于这样的算法!!中国联想、华为等等都想强占这块肥肉的市场,但是在高端领域(其实并不是硬件高端,而是算法高端!),我们还是彻底的空白。
庆幸的是,我知道国内有人在做这样的事情了,当宽带不可避免的成为主流的时候,这种算法的强度和要求,会成为攫取利润的最好途径。
中国在这方面能达到标准的,又有几个人呢?

出了这四个考题,没别的意思,我刚大学毕业的时候,也是自视甚高,因为当时的感觉是,和专业课的计算机作业相比(我是力学专业的,动不动要求编程解一个偏微分方程的收敛解,来分析什么旋流场的速度、温度等的分布),做wewebb开发简直毫无算法可言。再加上当时国内做web数据库的也少,动辄以为自己已经是满高手了,结果幸好跑到给电信做计费的企业混了一年,接触了国内最大的电信集中计费中心的解决方案(一直在运营,还不错),才知道敢情OLTP应用里面学问大的很,自己这点皮毛拿出来吹嘘简直是不知天高地厚。现在看看外面一堆和我当初一样的小毛孩子整天做两个烂程序就自诩高手,只好出来说几句。

其实对于OLTP应用而言,功能的实现一般都非常容易,和那些从事力学、数学、物理等行业的数值计算相比简直毫无算法可言,而OLTP的技术难点主要在于性能,也就是你做一个桌面程序或算法程序,都不会面临并访过高的处理问题,但是做一个OLTP应用,无论如何你都必须直视一下子很多访问冲上来的情况,如果这个问题解决不了,无论多好的创意,多好的功能,都不会得到持续和长远的发展。

由于很多创业者和投资者对技术不通或半通,他们往往拿一个性能指标有很大缺陷的东东当个宝贝,因为一般而言,开发出新东东大家都只是忙着测试功能,很少有对性能进行完整测评的,只有持续运营到一定阶段,并访达到一定程度,性能缺陷开始暴露,才临急抱佛脚,这时候造成的损失就很不核算,甚至是压根解决不了,只好放弃某种功能,从而使品牌信誉整体下降。

加强算法基础,加强技术基础,少卖弄一些花里胡哨的东西,是走向技术高手的真正路线,那些今天学会了什么语言,明天又学会了什么语言的主儿,别吹嘘了,从70年代到现在,最值钱的程序员一直是写汇编和写标准C的,不为什么,因为这是真功夫。

星期一, 十月 18, 2004

Topix.net Weblog: Memory resident

A while ago I was chatting with my old boss Wade about a nifty algorithm I found for incremental search engines, which piggybacked queued writes onto reads that the front end requests were issuing anyway, to minimize excess disk head seeks. I thought it was pretty cool.

Wade smacked me on the head (gently) and asked why I was even thinking about disk anymore. Disk is dead; just put the whole thing in RAM and forget about it, he said.

Orkut is wicked fast; Friendster isn't. How do you reliably make a scalable web service wicked fast? Easy: the whole thing has to be in memory, and user requests must never wait for disk.

A disk head seek is about 9ms, and the human perceptual threshold for what seems "instant" is around 50ms. So if you have just one head seek per user request, you can support at most 5 hits/second on that server before users start to notice latency. If you have a typical filesystem with a little database on top, you may be up to 3+ seeks per hit already. Forget caching; caching helps the second user, and doesn't work on systems with a "long tail" of zillions of seldom-accessed queries, like search.

It doesn't help that a lot of the scheduling algorithms found in standard OS and database software were developed when memory was scarce, and so are stingy about their use of it.

The hugely scalable AIM service stores everything in memory across a distributed cluster, with the relational database stuck off to the side, relegated to making backups of what's live in memory. Another example is Google itself; the full index is stored in memory. Servers mmap their state when they boot; no disk is involved in user requests after everything has been paged in.


The biggest RAM database of all...

An overlooked feature that made Google really cool in the beginning was their snippets. This is the excerpt of text that shows a few sample sentences from each web page matching your search. Google's snippets show just the part of the web page that have your search terms in them; other search engines before always showed the same couple of sentences from the start of the web page, no matter what you had searched for.

Consider the insane cost to implement this simple feature. Google has to keep a copy of every web page on the Internet on their servers in order to show you the piece of the web page where your search terms hit. Everything is served from RAM, only booted from disk. And they have multiple separate search clusters at their co-locations. This means that Google is currently storing multiple copies of the entire web in RAM. My napkin is hard to read with all these zeroes on it, but that's a lot of memory. Talk about barrier to entry.
Posted by skrenta at February 2, 2004 10:48 PM
Comments

This also means that the snippet service will be costing Google more and more to maintain as the web grows exponentially...
Posted by: Ben at February 25, 2004 10:23 AM

The point about the perception of latency vs. disk seek time is an interesting one. But I think your maths is a little off. ISTM you could support over 100 hits per second if you take a minumum of 9ms per hit. However, more than five hits within a 50ms period will put you outside the "window", which I think is what you were getting at.
Posted by: Mark Allerton at February 25, 2004 11:58 AM

Here's what someone who deals with big databases for my employer says:

"This was the holy grail in database administration a few years ago: 'keep it all in ram!'. While the performance of such systems is astounding, the paradigm is very difficult to implement on anything besides a data mine. (Search engines are good examples of data mines.)

"The reason? Data mines aren't updated in realtime -- they use a point-in-time snapshot of their data. Because it is just a copy of the 'real' db, there is no risk of data loss if the system goes down. The drawback to data mines is that data is not being updated in realtime.

"While I'm at it...

"The other end of the database spectrum is ruled by transactional systems. Electronic banking is a classic example -- lots of data, all interdependent, and all changing in real-time. Our systems are transactional. We keep our customer's data current to the millisecond, with a deliberate focus on accuracy and security. In this regard, we kick google's bu**, because there is notihing real-time about google! ;)"

"I hope this info is useful!"

星期日, 十月 17, 2004

高速缓存在宽带网中的应用

英特尔(中国)有线公司系统工程师 尤晋

建设宽带网络的初衷是提供Internet的高速接入服务,同时通过各种附加服务来吸引用户。所以,用户在访问Internet时,是否真正体验到了在网络上“冲浪”的感觉,是宽带接入服务商必须面对的问题。

缓存技术在宽带中的应用
内容缓存技术在解决宽带技术应用问题中得到了广泛采用。内容缓存技术通过缓存用户经常访问的站点的内容,将用户最关心的内容放到离用户最近的地方,将网络传输中各种不确定的因素排除出去,并通过自己经过充分优化的响应系统响应用户的请求,充分利用到用户“最后一公里”的高带宽,达到提高最终用户响应速度的目的。
缓存技术对最终用户、宽带接入服务提供商以及网站自身都能带来好处:
1. 加快了最终用户访问Internet的时间,节省了与宽带接入服务提供商联接的费用;
2.利用缓存技术,大部分用户的Internet访问请求都在本地得到响应,从而节省了宽带接入服务提供商的Internet带宽的占用率,这也就意味在同样的带宽条件下,服务提供商可以发展、支持更多的用户;
3.宽带接入服务提供商可以像数据中心一样开展多种业务,将缓存加速服务作为向它们的主机托管用户、主机租用用户提供的一项增值服务;
4.缓存技术的采用,不仅满足了网站最终用户对访问速度的要求,加强了客户的满意度,同时也减轻了网站原始Web服务器的负载,这对网站带来的好处是显而易见的;
5.利用分布式缓存技术,为原始网站提供增值服务,降低了网站自身建设、维护远程镜像站点的成本,拓展了自己的商机。

缓存技术类型
1. Forward-Proxy正向代理:
需要客户的Web浏览器配置Proxy代理服务器的IP地址及TCP端口号,这样客户的所有Web请求都经过Cache缓存服务器的代理访问Internet。在Cache缓存服务器代理用户请求访问Internet之前,它先检查自身是否已经缓存了用户请求访问的Web对象(每一个页面都是由单独的WebObject构成的,每一个URL都唯一对应一个Web对象),如果已经缓存并且没有过期,那么就用本地缓存的Web对象响应客户的请求,从而加快了用户的访问时间,并且节省了宝贵的广域网链路带宽资源。但此种类型因为需要更改客户Web浏览器的配置,所以只适合于中小企业。
2. Transparent-Cache透明缓存:
与Forward-Proxy正向代理类型的唯一区别在于,无需在客户的Web浏览器中配置任何信息,可以利用以下几种设备来与Cache缓存服务器配合实现:
1)Intel公司的具备第四层重定向功能的ES550路由交换机;
2)可以设置第四层过滤规则的L4交换机;
3)支持WCCP协议的Cisco路由器、交换机系列。
3. Reverse-Proxy反向代理:
与客户端无关,提供对Web服务器端的加速访问。它的应用方式是缓存服务器放置在Web服务器前端,代理Web服务器接受所有客户的 HTTP请求(通过DNS服务器配置实现),此时Cache缓存服务器类似于一台Web服务器,也在TCP80端口接受HTTP请求访问。根据 Internet上的统计表明,超过80%的客户经常访问的是20%的网站内容,在这个规律下,缓存服务器可以处理大部分的客户静态请求,而原始的Web 服务器只需处理约20%左右的非缓存请求和动态请求,于是大大加快了客户请求的响应时间,并降低了原始Web服务器的负载。
采用反向代理方式(或服务器缓存加速方式)与传统的Web服务器直接响应方式比较起来,具有以下优点(以Intel公司的1500缓存服务器为例) :
1)缓存服务器对客户Web请求的响应实际上是基于二级缓存技术:第一级是基于RAM随机访问内存来响应的,第二级是基于硬盘来响应的。这与Web服务器基于硬盘的响应速度显然不一样;
2)1500缓存服务器的Cache缓存软件InktomiTrafficServerEngine是基于数据库索引(Index)方式来组织Web对象,查询Web对象的速度比传统的Web服务器更快;
3)1500缓存服务器的Cache缓存软件InktomiTrafficServerEngine采用了最新的数据流技术 (DataFlow),基于原始磁盘(RawDisk)进行I/O读写访问操作,这比传统的Web服务器基于文件系统(FileSystem)的I/O读写效率更高;
4)多台1500缓存服务器可以很方便地配置成群集(Cluster)或负载平衡,不仅保证了Cache缓存服务器的冗余,并且线性地提高了Cache缓存服务器组整体处理Web请求的能力 ;
5)节省存储硬盘空间,缓存服务器不用100%复制原始Web服务器的内容,它只是缓存用户经常访问的静态页面对象,相比采用多台同等Web服务器扩展站点处理能力更为经济有效;
6)单台1500缓存服务器在理论上可以反向代理多达245台不同内容的Web服务器。
正因为Cache缓存服务器的反向代理类型具有以上特点,并且采用了这种技术以后,Web站点的响应速度通常会加快30%~50%以上,所以得到诸如Yahoo.com,CNN.com,Hotmail.com等大量E-Mail站点的广泛响应。

应用缓存技术应注意的问题
缓存设备应支持所有三种缓存类型,以灵活地运用到宽带接入网络中,并提供多种服务。例如,利用正向代理模式(Forward- Proxy),帮助宽带服务商控制Internet接入服务的用户;利用透明缓存模式(Transparent-Cache),为最终用户提供最方便简洁的服务;利用反向代理模式,吸引更多的内容服务商,在提高自身用户满意度的同时,拓展自己的商机。
缓存设备应基于开放的平台和技术,以确保与现有技术和设备的兼容性,发挥最大的效益。由于宽带技术是近一两年才出现的新兴技术,缓存技术在宽带接入网络中的应用远远落后于在其他网络环境中的应用,而且网络技术的发展突飞猛进,日新月异,所以确保缓存设备在宽带接入网络中的运用可以与现有及将来的技术兼容,相互配合,最大限度地发挥缓存的作用是每一个宽带接入服务商在选择缓存设备时必须慎重考虑的问题。只有基于开放平台和开放技术之上的产品,才能保证与已有技术和其他厂商的产品之间的兼容,并为将来出现的新技术做好准备,最大限度地保护服务商的投资。
缓存设备应该支持性能上的无级扩展,可以满足宽带接入服务商根据具体情况定制自己设备的需求,并根据服务规模的发展,快速、简单地实现性能上的升级。
缓存设备应该具有安装快速、维护简易方便的特性,具有异地远程管理、开关机的功能,以降低宽带接入服务商的运营维护成本。
缓存设备自身系统应该具有高度的稳定性,可靠性和安全性。缓存设备处于网络中的关键位置,易受到攻击,且由于通信量的巨大,系统自身的稳定性,可靠性和安全性非常重要。而这与系统本身的设计有密切的关系。
缓存设备应该具有几十Gbit的巨大容量,以支持大量用户的离散请求,提高用户的满意度,最大限度地保护服务商的投资。
缓存设备应该支持多种协议,包括HTTP、FTP、NNTP等,以适应各种网络应用。

星期一, 十月 11, 2004

利用模糊词匹配算法自动侦出/纠正中文文本中的文字错误

利用模糊词匹配算法自动侦出/纠正中文文本中的文字错误
文献类别 语音组和自然语言组 文件类型 pdf
文献作者 暂无 文件大小 207KB
Lei Zhang, Ming Zhou, Changning Huang, and Haihua Pan. "Automatic detecting/correcting errors in Chinese text by an approximate word-matching algorithm", ACL-2000. The 38th Annual Meeting of the Association for Computational Linguistics, Hong Kong, 3-6 October 2000.

利用词汇和N元模型进行中文信息检索

文献类别 语音组和自然语言组 文件类型 pdf
文献作者 暂无 文件大小 114KB
Jian-Yun Nie, Jiangfeng Gao, Jian Zhang, and Ming Zhou. "On the use of Words and N-grams for Chinese Information Retrieval". IRAL-2000, Fifth International Workshop on Information Retrieval with Asian Languages, Hong Kong, September 30 to October 1, 2000.

星期五, 十月 08, 2004

走出生活误区 保障身体健康

  人类想长生不老是违反生命规律的。但是人类长寿之谜,随着现代基因技术的进步而被揭开,人类正常寿命可达150岁,然而为什么如今人们的平均寿命只有75岁,只及人类正常寿命的一半呢?

  生命科学家经过多年的研究发现,影响人类寿命的因素很多,人类生存的环境、疾病是导致人类寿命减少的主要原因,而诱发疾病的主要原因是人类饮食营养不平衡造成的。

认识上的误区

  人类的长寿不长寿,是人们十分关注的问题,也认识到与饮食营养有着密切的关系。这是因为食品营养的质量好坏、膳食结构的合理程度和饮食习惯的科学与否,不仅与人类每个个体的生长发育、体质强弱、智商高低、疾病轻重和寿命长短紧密相连,而且直接影响到一个国家的前途命运和整个民族的兴衰存亡。然而,在现实生活中,由于人类对食品营养知识普遍缺乏,食物选择搭配不合理,只讲营养不讲均衡,因此陷入了饮食的认识误区:

高蛋白高营养可以满足人体需要

  人类从思想认识上认为:多吃好的贵的东西身体就会健康。高蛋白、高营养是提供人体所需要的多种维生素和无机盐、改善人体营养状况的极为重要的膳食组成部分。但是,人体的生长发育,需要多种多样的营养,而高蛋白、高营养是无法满足人类生命所需要的均衡营养的。人类体内所需要的营养,是分散于多种生物体内的,地球上并没有人体所需的各种营养“皆备于我”的食物。所以,高蛋白和高营养达不到人体全面而平衡的营养需要。单一追求高蛋白、高营养,最终会导致营养不良或营养缺乏,以至饱食终日,却记忆下降、思维迟钝、脂肪过剩、血脂升高,引发心血管等“文明病”、“富裕病”,甚至发生癌变。

聪明不聪明是先天的

  经过科研人员的研究结果证明,人的大脑由大约140亿万个细胞组成。然而,聪明不聪明不是先天的,是要经过后天的营养供给培养发育的。被称为“结构脂肪”的脂肪酸、脑磷脂、卵磷脂、糖脂和胆固醇是保证大脑智力的主要营养,特别是被称为“智慧之花”的卵磷脂是大脑结构脂肪的主要成分,它被人体吸收后可释放出胆碱,进而合成神经元中快速传递信息的物质乙酰胆碱。而亚油酸是形成和勾通脑细胞最重要的成分,它对人的记忆能力和思维能力有重要影响。不能供给足量的大脑营养,想聪明是聪明不起来的。

  大脑的发育有赖于后天足够的氧和能源物质的供应。因此,为维持大脑的正常功能,各种营养物质包含氧气必须源源不断地通过血液流向大脑,供给脑细胞需要。如果不注意大脑的营养供给,到了中年之后,随着代谢功能的减慢,大脑记忆力呈普遍下降的趋势,就会经常出现“丢三落四”的现象。

人体的高矮取决于遗传基因

  人身体的高矮60%取决于父母的遗传特征,即由遗传基因所决定。骨骼发育虽然受遗传基因的控制,但也有可塑性的一面。日本近50年人体增高了15厘米左右,就是改变了饮食结构、注意饮食营养平衡的结果。

不饿不渴不吃不喝

  生活中很多人不按时就餐,而是不饿不吃饭,或是不吃早餐,其理由之一就是“不饿”,还有些人工作忙时,常常是干完活再吃饭。这些做法容易损害胃,也会削弱人体的抗病力。因为食物在胃内仅停留4~5小时左右,感到饥饿时,胃早已排空,胃粘膜这时会被胃液进行“自我消化”,容易引起胃炎和消化道溃疡。

  水是维持生命正常运动和防病、健身的重要物质。人体缺水即会精神不振、口干舌燥、浑身无力、肝肾功能下降、毒性物质积蓄、病魔缠身。口渴,揭示体内缺水已颇严重。新的养生观认为,平时在渴感出现之前就应少量、多次补水。

餐具使用的误区

铝锅轻巧耐用

  用铝锅烧煮酸性或碱性食物,导致铝大量溶出,长期食用铝锅煮过的酸、碱食物,会加速人体衰老,对健康不利。

  用砂锅炖肉、煲汤及煎中药 砂锅中含有少量瓷釉铅,煮酸性食物时容易溶解出来,有害健康,故最好选用内壁白色的砂锅。新买回的砂锅可先用4%的食醋水浸泡煮沸,这样可去掉有害物质。

铁锅使用最安全

  铁锅是常用的炊具,其化学性质稳定,不易引起化学反应。用铁锅炒菜时要急火快炒少加水,以减少维生素的损失,炒菜时溶解出来的少量铁元素,可以被人体吸收利用,对健康有益。但铁锅易生锈,不宜盛食物过夜,用铁锅盛油容易氧化变质。

用铜锅存放食物

  铜锅外表华丽、传热快,特别是铜火锅颇受人们喜爱。用铜锅烹煮食物时溶解出来的少量铜元素,对人体有利。但铜锅易生铜绿,故不宜存放食物。

  使用搪瓷锅放心 搪瓷锅能耐酸碱腐蚀,化学性能稳定,是比较理想的炊具。但劣质搪瓷,可检出有害金属铅和镉,故在选购时应加以注意。

不锈钢锅万能

  不锈钢锅美观大方,轻便耐用,耐腐蚀不生锈,颇受人们青眯。不锈钢锅是由铁铬合金渗入镍、钼、钛、镉、锰等微量金属元素制成,这些微量金属元素对人体有害,因此使用时应注意,不要长时间盛放盐、酱油、醋等,因这些食物中的电解质与不锈钢长期接触会发生电化反应,使有害物质被溶解出来。不要用苏打、漂白粉等强碱洗涤不锈钢锅,这些物质都是强电解质,同样会与不锈钢发生电化反应。也不能用不锈钢锅煮中药,因为中药含有多种生物碱,在加热过程中与不锈钢发生化学反应,影响中药的效果,甚至会产生有毒的化合物。

从厨房到餐桌的误区

喜用热油炒菜

  在烧得过热的油锅底层,容易生成一种硬脂化合物,对人体健康极为有害。人如果常吃过热油锅炒出的菜,易患低酸性胃炎和胃溃疡,还可能诱发癌变。

米面放凉吃

  米面食品放凉后,淀粉分子就会自动有规律地定向排列,组合成一种质量坚硬的结晶,很难与消化液充分混合,不易被身体吸收。这种放冷变硬的淀粉食品,一定要经过加温重新蒸煮,让淀粉再次吸水、膨胀,才可以保持食品应有的营养价值。因此,米面食品放凉后应加热后再吃。

多用佐料调味

  据一项抽查表明,胡椒、桂皮、花椒、丁香、小茴香、生姜等天然调味品中有一定的诱变性和毒性,如多用调味品,可导致人体细胞畸变,形成癌症,会给人带来口干、咽喉痛、精神不振、失眠等副作用,还会诱发高血压、胃肠炎等多种疾病。

吃豆制品越多越好

  营养学家提出,黄豆中蛋白质能阻碍人体对铁元素的吸收。过量摄入黄豆蛋白质可抑制正常铁吸收量的90%,从而出现缺铁性贫血,表现出不同程度的疲倦、嗜睡等贫血症状。所以吃豆制品不要过量,还是适量为好。

虾米直接煮汤喝

  虾米或虾皮在加工过程中容易染上一些致癌物,如直接煮汤喝,不利于人体健康。专家建议,可将虾米煮数分钟后再换水煮汤,或在汤中加1~2片维生素C,就能阻断致癌物在体内合成。

用生水冷却煮熟的鸡、鸭、鹅蛋

  将煮熟的鸡、鸭、鹅蛋浸在冷水中,蛋壳虽好剥,但病菌却仍有机可乘。如果要让蛋壳好剥,只需在煮蛋时加入少量食盐即可。

饭后马上吃水果

  水果中含有大量单糖类物质,若被饭菜堵塞在胃中,就会因腐败而形成胀气,导致胃部不适。所以,吃水果宜选择在饭前一小时或饭后二小时。

保持青春延缓衰老

如果你想保持青春防止疾病延缓衰老,还要设计科学的饮食方案:1、多吃水果蔬菜,至少每天吃五次各种各样的水果蔬菜,这样可以获得最多样的最大量的抗氧化 物;2、多吃鱼,每周至少吃两次,各种鱼对人体健康都有益,鱼肉中含有抗衰老作用的Ω- 3脂肪酸; 3、喝绿茶,绿茶中含有大量的抗氧化物;4、多吃豆制品,每周至少吃2-3次,大豆中含有多种抗氧化物,能够预防某些癌症;5、限制卡里路的摄入,保持一 个低于正常水平的体重,就能使你保持青春延长寿命的机会大大增加;6、少吃不良类型的脂肪如肉类和乳制品中的脂肪,还有一些被加工过氧化的植物油;7、少 吃肉;8、戒烟限酒,要坚决戒烟,烟可以使你体内产生大量的氧自由基,并有多种致癌物。如果非要喝酒就喝葡萄酒,每天饮一两杯;9、少吃甜食,不要食用过 量的糖,和其它碳水化合物,包括果糖,体内糖含量多会升高血液中胰岛素,破坏动脉并可能促进癌症发生和其他衰老疾病的发生;10、多吃大蒜,它是最古老的 抗衰老明星,是各种抗氧化物最古老的载体,大量的对动物和对人类的实验研究证明:大蒜可以预防癌症,动脉栓塞和由于衰老引起的大脑功能退化,每天吃一头生 蒜或煮过的大蒜是最合适的抗老化剂量。

最后,为了使人类保持青春,健康长寿,我们还要保护环境,减少形形色色的污染。克服生活中的不良习惯,如暴饮暴食、熬夜打牌、起居无常、不吃经过精细加工 的"垃圾食品"。每天还要做一些适合自己的运动,但不要超量,运动量过大是有害的。另外还要有一个良好的心态,做自己有兴趣想做的事,多交友,保持心情平 静不动怒。

星期四, 十月 07, 2004

A Beginner's Guide to Creating a MMORPG

This article will focus on the first steps in building your own Massive Multiplayer Online Role Playing Games (MMORPG). It's target is the indie game developer, with limited resources and experience. After reading this article, you should know what it takes to get started, and some advises regarding what to do and what not to do. The very first step is to assess your skills, and your resources. You need to be honest with yourself, because it can be frustrating to waste your time trying to build something you just can't.

Step one: Assessing your skills

Required Skills:

  1. Know at least one programming language. So far, C++ is the most popular choice among game developers due to efficiency and performance advantages. Visual Basic, Java or C# might do the job as well.

  2. Become familiar with a graphic library. Popular choices are SDL, OpenGL, or DX/D3D.
  3. Choose the network library to utilize. You can chose between WinSock, SDL_net, or DirectPlay.

  4. Have general experience in game programming. For example, the events loop, multithreading, GUI design, etc.

Highly Recommended Skills:

  1. Client/Server communication and architecture.
  2. Multiplatform programming. You might want to design your MMORPG, and especially the server such that it can run on multiple OSs. For this purpose, I recommend using SDL, OpenGL and SDL_net.

  3. Web development. This will be needed if you want to enable people to view player statistics, server information, and other information on a website.
  4. Security & Administration. You don't want someone to hack your server, and mess around!
  5. Team skills. You will need a team that you can successfully lead and manage.

Step Two: Making a preliminary design

I have noticed many people posting in various forums looking for teams to make MMORPGs. Most of them start with something like this: "We are a starting company/game studio and we need 3 artists, 2 programmers, 1 musician, etc. for an innovative, never seen before MMORPG where you will have total freedom to do whatever you want and reshape the world, etc. We will pay you when it's done and we make some money." Unfortunately, with the current technology and limited bandwidth, you cannot have a dynamic world. Aiming at something impossible leads to failure. Rather, try to come up with a small, functional, expandable design and architecture.

Basic software architecture

First, try to focus on making a simple client/server model, where you will be able to:
  1. Create a new character
  2. Save that character (server side)
  3. Log in with the character
  4. Be able to chat with others
  5. Be able to navigate around in 3D
Saving characters might seem simple, but in fact, it isn't. For example, there are two ways of saving the characters: using a database server or using files. There are advantages and disadvantages for both:


Databases Files
Advantages
  • You can easily add new fields, or modify existing fields.
  • Updating player statistics (from outside the game) is much easier.
  • You can instantly and efficiently retrieve various statistics, via SQL queries.
  • There is no need to perform file I/O operations yourself, the database server will do that for you.

  • Easy to update/restore.
  • Very fast access (read/write).
  • Easy to implement.
  • No additional libraries needed.
  • No dependence on a database server. Therefore, you don't have to worry about getting database updates or security issues.

Disadvantages
  • Easy to make mistakes. For example, doing an update query where you omit the 'where' clause. It can have disastrous effects, especially if you have old (or no) backups.
  • Databases may be slower than actually opening/writing a player file. You might lose a few milliseconds when retrieving some data, especially if a lot of players log in/out at the same time.
  • Additional code is required to convert your data to/from the database.
  • Database and SQL experience is required. In addition, you will need a library to interface between your program and the database.
  • If for some reason the database file becomes corrupt, you are out of luck; you can lose all the players (especially if no recent backups).
  • It can be very difficult to add new fields, unless you carefully design the file format/structure from the beginning.
  • Inability to do player-wide queries (this can be circumvented by having a program that adds every night the important fields in a database server).
  • Needs special coding if you want to update/check player stats.

  • A little bit harder to update/restore.

Now that you decided which way to go about saving your characters, you'll need to chose what network protocol to use for the client/server communication: TCP or UDP? TCP is known to be slower but more accurate, and require additional bandwidth. In practice, I didn't notice any problem using TCP. Provided that you have enough bandwidth available, TCP is a good choice, at least for the beginning. UDP can be really annoying, especially for beginners. Keep in mind that the preliminary tests of the engine or game will be done in your local network, so all the packets will arrive to the destination in the same order. This can't be guaranteed over the Internet. While the packets will usually arrive in the same order, some packets can be lost, and this is usually a problem. Of course, you can design your protocols in way so that the client/server will be able to recover from lost packets. But this is a painful process which is not recommended for beginner.

Step Three: Choosing an internal protocol for data transmission

It might seem simple, but, again, it isn't. You can't just send strings, '\0' terminated. This is because you will need a consistent protocol, which will be able to send both strings and binary data. It is unwise to use 0 (or any other sequence) as a terminator, because that terminator can be part of the data stream you want to send. Furthermore, if you send 20 bytes, and then another 20 bytes, most likely the server will not receive a 20 bytes packet, then another 20 bytes packet. Instead, it will receive 40 bytes at once, to avoid wasting the bandwidth with unnecessary headers. Alternatively, you can send a 1KB packet, but the server will receive it in 2 smaller packets. So you will need to be able to know where a packet starts, and where it ends. In Eternal Lands, we use the following method:

  • Offset 0: 1 byte denoting the command transmitted.
  • Offset 1: 2 bytes, the length of the data transmitted.
  • Offset 3: variable length, the body of the message.

This method has the advantage of consistency: all the data transmitted follows the same standard. The disadvantage is that some commands have a fixed, known length, so some bandwidth is wasted. We will eventually switch to a hybrid approach, at a later date.

The next thing to decide is the server model: "Non-blocking sockets, non threaded", or "blocking sockets, threaded". Both methods (threaded vs. unthreaded) have their advantages and disadvantages.

Threaded:

  1. Somewhat smoother response from the server, since if a player needs a lot of time (such as reading data from the database) this is done on it's own threaded, not affecting others.
  2. Very hard to debug, and implement properly: You will need a lot of synchronization, and small oversights can have disastrous effects (server crashing, item duplication, etc.)
  3. Makes use of multiprocessors systems.
Non-threaded:
  1. Much easier to implement and debug.
  2. Slower response time.

In my company, we went for the non threaded way, because I just don't have the resources and disposition to cope with the threaded.

Step Four: The Client

Do you plan to make a 2D or 3D game? Some would argue that it's easier to make a 2D game. I've done both, and I tend to believe that 3D is easier. Allow me to explain.

In 2D, you usually have a frame buffer, which is a big array of pixels. The format of those pixels can differ, from video card to video card. Some have RGB modes, other have BGR modes, etc. The number of bits for each color can differ as well. This happens only for 16bpp video modes. 8-bit and 24-bit video modes are easier, but with their problems (8-bits gives you few colors (256), while 24-bit modes are slower). Also, you will need to make your sprite routines, and you have to sort your objects yourself, so they will be drawn in the right order. Of course, you can use OpenGL or D3D for 2D games, but it's usually not worth it. Not everyone has a 3D accelerated video card, so using a 3D library for a 2D game usually gives you the disadvantages of both worlds: Not everyone will be able to play it, and you won't be able to rotate the camera, have nice shadows, and various other eye candies specific to the 3D applications.

The 3D way is, like I said, easier, but requires some basic math (especially trigonometry) knowledge. Today's graphic libraries are very powerful, and will offer you the basic operations for free (you won't need to sort your objects back to front, changing the colors and/or texture of an object is very easy, the objects will be lit according to the light and their position (as long as you calculate the normal vectors for them), and more. Furthermore, 3D gives you much more freedom of creation and movement. The disadvantages are that not everyone will be able to play your game (you might be surprised how many people don't have 3D capable cards), and pre-rendered graphics will always look better than the real-time rendered equivalent.

Step Five: Security

Obviously, the users cannot be trusted. Under no circumstances can you assume that the users will not be able to defeat your cleverly-designed encryption scheme (if you use one), or your protocols. Everything the user sends to the server has to be validated. Most likely, on your server, you will have fixed buffers. For example, it is common to have a small (maybe 4K) buffer for the incoming data (from the sockets). A malicious user can send a really long data sequence. If not checked, this will overflow the buffer, resulting in a server crash, or, worse, the user being able to hack your server, executing arbitrary code. Every single message has to be checked: whether buffer overflow occurred, whether invalid data was sent (such as users sending "enter this door" even though the door is at the other end of the map, or "use the healing potion" although the user has no such potions, etc.). I will say it again: It is extremely important to validate all the data. Whenever there is a violation, log it along with the username, IP, time and date, and the nature of the violation. Every once in a while, check that log. If you find few violations from many users, this is usually a bug in the client, or a network problem. However, if you find a lot of violations from the same user or IP, this is a good indication that someone is toying with the server, trying either to hack it, or running a macro/script. Also, never store data on the client. The client should receive it's data from the server. In other words, It should not send things such as: "Ok, this is my list of items" or "my strength is 10, my mana is 200, and my life is 2000 out of 2000". Also, the client should not receive more data than it needs. For example, the client should not know where other players are, except if they are nearby. This is common sense, since sending all the players to everyone will consume a lot of bandwidth, and some players might hack the client to give themselves unfair advantages (like having the position of certain player displayed on a map). All this seems common sense, but, again, you'd be surprised to find out how many people do not possess what we call common sense.

Other things to consider, when it comes to security: The player walk speed should be enforced on the server, not on the client. The server should keep track of the time (in milliseconds) when a client last moved, and if a move request comes faster than the normal threshold, this request should be discarded. Do not log such bogus requests, because they can result in network latency (i.e. the player lags, and all the data he sent in the last 10 seconds comes at once).

Check the Distance. If a player attempts to trade with another player that is 10 billion kilometres away (or even on another map) log that. If a player attempts to look at, or use a map object that is far away, log that. Be careful for bogus IDs. For example, it's normal to assign an ID to every player (the ID can be assigned when they log in, or it can be permanent (unique ID). If the ID is given when the player logs in (or when a monster is created), it makes sense to use the position (index) in the players array (where that player is) as the ID.

So the first player that logs in has ID 0, the second has ID 1, and so on. Now, most likely you will have a limit of, say, 2000 indexes in that player list. So if a client sends a command such as: "look at actor with ID 200000" this will crash the server if unguarded since the server will attempt to access an invalid memory. So do a check such as: "if actor id<0> max players then log the violation and disconnect the player". If you program in C or C++, take care to either define the index as 'unsigned int' and check for the upper range, or if for some reason you define the index as int (int, by default is signed), remember to check against <0>max actor. Failure to do so will result in a lot of frustration both for you and the other users. Similarly, check for out-of-map coordinates. If you have some form of path finding on your server, and the clients move by clicking on a position on the ground, make sure they do not click outside of the map.

Step Six: Getting a team

Making a game is a lot of work (except for Pong and Tetris). This is especially true for MMORPG. You simply can't do it all by yourself. Ideally, an indie team should be comprised of:

  • At least 3 Programmers: 1 for the server, and 2 for the client (or 1 for the client, one for the tools, such as plug-ins for the artists, a world editor, etc.). Having up to 6 programmers is good, more than 6 might be too much. It really depends on your leadership abilities. At the very least 1 artist, but preferably 2 or 3. If it's a 3D game you will need a 3D artist, a 2D artist (textures, interface, etc.), an animator, and an art department leader. Unless you are a good artist, the art department needs to be kept together and coordinated by an experienced artist.
  • A few world builders: Building all your maps is a very long process, and it's critical to the game's success. Again, you will need a leader for the world building department. You can't just have anyone making whatever the hell they want since your world design should be consistent.
  • A webmaster is a must, unless you are really good at web design, and are willing to spend your time making a website. Having a sound and musician is not required, but a game with sound and music can be more enjoyable than a game without it.
  • A designer of the game's economy. You might think that this is easy, and you can do it all yourself, but in fact it is one of the most complicated things. If your economy is poorly designed (i.e. items not properly balanced, resources put randomly on the maps, etc.) the players will get bored/frustrated and will quit. We had a big problem in one of our early stages, especially because the economy was mainly made by me (a programmer), and it wasn't properly planned. So it took us about 2 months to rethink and re-implement an entire new economy system. This also required a total elimination of the items. Let me tell you, players are usually unhappy when you delete all their items. Fortunately, most of our players agreed with the idea, but it was still frustrating to spend so many hours arguing, compromising, explaining, and, in general, wasting time. But more on the economy later.

As mentioned previously, you will need a 10-15 people for a team, not including the moderators and admins. Those 10-15 people should also have previous experience in their field. If they are all beginners it's usually not worth it, since you will need to spend too much time explaining to them what to do, how to do something, why the way they are doing it is bad, etc.

Getting 10-15 people from the beginning is pretty close to impossible. No matter how much you will post on various forums, you will not get quality team members. After all, if someone is pretty skilled in his/her field, why would s/he join your team, when you have nothing to show? Many people have great ideas, but implementing them takes a lot of time and effort, so they would rather work at their own projects than join yours. So if you need 10-15 people, but you can't get them join your team, how can you ever make a MMORPG? Well, in reality, you won't need all of them from the start. What you really need is 1 programmer and 1 artist. If you are a programmer, just get an artist. Beg a friend with art skills, pay a colleague/friend of yours for some art or whatever works for you.

Now that you have an artist, and hopefully an idea on how the game should look like, it's time to start implementing the idea. Once you will have a semi working client/server engine, and some screenshots to show (or even better, the ability for players to actually log in to your world, walk around, and chat with each other), more people will be willing to join your team. Preferably, unless you brave some technology that no one has, you should make your client open source. Many programmers would join (as volunteers) an open source project, rather than a closed source project. The server, on the other hand, should be closed source (unless you plan from the beginning to make a totally open source MMORPG).

Some other advice: Do not brag about your game until you have something to show. One of the most annoying things ever is when a newbie posts a "help wanted" request, asking for a huge team to join his game, explaining how cool the game is. Once you go to the website advertised (usually on a free hosting service) you will see an impressive navigation menu, containing sections such as: "Download", "Screenshots", "Concept art", "Forums". You click on the Download link, and you get a nice "under construction" page (or, worse, a 404 error). Then you click on the Screenshots page, and you get the same result. If you don't have anything for download, then do not put a download link. If you have no screenshots to show, do not put a screenshots link. Better yet, do not even waste your time with a website until you are at least 10% into the project (programming and art wise).

Step Seven: Dispelling some myths

  1. You can't make an MMORPG, it takes a big company to build one.
    I disagree with that. While producing a game such as World of Warcraft, Ever Quest 2, Asheron's Call 2, Lineage 2, and others is impossible for a small, independent development team, making a decent game is possible, provided that you have the experience, motivation and time. You will need at least 1000 hours of programming to have a simple tech demo going, and perhaps up to 10-15K hours of programming to have an almost complete client/server. But as the team leader you'll have to do much more than just programming. Keeping the team together, solving conflicts, doing public relations (PR), tech support, setting up servers, banning troublemakers, brainstorming, etc. will be your attributions. So you will be swamped with non-programming tasks as well. Then you will most likely need to go to work/school, which shortens the time you can dedicate to your project. We are very lucky that no team member left the team, but if this happens it can really be a problem. Just imagine your artist leaves halfway through the project. And even worse, s/he doesn't give you permission to use his/her art anymore. Of course, this can be solved by having them sign a contract, but it would still tiresome to have to get another artist. Having two different art styles in the same project can be a problem.
  2. Large amounts of money (usually 4-6 digits) is required to maintain an MMORPG server.
    Well, this is simply not true. I've seen dedicated servers, with 1000 GB/month for ~100 USD/month (and a 2-300 USD setup fee). Unless your data transfer protocol is very poorly designed, 1000 GB/month should be enough for a server with a 1000 players online (on average). Of course, you will need another server to keep your website and the client download (the client download can get a lot of traffic, once the game becomes popular). Our client is about 22MB, and sometimes we have a 400 GB/month transfer. And we are not even that popular (yet). Another thing is, you won't need a dedicated server to start this project. A DSL/cable server can do it's job pretty well, until you get 20-30 people online at the same time. Then either find a friendly hosting company to host it for free, in exchange for some advertising, or just pay from your own pocket.

  3. Making an MMORPG is very fun.
    This is not true. You might think that everyone will appreciate you, that the players will be supportive, that you can make very innovative quests, and, of course, have a lot of players playing your game. Players could be annoying. Even if it is a totally free game, they will find reasons to complain. What's worse is people will often complain about contradictory things. The fighters will not like the fact that it's too hard to gain levels, while the merchants will be very disappointed that the fighters make too much money from loots. If you decrease the monster drops, some people will threaten to quit the game. If you increase it, the same people will not like the fact that now even beginners can make money easily. Letting it as is, isn't good either. There has to be some innovation and improvements. If you decide to change something, for instance adding some new challenges to those who manufacture items, some will say it's too hard. If you don't, they will say it's too easy or plain boring. You might notice that the content players will usually not say anything and be satisfied, while the disrupting people will complain the most.

The economy is an MMORPG is far harder to balance than the single player equivalent. In a single player game, you can have gradually improved weapons, so as the player advances s/he can afford better equipment, abandoning (or selling) the old. In a multiplayer game, on the other hand, this is concept fails since everyone will attempt to get the best weapon, skipping the low-level weapons. Most of the players would rather use no weapon and just save until they can afford the best possible weapon in the game. Economy design deserves it's own article.

All the things I enumerated so far, coupled with the extra work and challenges should make you think at least twice before deciding to engage in such an impressive project. You must understand the implications of your decision.

Conclusion

Hopefully this article gave you the insight you needed. My next article will be on how to set up an economy (more specifically, what mistakes to avoid), and some information about debugging a server and a client.

About the Author

This article was written by Radu Privantu, lead programmer and project leader for Eternal Lands www.eternal-lands.com, a free, open source client MMORPG. I can be contacted at chaos_rift at yahoo dot com

Perl 和网格基础设施

Martin C. Brown (questions@mcslp.com)
自由作家,Studio B
2004 年 4 月

不管您是要开发一个独立的网格,或是只想为现有的网格提供一个接口,Perl 都可以提供帮助。通过其可扩展的体系结构和对构成现代网格的众多协议和系统的支持,无论是在提交阶段还是在计算阶段,Perl 都是理想的候选者。

Perl 仍然是现有最流行和使用最多的通用脚本语言。它对于 Web 的关照仍然是其最大卖点之一,您可以利用这一点以及其他一些功能增强 ?? 如跨平台支持、众多数据库服务和连接选项 ?? 帮助构建网格服务。

在本文中,我分析 Perl 作为 Web 服务平台的机制,如果想将 Perl 集成到基于 OGSI 的网格应用程序和服务中,这是重要的一步,其中包括了对一些支持通信工具、数据库工具程序和 Web 界面组件的分析。

Perl,灵活的朋友
当您想要构建或者开发网格时,首先会选择哪种语言呢?

各 种选择太多了,从像 Pascal、C 和 C++ 这样的编译语言到 “实时(just-in-time)”的、基于字节的开发语言如 Java 语言。不过在网格中,通常最大的要求是语言要有灵活性,同时又有足够的实用性,使它可以用于不同的目的,而不会受到大的限制。

这种语言还应该具有可用性 ?? 就是说,容易使用和用它开发应用程序,这样就可以迅速和容易地延伸和扩展网格。可用性还使开发基于网格基础设施的新应用程序更容易,这在使用计算网格时特别重要,在那里您可能需要开发自定义的计算组件以处理进程。

最后,也是最重要的,如果希望支持异质的网格,那么这种语言就需要支持尽可能多的操作系统并提供平台独立的代码,这样才可以容易地部署网格应用程序。

所 有这些灵活性都指向一种脚本语言,不错,就是 Perl。从老的 Digital VAX 系统到 DOS、Windows、Unix、Mac OS 和许多其他操作系统都支持 Perl。除了容易使用外,特别是在开发应用程序时,Perl 的一个最强大的功能是它可以与另一种语言通信(主要是 C)。这使它除了在系统中构建的所有功能和通过 Perl 自己基于模块的扩展系统所支持的功能外,还可以使用范围广泛的外部工具和库。Comprehensive Perl Archive Network(CPAN,一个现成的模块和 Perl 语言扩展集合)使 Perl 特别有用和容易使用。它们是用户贡献的语言扩展,或者是完全用 Perl 编写的,或者是用 C 接口 连接到外部库。

CPAN 文档包括从 Postscript 驱动和 Web 界面构造器到数据库接口和 XML 解析器和处理器的所有内容。可以使用其中许多模块帮助构建网格应用程序,或者使用合适的扩展连接现有的网格环境,如 Globus。

通信工具
网格组件需要彼此通信以进行操作,这样拥有在不同的组件之间进行通信的方法就很关键了。有几种方法可以在计算机之间进行网格目的的通信。

直接的 TCP/IP 通信是可以使用的最基本的系统,在某些方面,它既是最灵活的,也是最难于有效使用的。IO::Socket 工具包提供了到基本 TCP/IP 套接字的最好接口。要处理多连接,您可以使用 fork()select() 或者 threads(在支持它的系统上),或者更简单的循环(round-robin)解决方案。

对 于具有容易使用和灵活的客户机/服务器结构的跨平台兼容解决方案,选择 POE(Perl 对象环境,Perl Object Environment)就对了。POE 是多任务网络框架,它支持基于服务器或者客户机的多连接,然后利用事件驱动的接口处理双向的信息传输。例如,下面是一个简单的服务器,它使用函数处理事 件:




use POE;



sub handler_start

{

...

}



sub handler_increment

{

...

}



sub handler_stop

{

...

}



for (0..9) {

POE::Session->create(

inline_states =>

{ _start => \&handler_start,

_stop => \&handler_stop,

}

);

}



$poe_kernel->run();

exit;

不过,如果准备使用事件驱动的环境,那么 Web 服务是更有效的解决方案,在范围更广泛的网格应用程序中,它们还有其他的好处。

Web 服务
Web 服务证明是许多网格解决方案的基础和未来。例如,Globus 和 OGSA/OGSI 标准就是基于 Web 服务平台的。其原因不难看出。Web 服务提供了主机之间透明和灵活的通信,对远程主机上的过程或者函数的调用就像调用的是本地过程或者函数。

Perl 提供了各种基于两个主要标准(SOAP 和 XML-RPC)的 Web 服务实现。OGSI 标准使用 SOAP 标准,它优于 XML-RPC 的一点是它让您除了可以使用远程过程调用之外,还可以使用远程对象。

在 Perl 中最好的 SOAP 支持模块是 SOAP::Lite。可以在 Perl 中用下面的代码创建一个基本的 SOAP 服务器:




use SOAP::Transport::HTTP;

SOAP::Transport::HTTP::CGI

->dispatch_to('/export/http/webs/grid/','DWGrid::Demo')

->handle();

您需要将它拷贝到一个脚本中 ?? 如 request.cgi ?? 并宿主到一个现有的 Web 服务器如 Apache 或者 IIS 中。这个脚本使用 CGI(通过 SOAP::Transport::HTTP::CGI 包)创建一个 Web 服务,作为请求进行传输。所有到远程脚本的 SOAP 请求都发送对这个类的一个 SOAP 函数和/或包 DWGrid::Demo 的请求。这个模块应当包含所要支持的函数的定义,包括类和对象方法,如构造函数和属性处理器。

对于独立的 SOAP 服务器,使用 SOAP::Transport::HTTP::Daemon 模块作为基础。如果需要加快 Web 服务的响应,可以用另一个传输模块 SOAP::Transport::HTTP::Apache 通过 mod_perl 实现。

在客户端,可以直接或者自动调用远程函数。直接方法像下面这样:




use SOAP::Lite;

print SOAP::Lite

->uri('http://test.mcslp.pri/SOAP/Demo')

->proxy('http://test.mcslp.pri/SOAP/request.cgi')

->getmessage()

->result;

上面的代码通过服务器上的 SOAP 调用远程函数 getmessage()。还可以使用 autodispatch 方法,它使您可以透明地使用远程函数,而不用通过服务器显式命名它们。例如,可以用下面的脚本调用同一个函数:




use SOAP::Lite +autodispatch =>

uri => 'http://test.mcslp.pri/SOAP/Demo',

proxy => 'http://test.mcslp.pri/SOAP/request.cgi';



print getmessage();

SOAP 真正强大之处在于创建远程对象并与之交互的能力。在网格中,可以将它与定义网格应用程序的类结合使用。发布网格应用程序时,可以将这个模块拷贝到不同的提 供者上。当作业到达分发者(distributor)时,可以创建一个新的网格对象,提供必要的参数并得到结果。因为对象是持久性的,所以您可以使用有状 态或者基于会话的网格应用程序。

例如,可以在需要状态信息的解决方案 ?? 如数据库处理 ?? 或者提供持久性存储或者到信息和其他系统的接口的解决方案中使用 SOAP。它们还可用于计算系统需要复合计算,同时不需要发送更多信息的地方。例如,视频编码通常使用来自上一帧的信息。交换像这样的大量信息会对网格的 网络造成严重影响,特别是当它跨越了局域网的边界时。

在像资源或者应用程序网格这样需要从网格提供者得到立即答复和响应的直接访问网格中,可以让网格对象在分发者上保持活动以便在需要时重复使用。

下面的脚本是一个典型分发者的例子(有删节),在基于对象的、分发者引导的网格应用程序中使用了 SOAP :




use DWGrid;



use SOAP::Lite +autodispatch =>

uri => 'http://test.mchome.com/SOAP/DWGrid',

proxy => 'http://test.mchome.com/SOAP/provider.cgi';



my $providers = get_providers();



for my $providerid (keys %{$providers})

{

$providers->{$providerid}->{'remote'} = DWGrid->new('DWGrid::Resource');

}



while(1)

{

my $requests = list_queue('requests');

for my $reqid (keys %{$requests})

{

for $providerid (keys %{$providers})

{

...

$providers->{$providerid}->{'remote'}

->store_document($requests->{$reqid});

...

}

}

...

}

可以看到,这里我是如何创建一个简单的、基于散列的结构来保持对提供者上的远程 SOAP 对象的引用。然后我可以直接调用提供者上的这个函数,无需再次打开连接。

OGSI::Lite
作 为 Perl 灵活性以及它适于集成到网格中的一个例子,只需要看看 OGSI::Lite 包就够了。OGSI::Lite 是一个网格服务的容器,使服务可以用 Perl 编写。使用 OGSI::Lite 时,通过创建一个继承标准 OGSI 类的类可以将 Perl 类导出为网格服务。与服务的通信是由您在前面的例子中看到的 SOAP::Lite 包处理的。

关于 OGSI::Lite 和已经用于 lattice Boltzmann 计算的网格服务(它们都是用 Perl 编写的)的更多信息请参阅 参考资料

Perl 和 Globus
Globus 是各种网格解决方案中最流行一种,它有一个 Perl Commodity Grid(CoG) 工具包使您可以用 Perl 作为网格中的服务或者管理组件。这适用于大多数 Globus 2.x 版本。对于 Globus 3.0 及以后的版本,应当使用 OGSI::Lite 包,因为 Globus 3.0 是 OGSI 兼容的。

数据管理
在 所有网格应用程序的背后,是一个提供信息中其他内容的可靠数据库系统。对于计算网格,数据库存储了未处理的工作单元和返回的结果。Perl 在这里(通过标准模块选择和 CPAN)提供了不同的解决方案,包括在磁盘解决方案中使用了基本的基于文件的系统或者 DBM 风格的散列。

数 据库接口(Database Interface,DBI)工具包通过用数据库驱动(DBD)连接到各个数据库提供了架构中立的解决方案。到底层数据库的接口可能是不同的,但是 DBI 模块提供了不变的接口(幸运的是大多数使用 SQL)。这意味着您可以在需要时和环境改变时改变数据库,同时不用对代码做大幅度修改。

独立的驱动程序系统使您可以用使用像 MySQL 和 PostGreSQL 这样的开放源代码解决方案,也可以使用像 Oracle 和 DB2 这样的商业软件,都通过相同的接口。

这 些接口可以在本地工作,也可以通过网络工作,这样就可以用这个系统使提供者访问远程数据库解决方案以下载工作和数据。因为有了对多种数据库的支持,所以可 以让网格应用程序分布在有一个数据库或者多个数据库源的网格上,也可以分布在网格的网格(支持几个独立的网格作为一个网格服务器集合的一部分)上, 其中不同的网格组使用不同的数据源。

如果希望一个本地化的解决方案,比如在一个不想安装全功能的数据库解决方案中,或者提供 对这样的数据库的远程访问的网格提供者上安装一个 '轻量级' 数据库实现,那么可以使用 DBD::CSV 驱动。这个模块使用简单的逗号分隔(CSV)文件,同时支持用 SQL 语言访问。可以创建数据库,更新记录并管理数据,就像使用一个典型的 RDBMS 一样,但是使用的是基本文本文件并且不需要外部应用程序。

Web 界面
网格开发语言的最后一项考虑是它在系统中的整体效果和使用性。所有网格都需要管理。需要一种向网格提交工作和信息的方法和在网格运行时管理及监视网格项目和信息的方法。

有大量完成这些任务的方法,但是一个突出的方法是使用 Web 站点作为监视和管理解决方案。同样,Perl 得分最高。它有支持动态 Web 网站和界面的长期历史,在 Web 上有很多动态内容是通过 Perl 支持的。

用同样的工具提供 Web 界面和管理网格使得将这两个系统集成到一起变得容易了。即使不是整个系统都使用 Perl,而是使用像 SOAP、XML-RPC 或者 C 扩展接口这样的工具,也可以用 Perl 作为到网格服务的接口。

结束语
在 本文中我们分析了典型网格的一些最常见的部分,以及 Perl 如何通过结合内置模块、系统和来自 CPAN 和其他地方的外部模块提供对这些元素的支持。这些主要内容包括数据库的使用、网格管理的 Web 界面和通信。最新的网格现在依靠 Web 服务体系结构,因此有必要了解用 Perl 编写的 SOAP 实现,以及其他机构是如何在现有网格环境如 Globus 和 OGSI 兼容的网格框架中使用 SOAP 系统的。

参考资料

关于作者
Martin C. Brown, Studio B 的作者,以前是一位具有跨平台集成经验的 IT 主管。他是一个目光敏锐的开发人员,曾经为一些重要客户构建动态站点,他是 Foodware.net 的技术主管。现在,MC 是一位自由作家和顾问,由于他的名气,他作为一个 SME 与 Microsoft 紧密合作;同时也是 LinuxWorld 杂志的 LAMP Technologies Editor;还是 AnswerSquad.com 团队的核心成员;他曾经编写的书籍包括 XML Processing with Perl、Python and PHP、Microsoft IIS 6 Delta Guide 等。可以通过 questions@mcslp.com 与 MC 联系。

经 典 进 程 通信 问 题

2.4.1 哲 学 家 用餐 问 题
哲 学 家 就 餐 问 题 是 一 个 典 型 的 进 程 同 步 问 题 它 是 由 Dijkstra 提 出 并 解 决 的, 该 问 题 的 描 述 如 下:
有 五 个 哲 学 家, 他 们 的 生 活 是 交 替 地 进 行 思 考 和 就 餐。 哲 学 家 们 共 一 张 圆 桌, 周 围 放 有 五 张 椅 子, 每 人 坐 一 张。 在 圆 桌 上 有 五 个 碗 和 五 只 筷 子, 当 一 个 哲 学 家 思 考 时, 他 不 与 同 事 交 谈, 饥 饿 时 便 试 图 取 左、 右 最 靠 近 他 的 筷 子, 但 他 可 能 一 支 都 拿 不 到。 只 有 在 他 拿 到 两 支 筷 子 时 方 能 就 餐。 餐 毕, 放 下 筷 子 继 续 思 考。

一 个 简 单 的 解 法 是, 用 一 个 信 号 量 表 示 一 支 筷 子, 这 五 个 信 号 量 构 成 信 号 量 数 组, 其 描 述 为:
var chopstick: array[0...4] of semaphore;
所 有 信 号 量 被 初 始 化 为1 , 第i 个 哲 学 家 的 活 动 可 描 述 为:
repeat
P (chopstick[i]);
P (chopstick[ (i+1) mod 5 ] );
..........
eat;
..........
V (chopstick[i]);
V (chopstick[(i+1) mod 5]);
..........
think;
..........
until false;
虽 然 上 述 解 法 可 保 证 不 会 有 两 个 相 邻 的 哲 学 家 同 时 就 餐, 但 可 能 引 起 死 锁。 假 如 五 个 哲 学 家 同 时 饥 饿 而 拿 起 各 自 左 边 的 筷 子, 使 五 个 信 号 量 chopstick 均 为 0; 当 他 们 再 试 图 去 拿 右 边 的 筷 子 时, 他 们 都 无 限 期 地 等 待。 对 于 死 锁 问 题 可 采 取 这 样 几 种 解 决 方 法:
(1) 至 多 只 允 许 四 个 哲 学 家 同 时 就 餐, 以 保 证 至 少 有 一 个 哲 学 家 可 以 就 餐, 最 终 总 会 释 放 出 他 所 用 过 的 筷 子, 从 而 可 使 更 多 的 哲 学 家 就 餐;
(2) 仅 当 哲 学 家 的 左、 右 两 支 筷 子 均 可 用 时, 才 允 许 他 拿 起 筷 子 就 餐;
(3) 规 定 奇 数 号 哲 学 家 先 拿 起 其 左 边 筷 子, 然 后 再 去 拿 右 边 筷 子; 而 偶 数 号 哲 学 家 则 相 反。 按 此 规 定,1、2 号 哲 学 家 竞 争 1 号 筷 子,3、4 号 哲 学 家 竞 争 3 号 筷 子, 即 五 个 哲 学 家 都 先 竞 争 奇 数 号 筷 子, 获 得 后, 再 去 竞 争 偶 号 筷 子, 最 后 总 会 有 某 一 个 哲 学 家 能 获 得 两 支 筷 子 而 就 餐。
|Back to Top|
2.4.2 读者- 写 者 问 题 (Reader-Writers Problem)
一 个 数 据 文 件 或 记 录 ( 统 称 数 据 对 象 ), 可 被 多 个 进 程 共 享, 其 中 有 些 进 程 要 求 读, 而 另 一 些 进 程 要 求 写 或 修 改。 我 们 把 只 要 求 读 的 进 程 称 为“ 读 者”, 其 它 进 程 称 为 “ 写 者”。 允 许 多 个 读 者 同 时 读 一 个 共 享 对 象, 但 绝 不 允 许 一 个 写 者 和 其 它 进 程 ( 读 者 或 写 者 ) 同 时 访 问 共 享 对 象。 所 谓“ 读 者- 写 者 问 题”, 是 指 保 证 一 个 写 者 必 须 与 其 它 进 程 互 斥 地 访 问 共 享 对 象 的 同 步 问 题。 该 问 题 首 先 在 1971 年 由 Courtois 等 人 解 决, 此 后 读 者- 写 者 问 题 常 被 用 来 测 试 新 同 步 原 语。
利 用 信 号 量 机 制 解 决 读 者- 写 者 问 题
为 了 解 决 读 者- 写 者 问 题, 可 设 置 两 个 信 号 量:
(1) 读 互 斥 信 号 量 rmutex , 用 于 使 读 者 互 斥 地 访 问 共 享 变 量 readcount;
(2) 写 互 斥 信 号 量 wmutex, 用 于 实 现 一 个 写 者 与 其 它 读 者 和 写 者 互 斥 地 访 问 共 享 对 象。
读 者- 写 者 问 题 可 描 述 如 下:
var rmutex,wmutex: semaphore :=1,1;
readcount: integer: =0;
begin
parbegin
reader: begin
repeat
P(rmutex);
if readcount = 0 then (wmutex);
readcount := readcount+1;
V(rmutex);
...
Perform read operation
...
P(rmutex);
readcount := readcount -1;
if readcount = 0 then V(wmute);
V(rmutex);
until false;
end
Writer:begin
repeat
P(wmutex);
Perform Write operation;
V(wmutex);
until false;
end
parend
end
|Back to Top|
2.4.3 睡 着 的 理发 师 问 题 (The Sleeping Barber Problem)
睡 着 的 理 发 师 问 题 又 是 一 个 有 趣 的 进 程 同 步 问 题。
在 理 发 馆 中, 有 一 个 理 发 师, 一 张 理 发 椅 和 n 个 为 等 待 顾 客 所 设 的 椅 子。 如 果 没 有 顾 客 来, 理 发 师 就 会 坐 在 理 发 椅 上 睡 觉, 当 一 个 顾 客 来 到 时, 他 必 须 唤 醒 睡 着 了 的 理 发 师。 如 果 在 理 发 师 理 发 时, 又 有 别 的 顾 客 到 达, 他 们 要 么 坐 下 ( 如 果 有 空 的 椅 子 ), 要 么 离 开 ( 如 果 所 有 的 椅 子 都 被 坐 满)。
解 决 方 法 是 使 用 三 个 信 号 量:
1. customers , 用 于 记 录 等 候 的 顾 客 的 数 量。
2. barbers, 用 于 记 录 空 闲 理 发 师 的 数 量。
3. mutex, 用 于 进 程 之 间 的 互 斥。
另 外 还 需 使 用 一 个 变 量 waiting, 也 是 用 于记 录 等 候 的 顾 客 的 数 量。
例 程 如 下:
#include "prototypes.h"
#define CHAIRS 5 /*chairs for waiting customers */
typedef int semaphore; /* use your imagination */
semaphore customers = 0 ; /* # of customers waiting for service */
semaphore barbers=0; /* # of barbers waiting for customers */
semaphore mutex=1; /* for mutual exclusion */
int waiting = 0; /* customers are waiting (not being cut) */
   
void Barber(void)  
{while (TRUE){  

p(customers);

p(mutex);

waiting=waiting-1;

v(barbers);

v(mutex);

cut_hair();

/* go to sleep if # of customers is 0*/
/* acquire access to 'waiting' */
/* decrement count of waiting customers*/
/* one barber is now ready to cut hair */
/* release 'waiting' */
/* cut hair (outside critical region) */
}}  
   
Void Customer(void)  
{  
p(mutex); /* enter critical region */
if (waiting < CHAIRS) { /* if there are no freee chairs, leave */

waiting = waiting + 1;

v(customers);

v(mutex);

p(barbers);

get_haircut();

/* increment count of waiting customers */

/* wake up barber if necessary*/
/* release access to 'waiting'*/
/* go to sleep if # of free barbers 0 */
/* be seated and be served */
} else { v(mutex); /* shop is full, do not wait */
}}  

星期三, 十月 06, 2004

Unix中多程序间共享内存

http://www.ccw.com.cn 北京网擎科技 许杨春 (2001-04-19 15:15:09)
共享内存 (shared memory)是 Unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。本文介绍如何在 Client/Server方式下实现多个程序间共享内存。  
问题分析 
多个程序之间共享内存 ,首先要解决的问题是怎样让各个程序能够访问同一块内存和相同的信号量。共享内存的 id可以通过调用 shmget (key_t key, size_t size, int shmflg)函数取得;信号量的 id可以通过调用 semget(key_t key,  int nsems, int semflg)函数取得。实际上,只要在调用这两个函数时使用相同的 key值,各程序之间就能达到共享内存的目的。  Unix通过调用 key_t ftok(const char* path, int id)函数来产生 key值 ,如果各程序都用同样的参数来调用此函数,自然也就得到相同的 key值了。例子中各个程序都使用 key=ftok(" /", 0)得到相同的 key值 ,再进而由 key值得到相同的共享内存 id和信号量 id。  
第二个要解决的问题是如何控制多个程序并发访问共享内存。本文的例子模拟在 Client/Server方式下,由一个 Server产生数据,多个 Client去读取数据的操作。常规的方法是设一个信号量,将访问共享内存的程序作为临界区来处理。程序进入时用 p()操作取得锁,退出时用 v()操作释放锁。但这样做有两个问题:一是这样各个程序就处于平等的地位,而实际中往往 Server的优先级应该比 Client更高。比如,在股票行情应用程序中 ,共享内存里存放行情信息, Server负责定时更新; Client是 CGI程序,负责按客户要求读取共享内存中的数据,然后再反馈给客户。在这种情况下, Server就不能等所有 Client进程都读完了才开始写,因为这样 Client取得的数据反而是过时的。二是各个  Client之间由于都是读操作,所以没有必要互斥。  
本文对这两个问题的解决方案是:只有 Server进行 p()、 v()操作,信号量初始值设为 0, p()操作将它加一, v()操作将它减一; Client读共享内存之前要先等待信号量的值为 0,这样 Server的 p()操作总是成功,而 Server的 p()操作后,尚未进入临界区的 Client只能等到 Server执行 v()操作后才能读。这样 Server比 Client优先, Client之间不互斥。但这样又产生另一个问题:一个 Server开始写时,部分 Client可能已经进入临界区,有可能出现读不完整的问题。因此,例子基于这样一个前提:  Client程序比较简单,不会被阻塞,并且能够在一个时间片内执行完读取操作。本例中处于临界区中的 Client数目是有限的,如果 Server等待一个时间片 (例子中是等待一分钟 )后, Client就能全部退出临界区,这个问题就能排除。很多 CGI程序能够满足这个假设条件,如果  Client确实不满足条件,可以生成访问共享内存的子进程,它的执行时间应该满足上述要求。  
应用实例 
下面给出实现多程序间共享内存的例子程序的部分代码:  
1.Server端程序  
# define SEGSIZE 1024  
# define READTIME 1  
union semun {  
int val;  
struct semid_ds* buf;  
ushort_t* array;  
} ;  
//生成信号量  
int sem(key_t key){  
union semun sem ;  
int semid;  
sem.val=0;  
semid=semget(key,1,IPC_CREAT|0666);  
if (semid ==- 1){  
printf(" create semaphore error\n" );  
exit(- 1);  
}  
//初始化信号量  
semctl(semid,0,SETVAL,sem);  
return semid;  
}  
//删除信号量  
void d_sem(int semid){  
union semun sem ;  
sem.val=0;  
semctl(semid,0,IPC_RMID,0);  
}  
int p(int semid){  
struct sembuf sops={0,+ 1,IPC_NOWAIT};  
return(semop(semid,& sops,1));  
}  
int v(int semid){  
struct sembuf sops={0,- 1,IPC_NOWAIT};  
return(semop(semid,& sops,1));  
}  
int main(){  
key_t key;  
int shmid,semid;  
char* shm;  
char msg[7]=" data " ;  
char i;  
struct shmid_ds buf;  
key=ftok(" /" , 0);  
shmid=shmget(key,SEGSIZE,IPC_CREAT|0604);  
if(shmid ==- 1){  
printf(" create shared momery error\n" );  
return- 1;  
}  
shm=(char* )shmat(shmid,0,0);  
if((int)shm ==- 1){  
printf(" attach shared momery error\n" );  
return- 1;  
}  
semid=sem(key);  
for(i=0;i<=3;i++ ){  
sleep(1);  
p(semid);  
sleep(READTIME);  
msg[5]=' 0'+ i;  
memcpy(shm,msg,sizeof(msg));  
sleep(58);  
v(semid);  
}  
shmdt(shm);  
shmctl(shmid,IPC_RMID,& buf);  
d_sem(semid);  
return 0;  
}  
2.Client端程序# define SEGSIZE 1024  
union semun {  
int val;  
struct semid_ds* buf;  
ushort_t* array;  
} ;  
//打印程序执行时间  
void secondpass(){  
static long start=0;  
time_t timer;  
if (start == 0){  
timer=time(NULL);  
start=(long)timer;  
printf(" now start \n" );  
}  
printf(" second:% ld \n" ,(long)(time(NULL))- start);  
}  
int sem(key_t key){  
union semun sem ;  
int semid;  
sem.val=0;  
semid=semget(key,0,0);  
if (semid ==- 1){  
printf(" get semaphore error\n");  
exit(- 1);  
}  
return semid;  
}  
//等待信号量变成 0  
void waitv(int semid){  
struct sembuf sops={0,0,0};  
semop(semid,& sops,1);  
}  
int main(){  
key_t key;  
int shmid,semid;  
char* shm;  
char msg[100];  
int i;  
key=ftok(" /" , 0);  
shmid=shmget(key,SEGSIZE,0);  
if(shmid ==- 1){  
printf(" get shared momery error\n" );  
return- 1;  
}  
shm=(char* )shmat(shmid,0,0);  
if((int)shm ==- 1){  
printf(" attach shared momery error\n" );  
return- 1;  
}  
semid=sem(key);  
for(i=0;i< 3;i++ ){  
sleep(2);  
waitv(semid);  
printf(" the msg get is \n% s\n" ,shm+ 1);  
secondpass();  
}  
shmdt(shm);  
return 0;  
}  
本程序在 Solaris 7下编译通过。 

布鲁明顿的近照

Out side of circuitcity, Bloomington, Indiana

星期二, 十月 05, 2004

网格让利润增加7倍
作者: 转载自《每周电脑报》
Wednesday, March 31 2004 9:50 AM

在两年时间内,Butterfly.net公司利用传统的集中式服务器模型部署的一个大众在线游戏在2400万美元预订收益中产生了160万美元利润,而在基于网格的基础设施上提供同样的游戏却能产生1280万美元利润,利润增加7倍。同时,该系统支持的同时在线游戏人数由4000名增加到100万名。

网格的另一个关键操作优势是自恢复能力,这是其核心构架中自管理特性的一个副产品。在传统在线游戏模型中,服务器掉线对游戏人员通常意味着在此服务器上的游戏已经结束了。而网格的固有自恢复特性能无缝隙地将所玩的游戏转到最近的可用服务器上。对于游戏玩家来说,这意味着更满意的体验,没有了故障停机的沮丧。

重新定义 Butterfly.net公司是一家游戏基础设施提供商,它通过PC机、操纵台和移动设备将游戏人员连接起来。该公司成立于2000年,位于西弗吉尼亚州的Martinsburg和加里弗尼亚州的洛杉矶市,其客户包括美国、欧洲和太平洋地区的在线游戏开发商、发行商和服务提供商。

一次偶然的机会使Butterfly.net公司总裁David Levine意识到传统娱乐公园和在线游戏之间的相似性,即娱乐体验的总体质量通常成为其自身成功的受害者,最吸引人的游览路线总是参与人数最多并导致等待时间最长的那个线路;而最好的在线游戏能吸引最多的游戏人员,由此通常会降低在线游戏的性能。两者实际上都依赖“固定的”平台容量。在在线游戏中,游戏基础设施不灵活,游戏人员被分配给游戏网络中的某一服务器(通常最多有4000个用户)。另外一个缺点是游戏基础设施缺乏自恢复能力,不论是故障还是定期软件升级造成的服务器停止工作。

传统在线游戏基础设施对在线游戏的提供商也有一些不足,其中最主要的是需要保养和维护服务器基础设施并确保其安全。在线游戏提供商需要为基础设施投入巨大的前期投资,同时,市场推动需要合理地降低用户价格??“大众市场”价格,更增加了传统在线游戏业务模型的内在固有风险。这些因素也妨碍了游戏提供商投资提供在线游戏峰值时段所要求的容量,使网络性能下降和增加了故障停机时间。

如何使网络游戏真正地成为“大众"游戏, Levine的大致计划是创建一个可扩展、自恢复的在线游戏基础设施,它可以被租借给游戏公司。从功能上说,他的想法是利用先进的监视和路由选择技术,将与游戏有关的处理动态地分配到大量分布式、低成本服务器中。通过提供一种方法,在随需应变的基础上,将处理负载透明地转移到空闲资源上,这种平台将能消除现有游戏基础设施普遍存在的瓶颈和自恢复能力问题。Livine 的计划中所隐含的是让游戏人员与专用服务器脱钩,这将使他们实际上能在更广泛的范围内互动。

开始行动在2000年年中,Levine开始将计划付诸实施。他组织了一个技术专家小组,他们成为Butterfly.net公司的第一批员工。没有用多长时间,该小组就提出了一个计划,叫做“组播网格(multicast mesh)”,它是一系列相互集成的专用服务器,随着游戏范围的扩展,它能随需应变扩展。难度更大的任务是如何连接系统和不同协议之间的转换。为了在这方面以及更大的开发过程中获得帮助,Levine及其小组开始向Worldcom、惠普和IBM全球服务部招标。

到2001年底,Levine和他的小组决定使用网格计算技术来提升他们的游戏网络,这是因为之前IBM对其的指导和咨询。Livine指出选择IBM有很多因素,其中信任名列前茅。“我们的想法是,如果我们准备把整个公司的安危系于仍在婴儿阶段的网格技术的话,那么,我们需要与这样一家公司结成合作伙伴,他们能组织、集中并动用一切努力在网格计算领域取得成功。”

Levine还希望这家厂商能在一个解决方案中提供硬件、软件和服务等所有要素:在硬件方面,能提供包括专门的游戏服务器以及数据库服务器。同样,该系统也需要强大的数据库引擎来处理大量实时交易量。尽管系统在很大程度上将是自动的,它仍需要一种方法让“游戏主人”来跟踪和控制游戏领域的关键数据,如性格表现等。这一功能将由基于Java的应用服务器完成,它需要强大的现成能力并与解决方案的数据库密切紧密集成。另外一个关键因素是在所有产品中需要强大的 Linux支持。Butterfly.net决定采用Linux是由非常实际的考虑推动的,其中最重要的是Linux在游戏开发商中的强大吸引力。 Levine还指出:Linux稳定性的良好记录以及低成本也是决定其选择的关键因素。“光是考虑到在此构架中预计的机箱数量,我们就需要限制软件成本,并尽量提高平台的稳定性和性能,”Levine解释说:“我们看到满足所有这些的惟一实际选择是Linux。”

形成方案 Butterfly.net的解决方案叫做Butterfly网格,它由2个集群组成,每个集群由大约50台IBM eServer x系列服务器,服务器在弗吉尼亚州的Sterling和加里弗尼亚州的洛杉矶的托管设施上运行。根据它们在网格中的作用,这些服务器被分为游戏服务器、网关服务器、 精灵(Demon)控制器和数据库服务器4类。

Butterfly网格构架的特点是:服务器全部是网格状的,每个服务器通过高速光纤连接到所有其他服务器上。在游戏期间,各服务器将与(两个托管中心之间的)网格中的所有其他服务器实时通信,即组播。在这种等同联网方法中,游戏人员被透明地传输到网格中的最佳服务器上,这样,服务器资源将被分配给最普及的游戏上。这种网状拓扑和智能路由选择能力是网格自恢复能力、可扩展性和性能的核心。

软件实现在高层,网格的主要软件部件分为游戏专用软件(客户机级和服务器级)和基础设施软件(数据库)。这些部件通过Globus工具集中的一系列实用程序集成到网格机构中,Globus工具集完成对网格环境操作非常重要的3个基本功能。

资源管理功能 包含分配网格所提供的资源。关键实用程序包括Globus资源分配管理器(GRAM)和Globus访问辅助存储器(GASS),前者将游戏资源分配到特定服务器上,后者简化移植和运行应用(如游戏等)。

信息服务功能 它提供有关网格资源的信息。关键实用程序包括元计算目录服务(MDS),它作为目录系统,记录哪个游戏资源在哪个服务器上,并提供服务器配置、能力和状态信息。根据轻型路由访问协议(LDAP),MDS是根据基础系统优化应用程序性能的关键。

数据管理功能 包括在网格环境中访问和管理数据。网格的最终软件要素是支持游戏管理员(如:游戏主人)所需的应用服务器软件。如前面所述,游戏主人的关键功能是给某一游戏引入新的要素或改变游戏中现有角色的行为。为了做到这一点。游戏主人需要一种有效的方法来在网格服务器上跟踪和修改必要的数据库要素。Butterfly网格通过WebSphere应用服务器servlet完成这一功能,后者在后台运行,按不同时间间隔自动读取服务器日志文件和活动。要想改变游戏要素,游戏主人通过Java远程程序调用操纵数据库,调用命令是通过在WebSphere应用服务器上运行的管理门户发出的。

Butterfly网格定义的网络安全特性是使用网络边缘防火墙后的专用操作系统。为了在网络中实现安全鉴别和通信,Butterfly网格采用了新出现的开放网格服务构架的核心安全特性,这一构架嵌入在Globus工具集中,统称为网格基础设施(GSI)。在Butterfly网格中,在路线优化过程中或用户玩游戏过程中,当游戏人员在服务器之间移动时,鉴别问题非常重要。为了方便这一点,Butterfly网格利用了GSI的通用安全服务,这是一个基于令牌环的公钥加密系统。网络安全基础设施的另一个关键方面是它使用了网络地址翻译,网络在其自己的专用IP地址空间内工作。它将内部地址对外隐藏起来,这实际上是提供了一道防火墙。Butterfly网格还使用了GSI的单一登录能力,考虑到用户需要访问网格中的多个资源,这一点是非常重要的。

Butterfly网格的基本构架
构架层次 解决方案要素
最终用户 游戏人员在DVD、CD-ROM通过下载购买"大众多用户" 游戏。该游戏包括Butterfly网格客户机软件。
管理门户 要想改变游戏要素,游戏主人通过在WebSphere应用服务器上运行的管理门户来操纵数据库。
网关服务器 网关服务器在IBM x系列x330服务器上运行,网关服务器 执行协议转换并将游戏人员连接选通到游戏服务器上。
精灵控制器 精灵控制器是控制不是直接由游戏人员动作所控制出的游戏 要素的服务器。精灵控制器与网格的网关服务器交互。
游戏服务器 游戏服务器负责在网格中运行游戏。决定游戏人员何时转到新服务器的智能常驻在游戏和网关服务器中。当游戏服务器 使用过度或故障时,该游戏服务器向网关服务器发出一个控制消息,网关服务器将最终将游戏人员重新指到新的游戏服务器上
数据库服务器 数据库服务器负责存储保持游戏连续所需的所有信息(物理、地理、游戏规则等)。

在服务器之间无缝隙地移植的能力使网格成为真正自主计算的典范??并使它最明显地区别于标准“单服务器”在线游戏配置。

如何使用Butterfly网格
在玩游戏前,某一游戏的所有要素??艺术资源、游戏逻辑和世界地理等??需要存储到配置管理系统中并进行测试。一旦测试完毕,Butterfly网格将这些要素自动提供到服务器上,服务器将开始支持游戏。在购买游戏后,游戏人员通过视频游戏操纵台、PC、机顶盒或运行Butterfly网格客户机软件的移动设备登录到网格上。游戏人员一旦登录到新的游戏中,通过查看存储在网格的DB2数据库中的所有有关用户数据,网格将需要从他以前的会话中恢复该游戏人员的游戏参数??即“具体化”。这一轮询过程由网关服务器发起(用户的第一个入口点)。网关服务器联络游戏服务器,游戏服务器反过来又联络常驻用户数据的数据库服务器。

在获取了游戏人员的数据后,通过在游戏服务器上将该游戏人员的数据表示为某一对象,游戏服务器将在游戏世界中重新确认该游戏人员。游戏人员在游戏世界中正是以临时对象这种形式存在的。与这一游戏人员有关的每个行动都涉及从数据库服务器读数据或向其写数据。

在游戏期间,Butterfly网格将世界分为一系列相互排斥的地区,叫作“地点”,每个地点被分配给某一特定服务器。在游戏期间,游戏人员可能会遇到在某一地点有过多活动的情况??这是由于游戏的内部因素产生的(如:人工智能系统触发的战斗)或者有大量用户??这增加了这一地点的服务器的利用率。在这种情况下,网格的“心跳检测”特性(Globus工具集的元计算目录服务)将把服务器标记为使用过度,并将高活动地点移到网格中利用率降低的服务器上。同样,在服务器故障时,利用同样的资源监视特性,游戏将被自动、无缝隙地转到网格中最近的最佳服务器上.

在游戏人员从一个地点(与服务器A相关)转到另一个地点(与服务器B相关)的例子中也可以看出Butterfly网格的内在活力。当游戏人员接近分开两个地点的边界时,网格启动一个叫做“哨兵”(Sentinel)的消息传递通道。哨兵的功能是访问DB2数据库上的游戏人员的有关游戏数据,并在新服务器上创建游戏人员的数据“快照”(即形成一个新对象)并删除原对象。一旦某一游戏人员被分配给新地点的新游戏服务器,那么就将从新地点的数据库服务器读数据或向它写数据。在此,Globus工具集实用程序??即GASS和GRAM??将起关键作用,它自动将游戏脚本导入到新的服务器。(责任编辑:刘燕之)