-
Apache Etag 生成规则算法 - [dev]
2011-12-26 | Tag:apache webserver
FileEtag Inode Mtime Size
Inode = Inode 十六进制
Mtime = last Modified time 十六进制
Size = File Size 十六进制
用-连接而成
-
转载参考备用:
我们在磁盘写操作持续繁忙的服务器上曾经碰到一个特殊的性能问题。每隔 30 秒,服务器就会遇到磁盘写活动高峰,导致请求处理延迟非常大(超过3秒)。后来上网查了一下资料,通过调整内核参数,将写活动的高峰分布成频繁的多次写,每次写入的数据比较少。这样可以把尖峰的写操作削平成多次写操作。以这种方式执行的效率比较低,因为内核不太有机会组合写操作。但对于繁忙的服务器,写操作将更一致地进行,并将极大地改进交互式性能。
下面是相关参数的调整:
一、2.6内核下
1、/proc/sys/vm/dirty_ratio
这个参数控制文件系统的文件系统写缓冲区的大小,单位是百分比,表示系统内存的百分比,表示当写缓冲使用到系统内存多少的时候,开始向磁盘写出数据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值,:
echo '1' > /proc/sys/vm/dirty_ratio2、/proc/sys/vm/dirty_background_ratio
这个参数控制文件系统的pdflush进程,在何时刷新磁盘。单位是百分比,表示系统内存的百分比,意思是当写缓冲使用到系统内存多少的时候,pdflush开始向磁盘写出数据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值,:
echo '1' > /proc/sys/vm/dirty_background_ratio3、/proc/sys/vm/dirty_writeback_centisecs
这个参数控制内核的脏数据刷新进程pdflush的运行间隔。单位是 1/100 秒。缺省数值是500,也就是 5 秒。如果你的系统是持续地写入动作,那么实际上还是降低这个数值比较好,这样可以把尖峰的写操作削平成多次写操作。设置方法如下:
echo "100" > /proc/sys/vm/dirty_writeback_centisecs如果你的系统是短期地尖峰式的写操作,并且写入数据不大(几十M/次)且内存有比较多富裕,那么应该增大此数值:
echo "1000" > /proc/sys/vm/dirty_writeback_centisecs4、/proc/sys/vm/dirty_expire_centisecs
这个参数声明Linux内核写缓冲区里面的数据多“旧”了之后,pdflush进程就开始考虑写到磁盘中去。单位是 1/100秒。缺省是 30000,也就是 30 秒的数据就算旧了,将会刷新磁盘。对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高太快。
echo "100" > /proc/sys/vm/dirty_expire_centisecs当然,如果你的系统内存比较大,并且写入模式是间歇式的,并且每次写入的数据不大(比如几十M),那么这个值还是大些的好。
5、/proc/sys/vm/vfs_cache_pressure
该文件表示内核回收用于directory和inode cache内存的倾向;缺省值100表示内核将根据pagecache和swapcache,把directory和inode cache保持在一个合理的百分比;降低该值低于100,将导致内核倾向于保留directory和inode cache;增加该值超过100,将导致内核倾向于回收directory和inode cache
缺省设置:100
6、 /proc/sys/vm/min_free_kbytes
该文件表示强制Linux VM最低保留多少空闲内存(Kbytes)。
缺省设置:724(512M物理内存)
7、/proc/sys/vm/nr_pdflush_threads
该文件表示当前正在运行的pdflush进程数量,在I/O负载高的情况下,内核会自动增加更多的pdflush进程。
缺省设置:2(只读)
8、/proc/sys/vm/overcommit_memory
该文件指定了内核针对内存分配的策略,其值可以是0、1、2。
0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2, 表示内核允许分配超过所有物理内存和交换空间总和的内存(参照overcommit_ratio)。
缺省设置:0
9、/proc/sys/vm/overcommit_ratio
该文件表示,如果overcommit_memory=2,可以过载内存的百分比,通过以下公式来计算系统整体可用内存。
系统可分配内存=交换空间+物理内存*overcommit_ratio/100
缺省设置:50(%)
10、/proc/sys/vm/page-cluster
该文件表示在写一次到swap区的时候写入的页面数量,0表示1页,1表示2页,2表示4页。
缺省设置:3(2的3次方,8页)
11、/proc/sys/vm/swapiness
该文件表示系统进行交换行为的程度,数值(0-100)越高,越可能发生磁盘交换。
二、2.4内核下
通过修改文件/proc/sys/vm/bdflush实现。文件中的九个参数含义如下:
nfract:dirty缓冲在缓冲区中的最大百分比。超过这个值将bdflush进程刷新硬盘。当可用内存比较少的情况下,将引发大量的磁盘I/O。为了均衡磁盘I/O,可以保持一个比较低的值。
Ndirty:bdflush进程一次写入磁盘的最大dirty缓冲块数量。这个值比较大将导致I/O急剧增加,如果这个比较小,bdflush进程执行不够从而可能导致内存的瓶颈。
Dummy2 :未使用
Dummy3:未使用
Interval:kupdated工作和刷新的最小频率,默认值是5秒。最小值是0秒最大值是600秒。
Age_buffer:缓冲数据写到磁盘之前操作系统等待的最大时间。默认值是30秒,最小值是1秒最大值是6000秒。
Nfract_sync:dirty缓存激活bdflush进程同步的百分比。默认值是60%。
Nfract_stop:dirty缓存停止bdflush进程的百分比。默认值是20%。
Dummy5:未使用
比如在一个写操作频繁的数据库服务器上设置:
10 500 0 0 50 30 10 0 0
-
32位为例
下载YUM:http://www.chinalinuxpub.com/yum.tgz
解压:tar zxvf yum.tgz
安装:cd yum && rpm -ivh *.rpm
配置:vi /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-5 - Base
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=os
baseurl=http://mirror.centos.org/centos/5/os/$basearch/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos5
#released updates
[update]
name=CentOS-5 - Updates
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=updates
baseurl=http://mirror.centos.org/centos/5/updates/$basearch/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos5
#packages used/produced in the build but not released
[addons]
name=CentOS-5 - Addons
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=addons
baseurl=http://mirror.centos.org/centos/5/addons/$basearch/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos5
#additional packages that may be useful
[extras]
name=CentOS-5 - Extras
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=extras
baseurl=http://mirror.centos.org/centos/5/extras/$basearch/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos5
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-5 - Plus
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=centosplus
baseurl=http://mirror.centos.org/centos/5/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos5
#contrib - packages by Centos Users
[contrib]
name=CentOS-5 - Contrib
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=contrib
baseurl=http://mirror.centos.org/centos/5/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos5
导KEY:rpm --import http://mirror.centos.org/centos/5/os/i386/RPM-GPG-KEY-CentOS-5
清理:
rpm -qa | grep kernel(查出内核包)
rpm -e --justdb --nodeps kernel-**** kernel-***-EL(上述结果)
rpm -e --justdb --nodeps zaptel* VFlib2
yum remove hal asterisk-addons
yum clean all
安装新内核:
wget -c http://mirror.centos.org/centos/5/os/i386/CentOS/kernel-2.6.18-194.el5.i686.rpm
rpm -Uvh kernel-2.6.18-194.el5.i686.rpm --nodeps
升级:
yum -y upgrade
搞定!
-
卡帕珠宝 传承经典
2010-01-28 | Tag:
卡帕珠宝 传承经典
今天去卡帕珠宝设计定制了个戒指准备偷偷送给女朋友。卡帕珠宝设计的专业真是让人感叹。很是期待,这是卡帕珠宝设计的官网http://www.3d2s.com
-
mkisofs 使用 - [system]
2009-10-15 | Tag:system linux mkisofs
在RH下使用mkisofs制作启动镜像时碰到问题
#mkisofs -R -J -T -V Boot -r -d -allow-multidot -allow-leading-dots -no-bak -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o boot.iso
Warning: creating filesystem that does not conform to ISO-9660.
INFO: UTF-8 character encoding detected by locale settings.
Assuming UTF-8 encoded filenames on source filesystem,
use -input-charset to override.
mkisofs: Missing pathspec.1、去掉-d选项,解决Warning: creating filesystem that does not conform to ISO-9660.
2、增加-input-charset UTF-8,解决INFO: UTF-8 character encoding detected by locale settings.
3、在句尾"-o /dada/boot/boot.iso"之后增加". "变成"-o /dada/boot/boot.iso ." ,解决mkisofs: Missing pathspec.
最终命令如下:
mkisofs -R -J -T -V Boot -joliet-long -no-bak -allow-multidot -allow-leading-dots -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -input-charset UTF-8 -o /dada/boot/boot.iso .
-
perl-DBD Can't load '/usr/lib/perl5/site_perl/5.8.*/i386-linux-thread-multi/auto/DBD/mysql/mysql.so - [system]
2009-07-20 | Tag:system linux perl db mysql
帮同事安装perl-DBD后测试出现:
Can't load '/usr/lib/perl5/site_perl/5.8.*/i386-linux-thread-multi/auto/DBD/mysql/mysql.so' for module DBD::mysql: libmysqlclient.so.16: cannot open shared object file: No such file or directory at /usr/lib/perl5/5.8.*/i386-linux-thread-multi/DynaLoader.pm line 230.
解决办法:
1. ldd /usr/lib/perl5/site_perl/5.8.*/i386-linux-thread-multi/auto/DBD/mysql/mysql.so
libmysqlclient.so.16 => not found
libcrypt.so.1 => /lib/libcrypt.so.1 (0x009f1000)
libnsl.so.1 => /lib/libnsl.so.1 (0x00257000)
libm.so.6 => /lib/tls/libm.so.6 (0x00ca7000)
libc.so.6 => /lib/tls/libc.so.6 (0x00111000)
/lib/ld-linux.so.2 (0x0049d000)2.locate libmysqlclient.so.16
/usr/local/mysql/lib/libmysqlclient.so.16
/usr/local/mysql/lib/libmysqlclient.so.16.0.03.ln -s /usr/local/mysql/lib/libmysqlclient.so.16.0.0 /lib/libmysqlclient.so.16
4.ldd /usr/lib/perl5/site_perl/5.8.*/i386-linux-thread-multi/auto/DBD/mysql/mysql.so
libmysqlclient.so.16 => /lib/libmysqlclient.so.16 (0x00df7000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x0028d000)
libnsl.so.1 => /lib/libnsl.so.1 (0x008e0000)
libm.so.6 => /lib/tls/libm.so.6 (0x005e4000)
libc.so.6 => /lib/tls/libc.so.6 (0x00980000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x003f4000)
/lib/ld-linux.so.2 (0x0049d000)5.done!(其中上述5.8.*,为perl版本如5.8.8)
-
问题描述:
在使用Perl写服务器服务群集监控程序时遇到这么个问题,在同一服务器上可能运行同名服务但是用不同端口(比如我们启动了两个nginx一个做反向代理一个做WEBSRV,再如起两个mysqld一个跑3306,一个跑3307端口,所以这种情况是比较常见的),那么我们在区分两个同名服务时只能以端口号来区分,当然,在root用户下我们很容易就可以通过shell命令获取,如netstat -anp, lsof -i :端口号, fuser -n tcp 端口号,但是当你使用其他普通用户执行时你会发现三个命令都没有权限获取相关的进程ID。
解决思路:
1.使用sudo去执行netstat -anp,lsof -i :端口号, fuser -n tcp 端口号,但是这么做的话需要输密码,那么你的脚本里不就是要写密码明文了?当然可以在/etc/soduers设置这个普通用户针对上述三个命令的某一个NOPASSWORD:netstat fuser lsof 但是这个监控程序的客户端将运行在几百乃至上千台服务器上,我若使用这种方法我则必须要在这么多台机器上使用root进行设置
chmod +w /etc/sudoers && echo "%用户 ALL=(ALL) NOPASSWD:netstat" && chmod -w /etc/sudoers
这样做的话会累死我,而且增加了这个程序的环境依赖性导致了程序的不完整性,抛弃
2.分析netstat,fuser或者lsof,刚开始我是以为它们都是从/proc/net/下读文件进行分析的,后来翻看了几页后没找到,没时间花这么多时间去完整的读这些代码,放弃(有读过的或者知道怎么实现的,请告诉我,万谢!)
3.使用linux的setuid()实现,在C语言中有setuid(),seteuid(),setgid(),setegid(),四个函数(关于setuid()就不赘述了,网上文档多的去了),但是Perl中是没有的,后来发现在Perl特殊变量中有
$< 用户真实ID也就是uid
$> 进程有效ID也就是euid
$( 当前进程的组ID gid
$) 当前进程的有效组ID egid
在shell下的id命令可以查看当前用户的这些属性,在perl中可以轻易的指定:$< = 500;但是在当前脚本文件下的话只允许root用户降权使用,普通用户至$< = 0;是不会生效的。但是可以使用调用带有setuid权限位的脚本去提升权限并执行系统命令netstat,fuser或lsof,具体实施过程为:
使用root用户创建setuid.pl
#!/usr/bin/perl -w
use strict;
#必须要设置环境变量,否则普通用户仍然是不允许执行的
$ENV{"PATH"} = "/bin:/usr/bin:/sbin:/usr/sbin";
$ENV{"BASH_ENV"}="";
$< = 0;
system("/bin/netstat -anp");
然后chmod 4755 setuid.pl
这时候你 ls -la setuid.pl查看到其权限应该是 -rwsr-xr-x,那么这就对了
这个时候你可以使用perl脚本或者shell脚本去调用setuid.pl,然后使用普通用户去执行这个perl或shell,而得到的输出将与你使用root用户直接执行netstat命令是一样的
-
URL: PHP-FPM on highload tips
When you running a highload website with PHP-FPM via FastCGI, the following tips may be useful to you : )
1. Compile PHP's modules as less as possible, the simple the bes... -
add_header Cache_Control private;
... -
gzip_min_length 1k;
从Content-Length中数值获取验证,小于1K会越压越大
gzi... -
绑定worker进程和CPU,只有LINUX内核高于2.4可用;
worker_rlimit_nofile 51200;
和系统的单进程打开文件数一致,不必理会进程个数,使用ulimit -SHn 51200 设置
events {
use epoll;
... -
WHOIS NGINX
高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。
Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的Rambler.ru 站点开发的,它已经在该站点运行超过四年多了。
Nginx 超越 Apache 的高性能和稳定性。
稳定性、功能集丰富、 冷源配置文件和系统资源低能耗
在高连接并发的情况下,N... -
gcc install
2009-06-26 | Tag:system linux
注意版本,顺序如下:
kernel-headers-2.6.7-1.i686.rpm
glibc-headers-2.9-3.i386.rpm
glibc-2.9-3.i686.rpm
glibc > 2.3.4 conflicts with glibc-common-2.3.4-2.41.i386
glibc-common-2.9-3.i386.rpm
真变态,glibc告诉我依赖glibc-common,glibc-common又告诉我需要glibc
glibc-devel-2.9-3.i386.rpm
binutils-2.9.1.0.15-2.src.rpm
libgcc-4.3.2-7.i386.rpm
libmpfr1-devel-2.2.1-6mdv2008.0.i586.rpm --nodeps
libmpfr1-static-devel-2.2.1-6mdv2008.0.i586.rpm
libgomp-4.3.2-7.i386.rpm
binutils-2.9.1.0.15-2.src.rpm
gcc-4.3.2-7.i386.rpm --nodeps
cpp-4.3.2-7.i386.rpm --nodeps
libstdc++-4.3.2-7.i386.rpm
libstdc++-devel-4.3.2-7.i386.rpm
-
关于程序RSS总数大于物理内存总数 - [system]
2009-06-17 | Tag:system linux
今天发现200个httpd进程占用的RSS总数远超过2G的物理内存
百思不得其解,开始以为是获取的数值错误,我是从/proc/pid/stat中取出所有httpd进程累加,后经过ps取httpd的RSS累加得出的数值是相同的
以为是单位好换算的问题,有资料表示RSS的单位为page,却也不是
原来是进程间共享内存的问题!
忽略!
-
从/proc统计端口连接数 - [system]
2009-05-31 | Tag:system linux dev
以ipv4 tcp为例,从/proc/net/tcp获取数据,如若ipv4 udp则/proc/net/udp,ipv6则:/proc/net/icp6 /proc/net/udp6
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
第一列是打开套接字的编号,表示打开了几个此种类型的套接字。
第二列是本地地址,格式为"十六进制(网络字节序)的IP地址:端口号"。
第三列是远程地址端口。
第四列是连接状态(st = status):为十六进制从0-11为以下状态数组对应标量
{
"ERROR_STATUS",
"TCP_ESTABLISHED",
"TCP_SYN_SENT",
"TCP_SYN_RECV",
"TCP_FIN_WAIT1",
"TCP_FIN_WAIT2",
"TCP_TIME_WAIT",
"TCP_CLOSE",
"TCP_CLOSE_WAIT",
"TCP_LAST_ACK",
"TCP_LISTEN",
"TCP_CLOSING",
};其他的就自己写脚本分析了,不再赘述。
-
以前写的一个生成mysql以下月为名称的数据库
并生成该月内以日期为表名的shell script
该数据库的设计是用来全量存储备份点击日志的,每三个月就从磁盘上打包移走前三个月的mysql的数据库数据文件
以前只会写shell script时的解决办法,有很大的改进空间(或者说很烂,不过不可否认,的确做到了,哈哈)
如果用其他语言的话,比如PERL会很容易,但是当时只会这个,能改进的人就去改进,不废话,贴代码
#!/bin/bash
DBHost="192.168.1.102"
DBUser="logdbuser"
DBPass='logdbpassword'
DBName="log_db"
Month=`/bin/date +%m`
Year=`/bin/date +%Y`
NextMonth=`/usr/bin/expr $Month + 1`
NextMonth=`/usr/bin/printf "%02d\n" $NextMonth`
if [ $NextMonth == "13" ]; then
NextMonth=01
Year=`/usr/bin/expr $Year + 1`
fi
/usr/local/mysql/bin/mysql --host=$DBHost --user=$DBUser --password=$DBPass <<EOF
CREATE DATABASE clicklog_$Year$NextMonth
EOF
NumOfNextMonth=`/usr/bin/cal $NextMonth $Year | /usr/bin/xargs /bin/echo | /bin/awk '{print $NF}'`
for Day in `/usr/bin/seq --equal-width 1 $NumOfNextMonth`; do
echo "DROP TABLE IF EXISTS \`$Year$NextMonth$Day\`;" >> /dev/shm/tmp_tb.sql
echo "CREATE TABLE \`$Year$NextMonth$Day\` ( \`id\` bigint(32) NOT NULL auto_increment, \`product_id\` int(32) NOT NULL, \`first_letter\` varchar(1) NOT NULL, \`cate_pid\` int(32) NOT NULL, \`cate_id\` int(32) NOT NULL, \`page_id\` int(32) NOT NULL, \`author_id\` int(32) NOT NULL, \`create_time\` date default '0000-00-00', \`user_id\` int(32) NOT NULL, \`click_time\` timestamp NOT NULL default CURRENT_TIMESTAMP, \`user_ip\` varchar(20) NOT NULL default '000.000.000.000', PRIMARY KEY (\`id\`), KEY \`click_time\` (\`click_time\`,\`product_id\`), KEY \`click_time_2\` (\`click_time\`,\`product_id\`,\`page_id\`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;" >> /dev/shm/tmp_tb.sql
done
/usr/local/mysql/bin/mysql --host=$DBHost --user=$DBUser --password=$DBPass clicklog_$Year$NextMonth < /dev/shm/tmp_tb.sql
/bin/rm -fr /dev/shm/tmp_tb.sql这个脚本在crontab中设定在每月的月底执行,生成下个月的数据库与日期表
应该注意的是,黄色那部分语句的数据库名变量与数据表名变量一定要用``括起来并用反斜杠\进行转义,即\`\`,
否则会出错,因为数据库名变量与数据表名变量都是数字,在进行mysql操作的时候会被认为是数值,从而认为你的MYSQL语法错误
-
分享一个简单的PHP分页函数 - [dev]
2009-05-16 | Tag:dev web php
/**
* 分页函数
* @param numeric $data_num 记录总数
* @param numeric $page_size 单页显示数目
* @param numeric $Gp 页数
*
* @return numeric $page['from'] 数据库起始参数
* @return numeric $page['size'] 单页显示数目
* @return numeric $page['curr'] 当前页数
* @return numeric $page['pages'] 总页数
* @return numeric $page['last'] 上一页
* @return numeric $page['next'] 下一页
*
*/
function pages($data_num, $page_size = 10, $Gp = 1) {
$page = array();
$page['size'] = $page_size; //单页显示数目
$page['curr'] = $Gp > 0 ? $Gp - 1 : 0; //当前页数
$page['from'] = $page['curr'] * $page_size; //数据库起始参数
$page['pages'] = @ceil( $data_num / $page_size); //总页数
$page['last'] = $Gp > 1 ? $Gp - 1 : 1; //上一页
$page['next'] = $Gp < $page['pages'] ? $Gp + 1 : $page['pages']; //下一页
return $page;
} -
非常有利于提高PHP效率的一些开发行为 - [dev]
2009-05-15 | Tag:dev web php
静态调用的成员一定要定义成 static
静态地调用非 static 成员,效率会比静态地调用 static 成员慢 50-60%。主要是因为前者会产生 E_STRICT 警告,内部也需要做转换。使用类常量的好处是:
- 编译时解析,没有额外开销
- 杂凑表更小,所以内部查找更快
- 类常量仅存在于特定「命名空间」,所以杂凑名更短
- 代码更干净,使除错更方便不要使用 require/include_once
require/include_once 每次被调用的时候都会打开目标文件!
- 如果用绝对路径的话,PHP 5.2/6.0 不存在这个问题
- 新版的 APC 缓存系统已经解决这个问题
文件 I/O 增加 => 效率降低
如果需要,可以自行检查文件是否已被 require/include。不要调用毫无意义的函数
有对应的常量的时候,不要使用函数。$is_win = DIRECTORY_SEPARATOR == '\\';
用 $_SERVER['REQUEST_TIME'] 替换 time()
加速 PCRE
- 对于不用保存的结果,不用 (),一律用 (?:)
这样 PHP 不用为符合的内容分配内存,省。效率提升 15% 左右。
- 能不用正则,就不用正则,在分析的时候仔细阅读手册「字符串函数」部分。漏掉好用的函数?加速 strtr
如果需要转换的全是单个字符的时候,用字符串而不是数组来做 strtr:
<?php
$addr = strtr($addr, "abcd", "efgh"); // good
$addr = strtr($addr, array('a' => 'e',
// ...
)); // bad
?>效率能够提升10 倍。
- 用 strpos 先查找(非常快),看是否需要替换,如果需要,再替换
效率:
- 如果需要替换:效率几乎相等,差别在 0.1% 左右。
- 如果不需要替换:用 strpos 快 200%。不要滥用 @ 操作符。虽然 @ 看上去很简单,但是实际上后台有很多操作。用 @ 比起不用 @,效率差距:3 倍。
特别不要在循环中使用 @,在 5 次循环的测试中,即使是先用 error_reporting(0) 关掉错误,在循环完成后再打开,都比用 @ 快。当需要对比「前 n 个字符」是否一样的时候,用 strncmp/strncasecmp,而不是 substr/strtolower,更不是 PCRE,更千万别提 ereg。strncmp/strncasecmp 效率最高(虽然高得不多)。
慎用 substr_compare (PHP5 ONLY)
按照上面的道理,substr_compare 应该比先 substr 再比较快咯。答案是否定的,除非:
- 无视大小写的比较
- 比较较大的字符串
不要用常量代替字符串
为什么:
- 需要查询杂凑表两次
- 需要把常量名转换为小写(进行第二次查询的时候)
- 生成 E_NOTICE 警告
- 会建立临时字符串
效率差别:700%。不要把 count/strlen/sizeof 放到 for 循环的条件语句中
<?php
for ($i = 0, $max = count($array);$i < $max; ++$i);
?>
效率提升相对于:
- count 50%
- strlen 75%短的代码不一定快
<?php
// longest
if ($a == $b) {
$str .= $a;
} else {
$str .= $b;
}
// longer
if ($a == $b) {
$str .= $a;
}
$str .= $b;
// short
$str .= ($a == $b ? $a : $b);
?>效率比较:
- longest: 4.27
- longer: 4.43
- short: 4.76<?php
// original
$d = dir('.');
while (($entry = $d->read()) !== false) {
if ($entry == '.' || $entry == '..') {
continue;
}
}
// versus
glob('./*');
// versus (include . and ..)
scandir('.');
?>效率比较:
- original: 3.37
- glob: 6.28
- scandir: 3.42
- original without OO: 3.14
- SPL (PHP5): 3.95提高 PHP 文件访问效率
需要包含其他 PHP 文件的时候,使用完整路径,或者容易转换的相对路径。<?php
include 'file.php'; // bad approach
incldue './file.php'; // good
include '/path/to/file.php'; // ideal
?>关于引用的技巧
引用可以:
- 简化对复杂结构数据的访问
- 优化内存使用
<?php
$a['b']['c'] = array();// slow 2 extra hash lookups per access
for ($i = 0; $i < 5; ++$i)
$a['b']['c'][$i] = $i;// much faster reference based approach
$ref =& $a['b']['c'];
for ($i = 0; $i < 5; ++$i)
$ref[$i] = $i;
?><?php
$a = 'large string';// memory intensive approach
function a($str)
{
return $str.'something';
}// more efficient solution
function a(&$str)
{
$str .= 'something';
}
?> -
抄一篇“PS磨皮去皱效果简易教程” - [others]
2009-04-30 | Tag:life
抄一篇“PS磨皮去皱效果简易教程” -- 以备不时之需,哈哈 等以后某人老了,要我P图我还有这手
STEP1 打开图片,复制一张图片,再点开通道复制绿色通道
STEP2 再按滤镜里的其他-高反差保留,就10的预设值
... -
textarea 的回车换行及使用PHP拆分至数组 - [dev]
2009-04-27 | Tag:dev web php
真是郁闷,居然要把时间花在这上面调试半天,无废话记录:
1、textarea回车换行为 \r\n,因为自己的实践经验不足,一直误读并误认为是\n\r,并一直尝试\n,\r,\n\r,\t,\n\r\t就是没尝试\r\n,失败!
2、刚开始准备使用php函数explode()拆分到数组,后发现其无法识别并正确拆分,最后使用split()成功解决。
-
PHP匹配数字中英文及下划线 - [dev]
2009-02-26 | Tag:dev php
网上找到这个通过测试
<?php
$action = trim($_GET['action']);
if($action == "sub")
{
$str = $_POST['dir'];
//if(!preg_match("/^[".chr(0xa1)."-".chr(0xff)."A-Za-z0-9_]+$/",$str)) //GB2312汉字字母数字下划线正则表达式
if(!preg_match("/^[\x{4e00}-\x{9fa5}A-Za-z0-9_]+$/u",$str)) //UTF-8汉字字母数字下划线正则表达式
{
echo "<font color=red>您输入的[".$str."]含有违法字符</font>";
}
else
{
echo "<font color=green>您输入的[".$str."]完全合法,通过!</font>";
}
}
?>
<form method="POST" action="?action=sub">
输入字符(数字,字母,汉字,下划线):
<input type="text" name="dir" value="">
<input type="submit" value="提交">
</form> -
在shell用for循环做数字递增的时候发现问题,特列出shell下for循环的几种方法:
1.
for i in `seq 1 1000000`;do
echo $i
done
用seq 1 10000000做递增,之前用这种方法的时候没遇到问题,因为之前的i根本就没用到百万(1000000),因为项目需要我这个数字远大于百万,发现用seq 数值到 1000000时转换为1e+06,根本无法作为数字进行其他运算,或者将$i有效、正确的取用,遂求其他方法解决,如下
2.
for((i=1;i<10000000;i++));do
echo $i
done
3.
i=1
while(($i<10000000));do
echo $i
i=`expr $i + 1`
done
因为本方法调用expr故运行速度会比第1,第2种慢不少不过可稍作改进,将i=`expr $i + 1`改为i=$(($i+1))即可稍作速度的提升,不过具体得看相应shell环境是否支持
4.
for i in {1..10000000;do
echo $i
done
其实选用哪种方法具体还是得由相应的shell环境的支持,达到预期的效果,再考虑速度方面的问题。
wel come 2 大过天
-
准备做个拥有大量用户的排行榜单,要求在比较普通的WEB环境,如在支持PHP MYSQL的环境中实现
今天试了mysql memory db 效果比较令人满意
准备从普通用户表中SELECT用户数据并ORDER BY 其中某个字段 DESC然后插入 榜单表
用MYSQL的内存表来实现榜单表,利用语句
TRUNCATE TABLE tank_table;
INSERT INTO rank_table SELECT * FROM user_table ORDER BY credits DESC;
在创建内存表rank_table时,创建rank自增主键字段,以表示用户排名
功能实现,接下去考虑的是效率了
从普通表查询排序3W多条数据并插入内存表其中带有自增字段用时 0.25sec
相同操作下 普通表 需要用时 1.2sec 整整快了0.8sec
而用27W数据做测试时, 写到11W左右数据时出现 The table ‘’ is full
经SHOW VARIABLES LIKE ‘%max_heap_table_size%’;
结果显示只有大概16M,查看了内存表的状态 发现数据与索引相加大概也就16M
遂修改my.cnf
max_heap_table_size = 32M
重启mysqld,发现还不够,这27W数据还真大,而后改成64M(测试用),再试成功
用时4sec左右。
另 mysql the table is full 还有个相关属性
SHOW VARIABLES LIKE ‘%tmp_table_size%’;
可知大小, 具体修改 my.cnf 中 tmp_table_size = 64M 重启MYSQLD服务可知结果
实现功能,效率非常明显的快
大过天 -
Linux rar解压 - [system]
2008-12-15 | Tag:system linux
Linux下rar解压工具
http://renylai.blogbus.com/files/12293287710.gz
rar for linux
mv 12293287710.gz rar4linux.tar.gz
tar zxvf rar4linux.tar.gz
cd rar4linux
make
make install ... -
Linux修改文件描述符 - [system]
2008-12-15 | Tag:system linux
Linux下永久修改文件描述符为65535
/etc/security/limits.conf,
增加一行* - nofile 65535
-
mysql CPU高占用 - [db]
2008-10-28 | Tag:system db mysql
今天发现一台几个月MYSQL机器CPU占用飙升很快
进去show status;
show processlist;
发现几乎就是几个语句重复出现,查看其表结构发现未建索引
根据条件建完索引,CUP占用骤降
另G出来的如果用很多GROUP BY语句的应用所在MYSQL最后增加 tmp_table_size值
-
HessianPHP Client 中文编码问题 - [dev]
2008-10-21 | Tag:dev php hessian
Protocol.php
function readString()下
return utf8_decode($string);
换成直接return $string;
不进行转换,中文便可正确显示UTF-8编码中文,
如果为GB2312,则return iconv('UTF-8', 'GB2312', $string);
-
CentOS5 yum source
2008-10-13 | Tag:system linux yum
[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
baseurl=http://mirror.be10.co... -
Anybody knows what day is it today? - [nonsense]
2008-09-27 | Tag:nothing
小禽兽面试
以为昨天面的, 昨天到了说今天,早上去了说下午面
小禽兽不爽了 因为请假扣薪水
我说了 先等等 准备下教案也是好的,也就快到下午了,过来吃完饭再过去就可以了
她说吃完饭就不过去了,一边一直请假一边还一直拖,不面了
我解释说 既然那边已经请假一天,那么 把这边的事情解决好再来解决那边请假的问题,要不两边都没做好
之前的一天也白过了
no word, off line forthwit.
-
转自 http://www.bsdmap.com/
#!/bin/bash
SEND_THREAD_NUM=13
tmp_fifofile=”/tmp/$$.fifo” # 脚本运行的当前进程ID号作为文件名
mkfifo “$tmp_fifofile” # 新建一个随机fifo管道文件
exec 6<>”$tmp_fifofile” # 定义文件描述符6指向这个fifo管道文件
rm $tmp_fifofile
for ((i=0;i<$SEND_THREAD_NUM;i++));do
echo # for循环 往 fifo管道文件中写入13个空行
done >&6for i in `seq 100`;do # 100 次 for 循环 开始
read -u6 # 从文件描述符6中读取行(实际指向fifo管道){
echo $i # 打印 i
sleep 3 # 暂停3秒
echo >&6 # 再次往fifo管道文件中写入一个空行。
} &# {} 这部分语句被放入后台作为一个子进程执行,所以不必每次等待3秒后执行
#下一个,这部分的echo $i几乎是同时完成的,当fifo中13个空行读完后 for循环
# 继续等待 read 中读取fifo数据,当后台的13个子进程等待3秒后,按次序
# 排队往fifo输入空行,这样fifo中又有了数据,for语句继续执行pid=$! #打印最后一个进入后台的子进程id
echo $piddone
wait
exec 6>&- #删除文件描述符6exit 0







