好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

php memcached mysql开发详细实例 - php高级应用

php memcached mysql开发详细实例

Memcached的工作方式:以下的部分中,读者最好能准备一份memcached的源代码.

Memcached是传统的网络服务程序,如果启动的时候使用了-d参数,它会以守护进程的方式执行,创建守护进程由daemon.c完成,这个程序只有一个daemon函数,这个函数很简单,如无特殊说明,代码以1.2.1为准,代码如下:

# include  <fcntl.h>  # include  <stdlib.h>  # include  <unistd.h>    int  daemon(nochdir, noclose)      int nochdir, noclose;  {      int fd;         switch  (fork()) {       case  -1:           return  (-1);       case  0:            break ;         default :          _exit(0);      }         if  (setsid() == -1)           return  (-1);         if  (!nochdir)          (void) chdir (]/]);         if  (!noclose && (fd = open(]/dev/null], O_RDWR, 0)) != -1) {          (void)dup2(fd, STDIN_FILENO);          (void)dup2(fd, STDOUT_FILENO);          (void)dup2(fd, STDERR_FILENO);           if  (fd > STDERR_FILENO)              (void)close(fd);      }       return  (0);  } 

这个函数 fork 了整个进程之后,父进程就退出,接着重新定位 STDIN 、 STDOUT 、 STDERR 到空设备,daemon 就建立成功了,代码如下:

<?php   class  Memcached   {   private   $mem ;   public   $pflag = '' ;  // memcached pconnect tag    private   function  memConnect( $serkey ){   require   'config.php' ;   $server  =  $memcached ;   $this ->mem =  new  Memcache;   $link  = ! $this ->pflag ?  'connect'  :  'pconnect'  ;   $this ->mem-> $link ( $server [ $serkey ][0], $server [ $serkey ][1])  or   $this ->errordie( 'memcached connect error' );   }   public   function  set( $ser_key , $values , $flag = '' , $expire = '' ){   $this ->memConnect( $this ->tag( $ser_key ));   if ( $this ->mem->set( $ser_key , $values , $flag , $expire ))  return  true;   else   return  false;   }   public   function  get( $ser_key ){   $this ->memConnect( $this ->tag( $ser_key ));   if ( $var = $this ->mem->get( $ser_key ))  return   $var ;   else   return  false;   }   private   function  tag( $ser_key ){   $tag = explode ( '_' , $ser_key );   return   $tag [0];   }   private   function  errordie( $errmsg ){   die ( $errmsg );   }   }   ?>    class  Mysql   {   private   $mysqlmaster ;   private   $myssqlslave ;   private   static   $auid =0;   public   function  __construct(){   require   'config.php' ;   $msg  =  $mysql ;    $this ->mysqlmaster =  new  mysqli( $msg [ 'master' ][0], $msg [ 'master' ][1], $msg [ 'master' ][2], $msg [ 'master' ][3]);  //master mysql    $this ->mysqlslave =  $this ->autotranscat( $msg );  // slave mysql    if (mysqli_connect_errno()){   printf( "Connect failed: %s " ,mysqli_connect_error());   exit ();   }   if (! $this ->mysqlmaster->set_charset( "latin1" ) && ! $this ->mysqlslave->set_charset( "latin1" )){   exit ( "set charset error" );   }   }   private   function  autotranscat( $mysql ){   session_start();   $_SESSION [ 'SID' ]!=0 ||  $_SESSION [ 'SID' ]=0 ;   if ( $_SESSION [ 'SID' ] >= count ( $mysql )-1)  $_SESSION [ 'SID' ] = 1;   else   $_SESSION [ 'SID' ]++;   $key  =  'slave_' . $_SESSION [ 'SID' ];   echo ( $_SESSION [ 'SID' ]);   return   new  mysqli( $mysql [ $key ][0], $mysql [ $key ][1], $mysql [ $key ][2], $mysql [ $key ][3]);   }   public   function  mquery( $sql ){  //insert update    if (! $this ->mysqlmaster->query( $sql )){   return  false;   }   }   public   function  squery( $sql ){   if ( $result = $this ->mysqlslave->query( $sql )){   return   $result ;   } else {   return  false;   };   }   public   function  fetArray( $sql ){   if ( $result = $this ->squery( $sql )){   while ( $row = $result ->fetch_array(MYSQLI_ASSOC)){   $resultraa [] =  $row ;   };   return   $resultraa ;   }   }   }   ?>  require   'init.php' ;   $mem  =  new  Memcached;   /* $mem->set('en_xx','bucuo');    echo($mem->get('en_xx'));    $mem->set('cn_jjyy','wokao');    echo($mem->get('cn_jjyy'));    */    $sq  =  new  Mysql;   $sql  =  "insert into mybb(pid) values(200)" ;   $mdsql  = md5( $sql );   if (! $result = $mem ->get( 'cn_' . $mdsql )){   $sq ->mquery( "insert into mybb(pid) values(200)" );  //插入到主mysql    $result  =  $sq ->fetArray( "select * from mybb" );  //查询 是 从mysql    foreach ( $result   as   $var ){   echo   $var [ 'pid' ];   }   $mem ->set( 'cn_' . $mdsql , $result );  //添加到 名为 cn 的 memcached 服务器    } else {   foreach ( $result   as   $var ){   echo   $var [ 'pid' ];   }   }   ?>    <?php   $memcached  =  array (  //用memcached 的 多 进程模拟 多台memcached 服务器 cn en 为 内存服务器名    'cn' => array ( '192.168.254.144' ,11211),   'en' => array ( '192.168.254.144' ,11212)   );  //开源代码phpfensi测试数据   $mysql  =  array (  // mysql 的主从 我的环境是 : xp 主 linux 从 mysql 5 php5    'master' => array ( '192.168.254.213' , 'root' , '1' , 'mydz' ),   'slave_1' => array ( '192.168.254.144' , 'root' , '1' , 'mydz' )  //可以灵活添加多台从服务器    );   ?>   

Memcached 本身的启动过程,在 memcached.c 的 main 函数中顺序如下:

1 、调用 settings_init() 设定初始化参数

2 、从启动命令中读取参数来设置 setting 值

3 、设定 LIMIT 参数

4 、开始网络 socket 监听(如果非 socketpath 存在)( 1.2 之后支持 UDP 方式)

5 、检查用户身份( Memcached 不允许 root 身份启动)

6 、如果有 socketpath 存在,开启 UNIX 本地连接(Sock 管道)

7 、如果以 -d 方式启动,创建守护进程(如上调用 daemon 函数)

8 、初始化 item 、 event 、状态信息、 hash 、连接、 slab

9 、如设置中 managed 生效,创建 bucket 数组

10 、检查是否需要锁定内存页

11 、初始化信号、连接、删除队列

12 、如果 daemon 方式,处理进程 ID

13 、event 开始,启动过程结束,main 函数进入循环.

在 daemon 方式中,因为 stderr 已经被定向到黑洞,所以不会反馈执行中的可见错误信息.

memcached.c 的主循环函数是 drive_machine,传入参数是指向当前的连接的结构指针,根据 state 成员的状态来决定动作.

查看更多关于php memcached mysql开发详细实例 - php高级应用的详细内容...

  阅读:42次