存档

2011年7月 的存档

ini_set知多少

2011年7月20日 effect 没有评论

想必大家都用过这个函数,可以动态的修改php的配置项。但是是不是所有的配置项都可以用ini_set来修改呢?答案肯定是否定的!因为如果都可以修改,那么有些ISP的disable_functions等安全性配置可以轻松被突破,那么哪些是可以修改的呢?本文就来寻找一下答案。

打开你的PHP手册,找到附录中的php.ini配置选项列表,每个配置选项都有一个可修改范围,范围有下面几种值:

PHP_INI_PERDIR 可以在php.ini    .htaccess   http.conf中设置。.htaccess和http.conf只能适用于apache的web server,并且是模块安装的才可以。手册中看到upload_max_filesize的配置范围就是PHP_INI_PERDIR,那么在.htaccess或者http.conf中这样配置:

php_value upload_max_filesize 180M

。这样你的上传文件的最大文件大小是180M了。

PHP_INI_SYSTEM 只能在php.ini和http.conf中配置。http.conf中的配置方法参看上面实例。

PHP_INI_ALL 可以在任何地方配置,所以只有访问是这个的才能在脚本中配置,所以ini_set可配置的选项只能是这个范围之内的

PHP_INI_USER 手册上说是可以在用户的脚本中可以配置,但是没有找到一个范围是这个的配置选项。

分类: php 标签:

给你的PHP加速

2011年7月19日 effect 没有评论

PHP作为一种解释性的语言,可以快速的构建各种WEB服务,并且有着良好的扩展性和维护性。然而每次请求时候,都会把PHP源码解释编译成操作系统可识别的机器码然后再执行,这样下来每次请求都会重复的进行解释编译,那有没有什么方法可以不重复解释编译呢?本文就介绍几种常用的PHP加速器。

什么是PHP加速器?

通过前面的了解,每次HTTP的请求都会进行一个过程:把编译解释成操作系统可以直接运行的机器码。这是一个重复的工作,加速器的功能就是把这一过程缓存起来重复使用。常用的加速器有:Alternative PHP Cache (APC)、XCache、eAccelerator。

Xcache

安装方式无非就是标准的PECL的按照方式,下面就说一下关键的配置文件和查看统计信息的方法。

配置

xcache.cacher = On    开启opcode 缓存器  当size为0时候无效

xcache.size  = 64M 缓存大小一般的网站64M足够,如果此台WEB SERVER有多个vhosts,那么可以适当的增加到256M或者512M等

xcache.count  CPU个数,如果是双核算2,8核的是8

xcache.var_size 同xcache.size

xcache.var_count 同xcache.count

xcache.ttl  缓存项目的ttl(Time To Live) 生命周期,0是永远

xcache.gc_interval  扫描过期项目的时间间隔, 0不扫描,

xcache.coverager  是否启用代码覆盖,测试时候发现关闭次选项加速效果更好

统计信息

拷贝源码中的admin目录下的文件到你的网站的目光目录下(比如是xcacheadmin),那么输入http://yourdomain/xcacheadmin/,这里会有验证框弹出,输入配置中的admin和pass即可。

eaccelerator

安装方式也是标准的PECL安装方式

配置

eaccelerator.shm_size = “8″     eAccelerator 可以使用的共享内存的数量 (以兆为单位) . “0″ 是指操作系统的默认值. 默认值是 “0″.
eaccelerator.cache_dir = “/tmp/eaccelerator”
eaccelerator.enable = “1″  是否开启 1打开 0关闭
eaccelerator.optimizer = “1″    是否开启内部优化 1打开
eaccelerator.check_mtime = “1″  是否开启文件修改的检测 1开启 0关闭
eaccelerator.debug = 0  是否打开日志记录。”1″ 为开启,”0″ 为关闭。默认值为 “0″。会将缓存命中得记录写入日志。
eaccelerator.filter = “”   判断缓存的文件,如果以叹号!开头,那么匹配的将不缓存,否则匹配的加入缓存,默认是空,表示所有的都缓存
eaccelerator.shm_max = “0″
eaccelerator.shm_ttl = 0
eaccelerator.prune_period = 0
eaccelerator.shm_only = 0
eaccelerator.compress = 1  是否压缩缓存内容  1允许
eacceleratorcompress_level = 9  压缩内容的等级 9是最高级

其他加速方法

编译

尽可能的只编译你需要的模块、很少用的模块编译成共享模式,执行时动态加载

配置

禁用register_globals

关闭magic_quotes_*

关闭expose_php

后记

加速PHP只是给PHP编译解析这一重复的过程进行优化,而一个WEB服务本身的执行速度还是取决于是否合理的使用了数据库、是否很好的使用了一些缓存系统(比如memcached)、整个架构是否是最优的。当然在这些条件都一致的情况下,使用这些加速软件还是能有一些效果。

APC一直没有实验,对比了一下xcache和eaccelerator,eacce稍微占优,而且配置文件也相对简单一点,所以个人倾向于使用eacce,当然每个项目可能结果不太一样,大家可以对比后再取舍。

分类: php 标签: ,

kohana3在nginx中的重写配置

2011年7月18日 effect 没有评论

在公司内部推广过kohana3,反应还算可以。不过有好几次同事来咨询在nginx下的重写配置,下面作为备忘:

 location / {
         root   /data/vhosts/k3.com/public_html;#这里改为你对应的目录
         index  index.php index.html index.htm;
          if (!-e $request_filename) {
                rewrite ^/(.*)$ /index.php/$1 last;
          }
        }
 
        location ~ ^(.+\.php)(.*)$  {
                root /data/vhosts/k3.com/public_html;#这里改为你对应的目录
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                set $script $fastcgi_script_name;
            if ($uri ~ "^/index.php(/.+)$") {  ###这个if语句表示如果是如果是以/index.php开头的URL,那么设置sectip为index.php path_info为后面部分
                set $script 'index.php';
                set $path_info  $1;<span style="color: #800000;">###这一行很重要</span>
            }
                fastcgi_param SCRIPT_FILENAME /data/vhosts/k3.com/public_html/$fastcgi_script_name;#这里改为你对应的目录
                fastcgi_param  PATH_INFO $path_info;<span style="color: #800000;">###这一行也很重要 在kohana3中是使用path_info来做route</span>
                include fastcgi_params;
        }

kohana3是一个简单高效的PHP5框架,拥有良好的OO特性,很强的扩展性(非修改源码方式来扩展,在这里小小的BS一下总是想通过修改源码来达到扩展目的的同学),强烈推荐!

分类: php 标签:

真的了解memcached吗?

2011年7月18日 effect 没有评论

1 什么是memcached?

Memcached 是一个高性能的分布式内存对象缓存系统,基于一个存储键/值对的hashmap,也就是常说的Key-Value。主要特性是分布式和内存存储,所以读写速度是非常神速的,1.5W/s没问题的。

2 memecached启动参数

memcached -d -m 2048  -p 11211 -P /tmp/memcached.pid

-d 守护模式

-m 分配最大的内存单位MB

-p 监听端口

-P 保存pid的文件,只有-d的时候才有效果

其他的参数见memcached -h

结合上面的启动参数,关闭memcached的命令是:kill `cat /tmp/memcached.pid`   ,需要注意的是:memcached是存储在内存中,所以kill之后,存储的数据全部没了。

3 服务器状态

使用命令:telnet memcached-server-address port,这样就可以连接上memcached服务器,然后输入stats 即可得到服务器各项状态数据,主要状态说明:

pid 服务器进程id

uptime 服务器运行秒数

time 服务器当前时间锉

version 服务器版本

pointer_size 操作系统指针大小(32位的就是32)

rusage_user 进程累计用户时间

rusage_system 进程累计系统时间

curr_connections  当前打开的连接数

total_connections 系统启动后的连接总数

cmd_get   get请求总数

cmd_set  set请求总数

cmd_flush  flush请求总数

get_hits  get请求命中次数

get_misses  get未命中次数

delete_misses   delete未命中次数

delete_hits delete命中次数

threads  线程数

bytes 存储的item占用的 字节数

curr_items 当前item数目

total_items  系统启动后的总字节数目

evictions  为获取空闲内存而删除的items数(分配给memcache的空间用满后需要删除旧的items来得到空间分配给新的items)

limit_maxbytes   分配的内存大小

bytes_read  读取字节数目

bytes_written  发送字节数目

缓存命中率 = get_hits/cmd_get * 100%

4  php-client

有三种php-client:

1)MemcachedClient.php   使用的是php socket和服务器交互,不推荐 。

2)pecl的memcache扩展 推荐

3) pecl的memcached扩展 基于libmemcached的扩展,相比memcache多了很多方法,而且效率各方面也优于memcache扩展。强烈推荐

5 推荐的分布式方式

memcached服务器本身没有分布式的功能,分布式都是通过客户端根据key值算出对应的服务器节点。比较常规的分布式是求余法,但是这个方法有个致命的硬伤:当要增加或者删减一个服务器节点的时候,当时的缓存命中率大大降低。推荐的方法是一致性hash模式。

如果你使用的是memcache扩展,那么想要使用一致性hash模式,请在php.ini中增加或者修改配置:

Memcache.hash_strategy =consistent
Memcache.hash_function =crc32

如果使用的是memcached,那么在代码中使用:
$mem->setOption(Memcached::OPT_DISTRIBUTION,Memcached::DISTRIBUTION_CONSISTENT);
$mem->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE,true);

6 参考资料

memcached api文档翻译:http://blog.csdn.net/lgg201/article/details/6002928

memcached 安装方式:http://www.9enjoy.com/php-memcached/

一致性hash: http://baike.baidu.com/view/1588037.htm

分类: php, 服务器 标签:

httpsqs配置记录&php client

2011年7月13日 effect 没有评论

什么是httpsqs?

基于http的开源队列服务,使用Tokyo Cabinet 的 B+Tree Key/Value来做持久化存储。

适用于什么应用场景?

比较适合于比较慢而又没有特别高的时效性的应用。比如发送邮件(用户进行了某个操作,需要发送邮件给他的email账户通知。)、图片裁剪、视频转换、日志记录等。这些时效性要求不怎么高,这样就可以采用异步方式 ,让后台来集中处理,可以降低前台的服务压力。

具有什么特点?

支持http GET/POST协议,所以支持HTTP协议的都可以和他通信。

非常快速

高并发

更加详细的内容见官方网站:http://blog.s135.com/httpsqs/

官方提供了两种php client。1)php扩展(门槛高、不使用于win下的用户) 2)httpsqs_client.php (这个代码真不敢恭维)。所以自己写了一个httpsqs的类,供大家使用。

<!--?php class Httpsqs{ 	private $host; 	private $port; 	private $auth; 	private $charset; 	private static $sockets=array(); 	public function __construct($host,$port,$auth='',$charset='utf-8'){ 		$this--->host = $host;
		$this-&gt;port = $port;
		$this-&gt;auth = $auth;
		$this-&gt;charset = $charset;
	}
 
	public function get($name,$kt=0){
		$query  = $this-&gt;build_query($name,'get');
		return $this-&gt;execute($query,'GET','',$kt);
	}
 
	public function put($name,$body,$kt=0){
		$query = $this-&gt;build_query($name,'put');
		return $this-&gt;execute($query,'POST',$body,$kt);
	}
 
	public function reset($name){
		$query = $this-&gt;build_query($name,'reset');
		$r = $this-&gt;execute($query);
		if($r &amp;&amp; $r['data'] == "HTTPSQS_RESET_OK"){
			return true;
		}
		else return false;
	}
 
	public function status($name,$type='text'){
		if($type=='json'){
			$cmd = 'status_json';
		}
		else{
			$cmd = 'status';
		}
		$query = $this-&gt;build_query($name,$cmd);
		$r = $this-&gt;execute($query);
		if($r== false || $r['data']==false || $r['data']=='HTTPSQS_ERROR'){
			return false;
		}
		return $r['data'];
	}
 
	public function view($name,$pos){
		$query = $this-&gt;build_query($name,'view',array("pos=".$pos));
		$r = $this-&gt;execute($query);
		if($r==false || $r['data']==false || $r['data']=='HTTPSQS_ERROR'){
			return false;
		}
		else return $r['data'];
	}
 
	private function build_query($name,$cmd,$extra=array()){
		$tmp  = array("name=".$name,"opt=".$cmd);
		if($this-&gt;auth){
			$tmp[]="auth=".$this-&gt;auth;
		}
		$tmp[]="charset=".$this-&gt;charset;
		$tmp = array_merge($tmp , $extra);
		return '/?'.implode('&amp;',$tmp);
	}
 
	private function execute($query,$type='GET',$body='',$kt=0){
		if($kt==1){
			$key = md5($this-&gt;host.':'.$this-&gt;port);
			if(!isset(self::$sockets[$key])){
				self::$sockets[$key] = fsockopen($this-&gt;host,$this-&gt;port,$error,$errstr,5);
			}
			$socket = self::$sockets[$key];
		}
		else{
			$socket = fsockopen($this-&gt;host,$this-&gt;port,$error,$errstr,5);
		}
		if(!$socket){
			return false;
		}
		$out = "{$type} {$query} HTTP/1.1\r\n";
		$out .="Host: {$this-&gt;host}\r\n";
		if($type=='POST'){
			$out.="Content-Length: ".strlen($body)."\r\n";
		}
		if($kt==0){
			$out .="Connection: close\r\n";
		}
		else{
			$out .="Connection: Keep-Alive\r\n";
		}
		$out .="\r\n";
		if($type=='POST' &amp;&amp; $body){
			$out .=$body;
		}
		fwrite($socket,$out);
		$line = trim(fgets($socket));
		list($proto,$rcode,$result) = explode(" ",$line);
		$len = -1;
		$pos_value = 0;
		while(($line = trim(fgets($socket)))!=""){
			if(strstr($line,'Content-Length:')){
				list($cl,$len) = explode(" ",$line);
			}
			elseif(strstr($line,"Pos:")){
				list($pos_key,$pos_value) = explode(" ",$line);
			}
		}
		if($len&lt;0){ 			return false; 		} 		$body = @fread($socket,$len); 		if($kt==0){ 			fclose($socket); 		} 		return array( 			'pos'=&gt;intval($pos_value),
			'data'=&gt;$body
		);
	}
}

使用demo:

//get
$httpsqs = new Httpsqs('192.168.219.128','1218');
$r = $httpsqs-&gt;get('my_query');
 
//put
$httpsqs = new Httpsqs('192.168.219.128','1218');
$r = $httpsqs-&gt;put('my_query',"my_query_value");
 
//其他的请看源码

后感:
这个队列服务真的很实用,以前也有不少类似的应用,可以异步操作,实现方式是通过日志,比如每5分钟创建一个日志文件,然后每隔5分钟来处理,这样的风险很大,很可能造成数据的丢失等。有了这个,居多的应用都可以实现,异步发邮件,异步打日志,异步裁剪图片等等。

分类: php 标签: