Archive for the ‘工具类’ Category

2011-12-31  开发中,积分系统;builder模式改造抽奖领奖流程

2011-12-31  待上线,修改代码,catch异常,即使tokyo崩溃,项目也可运行

2011-12-30  13:30人为操作导致tokyo server崩溃,数据丢失;15点左右,恢复一部分,使网页可运行;17点,全部恢复

今天在火丁笔记上看到介绍了Linux运维利器之ClusterShell,试用了一次,正好符合我上线代码的需求!

我们的环境如下:2台db server,4台web server,全部得通过跳板机登录,且跳板机不转发ssh命令(至少我目前没发现怎样操作),之前仅有2台web server的时候,我都是通过上线脚本,操控svn进行代码的更新。但是现在增长到4台之后,就显得麻烦了!

利用clustershell正好可以解决这个问题!在其中一台server上(我选择了一台web server),安装clustershell(它依赖于python),并且建立conf文件,在/etc/clustershell/groups中配置db和web服务器组:

[admin@v080027 clustershell-1.5.1]$ cat /etc/clustershell/groups
db: 192.168.80.103 192.168.80.104
web: 192.168.80.105 192.168.80.106 192.168.80.27 192.168.80.49
并且建立该server到其他机器的免密码ssh登录方式。

这样,就可以方便的管理其他服务器了!

交互的问题:因为上线前,都是要先比对新旧代码,确定无误后,输入“yes”,才正式merge代码的!由于上线脚本是自己写的,会read stdin的yes or no,所以只需要echo “yes” | ./push.sh 即可。当然,在这之前,需要先进入某一台服务器,查看push.sh的diff输出,确定无误!

虽然简陋,但是暂时可以满足我的需求。所以不再进一步学习了

深入理解linux的权限设置和SUID,SGID以及粘滞位

我们知道文件的权限可以用三个八进制数字表示。其实文件的权限应该用四个八进制来表示,不过用 ls -l 命令时,只显示三个罢了。那个没有显示的八进制数字其实是第一个,它用来设定一些特殊权限。这个八进制数字的三个位是:

SUID SGID sticky-bit

它们的含义是:

SUID 当设置了

SUID 位的文件被执行时,该文件将以所有者的身份运行,也就是说无论谁来执行这个文件,他都有文件所有者的特权。如果所有者是 root 的话,那么执行人就有超级用户的特权了。这时该位将变成一个安全漏洞,因此不要轻易设置该位。

SGID 与上面的内容类似。文件运行时,运行者将具有所属组的特权。

sticky-bit sticky 位要求操作系统既是在可执行程序退出后,仍要在内存中保留该程序的映象。这样做是为了节省大型程序的启动时间。但是会占用系统资源。因此设置该位,不如把程序写好。

set uid ;set gid;sticky bit区别

每一个文件有所有者及组编号,set uid ;set gid可以改变用户对文件具有的权限:写和执行.

setuid: 在执行时具有文件所有者的权限.
setgid: 设置目录. 一个目录被标上setgid位,此目录下创建的文件继承该目录的属性.
sticky bit: 该位可以理解为防删除位. 设置sticky bit位后,就算用户对目录具有写权限,但也只能添加文件而不能删除文件。
如何设置:

操作这些标志与操作文件权限的命令是一样的, 都是 chmod. 有两种方法来操作,
1) chmod u+s temp — 为temp文件加上setuid标志. (setuid 只对文件有效,U=用户)
chmod g+s tempdir — 为tempdir目录加上setgid标志 (setgid 只对目录有效,g=组名)
chmod o+t temp — 为temp文件加上sticky标志 (sticky只对文件有效)

2) 采用八进制方式. 这一组八进制数字三位的意义如下,
abc
a – setuid位, 如果该位为1, 则表示设置setuid
b – setgid位, 如果该位为1, 则表示设置setgid
c – sticky位, 如果该位为1, 则表示设置sticky

设置后, 可以用 ls -l 来查看. 如果本来在该位上有x, 则这些特殊标志显示为小写字母 (s, s, t). 否则, 显示为大写字母 (S, S, T)
如:

rwsrw-r– 表示有setuid标志 (rwxrw-r–:rwsrw-r–)
rwxrwsrw- 表示有setgid标志 (rwxrwxrw-:rwxrwsrw-)
rwxrw-rwt 表示有sticky标志 (rwxrw-rwx:rwxrw-rwt)

理解文件权限

所谓的文件权限,是指对文件的访问权限,包括对文件的读、写、删除、执行。Linux 是一个多用户操作系统,它允许多个用户同时登录和工作。因此 Linux 将一个文件或目录与一个用户和组联系起来。请看下面的例子:

drwxr-xr-x 5 root root 1024 Sep 13 03:27 Desktop

与文件权限相关联的是第一、第三、第四个域。第三个域是文件的所有者,第四个域是文件的所属组,而第一个域则限制了文件的访问权限。在这个例子中,文件的所有者是 root,所属的组是 root,文件的访问权限是 drwxr-xr-x。对于文件和目录讲,每个文件和目录都有一组权限标志和它们结合在一起,在上例中就是第一个域中的内容。下面来仔细分析这个域中各个符号的意义:

该域由 10 个字符组成,可以把它们分为四组,具体含义分别是:

d rwx r-x r-x

文件类型 所有者权限标志 组权限标志 其他用户权限标志

其中:

文件类型:第一个字符。由于 Linux 系统对与设备、目录、文件都当作是文件来处理,因此该字符表明此文件的类型,字符与对应的意义如下表:

文件标志

文件类型

例子

- 普通文件

数据文件、

ASCII 纯文本文件、程序

d 目录

/bin
b 块设备

/dev/hda(第一个 IDE 硬盘)
c 字符设备

/dev/ttyS1(与 DOS 种的串口等同)
s 套接字

/dev/log
p 命名管道

/dev/initctl(与“|”等同)
l 符号链接

/dev/modem->/dev/ttyS1

权限标志:

对每个文件或目录都有 4 类不同的用户。每类用户各有一组读、写和执行(搜索)文件的访问权限,这 4 类用户是:

root:系统特权用户类,既 UID = 0 的用户。

owner:拥有文件的用户。

group:共享文件的组访问权限的用户类的用户组名称。

world:不属于上面 3 类的所有其他用户。

作为 root,他们自动拥有了所有文件和目录的全面的读、写和搜索的权限,所以没有必要明确指定他们的权限。其他三类用户则可以在耽搁文件或者目录的基础上别授权或撤消权限。因此对另外三类用户,一共 9 个权限位与之对应,分为 3 组,每组 3 个,分别用 r、w、x 来表示,分别对应 owner、group、world。

权限位对于文件和目录的含义有些许不同。每组 3 个字符对应的含义从左至右的顺序,对于文件来说是:读文件的内容(r)、写数据到文件(w)、做为命令执行该文件(x)。对于目录来说是:读包含在目录中的文件名称(r)、写信息到目录中去(增加和删除索引点的连接)、搜索目录(能用该目录名称作为路径名去访问它所包含的文件或子目录)。具体来说就是:

1. 有只读权限的用户不能用 cd 进入该目录;还必须有执行权限才能进入。

2. 有执行权限的用户只有在知道文件名并拥有该文件的读权限的情况下才可以访问目录下的文件。

3. 必须有读和执行权限才可以使用 ls 列出目录清单,或使用 cd 进入目录。

4. 如用户有目录的写权限,则可以创建、删除或修改目录下的任何文件或子目录,既是该文件或子目录属于其他用户。

修改文件权限

首先讲修改文件的所有权,使用 chown 和 chgrp 命令:

chown new_user file or directory:修改文件或目录的所有者。

chgrp new_group file or directory:修改文件或目录的所属组。

这里需要注意的是:普通用户不能将文件或目录的所有权交与他人,只有 root 有这一权限。但是普通用户有权改变文件或目录的所属组。

由于每类用户的权限都是由 rwx 三位组成,因此可以用三个八进制数字表示文件的访问权。一个八进制数字可以用三个二进制数字表示,那么与其对应,权值为 4 的位对应 r,权值为 2 的位对应 w,权值为 1 的位对应 x。对于一类用户,将这三位与其对应的权值相乘求和,就可以得出对该类用户的访问权限。

改变文件访问权限的命令是 chmod,格式是:

chmod permission file_name

比如 chmod 764 a.txt,它表示对于文件的所有者,具有对该文件读、写、执行的权限。对于文件所属组的用户,拥有读、写的权限。对于其他用户,只有读权限。

这里需要注意的是:文件的创建者是唯一可以修改该文件访问权限的普通用户,另外一个可以修改文件访问权限的用户是 root。

还有一种表示方法,就是用字符串来设定文件访问权限。其中读用 r 表示,写用 w 表示,执行用 x 表示;所有者用 u 表示,组用户用 g 表示,其他用户用 o 表示,所有用户用 a 表示。那么上面例子就写成西面的模样:

chmod a+r,u+w,u+x,g+w a.txt

理解 SUID 和 SGID

在上面的章节中,我们知道了文件的权限可以用三个八进制数字表示。其实文件的权限应该用四个八进制来表示,不过用 ls -l 命令时,只显示三个罢了。那个没有显示的八进制数字其实是第一个,它用来设定一些特殊权限。这个八进制数字的三个位是:

SUID SGID sticky-bit

它们的含义是:

SUID 当设置了

SUID 位的文件被执行时,该文件将以所有者的身份运行,也就是说无论谁来执行这个文件,他都有文件所有者的特权。如果所有者是 root 的话,那么执行人就有超级用户的特权了。这时该位将变成一个安全漏洞,因此不要轻易设置该位。

SGID 与上面的内容类似。文件运行时,运行者将具有所属组的特权。

sticky-bit sticky 位要求操作系统既是在可执行程序退出后,仍要在内存中保留该程序的映象。这样做是为了节省大型程序的启动时间。但是会占用系统资源。因此设置该位,不如把程序写好。

zz from: http://hi.baidu.com/%B5%DA%C8%FD%B4%FA%B9%BA%CE%EF/blog/item/647c6b8bbe33af17c8fc7af2.html

在Linux操作系统中,有一个系统软件包,它的功能类似于Windows里面的“添加/删除程序”,但是功能又比“添加/删除程序”强很多,它就是Red Hat Package Manager(简称RPM)。此工具包最先是由Red Hat公司推出的,后来被其他Linux开发商所借用。由于它为Linux使用者省去了很多时间,所以被广泛应用于在Linux下安装、删除软件。下面就给大家介绍一下它的具体使用方法。

1.我们得到一个新软件,在安装之前,一般都要先查看一下这个软件包里有什么内容,假设这个文件是:Linux-1.4-6.i368.rpm,我们可以用这条命令查看:

rpm -qpi Linux-1.4-6.i368.rpm

系统将会列出这个软件包的详细资料,包括含有多少个文件、各文件名称、文件大小、创建时间、编译日期等信息。

2.上面列出的所有文件在安装时不一定全部安装,就像Windows下程序的安装方式分为典型、完全、自定义一样,Linux也会让你选择安装方式,此时我们可以用下面这条命令查看软件包将会在系统里安装哪些部分,以方便我们的选择:

rpm -qpl Linux-1.4-6.i368.rpm

3.选择安装方式后,开始安装。我们可以用rpm-ivh Linux-1.4-6.i368.rpm命令安装此软件。在安装过程中,若系统提示此软件已安装过或因其他原因无法继续安装,但若我们确实想执行安装命令,可以在 -ivh后加一参数“-replacepkgs”:

rpm -ivh -replacepkgs Linux-1.4-6.i368.rpm

4.有时我们卸载某个安装过的软件,只需执行rpm-e <文件名>命令即可。

5.对低版本软件进行升级是提高其功能的好办法,这样可以省去我们卸载后再安装新软件的麻烦,要升级某个软件,只须执行如下命令:rpm -uvh <文件名>,注意:此时的文件名必须是要升级软件的升级补丁

6.另外一个安装软件的方法可谓是Linux的独到之处,同时也是RMP强大功能的一个表现:通过FTP站点直接在线安装软件。当找到含有你所需软件的站点并与此网站连接后,执行下面的命令即可实现在线安装,譬如在线安装Linux-1.4-6.i368.rpm,可以用命令:

rpm -i ftp://ftp.pht.com/pub/linux/redhat/…-1.4-6.i368.rpm

7.在我们使用电脑过程中,难免会有误操作,若我们误删了几个文件而影响了系统的性能时,怎样查找到底少了哪些文件呢?RPM软件包提供了一个查找损坏文件的功能,执行此命令:rpm -Va即可,Linux将为你列出所有损坏的文件。你可以通过Linux的安装光盘进行修复。

8.Linux系统中文件繁多,在使用过程中,难免会碰到我们不认识的文件,在Windows下我们可以用“开始/查找”菜单快速判断某个文件属于哪个文件夹,在Linux中,下面这条命令行可以帮助我们快速判定某个文件属于哪个软件包:

rpm -qf <文件名>

9.当每个软件包安装在Linux系统后,安装文件都会到RPM数据库中“报到”,所以,我们要查询某个已安装软件的属性时,只需到此数据库中查找即可。注意:此时的查询命令不同于1和8介绍的查询,这种方法只适用于已安装过的软件包!命令格式:

rpm -参数 <文件名>

zz from: http://hi.baidu.com/mnkee/blog/item/efcb08467f4b950e6b63e538.html

————————————————-

改变默认安装路径:

首先用下面的命令查看一下该RPM包的默认安装目录,例如:

$ rpm -qpl ext3grep-0.10.0-1.el5.rf.i386.rpm
/usr/bin/ext3grep
/usr/share/doc/ext3grep-0.10.0
/usr/share/doc/ext3grep-0.10.0/INSTALL
/usr/share/doc/ext3grep-0.10.0/LICENSE.GPL2
/usr/share/doc/ext3grep-0.10.0/NEWS
/usr/share/doc/ext3grep-0.10.0/README

上面的命令列出了每一个文件即将被安装的位置,现在我们只需要重新用–relocate参数把安装目录定位一下就可以了:

rpm -i --relocate /usr/bin=/home/mysql/bin --relocate /usr/share/doc=/home/mysql/doc ext3grep-0.10.0-1.el5.rf.i386.rpm

全局性的vim配置可以写在.vimrc等配置文件里,而有的时候,希望针对某些特殊文件配置,也希望这些文件即使分发到其他人那里,也可以保留这些配置,这个时候,就需要vim modeline了!

在文件开头,或者最后,按照如下写法:

# vim: filetype=php

就可以把当前文件指定为php类型的文件。具体配置语法与vimrc没有区别。

具体参考:http://vim.wikia.com/wiki/Modeline_magic

cacti一款常用的图形化系统监控工具,今天在自己的虚拟机搭了一个试试,准备部署到服务器上。

尽量使用一个真实、单独的帐号运行cacti:sudo adduser cacti。

由于它依赖snmp、rrdtool等,所以这些都是需要装的:

通过yum安装:

net-snmp.i386 : 一个 SNMP 协议工具和库的集合。
net-snmp-devel.i386 : NET-SNMP 计划的开发环境。
net-snmp-libs.i386 : NET-SNMP 运行时间库。
net-snmp-perl.i386 : perl NET-SNMP 模块和 mib2c 工具。
net-snmp-utils.i386 : 来自 NET-SNMP 计划的,使用 SNMP 的网络管理工具。

通过rpm安装:

rrdtool-1.2.30-1.el4.wrl.i386.rpm  rrdtool-devel-1.2.30-1.el4.wrl.i386.rpm  rrdtool-perl-1.2.30-1.el4.wrl.i386.rpm

这三个rpm彼此之间有依赖关系,所以一定要一起安装:rpm -ivh rrdtool-*

具体安装过程可以参考官方文档:http://www.cacti.net/downloads/docs/html/install_unix.html

安装完毕之后,检查snmpd进程是否启动,如果没有,则手工启动之:sudo /sbin/service snmpd start

然后检查snmp是否正常启动:(如果出现大量输出,则正常)

snmpwalk -v 2c -c public 127.0.0.1 system

snmpwalk -v 2c -c public 127.0.0.1 if

如果异常,请修改/etc/snmp/snmpd.conf:

access  notConfigGroup “”      any       noauth    exact systemview none none

access  notConfigGroup “”      any       noauth    exact all none none

然后重启snmpd服务。

这时,进入cacti graph界面,如果不能出现图片,在firefox下可以看到,图片无法正常获取,可以看看apache log里是否有warning、notice等,因为cacti的图片由graph_image.php 生成,它声明header为png的图片,如果这时输出了文本信息,就会导致图片无法显示。或者关闭php的errorlog,或者修改一下cacti的代码:

lib/rrd.php 2023行:function rrdtool_function_graph($local_graph_id, $rra_id, $graph_data_array, &$rrdtool_pipe=null) {

这时,可能图片能显示,但是数据都是NAN,不要着急,因为cacti的数据来自rrdtool,而rrdtool需要一段时间养数据,等个10分钟左右,一般就会有数据了!

———————————————————————–
具体记录在服务器上安装cacti的过程,希望以一台服务器作为cacti server,监控多台服务器。

1、检查是否缺少软件:

[admin@v080049 ~]$ php -m | grep ‘mysql\|snmp\|gd\|session\|sockets’

gd mysql mysqli pdo_mysql session snmp sockets

[admin@v080049 ~]$ yum info net-snmp

[admin@v080049 ~]$ ps axu|grep snmpd

2、添加cacti用户:[root@v080049 ~]# adduser cacti

3、下载cacti源码,并解压,mv至web目录下

4、建立mysql相关:

[admin@v080049 cacti]$ mysqladmin -u root -p’×××××’ create cacti

root@(none) 05:15:09>grant all privileges on cacti.* to ‘cacti’@'localhost’ identified by ‘cactipwd’ with grant option; Query OK, 0 rows affected (0.01 sec)

[admin@v080049 cacti]$ mysql -u cacti -p’cactipwd’ cacti < cacti.sql

我汗,做到这里,突然发现,这个机器是合作方提供的vip组,我怎么定位到一台服务器上????

昨天,我们服务器交换机带宽占用率非常高,导致服务器访问延迟。

在这个时候,我尝试从其他3台机器进行了多次mysql远程连接尝试(期间还有几次打错了密码),现象是,客户端没有任何响应。在mysql server上查看,有一些连接处于connecting的状态,但是很快就断开了。

这时,使用netstat -anp|grep 3306,看到大量(400个左右)CLOSING状态的tcp连接。大致看了下,基本每个连接都是,server端向client端发送了61个包,而client仅向server发送了一个包。

tcp        1     61 local-ip:3306         remote-ip:11654       CLOSING     -  

当时比较慌乱,没有细思考,采取了以下两种无效的方法:

1、重启了mysql服务器,之后连接仍然存在,而且连接所属的pid没了。如上所示。

2、service network restart,连接也还在

在网上搜索,可能关键词不对,也没有找到合适的解决方法。只好自己想,在过程中,使用过fuser、lsof等命令,查看使用file或tcp、udp端口的进程信息等, /sbin/sysctl -A 查看tcp的超时配置。

因为closing状态,是代表server和client同时发出关闭socket请求,我猜想,是因为网络阻塞,延时或丢包造成的。而我重启了mysql之后,与socket关联的进程消失了,socket处于无主的状态,只能等待超时或者系统回收了。

这时我的想法是,既然socket也是一种文件,是否我找到该临时文件,删除就好了,但是很郁闷,我没找到。

又,如果我在client机器上,用同样的端口连接,发送关闭FIN包,是否可以关闭该连接呢?用了nc命令,还是无效。猜测是因为对端已经没有用户进程管理这个端口了。

折腾了两个小时,很奇怪的是,突然间,这些closing的端口就消失了。我猜测,如果是超时,因为我在不同时间去尝试连接的,前后总有一二十分钟的差距,不过也没有太注意到这些端口是逐渐消失,还是同一时间消失的。另一种可能是,系统内部有回收进程,当socket资源不足、或者一段时间之后,就会触发回收机制,释放了这些端口。

不明白,但是系统很有意思。

附上socket状态转移图:http://www.night-ray.com/TCPIP_State_Transition_Diagram.pdf


最近做了一个项目,提交给性能测试结果如下:

List: TPS =3400
Detail: TPS =480

Detail页面 资源消耗大:  CPU idle75%, Load average:10

服务器配置为8g内存,4cpu,linux 2.6的核,lighttpd+php,本机跑了memcached。另有一台同样配置的服务器跑mysql。

由于对方要求load必须降下来,所以开始调优。

首先分析为什么load会大呢?vmstat查看io和阻塞都不大,但是system cs即上下文切换峰值为万数量级。top看了下内存占用率也正常。而load代表的含义是,cpu中正在执行的进程与等待执行进程的数目。它过大的原因,要不就是进程数太多,要不就是某些进程占用时间片太长。

先从代码入手,把detail静态信息做缓存,动态信息ajax异步加载。但其实测试环境下,mysql数据量并不大,这样优化没啥效果。

第二步,想会不会是lighttpd并发数不够,所以增大了PHP_FCGI_CHILDREN,使总共派生的php-cgi数目达到500.还是没进展,而且貌似偶尔还有小下降。这时查看lighttd的errorlog,发现有mysql too many connection的错误。

第三步,调整mysql的配置,将Max_connections配置到500,wait_timeout配置为1000,即增大可用连接,防止长连接。这时看着有所进步。

第四步,既然我的tps已经达到要求,而load过高,那么调整lighttpd的并发并没有好处,所以仍旧修改php-cgi数目为100。

第五步,将memcached迁移到mysql服务器上,因为该服务器cpu、内存使用都比较低。

再次测试,load降到了4以下!bingo!

ps:记录一些命令

查看cpu信息:grep ‘model name’ /proc/cpuinfo

据说load average的值保持在  Load Average < CPU个数 * 核数 *0.7 比较好!

这里有一篇文章,把load average说的很明白:http://www.gracecode.com/archives/2973/

context switch rate(上下文切换)的说明,节取自:http://blog.csdn.net/marising/archive/2010/01/12/5182771.aspx

就是Process(Thread)的切换,如果切换过多,会让CPU忙于切换,也会导致影响吞吐量。《高性能服务器架构 》这篇文章的第2节就是说的是这个问题的。究竟多少算合适?google了一大圈,没有一个确切的解释。Context Switch大体上由两个部分组成:中断和进程(包括线程)切换,一次中断(Interrupt)会引起一次切换,进程(线程)的创建、激活之类的也会引起一次切换。CS的值也和TPS(Transaction Per Second)相关的,假设每次调用会引起N次CS,那么就可以得出

Context Switch Rate = Interrupt Rate + TPS* N

CSR减掉IR,就是进程/线程的切换,假如主进程收到请求交给线程处理,线程处理完毕归还给主进程,这里就是2次切换。也可以用CSR、IR、TPS的值代入公式中,得出每次事物导致的切换数。因此,要降低CSR,就必须在每个TPS引起的切换上下功夫,只有N这个值降下去,CSR就能降低,理想情况下N=0,但是无论如何如果N >= 4,则要好好检查检查。

对于ligttpd来说,一个请求,先发送至lighttpd,然后交给fastcgi模块(这个模块是编译在ligttpd里的,不知道会不会导致cs切换),最后交给php-cgi,应该最终还会把处理结果返回给lighttpd,从而传送给用户。这样算来,一次请求至少导致2次cs切换。

这个文章不错,存之:http://blog.csdn.net/tianlesoftware/archive/2011/02/21/6198780.aspx

前两天对lighttpd+fastcgi(php)进行了压力测试,在我的破虚拟机上,对一个简单的php页面访问QPS是60+,而纯静态页面QPS是700+。

所以坚定了对部分关键页面静态化的决心。但是希望尽量不破坏网站原有逻辑,所以使用了bash来做。具体流程图如下:

静态化流程图

静态化流程图

触发静态化

我们的内容是由运营人员在后台发布的,所以当新增、修改、删除(相当于修改了产品的状态为deleted)的时候需要触发静态化。我的做法是插入一条新纪录到static_help表,该表的id是自增的。

cron判断是否需要静态化

该脚本定时运行,首先会检查本地文件static_flag.txt,其中保存了上次运行的static_help.id。如果static_help.id不存在或者为空,则需要重新静态化。然后curl’获取线上的动态内容首页,获取其中的js变量index(动态获取的max(static_help.id)),如果static_help.id > page.index,说明有新变动,则需要更新。

cron单例

为了避免多个cron同时运行,造成冲突,所以使用了以下简单的脚本,保证同一时刻仅有一个进程运行:

function LockFile() {
        [ -e /dev/shm/${0##*/} ] && errorexit "Self already Run!"
        ln -s /proc/$$ /dev/shm/${0##*/}
        trap "Exit" 0 1 2 3 15 22 24
}
function Exit(){
        unlink /dev/shm/${0##*/} >/dev/null 2>&1
        exit 0;
}

在程序中,首先调用LockFile函数,检查临时目录中是否存在以当前程序名称命名的link,如果存在则退出;否则建立该link。同时,为了保证程序中异常中断的时候也可以调用Exit函数释放link,使用trap函数注册了single的handle。在程序结束的时候,调用Exit函数。

cron获取待静态化内容

这里,为了尽量少的破坏现有代码的结构,在lighttpd中做了如下配置:

url.rewrite                = (
                "^/try/(?:\?(?:s=(\w+)&?)?(?:page=(\d+))?)?$" => "/static/try_$1_$2.htm", # pure static
)

这里我希望把http://127.0.0.1/try/?s=time&page=1重定向到/path/to/dir/static/try_time_1.htm,而htm文件是不经过fastcgi的。

通过以上配置可以看出,如果url不匹配该正则,就不会发生这样的重定向。所以为了获取动态内容,可以使用http://127.0.0.1/try/?s=time&page=1&v=dynamic类似的链接。

但是,这样的配置还有一个问题是,如果静态化失败,/path/to/dir/static/try_time_1.htm类似的文件不存在,则返回404error。待解决。

ajax加载动态内容

页面上肯定会有动态内容,比如访问数、用户相关信息等,这些可以使用ajax的方式动态加载。

这样就完成了整个静态化的步骤,附上完整的bash脚本:http://staticize-webpage.googlecode.com/files/static_listpage.tar.gz。

在godaddy上买了域名,但是DNS服务器是放在linode的(同时也租用了linode的虚拟机)。

配置一级域名,首先需要在godaddy上讲nameserver指向DNS server(即linode)。二级域名的配置就不需要这一步了,它会默认使用一级域名的DNS server。

如果这时还没配置一级域名,那么需要在DNS server(即linode)新建该域名(不带www的!!)。然后,点击进入该一级域名,为其添加A record,填写二级域名(如 test.flykobe.com)和服务器的ip地址。稍等一会就会生效。

如果生效前,访问者(本机)的浏览器访问过未生效的网址,可能需要清理浏览器到dns缓存。最好cmd ipconfig /flushdns清理下本机的缓存。