I’m back.
域名转移完毕. 现在是新域名 nightsailer.com了.
wordpress中需要更新settings中的WordPress address (URL)和Blog URL.
然后使用301将night9.cn 重新定向到 nightsailer.com.
重新启用nightsailer.com,转移中
一直比较纠结要不要转移到godaddy中, 今天看到张宴的godaddy域名转移过程, 痛下决心
重新启用我原来的域名 nightsailer.com
这是我99年-2000年左右使用的个人域名,万网注册的,
当时用的mt3架的blog. 后来工作忙,不知道过期(可见万网的服务),当时连要自己设置ns记录都要收费!
索性就放弃了.
早上找了$7.49 的优惠码,注册2年,用支付宝付款,全部下来105.04RMB, 比起国内,真的很便宜了.
手里的几个cn域名马上也过期了,再也不续费了, .com的域名也准备转移走.
Notes: CentOS5.4编译Perl IO::Tty的处理
直接编译IO::Tty,会导致:
Can’t load ‘/root/.cpan/build/IO-Tty-1.08-PWZkbn/blib/arch/auto/IO/Tty/Tty.so’ for module IO::Tty:
undefined symbol: strlcpy at …..
快速修正, 打开Makefile
DEFINE = -DHAVE_DEV_PTMX -DHAVE_GETPT -DHAVE_GRANTPT -DHAVE_OPENPTY -DHAVE_POSIX_OPENPT -DHAVE_PTSNAME -DHAVE_PTSNAME_R -DHAVE_PTY_H -DHAV
E_SIGACTION -DHAVE_STRLCPY -DHAVE_SYS_STROPTS_H -DHAVE_TERMIOS_H -DHAVE_TERMIO_H -DHAVE_TTYNAME -DHAVE_UNLOCKPT -DHAVE__GETPTY
去掉 中间的-DHAVE_STRLCPY和最后的-DHAVE__GETPTY
重新编译, make test.
ok!
PHP编写命令行脚本和后台运行程序的注意事项
在一些场合(如开发,测试), 可能需要使用PHP编写一些命令行的处理脚本,或者是长时间
后台运行的任务, 需要注意以下准则:
准则1. 尽量避免使用PHP编写后台运行程序, 尤其是类似while(true){….} 这种循环的处理脚本.
比如,有时候我们需要定期检查数据库,然后有数据进行处理,没有数据等待.
我强烈建议不要使用PHP编写这样的类似service的脚本. php的gc并不稳定, 当运行到一定时候,
会异常退出. 另外, PHP也不擅长做命令行脚本. 看看Phing, 号称PHP port的Ant, 但是性能
糟糕的一塌糊涂, 远不如使用几个unix工具+shell来的快捷. (更别提windows,那基本是不可用).
使用Perl,Python来完成相应的任务吧, 那会让你很愉快, 或者,Ruby也不错.
准则2 编译特殊版本的php
如果一定要沉迷于PHP解决, 那么首先, 重新编译PHP,去掉所有不实用的模块. 增加PHP的稳定性.
准则3 不要直接使用fork 或者 nohup
不要在PHP中直接使用fork来进入后台运行, 也不要直接使用nohup来运行直接运行php 循环脚本.
准则4 使用 shell guard 来完成PHP的后台循环运行
php的脚本只需要处理一次数据后马上退出,不要使用任何while(true) 这样的脚本来挂起等待.
相反的, 可以使用以下的shell gurad 来完成上述工作:
night9.cn# cat guard.sh
DIR=`pwd`
while true; do
echo “start php script ..”
php $DIR/thumbnail_worker.php
echo “respawn the worker…”
上面这种脚本我称之为shell guard.这样的好处是你的后台脚本永远可以可靠的运行,一旦因为php自身出现问题(如内存溢出),那么马上就可以立即重新执行.
对于检查,执行,休眠模式,可以使用和以下类似的:
while true; do
php ./realtime_data_worker.php
echo “paused 10s”
sleep 10
done
上述shell guard的另一个好处就是一旦你更新了Php文件, 下次运行时就是新的了. 而无须kill掉在重启.
特别适合频繁变更的情况,减少你的工作量.
准则5 可以在你PHP脚本中监控执行的情况, 当执行了一定次数或者内存消耗到一定,则exit, 释放占用的内存,
防止内存泄露.
这条一定要和shell guard来配合.
如果你用windows, 抱歉, 这不在我考虑的范围之内.
准则6 如果以上仍然无法解决一些问题, 那么请参考第一条,使用Perl/Python重写. 立刻会药到病除
PS: 某些copy & paste的人儿, 转载我的笔记麻烦给个出处. 我现在知道某些人为何使用我不称我,而使用类似night9.cn认为这样的第三人称说法, 都是某些热衷把转载当自己原创使用的人害得,但每次我看到这样的第三人称总会稀稀拉拉掉一地鸡皮疙瘩.
我写的所有笔记和心得都是自己实践, 主要是为自己备忘使用,都是原创,无须声明.
有时候很纳闷, 转载有必要么?
google可以告诉你一切. 减少点碳排放吧.
Mouse,Moose和MooseX::Declare
如果你是一个Perl的开发者, 现在还不知道Moose那么你对Perl的了解基本上还停留在10年前了.
虽然国内Perl的开发者寥寥无几, 但Perl的强大远远超越一般人的想象空间.
我使用Perl是让自己更愉快,因为很多事情变得很简单.
Perl的OO一般人很难理解, 但是却用了最简单和巧妙的方式实现了,想想, 一个bless搞定, 再看看
PHP之类的,多么臃肿.
有了Moose,你会发现, 不仅仅OO,AOP这些东西实现起来是多么的轻松.
当看到MooseX::Declare, 你更会惊叹, “这还是Perl么?”.
use MooseX::Declare;
class BankAccount {
has ‘balance’ => ( isa => ‘Num’, is => ‘rw’, default => 0 );
method deposit (Num $amount) {
$self->balance( $self->balance + $amount );
}
method withdraw (Num $amount) {
my $current_balance = $self->balance();
( $current_balance >= $amount )
|| confess “Account overdrawn”;
$self->balance( $current_balance - $amount );
}
}
和教条的Python相比我喜欢Perl的哲学, 同样的结果可以有不同的选择, 如何做,取决你自己.
几个很有用的TextMate bundle
TextMate的这几个bundle对我来说非常有用:
1. CTags
和vim中的类似,可以ctrl+] 可以快速列出和跳转到symbol所在的文件位置. 有点遗憾的是不能想vim那样返回.
适合多数的编程语言.
2. Devel::IntelliPerl
Perl的自动解析和语法提示,能够根据指定变量的上下文给出语法提示,主要是列出可以调用的方法. 很cool.
除了TextMate,还支持vim. 由于使用Moose进行反射分析,可以显示出继承的方法. 比单纯的正则分析
要准确的多.
3. Act
可以使用正则表达式快速搜索项目中的文件. 使用Perl编写, 是一个快速和强大的grep 替代品.
TextMate中的search in project可以休息了. 如果你用TextMate,就知道在大的项目中使用search in project是
一种煎熬. 我很多次不长记性的调用,看着高起的CPU和风扇声,被迫kill掉textmate. 使用Act可以省去find+grep
的诸多不便. 而且, 由于是Perl编写,你可以使用完整的PCRE, 而不是GNU的精简版, 甚至你可以只搜索某种
编程语言的.很不错的.
其他如project plus,git bundle这些都是标配了.
Nginx技巧:如何使用X-Accel-Redirect同时输出ETag Header和其他自定义Header
在Nginx中,常见的技巧是后端fastcgi使用X-Accel-Redirect Header来通知nginx使用sendfile加速
文件的输出,避免后端重复读取文件.
当使用X-Accel-Redirect时, 后端输出的一些自定义header就被忽略掉了. 在upstream redirect到
内部location uri后, 这些header并没有被同时输出.
这2天,为了快速解决PHP的性能问题, 就用Perl做的一个Plack application, 用于dispatch MongoDB中的gridfs. 为了加速, 对于gridfs的文件
进行了cache, 并根据文件的md5值输出etag. 这样,当client 请求时, 如果mongodb中的主文件的md5
并没有改变,那么就直接输出304. 否则使用X-Accel-Redirect返回cache file的uri.
使用ETag的原因就是cache文件需要频繁清理, 仅仅依靠last modified time并不可靠.
, Plack的应用也是可以负载到不同的fastcgi upstream.
ETag的验证机制则可以很好的解决这些问题.
因为有很多文件其实很少读取的, 即便某些用户偶然访问, 那么通过ETag如果验证文件在MongoDB中
并没有变动,则直接返回304即可, 无需再重新创建cache文件,从而可以保持cache的热度.
如何能够输出ETag呢, 解决方式就是在X-Accel-Redirect 定向到的location中,使用add_header来
设置附加的ETag header:
location /__file_result__ {
internal;
root /cache;
add_header ETag $upstream_http_etag;
}
这样, 对应的X-Accel-Redirect的文件就有了对应的ETag header.
实际上, 你可以使用add_header加入其他更多的HEADER. 对应的$upstream_http_(header_name).
变量的格式可以在手册的upstream模块部分查到.
BTW, Plack 的效率和性能还是很爽的. 开发效率很高, 10几分钟就能完成一个高效的fastcgi应用.
相对以前手工写, 进步了一大块. 尤其是当你只是想解决几个小问题的时候,相比之下,Cgi::Application都像牛刀了.
技巧:用ETag产生更为有效的304 Not Modified
对于大流量的网站, 尽可能使用304 Not Modified, 这将大大节约带宽的使用,也节省你的资金投入.
通常,对于静态文件, 一般都无须配置, 多数的http server能够产生有效的last-modifed-time和Expires header,
同时下次请求的时候自动判断并输出304.
但是对于动态输出的页面, 依赖时间戳并不是一个有效的方式. 很多时候, 我们需要频繁更新文件,但是
文件内容并没有改变. 这是就要用到ETag了.
关于ETag即Entity Tag是W3C在HTTP 1.1中定义的. 对于动态输出,我们可以使用md5值作为etag的值, 这样
可以当内容没有变更,那么就可以直接返回304了.
结合MongoDB的GridFS,ETag更加有用. 当文件被存储到db中的时候, 计算文件的md5值,保存. 当输出gridfs中的文件时候,
同时输出日期和etag.
以下是一个简单的PHP类, 用于检查是否刷新, 这个类首先检查过期时间, 同时检查etag, 并且etag的优先级高于日期检查:
/**
* Cache Validator
*
* A helper class to mainipulate/validate cache.
*
* The code is ported from my oooold project(eps2004),but works!
* @author night
*/
class CZone_Core_Util_HttpCacheValidator {
/**
* Validate client headers and check wheather to send 304 header.
*
* @param int $lastModified timestamp to validate
* @param string $tag ETag to validate
*/
public static function is_expired($lastModified,$tag,$headers){
// $now = time();
// $headers = getallheaders();
$refresh=TRUE;
if(isset($headers["If-Modified-Since"])) {
$arraySince = explode(";", $headers["If-Modified-Since"]);
$since = strtotime($arraySince[0]);
if($since >= $lastModified) $refresh=FALSE;
}
/**
* Check Entity Tag(ETag)
*
* Entity tags are used for comparing two or more entities from the same requested resource.
* HTTP/1.1 uses entity tags in the ETag (section 14.19), If-Match (section 14.24),
* If-None-Match (section 14.26), and If-Range (section 14.27) header
* fields. The definition of how they are used and compared as cache
* validators is in section 13.3.3. An entity tag consists of an opaque
* quoted string, possibly prefixed by a weakness indicator.
*
* entity-tag = [ weak ]
* opaque-tag weak = “W/”
* opaque-tag =quoted-string
*
* A “strong entity tag” MAY be shared by two entities of
* a resource only if they are equivalent by octet equality. A “weak
* entity tag,” indicated by the “W/” prefix, MAY be shared by two
* entities of a resource only if the entities are equivalent and could
* be substituted for each other with no significant change in
* semantics. A weak entity tag can only be used for weak comparison.An
* entity tag MUST be unique across all versions of all entities
* associated with a particular resource. A given entity tag value MAY
* be used for entities obtained by requests on different URIs. The use
* of the same entity tag value in conjunction with entities obtained by
* requests on different URIs does not imply the equivalence of those
* entities.
*
* See HTTP/1.1(W3C)
*
*/
if(isset($headers["If-None-Match"])) { // check ETag
if(strcmp($headers["If-None-Match"], $tag) == 0 ){
$refresh=FALSE;
}
else {
$refresh=TRUE;
}
}
if(isset($headers["If-Match"])) { // check ETag
if(strcmp($headers["If-Match"], $tag) == 0 )
$refresh=FALSE;
else
$refresh=TRUE;
}
//firefox style,resume download
if(isset($headers["If-Range"])) { // check ETag
if(strcmp($headers["If-Range"], $tag) == 0 )
$refresh=FALSE;
else
$refresh=TRUE;
}
return $refresh;
}
?>