wordpress部署时碰到的php小问题~

25 Feb 2010 Posted in  web

看到windows live writer也支持wordpress,感觉这个博客系统确实流行,决定自己也试一把~install时,出了点问题,选择好sqlname和user、passwd信息后,另存为wp-config.php,next生成管理账户和密码的页面,居然顶上出现了“Warning: Cannot modify header information - headers already sent by …”,无视之,记下随机密码,下一步login——彻底废了,整个页面都是这个warning提示~~ 继续阅读……


memcached部署

25 Feb 2010 Posted in  web

wget http://www.monkey.org/~provos/libevent-1.4.13-stable.tar.gz
wget http://memcached.googlecode.com/files/memcached-1.4.4.tar.gz
wget http://pecl.php.net/get/memcache-2.2.5.tgz
tar zxvf libevent-1.4.13-stable.tar.gz
tar zxvf memcached-1.4.4.tar.gz
cd libevent-1.4.13-stable
./configure --prefix=/usr
make
make install
ln -s /usr/lib/libevent-1.4.so.2 /usr/lib64/libevent-1.4.so.2
cd memcached-1.4.4
./configure --prefix=/home/memcached --enable-64bit
make
make install
/home/memcached/bin/memcached -d -m 1024 -p 11211 -u root

参数说明:
-d 启动为守护进程
-m 分配给Memcached使用的内存数量,单位是MB,默认为64MB -u 运行Memcached的用户,仅当作为root运行时 -l 监听的服务器IP地址,默认为环境变量INDRR_ANY的值 -p 设置Memcached监听的端口,最好是1024以上的端口 -c 设置最大并发连接数,默认为1024 -P 设置保存Memcached的pid文件,与-d选择同时使用 继续阅读……


cacti安装记录

24 Feb 2010 Posted in  monitor

cacti运行在lamp环境下,采用net-snmp获得监控数据,由rrdtool绘图。所以cacti的安装,主要就是apache、mysql、php、rrdtool、net-snmp这几个的安装。其中apache2是我们服务器上早就有的,可以利用;而原有的php5因为不支持mysql,所以要重新编译。 继续阅读……


shell变量扩展

23 Feb 2010 Posted in  bash

第一种扩展形式,按长度截取:${PARAMETER:OFFSET:LENGTH};例: 继续阅读……


ESI 语言介绍

22 Feb 2010 Posted in  CDN

今天看到一个叫做 ESI 的东东,以此为线索,一路链接下去,颇为有趣,摘抄些新闻/博客段落来,算作长眼了: 继续阅读……


qhttpd

09 Feb 2010 Posted in  web

今天偷菜极不顺利,QQ空间老坏,看着那个Qhttpd的502提示页面就郁闷,决定自己也安一个看看。
http://www.qdecoder.org/qhttpd/download.qsp
话说网上人都说QQ的视频服务器用的是qhttpd,Qzone用的是自己的qzhttpd呀。为啥农场的错误是qhttpd呢?
以上,过完年在说。呵呵
过年回来鸟~~去韩国下载了qhttpd来看,默认安装配置什么的,真的超级简单——功能也超级简单(连logformat都没有)。如果想要玩出花样来,好吧,从源代码开始,慢慢写C去吧~~~ 继续阅读……


cache驻留时间(七、Vary)

09 Feb 2010 Posted in  CDN

之前的系列文章,只涉及squid本身,今天突然想到,其实这个网站加速,除了squid缓存这种缩短传输距离的办法以外,还有另一个办法——压缩内容以缩短传输时间。
而糟糕的问题是,squid对压缩内容的缓存,限制多多。因为squid默认是以HTTP/1.0进行内容传输的,对HTTP/1.1协议兼容性不怎么滴~~一个不小心,browser就会接受到squid交给它的无法理解的内容,并忠实的把这个错乱信息显示给网民……然后你就等着客户投诉电话吧~~
这个具体的限制就是:squid只支持静态压缩,不支持动态压缩。反应到header上,就是rep_header里必须指明Content-length是多少多少,不能采用Transfer-Encoding: chunked这样的动态块格式;rep_header里必须指明Vary是Accept-Encoding,而不能是其他的User-Agent等等。 继续阅读……


squid运行分析

06 Feb 2010 Posted in  squid

上回编译加载tcmalloc后,效果各有不同,所以还得细分具体运行情况,以便之后继续优化。
之前的架构是1个lvs下挂6台leaf+1台parent。现在已经给7台squid都加载tcmalloc了。leaf运行上佳,CPU占用率甚至降到了2%,loadavg也不过0.2。但parent的CPU占用率虽然降低,loadavg却依然在1以上——这对于单核服务器来说,可不是什么好事。分析日志,或者用squidclient分析cache情况,leaf如下:
cat access.log |awk ‘{if(/NONE/){a[NONE]++}}END{print a[NONE]/NR}’
0.981347
squidclient -p 80 mgr:info
Cache information for squid:
Request Hit Ratios: 5min: 97.8%, 60min: 98.3%
Byte Hit Ratios: 5min: 97.8%, 60min: 98.2%
Request Memory Hit Ratios: 5min: 85.8%, 60min: 86.8%
Request Disk Hit Ratios: 5min: 9.8%, 60min: 9.1%
Storage Swap size: 19891740 KB
Storage Mem size: 1048572 KB
Mean Object Size: 9.67 KB
可以看到缓存文件的平均大小不足10KB,绝大多数的请求都在内存中处理掉了。所以在加载了优化内存反应速度的tcmalloc后,效果那么明显。
parent如下:
$ cat access.log |awk ‘{if(/NONE/){a[NONE]++}}END{print a[NONE]/NR}’
0.179209
$ squidclient -p 80 mgr:info
Cache information for squid:
Request Hit Ratios: 5min: 31.1%, 60min: 32.3%
Byte Hit Ratios: 5min: 38.4%, 60min: 36.9%
Request Memory Hit Ratios: 5min: 7.8%, 60min: 12.2%
Request Disk Hit Ratios: 5min: 32.7%, 60min: 37.9%
Storage Swap size: 40300232 KB
Storage Mem size: 524284 KB
Mean Object Size: 11.68 KB
只有30%的缓存命中,而且基本还都是从磁盘读取的(awk结果排除了REFRESH_HIT,所以更低)。难怪上次优化没什么效用了……
为了保证服务,先给这组服务器加上了round-robin的双parent。新parent的硬件情况和老的一样。而squid配置上,则采用了aufs方式,不再使用diskd方式。运行到现在30个小时,分析如下:
$ cat /cache/logs/access.log |awk ‘{if(/NONE/){a[NONE]++}}END{print a[NONE]/NR}’
0.238754
$ squidclient -p 80 mgr:info
Cache information for squid:
Request Hit Ratios: 5min: 22.7%, 60min: 22.8%
Byte Hit Ratios: 5min: 22.9%, 60min: 20.1%
Request Memory Hit Ratios: 5min: 22.2%, 60min: 24.3%
Request Disk Hit Ratios: 5min: 64.4%, 60min: 65.0%
Storage Swap size: 4640308 KB
Storage Mem size: 1048588 KB
Mean Object Size: 9.08 KB 继续阅读……


netfilter的conntrack优化

06 Feb 2010 Posted in  linux

参考原文
中文版
说是zz,好歹也是自己看完以后的zz,所以组织语言次序都是自己来:
首先解释两个概念性的名词 继续阅读……


squid加载tcmalloc性能优化测试(编译)

04 Feb 2010 Posted in  squid

话接上文,同一组LVS下,昨天采用重编译方式部署了另一台squid服务器。同样跑上一天,再次对比一番。今天流量比上回稍微少些,未加载的服务器cacti监控截图如下:

CPU占用率
=====================

负载 继续阅读……


squid加载tcmalloc性能优化测试(动态)

01 Feb 2010 Posted in  squid

昨天下午在一台squid上加载了tcmalloc。运行到现在,整整一天时间。现取LVS下与其完全相同配置的另一台未加载tcmalloc的squid服务器进行比较。
环境说明:
CPUinfo:Intel(R) Xeon(R) CPU  E5405  @ 2.00GHz
MEM:4G
SQUID:Version 2.6.STABLE21
当单台流量20M,TCP连接数6w时,未加载tcmalloc的服务器CPU占用率和负载情况如下图:

CPU占用率

负载 继续阅读……


squid几个第三方工具

31 Jan 2010 Posted in  squid

GADMIN-SQUID 在linux环境下运行,经本人下载src后看,只能用于本机squid管理,不支持批量…… 继续阅读……


squid加载tcmalloc性能优化测试(原理)

31 Jan 2010 Posted in  squid

TCMalloc(Thread-Caching Malloc)是google开发的开源工具──“google-perftools”中的成员。其作者宣称tcmalloc相对于glibc2.3 malloc(aka-ptmalloc2)在内存的分配上效率和速度有6倍的性能提高,tcmalloc的常用场景是用于加速MySQL,不过据Wikipedia的hacker(Domas Mituzas)说,tcmalloc不仅仅对MySQL起作用,对squid也同样起作用(网上也有很多人在nginx上启用tcmalloc了),不过目前squid并没有official way来使用tcmalloc。
TCMalloc的实现原理和测试报告请见一篇文章:《TCMalloc:线程缓存的Malloc
那么让我们赶紧给squid加载上tcmalloc,提高cache服务器在高并发情况下的性能,降低系统负载吧。
因为服务器是64位OS,所以要先安装libunwind库。libunwind库为基于64位CPU和操作系统的程序提供了基本的堆栈辗转开解功能,其中包括用于输出堆栈跟踪的API、用于以编程方式辗转开解堆栈的API以及支持C++异常处理机制的API。(又cp一句话,^=^)
bashwget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99.tar.gz tar zxvf libunwind-0.99.tar.gz cd libunwind-0.99/ CFLAGS=-fPIC ./configure make CFLAGS=-fPIC make CFLAGS=-fPIC install
普通的./configure&&make&&make install可不行哟~
然后开始安装tcmalloc:
bashwget http://google-perftools.googlecode.com/files/google-perftools-1.8.1.tar.gz tar zxvf google-perftools-1.8.1.tar.gz cd google-perftools-1.8.1/ ./configure --disable-cpu-profiler --disable-heap-profiler --disable-heap-checker --enable-minimal --disable-dependency-tracking make && make install
然后配置动态链接库,因为是之前是默认安装,这里自然就是/usr/local/lib了。
bashecho "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf /sbin/ldconfig
然后给squid加载tcmalloc。官方推荐是重新编译:
先./configure,然后vi src/Makefile,修改如下:
c .... squid_LDADD = -L../lib \ -ltcmalloc_minimal \ \ repl/libheap.a repl/liblru.a \ .... .... data_DATA = mib.txt LDADD = -L../lib -lmiscutil -lpthread -lm -lbsd -lnsl -ltcmalloc_minimal EXTRA_DIST = ....
保存,make&&make install,OK!
如果不愿意重新编译,那么动态加载吧。在/home/squid/sbin/squid -s之前执行export
LD_PRELOAD=/usr/local/lib/libtcmalloc_minimal.so就可以了。
最后运行lsof -n | grep tcmalloc看看,如果有
squid 3811   root mem REG 202,1 1364560 446102 /usr/local/lib/libtcmalloc.so.0.0.0
squid 3813  squid mem REG 202,1 1364560 446102 /usr/local/lib/libtcmalloc.so.0.0.0
这样的输出,加载成功。效果如何,跑上几天再说咯~
另:
据网上说,如果squid的configure参数中,有–with-large-files的话,是没法加载tcmalloc的。 继续阅读……


header_replace试验

31 Jan 2010 Posted in  squid

在linuxtone论坛上,偶见一贴,说采用如下配置,browser就可以正常遵守originserver的过期设置,而且充分利用browser本身的缓存设置,对server来说就可以达到减少304请求的效果,从而提升机器性能,节省带宽云云…… 继续阅读……


防盗链二进阶(squid外部ACL)

31 Jan 2010 Posted in  CDN

服务器防盗链设置,从最简单的referer判断,到进阶的key+time生成md5值,应该说是比较可靠了,而还有一种防盗链方式,基于IP/COOKIE的,这个我没找到太多有用信息,似乎IIS有个相关插件?
只看到一篇squid的相关文章,简单的举了个防盗链的例子,未必有效(因为把cookie做明文处理,相比md5加密实在是防君子不防小人)。倒是从中学习一下external_acl_type用法,对squid进阶一番罢~~
首先按惯例,上权威:《squid中文权威指南》6.1.3章节和12.5章节。
用法如下:
external_acl_type name [options] FORMAT.. /path/to/helper
[helper arguments..]
options包括:ttl、negtive_ttl、children、concurrency、cache和grace;
FORMAT包括:%LOGIN,%EXT_USER,%IDENT,%SRC,%SRCPORT,%DST,%PROTO,%PORT,%METHOD,%MYADDR,%MYPORT,%PATH,%USER_CERT,%USER_CERTCHAIN,%USER_CERT_xx,%USER_CA_xx,%{Header},%{Hdr:member},%{Hdr:;member},%ACL,%DATA。
外部程序输出结果必须是OK或者ERR,不过可以再带上一些keyword,比如user/passwd,ERR的messages,access.log里记录的%ea等等。
cookie防盗链举例squid/libexec/check_cookie.pl如下:
perl #!/usr/bin/perl -w # 这个脚本仅仅是验证了Cache这个cookie的存在,没有严格的校验其值。 # disable output buffering $|=1; while () { chop; $cookie=$_; if( $cookie =~ /$COOKIE/i) { print "OK\n"; } else { print "ERR\n"; } }
squid.conf配置如下:
squid external_acl_type download children=15 %{Cookie} squid/libexec/check_cookie.pl acl dl external download acl filetype url_regex -i .wmv .wma .asf .asx .avi .mp3 .smi .rm .ram .rmvb .swf .mpg .mpeg .mov .zip .mid http_access deny filetype !dl
回过头来,想到之前的squid_session一文中,也是用的这个外部ACL~~ 继续阅读……


ubuntu 9.10下linuxqq经常挂掉的解决方案

30 Jan 2010 Posted in  linux

ubuntu 9.10下linuxqq(官方的QQ,八百年不更新的那个了) 继续阅读……


限速进阶

30 Jan 2010 Posted in  CDN

继续横向比较,之前有squid的限速配置,现在说nginx限速,nginx关于限速的模块有三个:HTTPLimitZoneModule、HTTPCoreModule和HTTPLimitReqModule,详见官方wiki,就不再贴链接了,能不能上天知道,真是地上芙蓉姐,天上绿坝娘呀…… 继续阅读……


防盗链进阶(nginx、lighttpd和squid类比)

30 Jan 2010 Posted in  CDN

在折腾squid的rewrite.pl时,参考的是公司原有的一个防盗链脚本。如下:
perl #! /usr/bin/env perl use strict; use Digest::MD5 qw(md5_hex); use POSIX qw(difftime mktime); $| = 1; my $errUrl = "http://www.test.com/no_such_url.html"; my $secret = "123456"; my $expired = 7200; while () { my ($uri, $client, $ident, $method) = split; print "$errUrln" and next unless ($uri =~ m#^(http://w*.?test.com)/(d{4})(d{2})(d{2})(d{2})(d{2})/(w{32})(/.+.mp3)$#i); my ($domain, $year, $mon, $mday, $hour, $min, $md5, $path) = ($1, $2, $3, $4, $5, $6, $7, $8); print "$errUrl\n" and next if $year < 1990 or $mon == 0 or $mon > 12 or $mday == 0 or $mday > 31 or $hour > 23 or $min > 59; print "$errUrl\n" and next if abs(difftime((int(time() / 100) * 100), mktime(00, $min, $hour, $mday, $mon - 1, $year - 1900))) > $expired; $path =~ s#%(..)#pack("c", hex($1))#eg; print "$errUrl\n" and next if $md5 ne md5_hex($secret . $year . $mon . $mday . $hour . $min . $path); print $domain . $path, "\n"; }
今天在网上看到lighttpd相似的配置。lighttpd自带mod_secdownload模块实现这种防盗链方法。具体配置及php代码如下例(详见http://trac.lighttpd.net/trac/wiki/Docs%3AModSecDownload):
php <? $secret = "verysecret";  //加密字符串,必须跟lighttpd.conf里边保持一致 $uri_prefix = "/dl/";    //虚拟的路径,必须跟lighttpd.conf里边保持一致 # filename $f = "/secret-file.txt";  //实际文件名,必须要加"/"斜杠 # current timestamp $t = time(); $t_hex = sprintf("%08x", $t); $m = md5($secret.$f.$t_hex); # generate link printf('%s', $uri_prefix, $m, $t_hex, $f, $f); ?>
lighttpd配置文件:
server.modules = ( …, “mod_secdownload”, … )
secdownload.secret          = “verysecret”
secdownload.document-root   = “/home/www/servers/download-area/”
secdownload.uri-prefix      = “/dl/”
secdownload.timeout         = 10 继续阅读……


日志管理

29 Jan 2010 Posted in  linux

第一个,最常见的cronolog,因为他配对apache,apache太常见,所以cronolog也就常见了~~稳定版本1.6.2,似乎不支持2G以上的日志,因为那时候linux内核也不支持。。。现在有beta版可以,另据网友分析,其实只要修改1.6.2源代码中的openfile函数成openfile64就行了……
使用方法: 继续阅读……


端口转发

28 Jan 2010 Posted in  linux

常见的linux端口转发,是iptables方式,方法如下:
bash #modprobe iptable_nat #modprobe ip_conntrack #service iptables stop #echo 1 > /proc/sys/net/ipv4/ip_forward #iptables -t nat -I PREROUTING -p tcp --dport 443 -j DNAT --to 1.2.3.4 #iptables -t nat -I POSTROUTING -p tcp --dport 8081 -j MASQUERADE #service iptables save #service iptables start
其次网上有不少推荐rinetd,方法如下:
bash #wget http://www.boutell.com/rinetd/http/rinetd.tar.gz #tar zxvf rinetd.tar.gz #cd rinted #./configure && make && make install # cat /etc/rinetd.conf 0.0.0.0 443 www.test.com 443 allow *.*.*.* logfile /var/log/rinetd.log
看起来比iptables有个优势,可以采用域名解析,可惜做不到根据域名的不同,把相同端口的请求转向不同IP,其实也就跟直接写IP没多少区别了。
第三还有ssh的端口转发,其实是把原TCP端口的数据转由ssh通道传输。方法如下:
本地转发:ssh -g -L :: 远程转发:ssh -g -R :: 不过客户未必(或许说基本不可能)给外人开放ssh吧~~ 第四,socket网络编程实现。我在网上发现了相关的perl脚本。 例一代码如下: ```perl #!C:Perlbinperl.exe #端口重定向(fork、IO::Select) #By shanleiguang@gmail.com, 2005/10 use strict; use warnings; use IO::Socket; use IO::Select; use Getopt::Std; use POSIX qw(:sys_wait_h strftime); use constant FOREVER => 1; use constant BUFSIZE => 4096; #父进程下处理僵死子进程 sub zombie_reaper { while(waitpid(-1, WNOHANG) > 0) {} $SIG{CHLD} = &zombie_reaper; } $SIG{CHLD} = &zombie_reaper; #处理参数 my %opts; getopts('h:l:t:p:', %opts); print_help() and exit if(defined($opts{'h'})); print_help() and exit if(not defined($opts{'t'}) or not defined($opts{'p'})); print_help() and exit if($opts{'t'} !~ m/^d+.d+.d+.d+$/); print_help() and exit if($opts{'l'} !~ m/^d+$/); print_help() and exit if($opts{'p'} !~ m/^d+$/); my $listen_port = (defined($opts{'l'})) ? $opts{'l'} : 8080; my $target_ip   = $opts{'t'}; my $target_port = $opts{'p'}; #在本地创建监听Socket my $socket_listen  = IO::Socket::INET->new( LocalPort => $listen_port, Proto => 'tcp', Listen    => 5, Reuse => 1, ); print timestamp(), ", listening on port $listen_port ...n"; #新建两个用于Socket IO监视的IO::Select对象 my $readers = IO::Select->new(); my $writers = IO::Select->new(); $readers->add($socket_listen); #父进程仅监视Listening Socket的accept事件 while(FOREVER) { my @readers = $readers->can_read; foreach my $reader (@readers) { if($reader eq $socket_listen) { #创建子进程处理后续的转发,父进程继续监视Listening Socket fork and next; my $socket_client = $socket_listen->accept(); #在子进程中,不再需要对Listening Socket进行操作 $readers->remove($socket_listen); $socket_listen->close(); #子进程 as_server($socket_client); exit; } } } #子进程 sub as_server { my $socket_client = shift; my $client_port = $socket_client->peerport(); my $client_ip   = $socket_client->peerhost(); #创建到目标地址:端口的Socket连接 my $socket_forward = IO::Socket::INET->new( PeerAddr => $target_ip, PeerPort => $target_port ); print timestamp(), ", $client_ip:$client_port$target_ip:$target_port.n"; #监视socket_client、socket_forward的IO情况 $readers->add($socket_client); $readers->add($socket_forward); $writers->add($socket_client); $writers->add($socket_forward); my ($rbuffer_forward, $rbuffer_client) = ('', ''); while(FOREVER) { my @readers = $readers->can_read; foreach my $reader (@readers) { my $rbuffer; #当socket_client可读时,将读取的内容追加到rbuffer_client后 #假如读取失败,则退出子进程 if($reader eq $socket_client) { exit if(not recv($reader, $rbuffer, BUFSIZE, 0)); $rbuffer_client.= $rbuffer; } #当socket_forward可读时,将读取的内容追加到rbuffer_forward后 #假如读取失败,则退出子进程 if($reader eq $socket_forward) { exit if(not recv($reader, $rbuffer, BUFSIZE, 0)); $rbuffer_forward .= $rbuffer; } } my @writers = $writers->can_write; foreach my $writer (@writers) { #当socket_client可写,且rbuffer_forward不为空时,将rbuffer_forward #内容写入socket_client,假如写失败,则退出子进程 if($writer eq $socket_client) { next if(not $rbuffer_forward); exit if(not send($writer, $rbuffer_forward, 0)); $rbuffer_forward = ''; } #当socket_forward可写,且rbuffer_client不为空时,将rbuffer_client #内容写入socket_forward,假如写失败,则退出子进程 if($writer eq $socket_forward) { next if(not $rbuffer_client); exit if(not send($writer, $rbuffer_client, 0)); $rbuffer_client = ''; } } } } sub timestamp { return strftime "[%y/%m/%d,%H:%M:%S]", localtime; } sub print_help { my $filename = (split /\/, $0)[-1]; print <>> $filename [-h,-l:] -h  print help -l  listening local port, default 8080 -t  target ipaddr -p  target port By shanleiguang@gmail.com, 2005/10 HELP } ``` 例二代码如下: ```perl #!C:Perlbinperl.exe #端口重定向(POE) #By shanleiguang@gmail.com, 2005/10 #POE结构: # #Driver->Filter->Wheel->Components # |______|______|________| # | #          Session # | # Kernel # #Driver:    底层文件操作的抽象,在编程时不会直接用到 #Filter:    底层、中层协议操作的抽象,通常不会直接用到 #Wheel: 高层协议操作的抽象,经常要用到 #Components:POE提供的一些拿来就能用的组件 #Session: 会话抽象,会话中需要创建高层协议抽象 #Kernel:    POE管理会话的内核 # #POE对象的数据结构: # #$_[HEAP]:是会话唯一的数据存储区; #$_[SESSION]:是指向会话自身的引用; #$_[KERNEL]:是指向会话管理内核的引用; #@_[ARG0..ARG9]:用于传递给各事件处理函数的参数; # #还是实例最直观: #在父会话中创建一个监听用的Socket,当有客户端连接,即有accept_sucess事件发生时, #则创建一个子会话处理后续事件,并将accept获得的客户端Socket传递给子会话;子会话 #创建到目标的Socket,连接过程中,如果客户端Socket中有input事件,则将客户端的input #内容缓存在一个队列中,当连接成功后,发送给到目标的那个Socket中,见下图: # #          +-------------------------------+ # /|      Socket_listen            | #        / +-------------------------------+ #Client|Socket_client Socket_server|Target #          +-------------------------------+ #                    Forwarder use strict; use warnings; use Socket; use Getopt::Std; use POSIX qw(strftime); use POE qw( Wheel::SocketFactory Wheel::ReadWrite Filter::Stream ); #Get Options my %opts; getopts('hl:t:p:', %opts); print_help() and exit if(defined($opts{'h'})); print_help() and exit if(not defined($opts{'t'}) or not defined($opts{'p'})); print_help() and exit if($opts{'t'} !~ m/^d+.d+.d+.d+$/); print_hekp() and exit if($opts{'p'} !~ m/^d+$/); my $listen_port = (defined($opts{'l'})) ? $opts{'l'} : 8080; my $target_addr = $opts{'t'}; my $target_port = $opts{'p'}; ###Create Parent - 'Listen Session'### ###创建父会话用于监听客户端的连接 ###会话创建的最后将进入_start状态,执行_start的handler ###accept_success即在_start的handler中创建监听Socket的Wheel中 ###的SuccessEvent事件,它的handler是forwarder_create函数 ###$_[ARG0]是wheel::SocketFatory的SuccessEvent传递的参数 POE::Session->create( inline_states => { _start => &forwarder_server_start, _stop  => sub { print timestamp(), ", forwarder server stopped."; }, accept_success => sub { &forwarder_create($_[ARG0]); }, accept_failure => sub { delete $_[HEAP]->{server_wheel} }, }, ); $poe_kernel->run(); exit; ###Event handlers for Parent Session### ###父会话中的事件处理函数 sub forwarder_server_start { print timestamp(), ", listening on port $listen_port and "; print "forward to $target_addr:$target_port\n"; #在父会话的存储区创建一个监听Socket类型的Wheel $_[HEAP]->{server_wheel} = POE::Wheel::SocketFactory->new( BindPort => $listen_port, SocketProtocol => 'tcp', ListenQueue    => SOMAXCONN, Reuse          => 'on', #ARG0 of SuccessEvent SuccessEvent => 'accept_success', FailureEvent => 'accept_failure', ); } ###Create Child - 'Forward Session'### ###创建子会话 sub forwarder_create { my $socket = shift; POE::Session->create( inline_states => { _start => &forwarder_start, _stop  => sub { print ' ' x 4, timestamp(), ', sessionId:'; print $_[SESSION]->ID, ", forwarder stop\n"; }, client_input => &client_input, client_error => sub { delete $_[HEAP]->{wheel_client}; delete $_[HEAP]->{wheel_server}; }, server_connect => &server_connect, server_input => sub { $_[HEAP]->{wheel_client}->put($_[ARG0]) if(exists $_[HEAP]->{wheel_client}); }, server_error => sub { delete $_[HEAP]->{wheel_client}; delete $_[HEAP]->{wheel_server}; }, }, #Parameters to '_start' Event args => [$socket], ); } ##Event Handlers of Child Session## sub forwarder_start { my ($heap, $socket) = @_[HEAP, ARG0]; print ' ' x 4, timestamp(), ', sessionId:'; print $_[SESSION]->ID, ", forwarder startn"; #Buffer client's input while connecting to the target $heap->{state} = 'connecting'; $heap->{queue} = []; #ClientForwarder server $heap->{wheel_client} = POE::Wheel::ReadWrite->new( Handle => $socket, Driver => POE::Driver::SysRW->new(), Filter => POE::Filter::Stream->new(), InputEvent => 'client_input', ErrorEvent => 'client_error', ); #Forwarder servertarget $heap->{wheel_server} = POE::Wheel::SocketFactory->new( RemoteAddress => $target_addr, RemotePort    => $target_port, SuccessEvent  => 'server_connect', FailureEvent  => 'server_error', ); } sub server_connect { my ($kernel, $session, $heap, $socket) = @_[KERNEL, SESSION, HEAP, ARG0]; #Replace $heap->{wheel_server} $heap->{wheel_server} = POE::Wheel::ReadWrite->new( Handle => $socket, Driver => POE::Driver::SysRW->new, Filter => POE::Filter::Stream->new, InputEvent => 'server_input', ErrorEvent => 'server_error', ); $heap->{state} = 'connected'; $kernel->call($session, 'client_input', $_) foreach(@{$heap->{queue}}); $heap->{queue} = []; } sub client_input { my ($heap, $input) = @_[HEAP, ARG0]; push @{$heap->{queue}}, $input and return if($heap->{state} eq 'connecting'); $heap->{wheel_server}->put($input) if(exists $heap->{wheel_server}); } #Common subroutines sub timestamp { return strftime "[%H:%M:%S]", localtime; } sub print_help { my $filename = (split /\/, $0)[-1]; print <>> $filename [-h,-l:] -h  print help -l  listen port -t  target ipaddress -p  target port A simple TCP forwarder server, 2005/10 By shanleiguang@gmail.com HELP } ``` 使用方法: # perl tcpForwarder.pl -l 8080 -t xxx.xxx.xxx.xxx -p 80 [xx:xx:xx:], listening on local port 8080 and forward to xxx.xxx.xxx.xxx:80... ... 继续阅读……


squid页面跳转试验

27 Jan 2010 Posted in  squid

某客户页面跳转试验记录 继续阅读……


CUshell版惊见中国特色脚本

24 Jan 2010 Posted in  bash

58同城:
bash #!/bin/bash #该脚本仅用于58同城网站刷票 #到达目的地 DES="(天水|兰州|西安)" #刷票url URL=http://bj.58.com/huochepiao/a1/ OLDMD5=`curl $URL | egrep "$DES" | sed '$d' | md5sum | awk '{print $1}'` while true; do if [ "$OLDMD5" == `curl $URL | egrep "$DES" | sed '$d' | md5sum | awk '{print $1}'` ];then sleep 300 else MESSAGE=`curl $URL | egrep "$DES" | sed '$d' | head -n1` SEND=`echo $MESSAGE | awk -F">" '{print $3}' | sed -e 's/<.*//'` DATE=`echo $SEND | awk -F":" '{print $2}'` #判断DATE变量,使其匹配你需要出发的日期 if [ "$DATE" == "2010-02-08" -o "$DATE" == "2010-02-09" -o "$DATE" == "2010-02-10" -o "$DATE" == "2010-02-11" -o "$DATE" == "2010-02-12" -o "$DATE" == "2010-01-28" ];then #输入需要发送信息的命令,飞信或mail等.....,发送的内容为$SEND变量 /usr/bin/curl -d cdkey=xxxx-xxx-xxxx-xxxxx -d password=xxxxxx -d addserial=xxx -d phone=13000000000 -d message="$SEND:58.com" http://sdkhttp.eucp.b2m.cn/sdkproxy/asynsendsms.action fi OLDMD5=`curl $URL | egrep "$DES" | sed '$d' | md5sum | awk '{print $1}'` sleep 300 fi done
赶集网:
bash #!/bin/bash #该脚本仅用于赶集网刷票 #到达目的地 DES="(天水|兰州|西安)" #刷票url URL=http://bj.ganji.com/piao/sell/ OLDMD5=`curl $URL | egrep "$DES" | md5sum | awk '{print $1}'` while true; do if [ "$OLDMD5" == `curl $URL | egrep "$DES" | md5sum | awk '{print $1}'` ];then sleep 300 else MESSAGE=`curl $URL | egrep "$DES" | head -n1` SEND=`echo $MESSAGE | awk -F">" '{print $3}' | sed -e 's/<.*//'` DATE=`echo $SEND | awk -F":" '{print $2}'` #判断DATE变量,使其匹配你需要出发的日期 if [ "$DATE" == "02-08" -o "$DATE" == "02-09" -o "$DATE" == "02-10" -o "$DATE" == "02-11" -o "$DATE" == "02-12" -o "$DATE" == "01-28" ];then #输入需要发送信息的命令,飞信或mail等.....,发送的内容为$SEND变量 /usr/bin/curl -d cdkey=xxxx-xxx-xxxx-xxxxx -d password=xxxxxx -d addserial=xxx -d phone=13000000000 -d message="$SEND:ganji.com" <a href="http://sdkhttp.eucp.b2m.cn/sdkproxy/asynsendsms.action">http://sdkhttp.eucp.b2m.cn/sdkproxy/asynsendsms.action</a> fi OLDMD5=`curl $URL | egrep "$DES" | md5sum | awk '{print $1}'` sleep 300 fi done 继续阅读……


squid自动配置web化

23 Jan 2010 Posted in  CDN

[root@test data]# cat index.htm
```html 继续阅读……


系统优化——TCP参数

19 Jan 2010 Posted in  linux

tcp_syn_retries :INTEGER
默认值是5
对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃。不应该大于255,默认值是5,对应于180秒左右时间。(对于大负载而物理通信良好的网络而言,这个值偏高,可修改为2.这个值仅仅是针对对外的连接,对进来的连接,是由tcp_retries1决定的) 继续阅读……


squid刷新缓存

13 Jan 2010 Posted in  CDN

这篇博文的起因是最近犯的一个低级错误。某客户要求立刻刷新掉一批url。格式是http://a.b.com/index.jsp?pid=123456&id=654321这样的。
我也没多想,上去就执行“squidclient -p 80  -m purge
http://a.b.com/index.jsp?pid=123456&id=654321”。结果硬是刷不掉……明明访问源站已经没有这个url了。我wget居然还能MISS/200~~~
直到同事提醒。才赫然发现其实我一直在purge和wget的,不是http://a.b.com/index.jsp?pid=123456&id=654321,而是http://a.b.com/index.jsp?pid=123456。linux把url里的&当作后台运行的命令执行了……而access.log中为了安全又没记录?后的具体参数,于是傻傻的跟客户客服扯皮了N久……
“squidclient -p 80  -m purge ‘http://a.b.com/index.jsp?pid=123456&amp;id=654321’”这么一刷立刻就好了~~
由此告诫自己,以后一定要严谨行事,引号最好还是要养成习惯都给带上~~ 继续阅读……