Archive

Archive for the ‘Computer Science’ Category

Linode VPS上安装pptpd VPN服务

February 12th, 2010 Wei No comments

从购买了Linode VPS服务之后,就一直考虑弄个VPN。今天终于实现了,该文档讲述了如何在Linode上配置基于pptpd的VPN服务,以及一些troubleshooting的问题。

前提:必须有VPS;必须有SSH。

接下来的步骤将完成pptpd的安装:

  1. 安装pptpd服务
    sudo apt-get install pptpd
  2. 修改pptpd服务的配置文件/etc/pptpd.conf(只需要修改最后的localip和remoteip部分):
    localip 192.168.10.1
    remoteip 192.168.10.100-150
    
  3. 修改/etc/ppp/chap-secrets文件
    username pptpd password *
  4. 设置pptpd的DNS服务器,修改/etc/ppp/pptpd-options文件:
    ms-dns 208.67.222.222
    ms-dns 208.67.220.220
    
  5. 设置ip4v转发,修改/etc/sysctl.conf文件,去掉如下行的注释:
    net.ipv4.ip_forward=1
  6. 使ipv4转发生效,运行:
    sysctl -p
  7. 重新启动pptpd服务,运行:
    /etc/init.d/pptpd restart
  8. 开启ipv4转发,运行如下命令:
    /sbin/iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j MASQUERADE
    /sbin/iptables -p FORWARD ACCEPT
    

需要注意的是,我的VPS不知为什么,FORWARD rule默认的action是DROP(可能是由于我之前配制了防火墙的缘故。这也令我在一段时间内,纠结于为啥VPN无法正常转发。

Categories: Computer Science Tags: , , , ,

iPhone通讯录中文条目在英文环境下的排序问题

January 30th, 2010 Wei No comments

由于工作的关系,另一方面是iPhone中文翻译的习惯问题,我个人更偏向在英文系统下操作iPhone。iPhone的操作系统可以完美的支持各国语言文字和风格,但是在英文环境下,通讯录的中文条目将无法按照中文的习惯排序,更无法分类在右侧的首字母分类中,如下图所示:

这些联系人被分类到#中,且“兰”、“关”、“冯”、“刘”的排序顺序也是不正确的。实际上这些问题在中文环境中确实没有问题的。在非jailbreak环境下,也无法通过修改系统文件的方法修改排序方式。

使用如下的方法,即可正确的将联系人分类,且排序也是正常的。

首先选择一个联系人,进入编辑状态。点击最下面的add field。再选中Phonetic Last Name。

输入该联系的拼音。用同样的方法添加Phonetic First Name。添加后,在联系人中会显示该联系人的拼音姓名。

回到通讯录列表,即可看到联系人正确的显示在列表中,且无论是在Contact还是Phone中,都可以正确排序和分类。连Search中也可以使用拼音排序。

Categories: Computer Science Tags: , , ,

iPhone 3GS+联通(北京)WCDMA 186 3G网络评测

December 3rd, 2009 Wei 5 comments

最近禁不住诱惑的入手了iPhone 3GS,又再次禁不住诱惑的入网了北京联通186号段的WCDMA网络。

前提

其实一直以来我都用移动的服务,但最近移动的EDGE网络慢的要死,网页都打不开,我公司的座位上信号又非常差。

另一方面,随着电话、网络使用频率的逐渐增加,发现作为大多数Class B的GPRS手机,都不能实现语音和数据的同传,即当有GPRS/EDGE数据活动的时候,语音是完全断开的,也无法接受呼叫。也就是说,当你用GPRS/EDGE打开网页的时候,任何语音电话呼叫都是收不到的。(这完全解释了我的手机信号良好的情况下,来电提醒业务发来的漏接电话的提醒信息)。这对于我这种使用推送邮件服务的人来说,简直就是灭顶之灾。如果在推送和数据传输的时候,恰巧有电话呼入,那呼叫者得到的只能是“您拨叫的用户暂时无法接通”。(如果不信,可以再手机上打开一个网页,在页面载入过程中,用另一部电话拨打手机)

更换

经过和同事(另一个先期更换186的同事)的沟通,发现联通186号段的WCDMA标准的3G网络非常不错。经过一番考察和犹豫,最终选中了186XXXXXXXX这个号码。北京联通网上选号,还免费配送。

选中号码并提交订单后的第二天早上,收到联通客服的电话确认订单,核对信息后告知72小时内送到。第三天,准时盼到了送货人员,在提交身份证复印件后,收到了一张USIM卡和用户协议。

我选择的是96元标准套餐,包括240分钟国内主叫,免费国内接听,300MB数据流量,30分钟可视电话等;另加了5元包60条短信的附加包。超过套餐内容,国内主叫0.15元/分钟;0.0003元/KB(折合0.3元/MB)。

踏上3G之路

iPhone换上3G卡后,迅速搜索到了3G信号。使用Google Map测试了一下网络速度:将地图移动到一个全新的位置,画面从网格到地图完全显示,用了不到2秒;同样测试移动EDGE的速度,则花费了30+秒(最终也没有完全打开,放弃了)。

由于首月是标准资费,1分钱/KB,不敢过于使用网络流量。第二天开始测试3G网络的数据功能。通过iPhone上的测速程序,测得下载速度为431KB/s,上传为36KB/s(本地服务器)。刚刚通过Internet Tethering用IE直接从美国网站上下载软件,速度显示为147KB/s。

一些评价

  • 联通WCDMA网络的速度让我非常满意。但在这样的速度下,网络流量显得非常不够。并且联通并没有为WCDMA提供数据可选套餐。当然,联通数据流量超过套餐时0.3元/MB的价格至少是比移动厚道多了。
  • iPhone的Internet Tethering功能默认打开了。当时移动的SIM卡之所以没有打开该功能,是因为iPhone手机上没有移动的运营商信息。
  • 通话质量非常清晰,完全没有移动网络中断续和变音的问题
  • 开启联通的呼叫等待(Call Waiting)功能后,iPhone内置的Add Call,Swap Call,Hold,Merge Call功能完全正常。
    • 电话A拨叫iPhone,iPhone接听,电话B拨叫iPhone,Hold+Answer后,切换到线路B,按Merge Call实现合并。
    • iPhone拨叫电话A,按Add Call拨叫第二个电话,按Merge Call实现合并。
  • 3G信号明显强于移动的信号,至少在我公司的座位上,联通信号满格,接听正常、清晰;而同样位置的移动信号,却很微弱,电话可以拨入,但对方经常听不到声音。
  • 联通的客服人员,不知道是不是因为有考核指标,说话快的像蹦豆一样,并且因为“系统忙”而直接把我要求查询呼叫等待功能的请求拒绝了,直接告诉我代码让我自己开通。
  • 还是联通的客服人员,我在晚上9点提交一个网上咨询,关于呼叫等待功能。2小时后,晚上11点,我收到联通客服的电话回复。这个事儿……我真的不觉得晚上11点给客户回电是明智的选择(虽然我很满意联通本次服务的反馈时间)

iPhone 3GS入手及使用评论

November 22nd, 2009 Wei 3 comments

最近一直以来很郁闷Windows Mobile的用户体验,在考虑换手机了。也一直在HTC Hero和iPhone之间徘徊。最近也比较中毒iPhone,就最终决定iPhone 3GS港版行货。

我买的是41周后生产的iPhone 3GS 16GB白色版香港行货,送到我这里的时候,还是未开封的。然而41周以后产品因为使用了新的Baseband,还无法实现完美的jailbreak(截止到2009年11月20日,如果jailbreak,每次重启都需要连接USB)。但如果不jailbreak的话,软件就只能通过iTune安装(当然也不能安装破解软件了)。

iPhone的整体用户体验非常好,电容屏(和WM需要使用指尖点击的电阻屏相比)的指触感觉也非常好。色彩效果也远比WM要强多了,毕竟WM受硬件限制,最大只能达到65K色。 AppStore上的应用非常多,除了设计系统的,绝大多数功能都能有具体的实现。

一些技巧:

  • 输入法中,临时需要标点符号,可以按住符号按钮不松手(这时键盘已经切换为符号),滑向需要输入的符号,松开后,符号已经输入进去,但键盘仍然为字母状态。
  • 输入法中,按住$、.(句号)等符号不松手,会出现与之类似的符号(比如¥和…);按住字母键也可以显示拉丁字母
  • Maps中,点击左下角的定位图标可以定位到当前位置(根据基站和GPS) ,再次点击会切换为“前方为上”的地图状态(之前是“北方位上”)。
  • 截屏:按住电源键同时按下Home键。

铃声:

iPhone不支持直接使用MP3作为铃声,但可以通过iTune制作铃声(不超过40秒)。具体方法是:首先进入iTune,将要作为铃声的MP3导入iTune;右键单击文件,选择Create AAC format;再次点击右键选择Get Info,查看文件存储的位置;找到该文件(扩展名为m4a),将扩展名修改为m4r;重新导入iPhone(原mp3文件删除即可),即可看到Library–>Ringtones里面看到刚刚导入的铃声。

目前iPhone 3GS存在的不足:

  • 短信回执:目前很多手机都已经有短信回执功能(即对方收到短信后,会发送一条delivered消息)了,这点上索尼爱立信的Symbian系统做的很好,回执会以一个图标的形式出现在“已发送短信”中;Windows Mobile很烂,只是一条单独的短信,每次发短信都要单独删除一次;而iPhone压根就没有(当然也省得删除了)。
  • 彩信会把每个Page展开为一条独立的短信,这样在同一个thread中如果有多条彩信,那么他们会被显示成类似于1篇文章(即第二条彩信会紧接着第一条彩信内容显示。
  • 多任务:除了iPod、Phone、Voice Memo、Internet tethering以外,其他应用程序都不支持多任务,按Home键就直接退出了。比如你在通过Safari或者其他应用下载一个文件,当有短信到来,如果选择回复短信,则下载会中断。部分软件可以通过Notification实现类似后台运行的效果,但像Skype这类的软件无法支持Notification的,则没有什么实际意义了。
  • Voice Memo不支持通话录音,App Store里面也没有类似软件可以实现。
  • 文件系统过于封闭:你不能修改和查看任何系统文件,应用程序之间的文件也不能共享。例如:电子邮件中非图片和音视频的内容,无法保存(如果邮件附件是个Word文档,则无法做到编辑后再回复给发件人);通过其他软件(例如WoTV)下载的视频,只能在该软件中使用,不能放到Video文件夹中;任何文件(包括铃声等),都只能通过iTune传送;除了视频和Photo Roll文件夹中的内容,其他内容均不可删除;
  • Bluetooth仅支持蓝牙耳机,不支持文件传输(同样是因为文件系统封闭)。
  • Internet Tethering:3GS的广告和spec中提到了网络共享功能,而我的中国移动SIM卡插进去后却完全没有这个选项。再看iPhone的spec,旁边有行小字:“Tethering is not currently offered in the U.S. and some other countries. See your carrier for availability.”(中国联通的3G业务却可以)
  • Merge Call:这也是iPhone广告中提到的功能。但经过我的实践,中国移动的卡只能在两个call之间切换,却不能将两个call merge。(中国联通3G号码可以实现两个call之间的切换,并且可以实现merge call)
  • Voice Message:这个是AT&T提供的可视化语音信箱(Virtual Voice Message)功能,在国内完全无法使用,却也没有设置语音信箱的问题,导致改功能彻底无法使用。
  • 比较耗电:开启邮件推送以后,正常使用手机(电话、短信等),24小时开机,只能坚持大约1~1.5天。
Categories: Computer Science Tags: , , ,

Outlook 2007提示Could not install the custom actions的解决方法

November 5th, 2009 Wei No comments

近来我的Outlook 2007突然出了一些问题,无论是回复还是转发,甚至是新建邮件,都会出现Could not install the custom actions错误(如图)。而在出现此问题前,Outlook会出现假死情况。

Outlook 2007 Could not install the custom actions

经过搜索和研究,发现问题出现Forms中。解决方法也很简单:删除如下文件夹:

%SystemDrive%\Users\%UserName%\AppData\Local\Microsoft\FORMS

重新启动Outlook即可。

Smugmug: 专业的摄影照片分享服务

November 1st, 2009 Wei No comments

Yahoo!旗下的Flickr相比大家都已经比较了解了,这次介绍的是Smugmug

SmugMug Home Page

Smugmug是个专业的摄影照片分享服务,具有非常友好和强大的用户界面。具有非常强大的功能:

  • 可以存放无限量的照片(JPEG、GIF和PNG格式),无存取流量限制。单张照片容量限制为: Standard和Power不大于12MB的照片,Pro不大于24MB,所有照片都不能大于48Megapixel(4800万像素)。所以对于目前的主流相机来说,可以直接存储原始JPEG照片了。
  • 购买SmugVault服务后,甚至可以上传任何格式的文件(包括TIF、RAW、PSD等)。
  • 没有广告
  • 照片存储在Amazon S3服务,Amazon提供存储空间和流量
  • 支持密码保护的相册(Gallery)和帐户
  • 支持照片不显示在公共列表中(Unlisted)和私人站点(Private Site)
  • 支持显示EXIF信息
  • 支持原始尺寸的照片
    SmugMug Photo Gallery
  • 支持相册(Gallery)和单独照片的共享(通过链接、邮件、共享组)、外链、嵌入式相册
    smugmug-share
  • 支持多种上传方式(Web、Java、第三方的上传/下载工具):这里有详细的上传和下载的工具列表。
    SmugMug Java Uploader
  • 支持多种方式取回照片(也支持邮寄DVD)
  • http://*.smugmug.com/的二级域名(Power和Pro用户支持域名绑定)
  • 支持嵌入picnik.com的简单编辑功能
  • 支持基于Flash的全屏SlideShow
    Smugmug Fullscreen SlideShow
  • 支持多种主题,Power和Pro帐户还支持自定义CSS功能
  • 支持FaceBook等Social功能
  • 支持购买照片打印服务
  • 支持按照物理方位标识照片
  • 支持照片时间线

Smugmug实际上使用了Amazon S3来存储照片的数据,S3服务的费用和质量总体都是非常不错的,在国外,S3经常被用来作为备份空间。

Smugmug最大的缺点应该就是费用了。它不提供免费帐户,试用账户可以使用14天,之后必须付费才能继续使用。费用也不算太低,Standard每年39.95美元,Power用户每年59.95美元,Pro用户每年149.95美元。

如果你对Smugmug感兴趣的话,不妨去注册一个试用帐户体验一下。如果想成为正式用户,Smugmug提供一个推荐计划,如果有用户推荐,可以在付款时减掉5美元。例如,如果你在注册时候,填写我的Coupon代码(tZl1azJPB9jzA),即可获得5美元的优惠。所以在你注册付款时,请记得填写我的Coupon代码tZl1azJPB9jzA

目前来说,Smugmug有个bug,因为Comment增加了Facebook Connection功能,所以如果你的网络因为一些问题导致无法访问Facebook,则会出现Comment画面无法打开的情况,导致匿名用户无法发表评论(注册用户不会有此影响)。

tZl1azJPB9jzA。
Categories: Computer Science Tags: , ,

QNAP TS-409 Pro添加中文UTF8 locale

October 24th, 2009 Wei 15 comments

QNAP TS-409 Pro NAS中除了C和POSIX以外,不包含utf8的locale,PHP中也不包含iconv。即使是最新版本的3.0.1 Build 0708T也是如此。最直接的结果就是MLDonkey等软件的下载文件名出现乱码或者“_”符号。但QNAP却提供了手工安装locale的方法。但最新的3.0.1版本中,却没有locale和localedef文件,导致按照官方安装locale的方法,无法操作。经过论坛上的各种讨论,可以采用如下的方法来实现。

首先通过SSH登录NAS,找到locale和localedef命令,并创建对应的符号链接:

ll /mnt/HDA_ROOT/rootfs_2_3_6/usr/bin/locale*
ln –s /mnt/HDA_ROOT/rootfs_2_3_6/usr/bin/locale /usr/sbin/locale
ln –s /mnt/HDA_ROOT/rootfs_2_3_6/usr/bin/localedef /usr/sbin/localedef
ll /usr/sbin/locale*

接下来下载Posix-locale文件(下载地址:http://wiki.qnap.com/w/images/7/77/Posix-locales.rar),解压后,上传到任意目录,并将LOCALES重命名为locales。为了节省系统盘空间,推荐在/share/HDA_DATA(或/share/MD0_DATA)中创建一个目录。

mkdir /mnt/HDA_DATA/i18n
ln –s /mnt/HDA_DATA/i18n /usr/share/i18n
cd /usr/share/i18n
wget http://wiki.qnap.com/w/images/7/77/Posix-locales.rar
unrar Posix-locales.rar
mv LOCALES locales

创建/usr/lib/locale目录,该目录用于存储locale-archive文件(也可以使用符号链接)

剩下的步骤就可以创建新的locale了

localedef –i zh_CN –f UTF-8 zh_CN.utf8

如果需要其他的locale,只需要将zh_CN、UTF-8更换为其他的locale即可,具体的参数,可以查看/usr/share/i18n/locales和/usr/share/i18n/charmaps中的文件列表,最后的zh_CN.utf8可以自己指定。

检查新的locale

locale -a

此时即可生成新的zh_CN.utf8的locale,剩下的工作可以为locale-archive创一个符号链接,以便节省/分区的空间。

mv /usr/lib/locale/locale-archive /share/HDA_DATA/locale-archive
ln –s /share/HDA_DATA/locale-archive /usr/lib/locale/locale-archive

特别说明

  1. QNAP NAS会在每次升级之后,重新在硬盘中写入操作系统,所以此过程需要在每次升级版本的时候操作一次。
  2. 为了避免在UTF8编码无效时,某些软件(如MLDonkey)出现乱码的问题,在操作/升级前,请先关闭所有的QPKG。
  3. HDA_DATA为不使用RAID配置的路径,如果启用RAID,则将更换为MD0_DATA。
Categories: Computer Science Tags: , , , , , ,

解决nginx和php-fastcgi上传大文件的问题

October 3rd, 2009 Wei No comments

近来需要在blog中上传一些比较大的照片,却发现无论是Flash Uploader还是Web Uploader均无法上传。经过一番试验,发现这种情况仅发生在上传较大图片的时候,而对于几百KB的图片却不出现问题。

我的Server使用了nginx和php-fastcgi,经过检查php的配置文件,发现upload_max_filesize、post_max_size都不应该会影响上传。从phpinfo()来看,这些配置也都正确读入了。经过查看/var/log/nginx/error.log,发现其最下面几行出现日志:

2009/10/03 22:06:23 [error] 6029#0: *20 client intended to send too large body: 1345385 bytes, client: x.x.x.x, server: weigblog.com, request: "POST /wp-admin/async-upload.php HTTP/1.1", host: "www.weigblog.com"

既然log是nginx报出来的,那问题自然出现在nginx上。经过查询nginx的wiki,解决方案如下:

在/etc/nginx/nginx.conf中添加如下配置:

http {
        ...
        client_max_body_size 100m;
        ...
}

之后运行/etc/init.d/nginx reload重新载入配置文件,上传搞定。

在Nginx下运行perl-cgi脚本

September 16th, 2009 Wei No comments

把Web Server更换为Nginx后,发现BugZilla不能用了。打开网站显示403 Forbidden,想来是因为BugZilla使用Perl CGI运行的原因。查了Nginx为数不多的文档,发现Nginx不能像其他Web Server(例如Apache)那样直接运行perl-cgi的脚本。

试用几个不同的方法后,发现确实有方法可以比较简单的实现perl-cgi的功能:

首先下载一个Perl Wrapper,我把它另存为~/perl-fastcgi.pl。

修改perl-fastcgi.pl的属性,添加可执行权限。运行该文件,该脚本会创建一个/var/run/nginx/perl_cgi-dispatch.sock文件。

修改nginx的配置文件,在server section中添加:

location ~ \.cgi$ {
        root           /srv/www/domain.tld/public_html;
        fastcgi_pass    unix:/var/run/nginx/perl_cgi-dispatch.sock;
        fastcgi_index   index.cgi;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include         fastcgi_params;
}

配置工作就此完成,重新启动nginx即可。

对于BugZilla,可能还需要运行http://domain.tld/testagent.cgi。

Categories: Computer Science Tags: , , , , ,

Web服务器更换到Nginx

September 16th, 2009 Wei 1 comment

禁不住诱惑,还是把Web服务器更换为Nginx(读音[engine x]),这个俄罗斯人写的高性能的web服务器。[因为在Linode360方案中,使用Apache如果想达到比较好的性能,确实会比较频繁的出现OOM;要避免OOM,就只能减少并发处理能力和内存配置]

Debian Lenny自带的nginx是0.6x的,而目前最新版本是0.7x。因此决定,从官方网站安装。

本文简单介绍了完整的安装过程。

首先安装必要的package,这些package将会在后面的过程中用到:

$ sudo apt-get install libssl-dev libpcre3-dev build-essential
$ sudo apt-get install php5 php5-cgi mysql-server mysql-client

接下来下载并安装nginx(注意,下载的地址的可能会发生变化,可以参考http://wiki.nginx.org/NginxInstall#Stable):

$ wget http://sysoev.ru/nginx/nginx-0.7.62.tar.gz
$ tar -zxvf nginx-0.7.62.tar.gz
$ cd nginx-0.7.62
$ ./configure --prefix=/usr --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx/nginx.pid  --lock-path=/var/lock/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --with-md5-asm --with-md5=/usr/include --with-sha1-asm --with-sha1=/usr/include --with-http_stub_status_module
$ make
$ sudo make install

安装spawn-fcgi(曾经lighttpd的一部分,用来管理php-cgi进程)

$ wget http://www.lighttpd.net/download/spawn-fcgi-1.6.2.tar.gz
$ tar -zxvf spawn-fcgi-1.6.2.tar.gz
$ cd spawn-fcgi-1.6.2
$ ./configure
$ make
$ sudo cp ./src/spawn-cgi /usr/bin/

创建nginx和php-fastcgi的init脚本

$ sudo vi /etc/init.d/php-fastcgi
$ sudo vi /etc/init.d/nginx
$ sudo chmod +x /etc/init.d/php-fastcgi
$ sudo chmod +x /etc/init.d/nginx

/etc/init.d/nginx文件内容:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: nginx init.d script for Ubuntu 8.10 and lesser versions.
# Description:       nginx init.d script for Ubuntu 8.10 and lesser versions.
### END INIT INFO
#------------------------------------------------------------------------------
# nginx - this script, which starts and stops the nginx daemon for ubuntu.
#
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server.  This \
#               script will manage the initiation of the \
#               server and its process state.
#
# processname: nginx
# config:      /usr/local/nginx/conf/nginx.conf
# pidfile:     /acronymlabs/server/nginx.pid
# Provides:    nginx
#
# Author:  Jason Giedymin
#          <jason.giedymin AT acronymlabs.com>.
#
# Version: 1.0 01-Apr-2009 jason.giedymin AT gmail.com
# Notes: nginx init.d script for Ubuntu 8.10 and lesser versions.
#
#------------------------------------------------------------------------------
#                               MIT X11 License
#------------------------------------------------------------------------------
#
# Copyright (c) 2009 Jason Giedymin, http://AcronymLabs.com
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#------------------------------------------------------------------------------

#------------------------------------------------------------------------------
#                               Functions
#------------------------------------------------------------------------------
. /lib/lsb/init-functions

#------------------------------------------------------------------------------
#                               Consts
#------------------------------------------------------------------------------
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/nginx

NAME=nginx
DESCRIPTION="Nginx Server..."

PIDSPATH=/var/run/nginx
PS=$NAME                                #the process, which happens to be the NAME
PIDFILE=$NAME.pid                       #pid file
RUNAS=root                              #user to run as

SCRIPT_OK=0                             #ala error codes
SCRIPT_ERROR=1                          #ala error codes
TRUE=1                                  #boolean
FALSE=0                                 #boolean

lockfile=/var/lock/subsys/nginx
NGINX_CONF_FILE="/etc/nginx/nginx.conf"

#------------------------------------------------------------------------------
#                               Simple Tests
#------------------------------------------------------------------------------

#test if nginx is a file and executable
test -x $DAEMON || exit 0

# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
        . /etc/default/nginx
fi

#set exit condition
#set -e

#------------------------------------------------------------------------------
#                               Functions
#------------------------------------------------------------------------------

configtest() {
        $DAEMON -t -c $NGINX_CONF_FILE
}

getPSCount() {
        return `pgrep -f $PS | wc -l`
}

isRunning(){
        pidof_daemon
        PID=$?

        if [ $PID -gt 0 ]; then
                return 1
        else
                return 0
        fi
}

status(){
        isRunning
        isAlive=$?

        if [ "${isAlive}" -eq $TRUE ]; then
                echo "$NAME found running with processes:  `pidof $PS`"
        else
                echo "$NAME is NOT running."
        fi

}

removePIDFile(){
        if [ -f $PIDSPATH/$NAME.pid ]; then
                rm $PIDSPATH/$NAME.pid
        fi
}

start() {
        log_daemon_msg "Starting $DESCRIPTION"

        isRunning
        isAlive=$?

        if [ "${isAlive}" -eq $TRUE ]; then
                log_end_msg $SCRIPT_ERROR
        else
                start-stop-daemon --start --quiet --chuid $RUNAS --pidfile $PIDSPATH/$PIDFILE --exec $DAEMON
                chmod 400 $PIDSPATH/$PIDFILE
                log_end_msg $SCRIPT_OK
        fi
}

stop() {
        log_daemon_msg "Stopping $DESCRIPTION"

        isRunning
        isAlive=$?
        if [ "${isAlive}" -eq $TRUE ]; then
                start-stop-daemon --stop --quiet --pidfile $PIDSPATH/$PIDFILE

                removePIDFile

                log_end_msg $SCRIPT_OK
        else
                log_end_msg $SCRIPT_ERROR
        fi
}

reload() {
        configtest || return $?

        log_daemon_msg "Reloading (via HUP) $DESCRIPTION"

        isRunning
        if [ $? -eq $TRUE ]; then
                `killall -HUP $PS` #to be safe

                log_end_msg $SCRIPT_OK
        else
                log_end_msg $SCRIPT_ERROR
        fi
}

terminate() {
        log_daemon_msg "Force terminating (via KILL) $DESCRIPTION"

        PIDS=`pidof $PS` || true

        [ -e $PIDSPATH/$PIDFILE ] && PIDS2=`cat $PIDSPATH/$PIDFILE`

        for i in $PIDS; do
                if [ "$i" = "$PIDS2" ]; then
                        kill $i
                        removePIDFile
                fi
        done

        log_end_msg $SCRIPT_OK

}

pidof_daemon() {
    PIDS=`pidof $PS` || true

    [ -e $PIDSPATH/$PIDFILE ] && PIDS2=`cat $PIDSPATH/$PIDFILE`

    for i in $PIDS; do
        if [ "$i" = "$PIDS2" ]; then
            return 1
        fi
    done
    return 0
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart|force-reload)
        stop
        start
        ;;
  reload)
        $1
        ;;
  status)
        status
        ;;
  configtest)
        $1
        ;;
  terminate)
        $1
        ;;
  *)
        FULLPATH=/etc/init.d/$NAME
        echo "Usage: $FULLPATH {start|stop|restart|force-reload|status|configtest|terminate}"
        exit 1
        ;;
esac

exit 0

/etc/init.d/php-fastcgi文件内容:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          php-fastcgi
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start and stop php-cgi in external FASTCGI mode
# Description:       Start and stop php-cgi in external FASTCGI mode
### END INIT INFO

# Author: Kurt Zankl <[EMAIL PROTECTED]>

# Do NOT "set -e"

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="php-cgi in external FASTCGI mode"
NAME=php-fastcgi
DAEMON=/usr/bin/php-cgi
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
PHP_CONFIG_FILE=/etc/php5/cgi/php.ini

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

# If the daemon is not enabled, give the user a warning and then exit,
# unless we are stopping the daemon
if [ "$START" != "yes" -a "$1" != "stop" ]; then
        log_warning_msg "To enable $NAME, edit /etc/default/$NAME and set START=yes"
        exit 0
fi

# Process configuration
export PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS
DAEMON_ARGS="-q -b $FCGI_HOST:$FCGI_PORT -c $PHP_CONFIG_FILE"

do_start()
{
        # Return
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
                || return 1
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON \
                --background --make-pidfile --chuid $EXEC_AS_USER --startas $DAEMON -- \
                $DAEMON_ARGS \
                || return 2
}

do_stop()
{
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   other if a failure occurred
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE > /dev/null # --name $DAEMON
        RETVAL="$?"
        [ "$RETVAL" = 2 ] && return 2
        # Wait for children to finish too if this is a daemon that forks
        # and if the daemon is only ever run from this initscript.
        # If the above conditions are not satisfied then add some other code
        # that waits for the process to drop all resources that could be
        # needed by services started subsequently.  A last resort is to
        # sleep for some time.
        start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
        [ "$?" = 2 ] && return 2
        # Many daemons don't delete their pidfiles when they exit.
        rm -f $PIDFILE
        return "$RETVAL"
}
case "$1" in
  start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
          0|1)
                do_start
                case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
          *)
                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
        exit 3
        ;;
esac

创建nginx配置文件/etc/nginx/nginx.conf(并实现VirtualHost)

user www-data www-data;
worker_processes  4;
events {
    worker_connections  1024;
    use epoll;
}
http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        tcp_nopush     on;
        tcp_nodelay    on;

        keepalive_timeout  65;
        gzip  on;

        include /etc/nginx/sites-enabled/*; #这一句就是实现nginx VirtualHost的
}

创建VirtualHost文件/etc/nginx/sites-available/domain.tld

server {
        listen       80;
        server_name  domain.tld www.domain.tld;
        access_log      /srv/www/domain.tld/logs/access.log;
        location / {
                root   /srv/www/domain.tld/public_html;
                index  index.html index.htm index.php;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
                root   /usr/html;
        }

        location ~ \.php$ {
                root           /srv/www/domain.tld/public_html;
                fastcgi_pass    127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                include        fastcgi_params;
        }
}

Enable VirualHost

$ sudo ln -s /etc/nginx/sites-available/domain.tld /etc/nginx/sites-enabled/domain.tld

启动php-fastcgi和nginx

$ sudo /etc/init.d/php-fastcgi start
$ sudo /etc/init.d/nginx start

配置php-fastcgi和nginx自动启动

$ sudo apt-get install rcconf
$ sudo rcconf # 选中php-fastcgi和nginx

此时,php的配置文件使用/etc/php5/cgi/php.ini。

创建WordPress的rewrite rule:修改/etc/nginx/sites-available/domain.tld,在location /中添加如下的内容:

location / {
        root   /srv/www/weigblog.com/public_html;
        index  index.html index.htm index.php;
        if (!-e $request_filename) {
                rewrite (.*) /index.php;
        }
}

其中:
-e为存在目录或文件
-d为存在目录
-f为存在文件

Categories: Computer Science Tags: , , ,