« April 2005 | Main | June 2005 »

May 30, 2005

Yasukuni Shrine - 日本“死亡文化”:靖国神社

对于日本上个世纪给我们中华民族所带来的深重灾难,任何一个中国人都会忍不住怒火中烧。而对于最近反日呼声高涨的国内民情,作为一个生于和平年代的普通公民,更加应该冷静思考历史问题,多去了解日本的文化和过去的历史,才能深刻理解上个世纪的战争和灾难,才能真正看清楚我们的邻邦--日本,是怎样的一个国家,才能明白“大和”是怎样的一个民族!

对于大部分青壮年国人而言,大家都忙于眼前和平幸福的生活,对于从过去延续到现在的危机却不甚了解,也都不经意间忘却了这段屈辱而沉重的历史。但为了使我们的文化继续发扬光大,为了永不重复那段屈辱的历史,在这个开放的世界立于不败之地,我们有责任去重新认识这些所有的一切。

而要认识我们的邻邦--日本,大和民族,就要先了解他们的文化,先从日本“死亡文化”开始,其中靖国神社就是日本怪异的“死亡文化”之代表。

什么是靖国神社

“靖国神社”是日本为祭祀在历次战争中战死的人修建的,里面供奉有战犯,也有其他的战死者。靖国神社,英语译作“Yasukuni Shrine”,“参拜靖国神社”译成英语是“to pray at the Yasukuni Shrine”。   

靖国神社是日本明治时期建立的,日本政客频频参拜的东京靖国神社里供奉着东条英机等14名二战甲级战犯和约2000名乙、丙级战犯的牌位。靖国神社已成为日本右翼势力的精神支柱和聚会地。

上述是引自tom.com的一段文字

靖国神社迄今已有130年的历史。1868年1月3日,年仅16岁的明治天皇建立了一个天皇为最高统治者的新政府。幕府不甘心丧失政权,以武力抗拒。双方激战四昼夜。为了合祀在这次会战中牺牲的人,在天皇的建议下,不久在京都东山建立了一所招魂社。1879年6月,东京招魂社改称靖国神社。

“靖”与“安”同义,“靖国”两字是安邦定国的意思。但是,随着日本资本主义的发展和国际法西斯主义的兴趣,为天皇、财阀和法西斯军国主义卖命而死去的人,也作为“神”进入靖国神社,它的性质和建立的初衷也随之起了变化。1978年,日本偷偷把东条英机、广田弘毅、松井石根等14个甲级战犯(7个绞死、7个狱死)和2000多个乙、丙级战犯的牌位,以“昭和殉难者”的名义塞进了靖国神社,成为“护国神灵”,从而也增加了宣传侵略战争有理和为战犯翻案的新内容。

多年来,在“死亡文化”充斥下的日本,靖国神社成为一种政治怪胎,始终对日本政要有着特殊的吸引力。

日本战败投降后,美国占领军当局宣布废除国家神道,实现国家与宗教、政治与宗教的分离。但是,自50年代起,日本的某些势力不断向政府施加压力,要求将靖国神社重新改由国家管理,并实行国家公职人员“正式参拜”。时至今日,以小泉为首的日本政要们为何要如此热衷于参拜靖国神社呢?

从历史根源来看,主要是战后不久,美国便改变对日政策,由战时的打击削弱日本,改为扶植日本,使日本战争罪行未能得到彻底地清算,其次,战后日本的教育误导了民众,特别是年轻的一代,使二战残留的军国主义余毒在日本有持续存在和泛滥的空间和市场。此外,随着经济实力的日渐强盛,日本想当政治、军事大国的野心不断膨胀。

从日本现实社会状况来看,右倾化思潮已经渗透到日本国内各个领域,并占据着统治地位,不仅在自民党内,而是在整个日本政界、教育界、文化界、大众传媒乃至经济界,右倾思潮都在不断蔓延,而反对这种历史性倒退的和平力量却处于劣势。另外,靖国神社合祭的246万个“神灵”的遗族及其后代数目不小,能量巨大,他们中间最大的组织“战争遗族会”,拥有百万以上会员,还有军恩联盟全国联络会、报答英灵会、全国战友会等组织。在日本国会中,遗族议员协议会、大家都来参拜靖国神社国会议员会、报答英灵议员协议会等五花八门,但多为靖国神社在政界的代言人。这些团体与四大经济团体(经济团体联合会、日本经营者团体联盟、日本工商会议所和经济同友会)等许多组织又组成了“靖国神社崇敬奉赞会”,而对小泉及其自民党来说,为拉住这一大批选票,也轻易不会放弃参拜靖国神社立场的。

当然,在关注和谴责日本政要是否参拜靖国神社问题时,也应当看到日本国内积极力量的一面。例如,以外相田中真纪子为代表的政治家明确表示不去参拜,而且反对小泉首相参拜靖国神社。同时,日本舆论调查结果显示,多数日本民众(45.9%)不赞成首相参拜靖国神社,等等。说明了在当今日本,虽然一些身居高位的政治家不断迎合日益猖獗的右翼势力,极力否定侵略加害的历史,但正义尚存,这是日本的希望所在,也是拓展中日友好及其开创和平未来的希望所在。(朱成山)

上述文字引自CCTV的新闻

我个人强烈的感觉到,作为一个中国人,作为一个知识分子,不仅要关心身边的事,更不能忘记昨天的事,昨天的历史,不懂得历史的人,不是完整的人,日后将继续坚持整理相关的内容,一来加强学习和对历史的任知,二来也希望对来访的朋友有所启迪和帮助。

不能忘却历史,更要清楚历史

参考资料:

http://www.cctv.com/news/world/20010806/124.html
http://heritage.news.tom.com/zhuanti/jgshenshe/
东条英机(wiki百科)
靖国神社(wiki百科)
http://personal.nbnet.nb.ca/stao/yuj011.htm

Posted by hzqbbc at 11:53 PM | Comments (1)

May 29, 2005

基于PowerPC的嵌入式Linux - 好书介绍

在读大学的时候,我曾非常热衷于嵌入式,还在自己的机器及实验室的机器摆弄了一个仿真环境,跑起了Uclinux和另一个针对Motorola M68K的仿真环境。由于时间久远,现在都忘记是叫什么了,只记得当时艰苦奋斗了几个星期,终于让仿真器跑起来,垮平台编译成功,并将ROM“烧”(其实应该说是download到仿真环境里吧)到仿“硬件”里,看着嵌入Linux启动的信息,到最后显示的提示符,真的是激动不已!

那个小Linux系统还只能实现十多个基本的系统命令,啥也不能干,但也足够玩好久了。但最可惜的是当时一来缺钱,没钱买硬件开发板,没钱买任何实验的东西,二来没什么好的参考资料,虽然英文的一堆,但是都不系统,要自己吃力的摸索,加之嵌入这一块只是业余小小爱好,忙着做毕业的东西,后来就荒废了,甚为可惜。

基于PowerPC的嵌入式Linux - 北航出版

前两天在书店除了看到介绍过的《Web性能优化》一书外,还无意看到一本我能让我有所注意的嵌入Linux的书--《基于PowerPC的嵌入式Linux》,由北航出版社出版的。这本书引起我注意的地方,并不是高深的技术,而是详尽而平实的内容,按步就班的讲述了一些基本原理,实验环境的建立,移植,以及方方面面的东西。并不是一般嵌入式书籍将内容一堆砌,啥也没说清楚就结束的感觉。一个比较深刻的印象就是实用,从初学者的角度来评价,就是经过模仿书本里的东西,成功率稍高。

基于PowerPC的嵌入式Linux一书简介

本书详细地介绍了如何打造一个完整的嵌入式Linux,主要内容包括: Bootloader定制、Linux内核定制、Linux Rootfs定制、Linux守护进程定制、Linux设备驱动编程、Linux编程、实时Linux扩展等。同时本书结合PowerPC芯片,介绍了PowerPC芯片的基本结构、配置引导以及开发方法。本书的特点是注重实用,每篇内容都有具体的实例供参考。读者阅读了本书后,能够快速地在嵌入式PowerPC平台上运行起嵌入式Linux操作系统,开始系统的设计和研发。
本书可供PowerPC和嵌入式Linux研究、开发及应用技术人员参考,也可作为高等院校计算机专业及Linux领域的师生的教学参考书。

前言(经删节)

自1991年Linux操作系统发表以来的10年间,Linux操作系统以令人惊异的速度迅速在服务器和桌面系统中获得了成功。它已经被业界认为是未来最有前途的操作系统之一。并且,在嵌入式领域,由于Linux操作系统具有开放源代码、良好的可移植性、丰富的代码资源以及异常的健壮,使得它获得越来越多的关注。据近日Gartner Dataquest和Electronic Engineering TimesAsia联合进行的调查报告,大约有32 %的工程师选择了VxWorks,21.4 %的工程师使用Linux操作系统。在未来,大约有34 %的工程师打算使用VxWorks,而29 %的工程师打算使用Linux。

PowerPC是Motorola、 IBM和Apple公司联合开发的CPU芯片,如今由于PowerPC良好的架构、优秀的性能以及稳定的兼容性,使得PowerPC在各个领域都获得了广泛的运用。Motorola公司的PowerPC处理器早已广为人知,其在全世界通信处理器市场上处于无可争议的领袖地位。迄今为止,它已经向全球350多家客户销出了1亿多只通信处理器,并赢得了5000多项设计合同,其中大部分归功于它的PowerQUICC处理器系列。Gartner Dataquest在2002年5月公布的一份报告中说,Motorola公司在通信处理器集成电路市场上的占有率排名第一,占据74.7 %的市场份额。不仅仅是在通信领域,PowerPC在服务器和桌面领域也取得了巨大的成功,IBM使用PowerPC604s组建巨型计算机(例如深蓝),Apple公司使用G3、G4组建个人多媒体电脑。

PowerPC是Linux较早支持的芯片之一,Linux对PowerPC有成熟、优秀的支持。Linux不仅已经在IBM的S390服务器及Apple公司的Macintosh个人电脑上运行多年,而且在嵌入式PowerPC芯片(Motorola和IBM公司都有嵌入式PowerPC产品)也已经有了成功的案例。虽然目前关于如何在嵌入式PowerPC平台上运行Linux的资料不少,但是都不成系统,并且非常简单。本书是一本介绍如何在嵌入式PowerPC平台上运行Linux的所有必需知识的集合,并且结合实例讲解如何使用Linux开发一个完整的产品。通过阅读本书,读者将有能力运用嵌入式PowerPC平台开发一个完整的系统。

本书的特色如果用一句话来概括本书的特色,那么这句话应该比较贴切:在PowerPC开发板上把Linux运行起来,《基于PowerPC的嵌入式Linux》是一本完全实例化的书籍,它Step by Step地指导读者在PowerPC开发板上运行Linux,并且实现一个二层交换机的开发实例。

《基于PowerPC的嵌入式Linux》的目的是让读者能够:了解PowerPC的基本结构和MPC8xx的常用知识;在PowerPC开发板上运行Linux系统;了解Linux引导的知识;了解inetd守护进程的知识,将ftpd服务器、telnetd服务器、www服务器移植到PowerPC开发板中来;了解编写Linux模块的知识;了解编写Linux 设备驱动的知识;了解如何定制一个实时Linux的知识;了解建立一个完整的嵌入式产品的知识。

作者曾经阅读过许多嵌入式系统开发的书籍,它们有许多是非常优秀的,而且很有实际参考价值。然而,由于嵌入式系统的多样性,这些作者的硬件环境和开发工具读者可能没有,大多数作者在书籍的代码和实例也不一定适合读者的需要,或者说在读者的硬件开发板上无法运行和调试。特别是当读者寻找Linux在嵌入式系统中的运用时,目前大部分相关书籍还是概念型且没有具体实例,在看完这些书籍以后,读者依然无法在其硬件开发板上运行Linux。

本书将不一样,它是一本Step by Step的实例化编程的书籍,几乎涉及了Linux所有的重要知识,并且有许多代码和实例能让读者充分了解如何从零开始,将PowerPC版本的Linux移植到自己的PowerPC开发板中去。

.......

在编写本书之前,作者以前一直很好奇: Linux是如何引导和启动的?那些神秘的/etc、/sbin和/var目录是起什么作用的?Linux的配置文件是如何组织的?网络守护进程是怎么回事?在阅读了这本书后,读者将一清二楚。

本书所有的内容都将结合实例,而且光盘中带有源代码,所以本书几乎涵盖了所有嵌入式Linux所需要了解的内容。
......

读者可以学到什么

如果读者是一位嵌入式系统的软件开发人员,或者是一位硬件开发人员,或者是一位产品管理者,正在准备关注嵌入式Linux在自己的系统中的应用,那么《基于PowerPC的嵌入式Linux》将是一本很好的开发实例的书籍。

如果读者是一位产品管理者,将可以了解:
 Linux的简介,它的优缺点(当然,部分也许是作者的偏见)。
 Linux在嵌入式系统中应用的优缺点。例如,在产品上市时间、产品开发的难度及系统的稳定性等方面与商业RTOS开发套件的比较。

如果读者是一位产品开发人员,将可以了解:
 Motorola公司的PowerQUICC处理器;
 如何创建一个PowerPC交叉编译和调试开发环境;
 如何为PowerPC产品定制Linux引导程序PPCBoot;
 如何定制PowerPC版本的Linux内核以适合自己的开发板;
 如何创建一个小型的Root文件系统;
 如何在PowerPC系统上引导Linux内核和系统;
 如何定制实时嵌入式Linux内核;
 如何在嵌入式Linux上编制网络设备驱动程序。

......

致谢
我的同事们张月亭、金叶、蔺杰和沙明也参加了本书的编写,在此对他们表示衷心的感谢。

作者
2003年10月

目录

第1章 目标产品和开发简介
1.1 二层交换机简介1
1.2 硬件系统简介2
1.3 软件系统简介2
1.4 嵌入式Linux系统开发简介3
1.4.1 主开发机/开发目标和交叉编译3
1.4.2 用户交互4
1.4.3 Linux Image结构布局5
1.5 开发流程6

第2章 Linux系统简介
2.1 Linux系统的特点8
2.2 什么是嵌入式系统10
2.3 Linux嵌入式系统简介和可行性分析11
2.3.1 引导内核的Bootloader12
2.3.2 Linux内核12
2.4 实时Linux系统14
2.4.1 MontaVista Linux和TimeSys Linux16
2.4.2 RTLinux16
2.4.3 RTAI17

第3章 PowerPC处理器
3.1 Motorola公司的PowerQUICC通信处理器18
3.1.1 MPC8xx19
3.1.2 MPC826021
3.2 MPC850芯片简介24
3.2.1 概述24
3.2.2 MPC850 功能列表24
3.2.3 主要模块简介27
3.3 MPC850配置和复位34
3.3.1 系统接口模块SIU34
3.3.2 系统配置和保护34
3.3.3 SIU编程35
3.3.4 复位39
3.4 存储控制器44
3.4.1 基本结构44
3.4.2 GPCM和UPM片选编程机制相同之处46
3.4.3 基地址寄存器BRx48
3.4.4 配置寄存器ORx50
3.4.5 存储器状态寄存器MSTAT52
3.4.6 控制器A/B模式寄存器MxMR53
3.4.7 存储器命令寄存器MCR54
3.4.8 存储器数据寄存器MDR55
3.4.9 存储器地址寄存器MAR56
3.4.10 存储器周期时钟预分频寄存器MPTPR56
3.5 外部中断异常57
3.5.1 中断机制58
3.5.2 中断优先级58
3.5.3 中断处理流程59
3.5.4 SIU中断登记寄存器SIPEND60
3.5.5 SIU中断掩膜寄存器SIMASK60
3.5.6 SIU中断触发形式寄存器SIEL61
3.5.7 SIU中断向量寄存器SIVEC62
3.6 MPC850通信处理器CPM62
3.6.1 功能63
3.6.2 通信处理器CP64
3.7 GE850EH开发板79
3.7.1 GE850EH开发板功能简介79
3.7.2 硬复位配置字80
3.7.3 内部寄存器起始地址81
3.7.4 GE850EH的时钟81
3.7.5 Flash ROM82
3.7.6 SDRAM83
3.7.7 BM8024 二层交换芯片84
3.7.8 以太网口84
3.7.9 UART串行口85

第4章 嵌入式Linux开发工具ELDK
4.1 ELDK简介86
4.2 安装ELDK88
4.3 删除ELDK89
4.4 配置使用ELDK89
4.5 从零开始编译ELDK90
4.6 其他交叉编译环境90
4.7 GNU 系列编译工具简介91
4.7.1 GCC91
4.7.2 ld93
4.7.3 ldd93
4.7.4 nm93
4.7.5 ar93

第5章 移植PPCBoot到GE850EH板
5.1 PPCBoot简介94
5.2 获得源代码95
5.3 解开源代码95
5.4 PPCBoot源代码简介95
5.5 配置编译PPCBoot98
5.6 移植PPCBoot到GE850EH开发板中去98
5.6.1 了解GE850EH开发板99
5.6.2 建立自己的移植目录和文件100
5.6.3 修改Makefile文件101
5.6.4 修改ppcboot/include/configs/ge850eh.h 文件101
5.6.5 修改ppcboot/board/GE850EH/config.mk 文件110
5.6.6 修改ppcboot/board/GE850EH/ge850eh.c 文件111
5.6.7 修改ppcboot/board/GE850EH/flash.c 文件115
5.6.8 修改ppcboot/include/commproc.h 文件116
5.7 编译PPCBoot117
5.8 安装、运行PPCBoot到GE850EH开发板上去117
5.8.1 使用BMD/JTAG调试工具安装PPCBoot117
5.8.2 使用已有的安装Bootloader的程序安装PPCBoot119
5.8.3 使用已在GE850EH板上运行的PPCBoot安装PPCBoot120

第6章 在GE850EH开发板上运行Linux
6.1 获得Linux内核源代码121
6.2 Linux内核简介121
6.2.1 Linux 引导121
6.2.2 RAMDISK和Initrd122
6.2.3 MTD122
6.2.4 JFFS2文件系统123
6.3 配置编译Linux内核123
6.4 将Linux内核移植到GE850EH开发板中去124
6.4.1 确认linux/Makefile文件124
6.4.2 修改/linux/arch/ppc/configs/ge850eh_defconfig文件125
6.4.3 修改/linux/arch/ppc/config.in文件133
6.4.4 增加/linux/include/asmppc/ge850eh.h 文件133
6.4.5 修改/linux/include/asmppc/processor.h文件134
6.4.6 修改/linux/include/asmppc/mpc8xx.h文件134
6.4.7 修改/linux/arch/ppc/8xx_io/commproc.h文件134
6.4.8 增加/linux/drivers/mtd/maps/ge850eh.c文件135
6.4.9 修改/linux/drivers/mtd/maps/Makefile文件136
6.4.10 修改/linux/drivers/mtd/maps/Config.in文件136
6.4.11 修改/linux/drivers/char/flash_config.c文件136
6.5 编译Linux kernel for GE850EH137
6.6 从GE850EH开发板上引导Linux内核137
6.6.1 基本的环境变量137
6.6.2 从Flash 引导Linux内核137
6.6.3 环境变量和Linux内核引导参数141
6.6.4 网络bootp引导Linux内核142
6.6.5 bootp命令143
6.6.6 bootargs引导变量144
6.6.7 bootm命令144
6.6.8 引导一个完整的Linux系统145
6.6.9 Flash中的Rootfs146
6.6.10 网络NFS的Rootfs146

第7章 Rootfs和RAMDISK
7.1 千变万化的RAMDISK150
7.1.1 一个C库150
7.1.2 一个用户交互的Shell151
7.1.3 一个工具集151
7.1.4 一个Telnet服务器151
7.1.5 一个FTP服务器151
7.2 创建不使用Busybox的RAMDISK152
7.2.1 建立RAMDISK Image文件152
7.2.2 给RAMDISK建立文件系统152
7.2.3 建立必需的Linux目录153
7.2.4 /dev目录153
7.2.5 /lib目录156
7.2.6 NSS157
7.2.7 /etc目录158
7.2.8 /bin和/sbin目录160
7.2.9 生成最后的RAMDISK Image文件161
7.2.10 减小体积161
7.3 基于glibc的Busybox161
7.3.1 获得Busybox的源代码162
7.3.2 配置Busybox162
7.3.3 编译Busybox165
7.4 创建使用Busybox和glibc的RAMDISK166
7.5 测试制作的RAMDISK167

第8章 inetd 和 telnetd、ftpd、httpd网络进程
8.1 inetd网络守护进程171
8.1.1 获得inetd的源代码172
8.1.2 给inetd源代码打patch173
8.1.3 编译inetd173
8.2 login守护进程173
8.3 telnetd守护进程174
8.4 ftpd守护进程175
8.5 boa webserver175
8.6 insmod rmmod176
8.7 安装inetd、login、insmodtelnetd、ftpd、boa webserver进程177

第9章 Linux字符设备驱动——LED驱动实例
9.1 Linux设备驱动概述180
9.2 Linux Module183
9.2.1 一个Linux Module例子(Intel 版本)183
9.2.2 PowerPC版本的Module例子185
9.2.3 Linux Module的机制185
9.2.4 Module和Application的区别186
9.3 主设备号和次设备号190
9.4 file_operations数据结构191
9.5 GE850EH开发板LED字符设备驱动(PowerPC版本)193
9.5.1 GE850EH LED硬件配置193
9.5.2 源代码分析194
9.5.3 编译LED设备驱动195
9.5.4 测试LED设备驱动196
9.5.5 GE850EH开发板LED设备驱动程序源代码197
9.5.6 LED模块Makefile文件205
9.6 I/O端口205
9.6.1 申请/释放I/O区域206
9.6.2 避免编译器优化I/O访问206
9.6.3 I/O端口大小207
9.7 优化问题207

第10章 二层交换芯片BM8024设备驱动
10.1 BM8024简介208
10.2 功能列表208
10.3 BM8024交换机制和设备驱动209
10.4 Linux网络设备驱动编程210
10.4.1 Linux网络设备驱动的结构211
10.4.2 初始化212
10.4.3 发送和接收213
10.4.4 网络接口数据结构struct net_device213
10.5 BM8024接收/发送以太网包和MPC850218
10.5.1 接收以太网包219
10.5.2 发送以太网包219
10.6 BM8024 I/O存储器220
10.6.1 ioremap()220
10.6.2 配置BRx/ORx222
10.7 BM8024中断223
10.7.1 interrupt操作223
10.7.2 BM8024中断操作224
10.7.3 BM8024中断处理函数和tasklet224
10.8 延时225
10.9 BM8024内存操作226
10.10 BM8024网络设备驱动源代码分析226
10.10.1 Module_init()函数226
10.10.2 bm8024_init()函数227
10.10.3 bm8024_open()函数228
10.10.4 bm8024_interrupt()中断处理函数229
10.10.5 bm8024_do_tasklet()函数229
10.10.6 bm8024_rx()函数230
10.10.7 bm8024_tx()函数231
10.10.8 bm8024_hw_tx()函数231
10.10.9 BM8024网络设备驱动源代码231

第11章 嵌入式Linux 编程
11.1 task queues和kernel timer版本的LED驱动程序232
11.1.1 task queue232
11.1.2 使用tq_scheduler的LED Module234
11.1.3 kernel timer239
11.1.4 使用kernel timer的 LED Module239
11.2 semaphore243
11.3 Application直接访问BM8024寄存器244
11.3.1 HAL BM8024存储器模块246
11.3.2 HAL BM8024存储器模块源代码247
11.3.3 HAL BM8024寄存器API源代码255

第12章 实时Linux扩展——RTAI
12.1 RTAI模块259
12.1.1 rtai模块259
12.1.2 rtai_sched模块259
12.1.3 rtai_shm模块260
12.1.4 rtai_fifos模块260
12.1.5 LXRT模块260
12.2 在GE850EH开发板上安装RTAI260
12.2.1 获取Linux内核源代码260
12.2.2 获取24.1.8版本的RTAI源代码261
12.2.3 给Linux内核源代码加上RTAI的patch261
12.2.4 定制此Linux内核261
12.2.5 定制及编译RTAI模块261
12.2.6 安装及测试RTAI262
12.3 RTAI版本的LED例子264
12.4 常用RTAI API函数266
附录ARTAI常用API函数
A.1 task函数(rtai_sched.o模块) 267
A.2 timer函数(rtai_sched.o模块)274
A.3 semaphore函数(rtai_sched.o模块)276
A.4 task间通信函数(rtai_sched.o模块)280
A.5 远程函数调用(RPC)函数(rtai_sched.o模块)282
A.6 mailbox函数(rtai_sched.o模块)283
A.7 rtai.o模块提供的API函数285
A.8 rtai_shm.o提供的API函数289
A.9 rtai_fifo.o提供的API函数290
附录BCVS使用简介
B.1 简介294
B.2 安装CVS服务器294
B.3 使用CVS客户端298
B.4 一些小技巧304
附录CGNU通用公共许可证(GPL)
附录D附带光盘的使用方法
D.1 内容简介311
D.2 使用方法312
参考文献

推荐几个有关嵌入式系统的网站:
Linuxdevices.com
Embedded Linux
UcLinux
Uclinux developer forum

Posted by hzqbbc at 11:49 PM | Comments (1)

Web性能优化 - 好书介绍

这两天在书店看到了两本不错的书,给了自己耳目一新的感觉,在这里做一个简单的介绍和推介。首先是介绍涉及世界上应用最为广泛的Web服务优化的书-- 《Web性能优化》。

《Web性能优化》由Patrick Killelea编写,谢文亮翻译,清华大学出版社出版。该书讲述了如何对Web应用性能进行调整,提供高品质的Web Service。

Web性能优化

看了本书,我惊叹作者拥有非常扎实的根基,各种专业术语和技术解释得很简明易懂,作风严谨,而且全书配有大量的真实例子和丰富的图例,着实是Web开发/维护人员的宝典,极具参考价值。

以下是该书的自述介绍:

《Web性能优化》前言:

自从Web诞生以来,人们就一直在尽力让它跑得更快。今天,Web获得成功也意味着它拥有了更多用户、更多数据、更多功能……和更长时间的等待。因此,优化其性能就成为 Web网站、特别是个人网站的"生杀之奉始"。

本书讲述如何将Web性能调至最佳状态。书中不仅谈到了Web服务器软件的优化,而且还涉及到如何流水化处理Web内容,如何从浏览器端着手优化性能,如何调校客户端和服务器端的硬件,以及如何最大限度地使用网络本身的特性。

书中的内容涉及到影响性能好坏的本质,并为得到立竿见影的效果提供了具体建议。本书向您娓娓道出评价计算性能高低的准则,并在后半部分讲述从客户端、网络直到服务器这一链条中每个环节的薄弱之处,同时给出了加强巩固这些薄弱环节的金玉良方。

本书在第一版的基础上对内容进行了扩展,具体包括:

. 增加了有关Web站点结构、安全性、可靠性的新章节,讲述了这些方面对性能的影响
. 详细讨论了在有多个处理器的服务器上Java的可扩展性
. 增加了一些与Web性能相关的用于处理注册、cookie、SSL的Peri脚本
. 给出了如何使用PeriDBI和开源程序gnuplot来生成性能图表的详细指令
. 增加了rstat的有关内容,rstat是一种基于Unix的源代码开放的实用程序,其作用是远程地收集性能统计数据

除此之外,书中还有很多实际中可能遇到的性能问题的示例和图表,当然也提供了相应的解决方法。

与第一版相比,书中的内容都"升级"到了Java 2。

如果您需要长时间地等待一个Web页面的显示,或者您所管理的服务器的速度慢得令人难以忍受,那么读一读《Web性能优化》这本书吧,它一定会对您有所帮助,使您的Web体验更上一层楼。

该书目录

前言
第一部分 基础篇
  第一章 首要问题
  浏览器端的问题
  服务器端的问题
  关键性建议

第二章 Web站点体系结构
  进行权衡
  组成元素
  Web站点体系结构示例
  趋势
  示例配置
  关键性建议

第三章 容量规划
  算算账
  相信数字,但更相信自己的眼睛
  常见问题
  你需要多大的带宽
  你需要多快的服务器
  你需要多大的内存
  关键性建议

第四章 性能监控
  性能参数
  延迟和吞吐量
  利用率
  有效性
  使用Perl监控Web性能
  使用spocket自动生成监控脚本
  使用关系型数据库存储和获取监控数据
  使用rstat监控机器的使用情况
  监控每一个进程的统计数据
  根据ps数据生成图表
  监控其他内容
  制作一个系统面板Web页面
  关键性建议

第五章 负载测试
  负载测试的准备工作
  权衡负载测试工具
  编写你自己的负载测试工具
  基准规范和基准测试 
  其他资源
  关键性建议

第六章 性能分析
  使用analysis.cgi找到瓶颈所在
  使用sprocket探听HTTP
  查看连接
  日志文件分析
  点击率
  更多提示
  关键性建议

第七章 可靠性
  常见问题
  相关性
  处理故障
  关键性建议

第八章 安全性
  HTTPS和SSL
  防火墙
  堡垒主机
  chroot
  关键性建议

第九章 案例分析
  数据库表无限制地增长
  反向DNS查找降低了日志记载的速度
  扭结的电缆
  数据库连接池的增长限制了性能
  关键性建议

第十章 原则与模式
  优化性能的原则
  改进性能的模式
  关键性建议

第二部分 高级篇
第十一章 浏览器
  浏览器的工作原理
  浏览器的类型
  最佳的浏览器
  浏览器的速度
  浏览器优化技巧
  非浏览器的Web客户端
  关键性建议

第十二章 客户端操作系统
  Windows
  Macintosh
  UNIX
  关键性建议

第十三章 客户端硬件
  CPU
  内存
  高速缓存
  总线
  磁盘
  显卡
  BIOS
  关键性建议

第十四章 线路和终端器
  超前和延迟
  调制解调器 —— 信息的通道
  ISDN
  电缆调制解调器
  xDSL
  高容量线路
  内联网
  网络建模工具
  因特网
  PTT
  关键性建议

第十五章 网络协议
  权力和协议
  影响网络协议性能的因素
  Web协议
  关键性建议

第十六章 服务器端硬件
  把服务器看成线路上的设备
  性能良好的I/O
  多个总线
  快速磁盘
  大量内存
  可扩展性
  网卡
  总线
  内存
  内存的特点
  CPU
  对称多处理
  磁盘活动和PID
  关键性建议

第十七章 服务器端操作系统
  Unix和Web的起源
  Unix特色
  系统调用和库调用
  进程和内核
  文件系统
  窗口系统
  版本和补丁
  可配置的操作系统参数
  Unix操作系统监控工具
  系统调用跟踪程序
  网络探听工具
  服务器可以处理多少个连接
  服务器可以处理多少个进程
  服务器派生新进程的速度能有多快
  UNIX与Windows NT的对比
  外核
  关键性建议

第十八章 服务器端软件
  Web服务器软件的发展过程
  Web服务器的系统调用
  服务器连接是怎么失败的
  配置Apache和Netscape的Web服务器
  其他服务器
  不具备的一些功能
  代理服务器
  分级缓存
  关键性建议

第十九章 内容设计
  内容的规模
  努力做到最好
  缓存技术和区别
  HTML及其压缩
  HTML制作者需注意的性能技巧
  文档对象模型
  图形
  音频内容
  视频内容
  关键性建议

第二十章 自定义应用程序
  程序员
  CGI编程
  CGI内幕及性能问题
  常用的CGI技巧
  CGI语言特有的优化技巧
  后台运行CGI
  CGI访问数据库的性能
  日志
  NSAPI和ISAPI
  DOM
  JSP、ASP和PHP
  关键性建议

第二十一章 Java
  对于GUI应用程序来说,Java永远存在不足之处
  对服务器端来说,Java提供了很多便利
  Java固有的性能问题
  编码技巧
  编译器
  分析代码
  反编译器
  操作系统级分析工具
  JIT
  静态编译器
  虚拟机
  运行时选项
  Java芯片
  Java基准
  有Java性能信息的Web站点
  关键性建议

第二十二章 数据库
  你真的需要一个关系型数据库吗
  性能优化技巧
  数据库可以处理多少个连接
  数据库何时会超载
  分析
  关键性建议

附录 有关Web性能的产品列表与回顾

在Oreilly 网站上该书的介绍:http://www.oreilly.com.cn/book.php?bn=7-302-07120-9

Posted by hzqbbc at 08:46 PM | Comments (0)

May 27, 2005

perl 性能优化

Perl是强大的语言,是强大的工具,也是一道非常有味道的菜:-) 利用很多perl 的特性,可以实现一些非常有趣而实用的功能。

利用Perl开发一些服务应用时,有时会遇到性能或资源占用的问题,如何解决呢?以下是自己过去开发实践的一些经验,几个主要的技巧分别是:

巧用require装载模块

为避免程序一启动就加载大量模块,降低启动速度,可以在必要的时候再装载模块,这时候就是require大派用场的时候了。

如:


#!/usr/bin/perl -w
use pre_load_module;

# Initialize some thing
init_args();

# if $use_this_module is true, load the Module
if($use_this_module) {
     require Module;
}

上述代码中,如果变量$use_this_module设置了,那么才加载Module,如果没设置则不需要加载,实现了:use on demand的功能。在CGI应用程序中,这相当有用,如果每次请求(fork)都加载大量无用模块的话,响应速度会有所降低,而在特定场合才加载一些模块将加块启动、解析的速度。

再看一个例子:


#!/usr/bin/perl
my $pid = fork or die "can't fork:$!\n";
if($pid) {
     print "i'm father\n";
     sleep;
}else {
     print "i'm child\n":
     require IO::Socket;
     sleep;
}

上述代码中,如果在程序一开始就用use 来载入IO::Socket模块,那么子/父进程都加载了该模块,通过top命令发现子父进程大小都是3.07MB;如果只在子进程里加载,则只在子进程里有效,内存的消耗将降低,top命令发现子进程3.04MB,父进程变为1.4MB。

使用系统函数及XS化模块

Perl内建的系统函数及用c编写的perl XS扩展模块的速度和效率都比纯perl的实现要好得多。在性能要求较高的场合(如开发Application Server,Network Server等),可以考虑使用这些内建函数或XS化模块。

如Socket就比IO::Socket的内存消耗要低,XS编写的Data::Dumper就比纯Perl的Data::Dumper要快4-5倍。

此外,一些简单的任务并没必要使用Perl 模块,如获得主机IP地址就大可不必载入庞大的Net::DNS而只是使用gethostbyname()系统函数即可。

以下是一些常用的替代方案以获得更快的速度,更好的效率:
  • 用sys*系列函数等替代open/seek/tell/<>等标准IO操作
  • 用Socket代替IO::Socket以获得更低开销和内存占用
  • 用get*by*系列函数代替Net::DNS
  • 用index/substr等代替部分低效正则表达式
  • 用select(3参数版本)代替IO::Handle部分功能
  • .......

    自写低开销模块

    通常我们使用一些Perl模块时,只使用了其中很小一部分的功能,可是却不得不载入整个模块,甚至要载入其他不相关的模块。因此往往使整个程序非常臃肿庞大。

    著名的web管理软件webmin的miniserv(一个简化的http服务端)功能强大,还支持SSL,但资源占用却出奇的少,只有大约5.6MB的大小!这是为什么呢?因为miniserver只使用了2个Perl 系统模块(Socket及POSIX),没有载入其他的模块。一些本需要其他perl 模块的功能,均由web-lib.pl等用系统函数编写代替。

    例如以下是一个获得A记录的高速函数get_mx(),它不依赖任何模块,速度非常快。

    
    sub get_mx {
         my @info = gethostbyname shift;
         my @addr = splice(@info, 4);
         my @rt;
         foreach(@addr) {
              push @rt, join('.', unpack('C4', $_));
          }
         \@rt;
    }
    

    另一个例子,对于标准的IO::Handle对象,可以使用$obj->autoflush(1);来设置缓冲的特性,我们通过使用系统函数select()来获得同样的能力,而无需要载入IO::Handle,代码如下:

    
    sub autoflush {
         my $io = $_[0];
         select((select($io), $|=1)[0]);
    }
    

    使用方法很简单,例如要对IO::Socket::INET类型的$sock设置为立即冲刷,则autoflush($sock)即可。

    ...to be continue...

    Posted by hzqbbc at 05:30 PM | Comments (0)

    May 24, 2005

    Apache rewrite技术实现Apache到lighttpd迁移

    毫无疑问Apache是一个优秀的web server,但它也不万能的,在一些特定的环境下,也有Apache力不从心的时候。手上一台server由于瞬间高密度的访问非常多,因此Apache 1.3.x应付起来有点吃力,表现为响应速度慢,而且非常耗资源,Swap经常都是占满的。有一两次还导致机器负载过高(高达30-40,有个别时刻居然达到150之巨),感觉要死机的样子。

    为此,必须寻求一个解决之道。分析之下,这台server目前的情况主要是由于运行了大量的fastcgi应用,而且这些应用的并发非常密集,平时白天就有200-300个连接,厉害的时候有近1000个在用进程。apache的运行情况top如下:

    25806 nobody 15 0 7224 5888 1652 S 0.0 0.5 0:10 1 httpd
    28152 nobody 15 0 6576 5856 1680 S 0.0 0.5 0:01 1 httpd
    28686 nobody 15 0 7224 5808 1652 S 0.0 0.5 0:01 1 httpd

    可见每个process的Share 内存就有1.6MB之多,如果是1000个进程就是1.6G了。加上其他开销,实际需要2G的存储空间,机器的内存是1G,交换区是1G,那实际上Swap将全部耗尽。

    如何降低这些开销呢?fastcgi应用程序已经较好的优化了,耗费的资源很少,而且只有少于10个进程在运行,因此问题不在fastcgi。问题在Apache的并发响应能力,以及资源占用上。

    使用lighttpd可以较好的解决这个问题,lighttpd基于单进程多路复用技术,因此消耗的资源非常少。而且支持fastcgi,但由于对php的支持仅限于fastcgi,与机器现有的一些网站并不能很好的兼容,因此考虑前端(80端口)用Apache,后端(2088)用lighttpd,通过rewrite技术,将fastcgi请求转交(Redirect)给后端的lighttpd处理。

    这样原理上就能使apache的进程大幅度减少,并只是负责请求的转发而已,可以充分的利用原来的进程资源。而lighttpd消耗的cpu/memory资源也较低,因此完成同样的任务,Apache+lighttpd的方案就比原来的纯Apache要好得多。

    实际运行证明,效率要好得多,响应速度提高了一个数量级以上。客户反映良好。

    Apache rewrite + lighttpd 实现方法

    原来负载较高的网站主机名highload.xxx.com ,运行的fastcgi prefix是/fcgi-bin。因此需要对这个虚拟主机进行Rewrite配置。

    第一步,编译apache,激活mod_rewrite:

    ./configure \
    --with-layout=Apache --prefix=/usr/local/httpd \
    --enable-shared=max --enable-module=rewrite \
    --enable-shared=rewrite
    

    安装并加载好之后,配置highload.xxx.com的虚拟主机,在VirtualHost里增加:

    RewriteEngine on
    RewriteRule   ^\/fcgi-bin\/(.+)      http://highload.xxx.com:2088/$1
    

    第二步,编译lighttpd,配置fastcgi并使lighttpd监听于2088端口:

    ./configure --prefix=/usr/local/lighttpd
    

    配置:

    server.modules              = (
                                   "mod_access",
                                   "mod_fastcgi",
                                    "mod_accesslog" )
    
    server.document-root    = "/var/www/vhost/highload/fcgi-bin/"
    server.errorlog             = "/var/log/lighttpd/lighttpd.error.log"
    
    server.indexfiles           = ( "index.php", "index.html",
                                    "index.htm", "default.htm" )
    
    mimetype.assign             = (
      ".pdf"          =>      "application/pdf",
      ".sig"          =>      "application/pgp-signature",
      ".spl"          =>      "application/futuresplash",
      ".class"        =>      "application/octet-stream",
      ".ps"           =>      "application/postscript",
      ".torrent"      =>      "application/x-bittorrent",
      ".dvi"          =>      "application/x-dvi",
      ".gz"           =>      "application/x-gzip",
      ".pac"          =>      "application/x-ns-proxy-autoconfig",
      ".swf"          =>      "application/x-shockwave-flash",
      ".tar.gz"       =>      "application/x-tgz",
      ".tgz"          =>      "application/x-tgz",
      ".tar"          =>      "application/x-tar",
      ".zip"          =>      "application/zip",
      ".mp3"          =>      "audio/mpeg",
      ".m3u"          =>      "audio/x-mpegurl",
      ".wma"          =>      "audio/x-ms-wma",
      ".wax"          =>      "audio/x-ms-wax",
      ".ogg"          =>      "audio/x-wav",
      ".wav"          =>      "audio/x-wav",
      ".gif"          =>      "image/gif",
      ".jpg"          =>      "image/jpeg",
      ".jpeg"         =>      "image/jpeg",
      ".png"          =>      "image/png",
      ".xbm"          =>      "image/x-xbitmap",
      ".xpm"          =>      "image/x-xpixmap",
      ".xwd"          =>      "image/x-xwindowdump",
      ".css"          =>      "text/css",
      ".html"         =>      "text/html",
      ".htm"          =>      "text/html",
      ".js"           =>      "text/javascript",
      ".asc"          =>      "text/plain",
      ".c"            =>      "text/plain",
      ".conf"         =>      "text/plain",
      ".text"         =>      "text/plain",
      ".txt"          =>      "text/plain",
      ".dtd"          =>      "text/xml",
      ".xml"          =>      "text/xml",
      ".mpeg"         =>      "video/mpeg",
      ".mpg"          =>      "video/mpeg",
      ".mov"          =>      "video/quicktime",
      ".qt"           =>      "video/quicktime",
      ".avi"          =>      "video/x-msvideo",
      ".asf"          =>      "video/x-ms-asf",
      ".asx"          =>      "video/x-ms-asf",
      ".wmv"          =>      "video/x-ms-wmv",
      ".bz2"          =>      "application/x-bzip",
      ".tbz"          =>      "application/x-bzip-compressed-tar",
      ".tar.bz2"      =>      "application/x-bzip-compressed-tar"
     )
    
    url.access-deny             = ( "~", ".inc" )
    server.port                = 2080
    
    fastcgi.server             = ( "prog1" => 
                                    ("prog1" =>("socket" => "/tmp/prog1.socket")),
                                   "prog2" =>
                                    ("prog2" =>("socket" => "/tmp/prog2.socket"))
                                )
    

    这样lighttpd将监听于2088端口,访问http://highload.xxx.com:2088/prog1或prog2就可以执行fastcgi应用了。

    注意,由于prog1/prog2等程序是非PHP 的fastcgi程序,由perl/c写成,因此必须用lighttpd的spawn-fcgi程序实现将这些fcgi应用运行,才能启动lighttpd,否则lighttpd会出错。

    进入/usr/local/lighttpd/bin,执行:
    ./spawn-fcgi -s /tmp/prog1.socket -f /var/www/vhost/highload/prog1
    
    ./spawn-fcgi -s /tmp/prog2.socket -f /var/www/vhost/highload/prog2
    

    执行成功的话,将显示:

    spawn-fcgi.c.160: child spawned successfully: PID: 602
    

    重新启动apache,这样凡是访问http://highload.xxx.com/fcgi-bin/prog1或prog2,将自动定向到http://highload.xxx.com:2080/prog*。

    经过这样改进后,平均的Apache进程数从650-700降低到250,其余的400-500个并发就由lighttpd来处理。整机的负载也降低了很多。主要是内存使用大幅度降低了。只有原来的40%用量,swap余量非常足够:-)

    而且最重要的是,响应速度快了很多。以下是并发请求的监视图:
    lighttpd-requests-day-demo.png

    注意:图上显示的是按每秒的并发请求次数,而不是并发连接数,并发连接数大概是这个数的10倍,也即如果有25请求/秒,那么实际在一段时间内的持续并发连接数就有250-300个。

    Posted by hzqbbc at 10:18 AM | Comments (8)

    May 22, 2005

    lighttpd,thttpd,shttpd - 轻量级webserver介绍

    国内绝大部分的web server不是IIS就是Apache,而论市场占有率,我认为Apache是大赢家了,至少是占据了半壁江山。

    但除了IIS/Apache外,其实我们有很多选择,对于高负载/大并发的网站而言,高性能、轻量级的web server是一剂良药。最近手头一台Server 的负载太高,居然将swap吃光导致机器非常缓慢,后来一查,原来是Apache耗掉了几乎所有资源,当时apache进程已有9XX个了。

    于是用轻量级的web server替换掉apache就进入了日程表。这里顺带介绍一下这些可选的对象:
    lighttpd | thttpd | shttpd

    lighttpd

    官方主页:www.lighttpd.net
    Lighttpd是一个德国人领导的开源软件,其根本的目的是提供一个专门针对高性能网站,安全、快速、兼容性好并且灵活的web server环境。具有非常低的内存开销,cpu占用率低,效能好,以及丰富的模块等特点。

    lighttpd是众多OpenSource轻量级的web server中较为优秀的一个。支持FastCGI, CGI, Auth, 输出压缩(output compress), URL重写, Alias等重要功能,而Apache之所以流行,很大程度也是因为功能丰富,在lighttpd上很多功能都有相应的实现了,这点对于apache的用户是非常重要的,因为迁移到lighttpd就必须面对这些问题。

    在google搜索了一下,简体中文介绍lighttpd的文章几乎没有,大多数都是台湾同胞的Big5内容。因此在接下来的时间里,想好好写一篇介绍lighttpd,以及简单的benchmark的文章。

    实用起来lighttpd确实非常不错,上文提到的apache overload的问题,用lighttpd就完全解决了。apache主要的问题是密集并发下,不断的fork()和切换,以及较高(相对于lighttpd而言)的内存占用,使系统的资源几尽枯竭。而lighttpd采用了Multiplex技术,代码经过优化,体积非常小,资源占用很低,而且反应速度相当快。

    利用apache的rewrite技术,将繁重的cgi/fastcgi任务交给lighttpd来完成,充分利用两者的优点,现在那台服务器的负载下降了一个数量级,而且反应速度也提高了一个甚至是2个数量级!

    thttpd

    官方网站:http://www.acme.com/software/thttpd/
    thttpd是一个非常小巧的轻量级web server,它非常非常简单,仅仅提供了HTTP/1.1和简单的CGI支持,在其官方网站上有一个与其他web server(如Apache, Zeus等)的对比图+Benchmark,可以参考参考。此外,thttpd 也类似于lighttpd,对于并发请求不使用fork()来派生子进程处理,而是采用多路复用(Multiplex)技术来实现。因此效能很好。

    Thttpd支持多种平台,如FreeBSD, SunOS, Solaris, BSD, Linux, OSF等。对于小型web server而言,速度快似乎是一个代名词,通过官方站提供的Benchmark,可以这样认为:thttpd至少和主流的web server一样快,在高负载下更快,因为其资源占用小的缘故。

    Thttpd还有一个较为引人注目的特点:基于URL的文件流量限制,这对于下载的流量控制而言是非常方便的。象Apache就必须使用插件实现,效率较thttpd低。

    shttpd

    官方网站:http://shttpd.sourceforge.net/ Shttpd是另一个轻量级的web server,具有比thttpd更丰富的功能特性,支持CGI, SSL, cookie, MD5认证, 还能嵌入(embedded)到现有的软件里。最有意思的是不需要配置文件!

    由于shttpd可以嵌入其他软件,因此可以非常容易的开发嵌入式系统的web server,官方网站上称shttpd如果使用uclibc/dielibc(libc的简化子集)则开销将非常非常低。以下是其特点:

    Stand-alone server, or embeddable into existing C/C++ program
    GET, POST, PUT, DELETE methods
    CGI
    SSL
    Digest (MD5) authorization
    Multiple (and user defineable) index files
    Directory listing
    Standard logging
    Cookies
    inetd mode
    User-defineable mime types
    No configuration files
    No external dependencies

    由于shttpd可以轻松嵌入其他程序里,因此shttpd是较为理想的web server开发原形,开发人员可以基于shttpd开发出自己的webserver!

    Posted by hzqbbc at 07:17 AM | Comments (4)

    May 21, 2005

    人间真情:“弟弟”病危托孤,“大姐”守10年之诺

    昨天晚上浙江电视台播出了一集节目,讲述了河南一位贫困农民与一名下岗大姐的故事。本来想用“感人”一词来形容这个真人真事,但又觉得太普通了。事情里折射出主人公人性善良、果敢和坚毅的一面,与现在社会一些追求名利、漠视的人性的风气真的形成了非常鲜明的对比。

    后记:电视节目的尾声,主人公之一:薛荣告诉了电视观众一个消息,她要搞一个网站,专门给那些希望奉献爱心的人,网址是爱心妈妈

    以下引用《知音》网站的报道:
    

    河南省中牟县刘集镇岗赵村村民赵景跃,在一次即将发生的群殴事件中保持冷静的头脑,替当事人薛荣解了围。薛荣感激之中随口对赵景跃说了一句:“以后,有啥困难来找大姐。”

    10年后,正值壮年的赵景跃却不幸确诊为肝癌晚期。为了不拖累家人,万念俱灰的他决心一死了之。但是,他又放心不下体弱多病的妻子和两个聪明懂事的女儿,绝望中他想起了10年前薛荣的那句话,于是,他开始紧急寻找已经整整10年没有任何音信的薛荣,希望她能履行10年前的那句承诺……

    施恩思报,绝症男儿急寻“大姐”托孤赴死

    2002年10月下旬,35岁的赵景跃在中牟县中医院做胃穿孔手术时,意外地发现其肝部有恶性肿瘤阴影。这个消息简直如晴天霹雳,击倒了他和妻子徐琳软。11月上旬,他们又到郑州煤炭总医院重新检查,结果更是将他们推向了万丈深渊:恶性肿瘤晚期!

    赵景跃家在村里是最典型的贫困户。妻子徐琳软在生大女儿时大出血,体质一直虚弱,此外还患有胃病、风湿性关节炎、妇科病等多种慢性疾病,平时只能干点轻活,两个女儿还在上学,家里的担子全压在赵景跃一个人身上。现在为了给他做胃穿孔手术,家里已经负债累累。对妻女的愧疚和手术后各种并发症的折磨,让这个原本1.80米的铁骨铮铮的汉子从身体到精神完全垮了。每个不眠之夜,赵景跃想得最多的就是如何在自己死前安排好妻子和两个女儿。妻子体弱多病,两个聪明懂事的女儿还在读小学,他怎么能放心地丢下她们娘儿仨撒手西去呢?他想来想去,只有一个办法:在自己走后,让妻子再找个人家,支撑起这个苦难的家。但一想到孩子寄人篱下受委屈,他便又心如刀绞。2003年1月下旬,他偷偷地写好了遗书,叮嘱妻子在他死后再找个合适的人嫁掉,但一定要善待两个孩子。写完遗书,他准备服安眠药自杀。

    几天后的一个早晨,大女儿红星该上学了,她却迟迟不肯去学校。徐琳软催她,红星嗫嚅着说:“爸爸、妈妈,我不想上学了。”她又哭着说:“爸爸病成这个样子,我根本没心思学习,我想出去打工,挣钱给爸爸看病!等爸爸的病好了,我再回来上学!”

    才12岁的女儿,能说出这样懂事的话来,感动、欣慰、歉疚齐聚赵景跃心头。他猛然觉醒,如果自己这样自杀,将给孩子心头留下难以愈合的创伤,于是决定暂时取消自杀的念头。那天他和妻子把小红星“赶”出去上学后,夫妻俩在家里抱头痛哭……

    怎样才能拯救这个风雨飘摇的家呢?赵景跃愁断枯肠。忽然他脑子里电光石火般想起一个人:薛荣。

    薛荣是郑州市人,10年前,36岁的她因为企业破产成了一名下岗女工,后她到赵景跃所在的村附近,承包了800亩鱼塘养殖黄河鲤鱼。1993年5月上旬的一天,几个村民去薛荣的场部借拖拉机的拖斗,因为村民经常是有借无还,场部的工作人员没有答应。双方发生口角,进而打了起来。几个村民没有占到便宜,回村纠集了200多位村民,赵景跃也在其中。村民们都拿着锄头棍棒,赶往渔场,气势汹汹要将渔场踏平!

    村民们赶到渔场的时候,渔场的大门已经上了锁,身为老板的薛荣独自挡在大门外。大门里面,渔场的百十号职工都手持棍棒严阵以待。村民们吵吵嚷嚷要薛荣交出“打人凶手”。薛荣一口咬定打架的职工已经被她给“开除”了。村民们哪肯善罢甘休,叫嚷着要撞开大门进场部搜人。眼看一场群殴在所难免,薛荣就用身体堵着大门上的锁,大叫:“你们除非从我身上踏过去,不然就别想进这个大门半步!”

    200多人如果发生混战,后果不堪设想!赵景跃觉得自己应该站出来控制事态的发展。于是在这紧急关头,他站了出来,大声喊道:“大家安静!……要想真正解决问题,双方都派个代表出来谈!打起架来东西不认人,都是有老婆孩子的人,打死打伤谁都不是什么好事情!”经他这么一说,村民们都理智下来,最终统一意见,由村支书和村主任第二天出面跟渔场方面谈判。一场剑拔弩张的群殴就此平息。

    通过这件事,赵景跃和薛荣认识了。两个月后,由于跟村民关系难以相处,薛荣不得已决定提前终止承包合约。离开之前,薛荣摆告别宴答谢亲朋好友,也请了赵景跃。席间,薛荣特地给赵景跃敬酒,感谢他对自己的帮助,并流着泪说:“大兄弟,大姐感谢你!以后有什么困难,尽管来找大姐!不管大姐过得咋样,只要能帮上忙,我一定不会推辞!”

    往事历历在目,不知道薛姐现在过得怎么样?两个孩子如果有一个像她那样能干又仗义的人照着,自己也可以放心地“走”了。可是一别10年,两人无任何往来,薛姐现在人在何处、过得怎么样,还记得10年前的那句承诺吗?就算记得她会当真吗?赵景跃心里宛如一团乱麻,试着跟妻子说起这事,妻子也觉得太过渺茫。

    但是,赵景跃觉得在别无他法的情况下还是要试一试。当务之急,是要找到薛姐。可是,茫茫人海,哪儿去找她呢?赵景跃绞尽脑汁。薛姐的家在郑州,应当不会离开河南。最后,他想出了一个办法:向报社求助。

    2003年2月19日,赵景跃在妻子的陪同下来到郑州。跑了几家报社,最后,《东方家庭报》的朱顺忠记者答应为他帮忙。

    大姐来了,“第二妈妈”深情拯救绝地之家

    2003年2月20日,这家报纸果然在头版刊登了《施恩图报,我咋张口》的报道。报道用化名讲述了赵景跃和“雪女士”之间的往事和他现在的困境,并鼓励人们对他该不该恳请薛荣帮助进行讨论。

    幸运的是,这篇文章刚好被薛荣看见了。10年之后的薛荣,此时是一家家政公司的总经理。那天中午下班后,她在路边报摊上随手买了一份《东方家庭报》,刚好看到了这篇报道,她一看就知道文中的“雪女士”是指自己。历历往事浮上心头。为了保护三个打架的职工,那时她真的豁出去了,当时,如果不是赵景跃出面解围,后果不堪设想。分别时她对赵景跃所说的话,正是她内心感激的一种流露。10年间,她9次创业全都失败,只落下一身债务,为了还债,她做起了保姆,扫厕所、洗门窗、看孩子,一步一步做到了现在拥有7000多名员工的郑州圆方家政服务公司总经理的位置上。这期间她也偶尔会想起赵景跃。在她眼中,赵景跃身体强壮,有思想有知识,未曾想命运却对他如此残酷!

    薛荣的心情十分沉重,立即从报社值班室查到朱顺忠记者的电话,向他询问赵景跃的联系方式。当她了解到朱记者那儿拍有很多他的照片,就赶到报社。当她看到电脑里苍白瘦弱、毫无生机的赵景跃时,不由感到一阵揪心的疼。她决定第二天去探望赵景跃。

    下午,薛荣给赵景跃买了不少营养品,又给两个孩子买了新书包、新衣服。第二天,下起了瓢泼大雨,而去刘集的路都是土路,一路上,薛荣带的车几次陷入泥坑,几个人冒雨下来推车,弄得满身泥污。到达村口时,赵景跃一家4口已经打着伞站在那儿迎接他们。久别重逢,薛荣看着瘦得不成样子的赵景跃,心里好一阵酸楚,紧紧握住了他的手。赵景跃叫了声“薛姐”,话还没说出口,眼泪已先流了下来……

    薛荣搀着赵景跃,一行人到了他家里。薛荣把赵景跃扶到床上躺下,只走了几步路,赵景跃已是气喘吁吁。薛荣四下环顾,这是一个怎样的家啊,两间半屋子,空荡荡的,两张简易木床,一个破柜子,一张旧方桌、几张小矮凳和一台所有开关旋钮已经掉完了的14寸的黑白电视机,便是全部家当。眼前的情形让薛荣无比心酸。唯一让人欣慰的是,堂屋正中的墙上一排大女儿红星得的奖状。

    薛荣简单地跟赵景跃介绍了自己的情况,对赵景跃说:“景跃,你放心,大姐对你说过的话,永远都算数!有什么要求,你只管跟大姐说!”她说这些的时候,已经下定决心要帮赵景跃治病。

    赵景跃说:“薛姐,其实我真的不想麻烦你,只恨我自己没用,不但不能养家糊口,还拖累家里为我看病借下2万多元债务……我死了不要紧,琳软也可以再找个人家,可我这两个孩子咋办啊?”说着说着,一个五尺多高的大男人,竟然忍不住哭了起来。在他的感染下,妻子和两个孩子也都哭了起来,眼前的场面让薛荣和随行的朱顺忠记者也忍不住泪湿了眼眶。

    “薛姐,我想把两个孩子托付给你,这是我死之前唯一的愿望……你是个侠义心肠的人,你要能满足我这个愿望,我就是死也安心了……”

    薛荣没料到赵景跃竟然会“临死托孤”,这明显是要让她认领两个孩子。这份责任太沉重了!她还没来得及细想,赵景跃已挣扎着从床上坐起来,一只手拉着大女儿红星,一只手拉着小女儿航航,命令她们:“快给薛妈妈下跪磕头,叫薛妈妈!”两个孩子还有点犹豫和胆怯,他便使劲摁着她们给薛荣下跪。两个孩子于是双双跪在薛荣面前,怯生生地叫了声“薛妈妈”。薛荣只好答应,然后将她们从地上扶起,说:“好吧,你们两个我认下了,以后,我就是你们的第二个妈妈!”

    薛荣从中牟回家后,当晚,她辗转反侧不能入睡。无论如何,认了两个女儿,她不能不跟丈夫商量一下。她给在外地出差的丈夫李河通打了个电话,没想到丈夫并没有责备她,反而说:“好啊!咱俩只有一个儿子,再认两个女儿,也不是件坏事!”见丈夫这样支持她,她悬着的心才放下了。

    按照目前的情况看,薛荣知道,赵景跃已经根本没有任何治疗的能力了,他是把孩子托付给自己后,便一心在家里等死。现在,既然两家人认成了亲人,无论如何,自己也不能看着他就这样等死啊!有了老公的支持,薛荣觉得自己首要的问题是尽全力帮助赵景跃看病。如果能帮他看好病,这个风雨飘摇的家就有救了!

    薛荣分析,赵景跃的病情之所以到这种地步,关键是因为“心病”——担心自己哪天“走”了,老婆孩子没人照应。要治好他的病,必须先帮他卸下心理包袱,让他的心情先好起来。在此基础上,再让他接受治疗……

    于是,第二天,她再次赶到赵景跃家正式认红星和航航做自己的干女儿,认认真真地让她们行了跪拜礼。然后,她又对赵景跃说:“景跃,从今以后,红星和航航的事就归我这第二个‘妈妈’了,我就是再苦再难,也要一直供到她们读完大学!弟媳妇的事你也别担心,万一将来你要有啥不测,我就让她到我们公司去工作,做个保洁工,虽然辛苦点,但吃穿不用愁。空口无凭,今天我带着朱记者来给我们作证!”

    赵景跃听了感激涕零:“大姐,你叫我怎么感谢你呢?等我死了,下辈子做牛做马报答你的恩情!”

    薛荣话锋一转,说:“不过,我也有个条件,你必须答应我。”

    赵景跃说:“什么条件,你说吧!只要我能办到,我一定答应!”

    薛荣说:“那好。其实也没什么,就是你必须坚强地面对病魔,保持快乐的心情,好好地接受治疗。我看你现在一心只想着死,这怎么能行呢?病就是你的敌人,你进它就退,你退它就进!现在你就跟着大姐一起,到郑州看病去!赶紧把东西收拾收拾吧!”

    赵景跃嗫嚅着说:“大姐,我现在哪还有钱看什么病啊!”

    “你放心,只要能治好你的病,就是砸锅卖铁,大姐都给你凑!”薛荣斩钉截铁地说。

    “不行,大姐,我已经是快要死的人了,说什么也不能再给你添麻烦了!”赵景跃怎么也不肯答应。薛荣给他下了最后通牒:你要不答应,你这个家我也就不再管了!

    无奈,赵景跃只好答应下来。薛荣当即为红星和航航补交了欠下的学杂费,然后带着赵景跃来到郑州检查治疗,安排他住进了郑州市煤炭总医院。

    雨过了,天晴了,“第二妈妈”的心放下了

    赵景跃在煤炭医院治疗期间,薛荣不仅负担了他的医药费,还在百忙之中基本上每天都要抽出时间去医院探视他,给他送去各种营养品。

    高昂的住院费使赵景跃感到忐忑不安。只住了两三天,他就说什么也不愿再住下去,偷偷出了院。

    当晚,薛荣在应酬完一个客户后,来到医院看望赵景跃,发现他擅自出院后不由大吃一惊,急忙驱车赶往中牟县刘集镇。恰逢刚刚下过大雨,从刘集镇到岗赵村的路全是土路,泥泞不堪,车子走得异常艰难,途中还陷入了泥坑。最后,薛荣只好下车徒步行走,一不小心,竟然将脚崴了,钻心地疼。她咬着牙自己揉捏了一下,最后坚持着一瘸一拐地来到赵景跃。

    薛荣的突然出现,让赵景跃一家人大吃了一惊。赵景跃哭着对薛荣说:“大姐,我知道你对我是真好,可是,要治我这病,那不是花钱,是在烧钱啊!我咋个能忍心这样拖累你?不行,我就是死,也不去治了!”面对赵景跃的固执,薛荣生气了,大声地骂他说:“赵景跃!你太让我失望了!你瞧瞧你那熊样,还没得个病,就没一点精气神了,天天就是死啊死的,让周围的人跟着你一起难受!得了癌症看好的人多了,你要真是个男人,就应该拿出男人的种来,不要成天想着以死来解脱,而是跟病魔抗争到底!不管多么困难,我们一起挺过去!将来等你病好了,你花我多少钱,再挣钱还给我!”

    赵景跃完全理解薛荣使用“激将法”的一片苦心,他知道,自己无论如何拗不过大姐,内心纵有千言万语,也无法表达他的感激之情,他泪如雨下,咬着牙向大姐承诺:“大姐,你放心,我赵景跃以后绝不再为你丢脸,我一定要战胜病魔,重新负担起这个家庭的责任来!”

    就这样,赵景跃又重返郑州煤炭总医院住院治疗。在整个治疗期间,薛荣不但经常抽出时间前往探视,还在每个周末开车将红星和航航接到医院里,教她们一起鼓励赵景跃战胜病魔。在薛荣的教授下,红星在爸爸的病床头用纸板写下了一句勉励爸爸的话:“爸爸,你是一个勇敢而又坚强的男子汉,是我们大家学习的榜样,你一定会用自己的快乐和坚强战胜病魔!”每一次痛苦的化疗中,当赵景跃不堪忍受时,他就看看这句话,心头便涌起了无限的力量……

    经过一段时间的化疗,赵景跃的病情得到了控制,整个人的精神状况也比以前好了许多。见到这种情况,赵景跃全家和薛荣都十分振奋。两个月后,为了节省治疗费用,经过医院允许,赵景跃决定采取出院回家进行保守治疗。出院那天,薛荣特地向大夫询问赵景跃的病情,大夫说:“如果积极采取治疗,再加上良好的心态,也不能说没有奇迹发生的可能。”这话,让薛荣更加坚定了帮助赵景跃继续治疗的决心。

    在这期间,薛荣为了给赵景跃看病费尽心思。无论走到哪儿,她都四处打听治肝病的名医或者单方偏方,替赵景跃求医问药。打听到后,不管药价多昂贵,她都毫不犹豫地按疗程购买,然后送到赵景跃家中。因此,她每次去看望赵景跃时,都带着求来的大包小包的药物。每一次求医问药,花费都高达数千元。次数多了,连她自己都记不清花了多少钱!

    “第二妈妈”还与两个“女儿”红星和航航很快打成了一团,经常开车接她们到医院探望爸爸,还带着她们去动物园游玩,或带她们到自己的公司玩,,给她们梳头发、扎小辫,跟她们谈心,鼓励她们好好学习。孩子们很快就和她亲如一家了。

    为了时刻了解赵景跃的病情,在岗赵村电话线路装机容量已满的情况下,薛荣多次上乡电信部门请求他们给他家装一部电话,多少钱她都出。最后县网通公司领导被她的精神所感动,特地架专线为赵景跃家里装上了电话!有了电话,薛荣更是每天都要打电话到赵景跃家嘘寒问暖。

    赵景跃夫妇对薛荣感激不尽。每次薛荣来了,赵景跃都让妻子打荷包蛋招待她。每次薛荣走的时候,赵景跃和妻子还会将家里的苞谷、小米等农产品强行塞到薛荣车的后备箱。这朴素的感谢,让薛荣觉得,自己所有的付出都是值得的!

    由于没有了任何心理包袱,再加上治疗和休养得比较好,赵景跃的病情一天比一天好,不仅人能吃饭了,以前的神经官能症和失眠也全好了,还能下地干一些轻活了。2004年10月初,赵景跃在进行复查时,发现肿瘤在慢慢缩小,其肝功能正在慢慢地恢复。奇迹,就这样出现了!当天晚上,在赵景跃家里举办了一个小型的庆祝会,赵景跃以水代酒,饱含着热泪说:“大姐,要不是你,哪有我的今天;要不是你,哪有我们现在这幸福的一家!今天,我要敬你这一杯,祝愿好人一生平安!”薛荣也流泪了,尽管这一天屋外狂风暴雨,她却有一种雨过天晴的幸福之感。

    这两家人的真情故事传出后,感动了中央电视台《讲述》栏目组。2005年2月,中央电视台《讲述》栏目组特地赶赴河南采访了薛荣和赵景跃。爱,是可以创造奇迹的。赵景跃的主治医生,在郑州煤炭总医院坐诊的全国肝病科目防治办公室、河南专家指导站的刘开静教授说,从目前的检查结果看,赵景跃的肿瘤已基本消失,出现这种医学奇迹除了医院的化疗,薛荣的偏方外,他自身的心理调节也十分重要。

    如今,幸福和欢乐又重新回到了这个差点就支离破碎的家。而薛妈妈也有了全新的想法:她打算在今年秋季红星小学毕业后,将品学兼优的她接到郑州读中学,还打算在航航毕业后也让她去郑州上学,让她们都有机会接受更好的教育。现在,小红星热切地期盼着到薛妈妈身边读书的那一天。

    所有人都相信,这已无法分开的两家人的日子会越过越好!

    原文地址:http://www.zhiyin.com.cn/zy/ca5819.htm
    

    Posted by hzqbbc at 12:37 PM | Comments (1)

    May 18, 2005

    个性化GMail, hotmail, Yahoo!邮箱图标

    不知道在什么时候,Blog这个圈子里有人就开始使用邮箱图标来代替签名。这样做除了能彻底解决邮箱爬虫(一些专门在网页里搜刮邮件地址的软件,多数由Spamer操纵着)的问题外,还非常醒目。

    很快,这样的个性化邮箱图标就开始流传了。我最早还以为是个人自己用Photoshop之类的软件做的,但后来发现有不少人在用,才到google搜索了一下,结果发现原来都是利用Email Icon Generator之类的工具生成的。

    自己原来离“先进分子”那么遥远,于是赶紧也搞了几个回来。

    Gmail
    hzqbbc-gmail.png

    Hotmail
    hzqbbc-hotmail.png

    MSN
    hzqbbc-msn.png

    在google上搜索到了一些提供这种图标生成的网站:

    NHacks.com
    这个网站支持的比较全面,主流的GMail, Hotmail, MSN, lycos, yahoo, bigfoot, netscape, AOL, ATT等都支持。

    地址:http://www.nhacks.com/email/index.php

    Gmail Signature Generator
    另一个专门针对Gmail的邮箱图标的网站,图标比较有趣。不过比较大。
    地址:http://gizmo967.mgs3.org/Gmail/

    Playtime
    这个网站提供了GMail, Hotmail, MSN, Yahoo, AOL的图标个性化生成,而且还有相关的小程序下载,非常不错。

    地址:http://email.playtime.uni.cc/

    什么时候,我也设计一个@hzqbbc.com的呢?

    Posted by hzqbbc at 09:35 PM | Comments (0)

    May 15, 2005

    发布lilina 预缓存补丁(lilina cache patch)

    前几天对lilina的提速修改,经过整理后,做了一个补丁。经过约一周时间的测试,感觉稳定性和可靠性方面已没什么问题。由于浏览器访问的是html文件,所以速度相当满意。为了使cache文件能自动更新,我使用了一个小技巧:用<frame> 嵌套了index.php,这样每次访问cache文件时,都会调用index.php,index.php会判断cache文件是否过期,过期了则后台重建;如无过期则显示cache文件的创建时间,这样非常方便。

    下图是更新cache时显示的信息,注意看红圈内的信息:
    更新cache时的信息

    这是使用cache时显示的信息:
    使用cache时的信息

    对于没有Unix环境的朋友,可以下载打了补丁后的lilina-0.7

    补丁后的lilina-0.7下载

    下载地址: lilina-0.7-patched.tar.gz

    安装与标准的lilina没有什么区别,可以参考:小试RSS聚合器lilina,附安装方法,唯一要配置的就是$index_file及其对应的文件属性。详细见下文。

    补丁的全部内容入如下:

    
    --- index.php.old	2005-05-15 22:43:16.000000000 +0800
    +++ index.php	2005-05-16 13:37:59.000000000 +0800
    @@ -1,4 +1,10 @@
     <?
    +/* output buffer control start */
    +ob_start("callback");
    +$index_file = "cache.html";
    +$mt = mtime();
    +$rebuild = 0;
    +
     header("Content-Type: text/html; charset=utf-8");
     require_once './lib.php' ;
     
    @@ -7,6 +13,39 @@
     	define('MAGPIE_CACHE_AGE',1) ;
     } 
     
    +/* rebuild cache or not? */
    +if(time()-$mt>MAGPIE_CACHE_AGE) {
     +	$rebuild = 1;
     +}else {
     +	return 0;
     +}
    +
    +/* Function used to do cache */
    +function mtime() {
     +	global $index_file;
     +	$fd = fopen($index_file, "r");
     +	$fstat = fstat($fd);
     +	fclose($fd);
     +	return $fstat['mtime'];
     +}
    +
    +function callback($str) {
     +	global $rebuild, $index_file, $mt;
     +	$color = '#000000';
     +	$res = "<style><!-- body { font-size: 10px; font-family: Verdana; } --></style>";
     +	if($rebuild) {
      +		$color = '#ff0000';
      +		$fd = fopen($index_file, "w");
      +		fputs($fd, $str, strlen($str));
      +		fclose($fd);
      +		$time = strftime("%a %b %d %H:%M:%S, %Y", time());
      +		return $res."<b><font color=$color>Built index: $time</font></b>";
      +	}else {
      +		$time = strftime("%a %b %d %H:%M:%S, %Y", $mt);
      +		return $res."<b><font color=$color>Cache index: $time</font></b>";
      +	}
     +}
    +
     /* Function used to sort rss items in chronological order */
     function date_cmp($a, $b) {
         if ($a['date_timestamp'] == $b['date_timestamp'] ) {
      @@ -166,5 +205,15 @@
         <div id="footer">powered by <a href="http://lilina.sourceforge.net/"><img src="i/logo.gif" alt="lilina news aggregator" title="lilina news aggregator" /></a> v
           <?= $LILINAVERSION ?>
         </div>
      +
      +  <div id="updater" style="display: block; position: absolute; top: 10px; right: 100px;">
      +  <iframe marginheight=0 frameborder=0 scrolling=no height=20 src="index.php"></iframe>
      +  </div>
      +
       </body>
       </html>
      +
      +<?php
      +/* flush output buffer */
      +ob_end_flush();
      +?>
    

    将上述这段代码复制,保存到本地文件,例如lilina-cache.patch。并将patch文件上载到lilina的目录里,执行如下命令:

    patch -p0 < lilina-cache.patch
    
    这样就完成了补丁的操作。不过需要注意几点:
  • lilina-cache.patch必须放在与index.php同级目录里补丁操作方可成功
  • 默认cache文件名为cache.html,修改index.php里的$index_file变量为需要的cache文件名。
  • 注意$index_file所指向的文件/目录对于web服务器必须是可写的,建议属性改为777

    例如目前HZQBBC首页的lilina页面就是由/lilina/index.php生成的。其中$index_file = "../index.html"。除此参数及文件属性要注意外,不需要修改任何配置。

    补丁程序也可在这里下载

    Posted by hzqbbc at 03:41 PM | Comments (20)

    May 11, 2005

    为lilina增加文本预缓存支持(html cache)

    Lilina是一个不需要使用数据库的RSS新闻聚合器,由PHP编写而成,而且不需要数据库支持,纯文本操作,非常方便。

    但lilina的缺点也是很明显的,最严重的问题是性能/速度(performance!),虽然lilina已内置了cache功能,但如果订阅的新闻源一多,由于遍历的文件也随之增加,因此速度会越来越慢。

    我用lilina做首页,很多朋友都反映速度很慢。于是琢磨着给其提速,好几年没写过php了,估计快忘光了。于是到www.php.net去找找资料。

    提速原理:Cache

    大部分的web提速都是基于缓冲(cache)的原理,将输出的内容保存到一个静态文件里,在一定周期(Life time)内将结果从静态文件(cache file)里直接提取甚至直接输出这个静态文件。因此避免了大量的数据库或速度缓慢的操作,可大幅度提高性能。

    lilina的缺陷很明显,输出是由index.php完成。不可避免的需要大量耗时的操作。能否将输出的结果Cache起来呢?默认lilina 的cache data life time 是60*60秒(1小时),那么在1小时内,每次访问都只是访问cache而已,如果将输出结果保存成html文件,无疑能极大的提高速度。

    基本构思

    如何捕获lilina的输出呢?这个是关键问题。chedong的做法是使用wget来“获取”输出,保存到index.html里,这样最大的好处是实现简便,不需要任何额外的技术。只要系统安装了wget,在crontab里加一个定期更新index.html的指令即可。有关chedong的wget实现请参阅Lilina的简单预缓存加速

    但wget一法有一些小缺陷,对于虚拟主机用户没有crontab的权限,因此这个方法不太可行。而通过修改lilina的输出头,由浏览器代为Cache也是一个可行的方法。

    但我有个癖好,喜欢pure solution,希望不借助任何其他工具,在lilina里实现快照(Cache)提速。基本原理很简单:,利用php的Output Control技术,捕获php的输出,将输出写入Cache文件index.html里。如果在一定周期内Cache不过期,则不需要重建。

    具体实现

    真正需要涉及的Output Control函数是ob_start()和ob_end_flush(),前者标记了output buffering 开始,而后者则刷新buffer,将结果输出。

    以下是基本代码结构:

    
    <?PHP
    ob_start("callback"); // begin output buffer
    
    /* some varible defination goes here */
    $index_file = "/path/to/index.html";
    $mt = mtime();
    $rebuild = 0;
    
    if(time() - $mt > 3600) { // cache file expire?
             $rebuild = 1; // rebuild it
    }else {
             return 0; // ignore RSS process
    }
    
    /* cache index hack functions */
    // get cache file modify time
    function mtime() {
             global $index_file;
             $fd = fopen($index_file, "r");
             $fstat = fstat($fd);
             fclose($fd);
             return $fstat['mtime'];
    }
    
    // callback func for ob_start()
    function callback($str) {
             global $rebuild, $index_file, $mt;
             if($rebuild) {
                      $fd = fopen($index_file, "w");
                      fputs($fd, $str, strlen($str));
                      fclose($fd);
                      return "Index rebuild done";
              }else {
                      return "Using cache index";
              }
    }
    
    /* begin the main RSS processing..*/
    ......
    ?>
    some html..
    
    <?PHP
    ob_end_flush();
    ?>
    

    代码的实质功能无非是:检查cache文件是否过期,如过期则设置rebuild标记,如没有则终止程序。通过ob_start()设置了一个叫callback的回调函数,从而捕获了整个程序的输出,并保存到本地的index.html里。

    ...to be continue..

    Posted by hzqbbc at 11:41 AM | Comments (6)

    May 06, 2005

    如何捕捉CGI程序exception

    用perl写cgi程序的时候,如果出现了问题,大多数都必须查看Web server的日志才能知道程序哪里出了错误,页面一般只返回500服务器错误,不能立刻获得错误的原因。

    使用php的程序员就没有这个烦恼,因为php默认会将错误都打印到页面上。CGI程序里如何才能做到这一点呢?

    CGI::Carp这个模块支持这个功能,以下是例子:

    
    use CGI::Carp qw(fatalsToBrowser);
    die "Bad error here";
    

    详细请参阅CGI::Crap的在线手册

    那如果是自己写的简单CGI程序,不使用CGI.pm怎么办?以下是简单的方法......

    原理简述

    Perl 提供了%SIG 这个特殊的HASH,通过定义信号响应函数,可以捕捉die及一些warning的信息,并将这些信息打印到web页上。但为了尽可能早的加载这些代码,最好将信号捕捉代码放到BEGIN块中,这样就能保证程序一执行就先执行异常捕捉这段代码了。
    
    BEGIN {
         # fatal handler setting.
         $SIG{__DIE__} = $SIG{__WARN__} = \&some_func;
    }
    

    代码例子

    以下是一个简单的例程,定义了一个叫handler_fatal处理函数来处理意外错误信息。
    
    #!/usr/bin/perl -w
    use strict
    
    BEGIN {
         # fatal handler setting.
         $SIG{__DIE__} = $SIG{__WARN__} = \&handler_fatal;
    }
    # some perl code goes here
    ......
    
    sub handler_fatal {
         print "Content-type: text/html\n\n";
         print "@_";
    }
    

    上面这段perl程序中,如果调用一个名称为abc();的子例程,浏览器将看到如下的错误信息:

    Undefined subroutine &main::abc called at /home/hzqbbc/cgi-bin/fatal.cgi line 8.
    

    通过这个方法就可以很简便的进行程序调试了。Extmail中的CGI.pm就是使用类似的方法,可以捕捉die(), warn() 等函数产生的错误及系统的错误提示。

    Posted by hzqbbc at 09:00 AM | Comments (2)

    May 03, 2005

    Ad2disk项目相关帮助内容

    Ad2disk项目自推出以来,已有不少人申请并开通。但随这而来的是技术支持的问题。以下将一些常见问题及解决方法罗列出来,希望对Ad2disk项目成员有所帮助。

    * 本站提供的基本服务
    * FTP的使用及相关注意事项
    * 数据库使用的注意事项

    基本服务说明

    空间支持特性
    默认系统分配100MB的空间,该空间支持PHP/HTML,对于需要cgi支持的申请人,需要额外提出申请,系统默认不带CGI支持。CGI申请通过后即可根据配置使用,而且也是免费的。

    注意事项: 开通空间后,通过ftp登陆会发现有3个目录:log、ftp及html,主要用途是:

  • html是存放网页的根目录

  • ftp目前暂不提供用途

  • log存放系统日志,不能随意删除
  • 此外,由于系统是Unix系统,因此区分文件名大小写,请用户注意文件名的大小写问题。

    例如某帐号对应一个域名http://abc.hzqbbc.com,那么如果将一个叫test.html的文件上载到html目录里,那么访问的地址将变成:http://abc.hzqbbc.com/test.html了。

    域名指向问题
    如果申请人没有自己的域名或免费域名,本站可以免费提供一个xxx.hzqbbc.com的域名。原则上ftp用户名与该二级域名xxx部分一致。如申请人有自己的域名或国际域名,本站可提供正确指向。

    CMS/内容管理系统问题
    有部分申请者不熟悉如何使用php/perl开发的内容管理系统,bbs软件等,因此本站提供基本的CMS及相关配套软件使用,免除了用户的安装和调试麻烦。

    CMS(个人主页系统/内容管理系统)会采用MovableType 3.1x/2.6x版本。其中2.6x版本支持中文,但缺乏一些新功能,而3.1x目前只有英文版,但提供了更强劲的功能。MT的使用方法可以参考如下链接:
    http://mtbook.net
    Jedi's blog

    当然官方的MT手册是最优秀的教程。

    FTP使用方法及注意事项

    Leapftp使用方法:
    http://www.chinadds.com/support/learn00201.asp (这个稍微简单了点)
    http://cpatch.org/yangnan/is/leapftp/leapftp.htm (这个是台湾的,较详细)
    http://vip.zccn.net/help/HelpLeapFTP.asp (这个简体帮助,较详细)

    CureFTP使用教程之一:
    http://xz6.2000y.net/mb/2/ReadNews.asp?NewsID=184461

    数据库使用指南

    本站提供的数据库类型是MySQL,web管理后台地址是:
    http://www.hzqbbc.com/mysql

    每个申请mysql支持的申请者都将被分配一个单独的用户名,密码由申请人提供,并且限制了存取的权限,只下放了指定数据库的全部操作权限,对其他人的数据库没任何存取能力。

    详细的使用请查看phpmyadmin的手册或官方网站:
    http://phpmyadmin.sourceforge.net

    Posted by hzqbbc at 06:49 PM | Comments (2)