存档:2009年五月

如何优化你的php(二)

五月 26, 2009 | php | RSS 2.0

–> –>

翻译:http://phplens.com/lens/php-book/optimizing-debugging-php.php

今天翻译着翻译着,已经烦了,看来真的持之以恒做一件事很难,尤其是不太喜欢的事情,我略过和跳过,和翻译错了很多。

php调试你的web服务器

我们将论述在今天两种非常常用的web服务器如何得到最好的性能,apache1.2iis,当然也有许多关于服务html的建议。

Php的作者表示apache2.0相对于apache1.3没有性能和架构的优点,特别是多线程模式,但apache2.0以预分配模式运行的时候,下面的讨论依然有关系(200311 21

aapache1.3/2.0

apache可以运行在unixwindows上面,它是当今世界最流行的服务器,apache1.3在服务器运行时用了预分配模式,但它启动时,它会创建多个子进程来处理http请求,初始化的父进程间就像一个呵护天使,确保每个子进程工作地顺利同时协调所有的事情,越多的http请求过来,越多的子进程出来处理它们,但http请求慢下来的时候,父进程会杀死一个空闲的进程,为别的进程释放资源,这个模式使得apache非常的健壮,即使一个子进程崩溃了,父进程和别的进程是和这个崩溃的进程独立的。

预分配模式不像别的设计的那么快,但对我来说,服务一个php脚本足够了,当apache性能组织非常重大的影响前还有很多别的瓶颈要找。Apache的健壮性和信赖性非常重要。

Apace2.0提供了在执行时采用多线程模式,我的测试表明在这种模式下只有一点性能上的优点。当然好多php的扩展部兼容。Apache2.0.472003)。

Apache的配置使用httpd.conf,下面的参数在配置子进程的时候非常重要。

命令

默认

描述

MaxClients

256

最大的子进程的数量,默认的意思是最多同时处理256http请求,多的连接被放在队列里。

StartServers

5

启动时候创建的子进程个数

MinSpareServers

5

需要创建的空闲子进程的数目,如果子进程的数目低于这个数字,1个子进程被初始化创建,然后是2个,后来是4个,直到32个被创建每秒钟

MaxSpareServers

10

如果激活的子进程多于这个数字,多的进程将被中止掉

MaxRequestsPerChild

0

子进程中止前能处理的http请求数.设置成0 表示永远不终止.设置为10010000如果你怀疑有内存泄漏,或者来释放一些没有用的资源.

如果是大一点的网站,值设置成下面的会好一点:

MinSpareServers32

MaxSpareServers64

Apachewindows有点不一样,它不是用子进程,而是用线程,上面的参数将不会用到,相比我们有一个参数:ThreadsPerChild,默认的是50,这个参数表示apache可以多少个线程交换.windows的版主中只有一个子进程,默认的设置成50 当前只可以处理50个请求。但web服务器经历高的网络流量时,增加它在2561024之间,一些有用的参数你可以改变,包括如下:

参数

默认

描述

SendBufferSize

设置成操作系统默认的

决定在用tcp/ip连接时候用到的输出的缓冲大小。对于忙的网络是非常有用的当你缓存时候,你可以设置这个参数关闭最大的文件下载。每个客户端连接的时候tcp/ip缓冲都会创建。

KeepAlive [on|off]

On

在老的http协议中,每个http请求都需要在服务器上单独建立个连接。为了减少过多的正常连接,keep-live的头被发展开了,它告诉服务器继续使用同一个socket处理多个请求,如果一个独立的专为突破服务器的服务器,你可以关闭这个选项,这个技术很大的提高了资源的可用性.

KeepAliveTimeout

15

这个数字式保持socket连接的存活时间,这个时间包括服务器生成内容,和客户机响应,如果客户机不响应,他将生成一个新连接。这个值得将保持低值做为

没有评论 »

如何优化php(-)

五月 26, 2009 | php | RSS 2.0

翻译:http://phplens.com/lens/php-book/optimizing-debugging-php.php

Php是一门快速的web编程开发语言,远比php代码的执行的速度还有更多需要我们的优化,

这作者的文章中将给你介绍优化你的php有许多和编码不相关的多个因素,调试我们的php需要我们理解更多的和php运行相关的东西,如服务器,找出问题的瓶颈,修复他们,这里将讲述如何调试优化他们,使他们执行的更快。

       获得更好的性能

       当我们将好的性能的时候,我们不止是讲你的脚步运行的有多快,性能是你的架构和速度之间的平衡,脚步可能用少的资源可能比缓存的执行要慢,但是多个复制的同一个脚步在一个服务器上可以同时执行。

       在下面的例子中,A.php是一个短跑的能跑的很快,但是B.php则是一个马拉松选手在一个很长的时间内跑同样的速度,负载比较轻的情况下,A.php相继会很快,但是网络流量增加时,当A.php跑完了气力的时候B.php只是降低了一点。

如何优化php(-) - 玉树临风 - 小和尚真情无限

让我们举更现实的例子来阐述的更透彻,假设我们需要写一个php的脚本,来读取一个250k的文件来生成一个html的大致内容,写两个php来做同样一个事情,hare.php读取一次整个文件到内存,一次性处理文件,tortoise.php读文件,一次读取一行使内存中不保留更多的内容,tortoise.php但多次读取的时候会变慢,需要更多的系统的调用,hare.php需要0.04秒和10mramtoroise.php需要0.06秒和5mram,服务器有100m的空内存,这时cpu99%的空闲,简单的假设没有内存碎片。

    10次脚本,hare.php会内存泄漏,在这个时候toroise还有50m的空闲内存,当低11次的时候,hare.php不得不去请开始虚拟内存交换,这使得他的速度将会减少为原来的一般,每次hare.php的执行,将花费cpu0.08秒,同时,toroise.php将会继续保持原来的0.06秒,在下表中,在不同的负载下快的php将会用粗体标出:

 

 

 

 

 

      

连接

1http请求cpu需要的时间

10http请求cpu需要的时间

11http请求cpu需要的时间

hare.php

0.04

0.40

0.88
(runs out of RAM)

tortoise.php

0.06

0.60

0.66

从上面的例子我们将看出,获得好的性能,不仅关系到写好的php脚本,高性能的php需要理解硬件,操作系统,以及他支持的软件,如服务器,数据库。

瓶颈

       上面的sharetororse的例子说明了瓶颈导致慢了下来,有无限多的ram的时候hare.php将会永远的比tortoize.php快,不幸的是,上面的例子有点简单,除了ram还有许多瓶颈影响。

(a)   网络

你的网络将是最大的瓶颈,假设你有10m的连接到因特网上,你能在一秒钟输出1m字节的数据,如果一个页面是30k,只需要一秒钟33个页面就使得你饱和,许多微妙的网络瓶颈包括正常的请求到慢的服务如,dns,分配不够多的内存给网络软件,

(b) cpu

如果你监视你的cpu负载,通过网络发送一个html页面,不单单要耗费你的cpu,就像我们提到的瓶颈是网络,但是php生成的复杂的动态页面,你的cpu的速度将会变成有限度的因素,多核处理器或者服务器集群能做到。

(c) 共享内存

共享内存是用在进程内的交换,在多进程中存储资源,比如缓存数据和代码,如果内存分配的不足,任何连接这些用于内存共享,如数据库连接,代码执行等资源都会有很差的性能。

(d) 文件系统

    从硬盘中读取数据要比ram中慢50100倍,文件缓存用ram能完成这些,尽管低内存的状态讲减少文件缓存中内存利用的次数,文件系统当然也会带来系统碎片,降低硬盘的读取,过多的使用符号链接在unix系统中将减慢硬盘的读取。

e)进程管理

在一些操作系统中,比如windows中创建一个新进程将是一个很慢的操作,这就意味这cgi程序需要创建一个新进程在每一个激活的连接中,在这些操作系统中这将非常的慢,在多线程下跑php可能提高反应的时间。(注:老版本的php在多线程下不稳定)。

在你的服务器中避免过多的不需要的进程,比如,如果你的服务器只做web服务器,避免跑甚至装x-winows在机器上,在windows上,避免跑微软的查找部分,和三维的屏保会导致cpu100%.

一些程序包括你考虑移除掉没有用的网络协议,邮件服务器,杀毒扫描,硬件鼠标驱动,红外线端口,等,在unix下,加入你连接你的服务器你用ssh,你可以考虑卸载掉一下:一些守护进程如: telnetd, inetd, atd, ftpd, lpd, sambad,发送邮件的接受mailportmap for NFS
xfs, fvwm, xinit, X

你可以禁用一些各种各样的服务通过修改启动文件,这些文件通常保存在/etc/init* 或者/etc/rc*/init*文件下下。

同时查看下你的crontab文件,你是否需要移除他们,或者重新规划。

f)连接其他服务器

如 …

没有评论 »

回忆的介质想到的

五月 25, 2009 | 心情杂记 | RSS 2.0

什么是通向回忆的介质?一段歌声,一件旧物,一份情感,也许一切的事物在经过之后,会在我们记忆的神经网络中打下烙印,按照多维的去存储,其中有夹杂着多种参数,就像一个多元的高次的一个方程,至今还未能领会,时间的参数,让这段信息存储的某一维会更深,在人的现实世界种,人有有意识的压迫着这些意识的发展与活跃,故有时候在会出现在我们们中奇怪的现象,就像弗洛伊德的精神分析法,但我们触到这些物质时,这些存贮从相似的东西会产生一种介质,导致我们伤感,导致我们的幸福,让我们大胆的想象,大脑是不是一台更加高级的机器,有自己的运算法则,有自己的存储介质,有自己的算法等。他的算法是不是又一种新的数学分支,比如人脑数学,神经元数学等,人类在这方面是要进行更深的探索,在我看来,这个世界永远是着一套自己运行的法则,自然哲学,自然界的完美,这些很早以前就在探索,地心说,日新说,人们都一直在探索,这种历程还需要走多远????自

没有评论 »

取当前进程对应之静态映像文件的绝对路径/proc/self/exe

五月 22, 2009 | c/c++, linux | RSS 2.0

提供一个linux  advanced programming 上的得到绝对路径目录的函数:
char* get_self_executable_directory ()
{
  int rval;
  char link_target[1024];//目标地址
  char* last_slash;
  size_t result_length;//结果的长度
  char* result;

  /* Read the target of the symbolic link /proc/self/exe.  */
读取绝对路径
  rval = readlink (”/proc/self/exe”, link_target, sizeof (link_target) – 1);
  if (rval == -1)
    /* The call to readlink failed, so bail.  */
    abort ();
  else
    /* NUL-terminate the target.  */
    link_target[rval] = ‘0′;
  /* We want to trim the name of the executable file, to obtain the
     directory that contains it.  Find the rightmost slash.  */
找到最后一个/
  last_slash = strrchr (link_target, ‘/’);
如果是空或者是以/开头,则退出
  if (last_slash == NULL || last_slash == link_target)
    /* Something stange is going on.  */
    abort ();
last_slash保存的是最后的/的地址
  /* Allocate a buffer to hold the resulting path.  */
link_target开始的地址
  result_length = last_slash – link_target;
  result = (char*) xmalloc (result_length + 1);
  /* Copy the result.  */
  strncpy (result, link_target, result_length);
  result[result_length] = ‘0′;
  return result;
}

同时可以用以下程序得到绝对路径
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAXBUFSIZE 1024

int main ( int argc, char * argv[] )
{
    char buf[ MAXBUFSIZE ];
    int  count;

    count = readlink( ”/proc/self/exe”, buf, MAXBUFSIZE );
    if ( count < 0 || count >= MAXBUFSIZE )
    {
        printf( ”Failed” );
       return( EXIT_FAILURE );
    }
    buf[ count ] = ’0′;
    printf( ”/proc/self/exe -> [%s]“, buf );
    return( EXIT_SUCCESS );

网站 :
1 http://www.smth.edu.cn/bbsanc.php?path=%2Fgroups%2Fos.faq%2FUnix%2F13%2Fhellguard_unix_faq%2FM.1031923592.U0
2  http://blog.linux.org.tw/~jserv/archives/002041.html

没有评论 »

解决location.href在ie下得不到referer

五月 19, 2009 | php | RSS 2.0

/**
*功能:解决onclick.href 跳转时候在ie下得不到refer的问题
*@url 需要跳转的地方
*@author fabin
*使用方法:onclick=”href(’url’)”
*/
function href(url){
    var fakeLink = document.createElement (”a”);
    if (typeof(fakeLink.click) == ‘undefined’)
        location.href = url;  // sends referrer in FF, not in IE
    else
    {
        fakeLink.href = url;
        document.body.appendChild(fakeLink);
        fakeLink.click();   // click() method defined in IE only
    }

}
另外一种方式

function goTo(url) {
    var a = document.createElement(”a”);
    if(!a.click) { //only IE has this (at the moment);
        window.location = url;
        return;
    }
    a.setAttribute(”href”, url);
    a.style.display = “none”;
    document.bodyappendChild(a);
    a.click();
}

没有评论 »

如何让自己写的服务器支持php?

五月 15, 2009 | c/c++, php | RSS 2.0

 写一个支持支持静态的文件的c服务器很简单,就是些文件目录等操作,如何写一个支持get方式php的呢?
很简单的可以用一个shell搞定 ,例如,但是如何支持post等操作呢?
#include <stdio.h>
void command_mess(char *command, char *buf, int length)
{
    FILE   *stream;

    stream = popen(command,”r”);
    fread( buf, sizeof(char), length,  stream);
    pclose( stream );
    return;
}

int main( void )
{
    char buf[4096] = “”;  //请注意系统命令要输出的数据大小,小心得到的数据不全哦
    char com[64] = “/home/liufabin/php/bin/php test.php”;
    command_mess(com, buf, sizeof(buf));
    printf(”Message:%s”,buf);
    return 0;

}

没有评论 »

我怎么了

五月 14, 2009 | 心情杂记 | RSS 2.0

曾一段段时间心情徘徊在低谷,毕业一年了,应该算是迷茫,抑或说自己心智不成熟,有些事情总是得不到释怀,职业规划的迷茫?自己到底想做什么?自己有能力做什么?如何找到自己的极致,如何做到合理的舍弃,勇敢的追求,很快,在流逝中,在思考这些问题的时间总,已经过去了,很少能真正的释怀,工作了,并没有感觉到前所未有的轻松,反而是更大的压力,不断地学习,对自己的,工作地不满,虽然在长达了一年的时间里,我汲取了好多知识,包括更方面的,尤其是数学,东城区图书馆的好多数学书我都浏览过,当然还有些别的书,然后就是技术,断断续续的也学了点c,从技术的io操作,到进程,线程,ipc,网络编程等,也曾试着去读linux的kernerl,当还是没有坚持下来,唯一让我欣慰的是一年来坚持锻炼了身体,并养成了锻炼身体的好习惯。在技术方面的追求和前进还是比较缓慢的,也许是我太局限了,太不敢向前了。纵然自己自认为有些计算机的基础,包括数据结构算法分析等。
很长一段时间自己把自己的计划打乱。改写的没有写。基本上周末很少写过程序,在家里也从来没有学过和php相关的,除了写点c语言,浏览点技术性论坛,博客。我是怎么 了?我不知道?我该怎么了?我不知道。久久的凝滞在一个地方,也行偶然的机遇让 我找到了你。thank you。

没有评论 »

speeding up your nginx server with memcached

五月 8, 2009 | 网站架构 | RSS 2.0

可以看这篇文章http://wiki.nginx.org/NginxChsHttpProxyModule ,说的是nginx和memcache可以提升你4倍的性能,请看他们   的图

speeding up your nginx server with memcached - 玉树临风 - 小和尚真情无限
nginx在前端可以通过重写规则写到app servrs 还可以通过原生的memcache去查看一些东西是否存在,比如一些小的用户头像,存到cache里,最近看qconbeijing2009的daouban的架构的演化好像经历过这一步,不过他们好像是lighhttd服务器,内置的memache的东西,看看他们的配置文件
user  usr usr;
worker_processes  2;

http {
types {
text/javascript    js;
application/xml    xml;
}

# By default, return content sa
default_type  application/xml;

access_log  /home/api/logs/nginx.log  main;

sendfile       on;
tcp_nopush     on;

keepalive_timeout  65;
tcp_nodelay        on;

# app. server(s) / cluster definition
upstream dynamic_srv { server 127.0.0.1:9020; }

server {
listen       9000;
server_name  srv;
root        /home/usr;

# Match any request that begins with /dynamic_request
location /dynamic_request {

# Append a file-extension to every request
if ($args ~* format=json) { rewrite ^/dynamic_request/?(.*)$ /dynamic_request.js$1 break; }
if ($args ~* format=xml)  { rewrite ^/dynamic_request/?(.*)$ /dynamic_request.xml$1 break; }

# Check if local memcached server can answer this request
memcached_pass 127.0.0.1:11211;

# Send to app. server if Memcached could not ansewr the request
error_page 404 = @dynamic_request;
}

location @dynamic_feed_id {
# only internal requests can reach this endpoint
internal;

# dispatch to our app_server cluster / instance
proxy_pass http://dynamic_srv;
}

}
}

然后在学习的过程中,发现一篇更好的文章http://lserinol.blogspot.com/2009/03/speeding-up-your-nginx-server-with.htmlnginx 的memcache的modual,豆瓣就是用的这个缓存小图片,减少磁盘的io操作,Serving content from memory will be faster than serving it from disk首先需要定义一个反向代理请求的的server,92.168.2.3 的性能要比92.168.2.4的好,所以我们他的权重写一些。

upstream backend {     server 192.168.2.3 weight=2;     server 192.168.2.4;} 

然后写他的配置文件 :

location ~* .(jpg|png|gif)$ {access_log   off;expires      max;add_header   Last-Modified "Thu, 26 Mar 2000 17:35:45 GMT";set $memcached_key $uri;memcached_pass     127.0.0.1:11211;error_page         404 = /fetch;}把图片文件重定向过来,然后查找在memcache中是否存在,不存在调到404,然后404错误页面会找到fetchlocation /fetch {internal;access_log   off;expires      max;add_header   Last-Modified "Thu, 26 Mar 2000 17:35:45 GMT";proxy_pass http://backend;break;}然后fetch就会反向代理到后端backend后面。这时候就需要负载均衡到相应的server。可以看出他的原生的memcache只能获取,而不能设置,所以我们需要自己手工完成如对图片存贮到memcache ,写个对应的脚本:

<?php

function rscandir($base='', &$data=array()) {$array = array_diff(scandir($base), array('.', '..'));

foreach($array as $value) :  if (is_dir($base.$value)) {    $data = rscandir($base.$value.'/', $data);

  }  elseif (is_file($base.$value)) {   $rest = substr($value, -4);   if ((!strcmp($rest,'.jpg')) || (!strcmp($rest,'.png'))                                || (!strcmp($rest,'.gif')) ){         $data[] = $base.$value;   } }

endforeach;return $data;}

$mylist=rscandir("/var/www/mysite");

$srch = array('/var/www/mysite');$newval = array('');

$memcache_obj = memcache_connect("192.168.2.1", 11211);

while (list($key, $val) = each($mylist)) {  $url=str_replace($srch,$newval,$val);  echo "$key => $val -> ".filesize($val)."";  $value = file_get_contents($val);  memcache_add($memcache_obj, $url, $value, false, 0);}

以上操作就应该能完成你所需要的功能。 以上文字主要来源于作者的文章,算我我的一个理解和翻译。

没有评论 »

c获取文件的大小的两种方法和行读取

五月 6, 2009 | c/c++, linux, 网站架构 | RSS 2.0

1 fseek移动指针获取
#include <stdio.h>
#include <stdlib.h>

long filesize( FILE *fp )
{
    long int save_pos;
    long size_of_file;

    /* Save the current position. */
    save_pos = ftell( fp );

    /* Jump to the end of the file. */
    fseek( fp, 0L, SEEK_END );

    /* Get the end position. */
    size_of_file = ftell( fp );

    /* Jump back to the original position. */
    fseek( fp, save_pos, SEEK_SET );

    return( size_of_file );
}

int main( void )
{
    FILE *fp;

    fp = fopen( “aa.txt”, “r” );

    if( fp != NULL ) {
        printf( “File size=%ld”, filesize( fp ) );
        fclose( fp );

        return EXIT_SUCCESS;
    }

    return EXIT_FAILURE;
}

2 stat获取

#include <stdio.h>#include <stdlib.h>#include <sys/stat.h>

int main( void )  {    struct stat buf;

    if( stat( "file", &buf ) != -1 ) {      printf( "File size = %d", buf.st_size );    }    return EXIT_SUCCESS;

  }

但是是有区别的,如
参考fseek()。
  通过fseek()、ftell()两个函数,我们就可以随意访问文件的任何位置了,想了想好像操作文件就这么easy,实在也没有更多可说的了。对了,fseek()和ftell()存在一个潜在的问题就是他们限制文件的大小只能在long类型的表示范围以内,也就是说通过这种方式,只能打开2,000,000,000字节的文件,不过在绝大多数情况下似乎也已经够用了。如果需要打开更大的文件,你需要用到fgetpos()、fsetpos()函数了,那是另一个命题了。

#include <stdio.h>
#include <string.h>

int main()
{
    int  i;
    long k;
    char buf[100];
    long int save_pos;

    FILE *fp;

    fp=fopen(”aa.txt”,”rb”);
    for(i=1;i<10;i++)
    {
        fscanf(fp,”%[^]“,buf);
        //这句读取一行,直到遇到,停止,并把读到的内容放到buf里,而此时文件指针的位置指向
        printf(”%s”,buf);
        //k=strlen(buf);
        fseek(fp,1,SEEK_CUR);
    //跳过,则从下一行的开始读。这里主要是跳过换行符。如果为k的话,就是从第二行跳过k个字符的位置开始读,当然是不对的了。
        buf[0]=’0′;

    }
    fclose(fp);
    return 0;
}

没有评论 »