资源描述:
《基于swoole扩展开发异步高性能的mysql代理服务器》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库。
1、基于Swoole扩展开发异步高性能的MySQL代理服务器MySQL数据库对每个客户端连接都会分配一个线程,所以连接非常宝贵。开发一个异步的MySQL代理服务器,PHP应用服务器可以长连接到这台Server,既减轻MYSQL的连接压力,又使PHP保持长连接减少connect/close的网络开销。此Server考虑到了设置了数裾库连接池尺寸,区分忙闲,mysqli断线重连,并设置了负载保护。越于swoole扩展开发,io循环使用epoll,是全昇步非肌塞的,可以应对大量TCP连接。程序的逻辑是:启动时创建N个MySQL连接,收到客户端发来的SQL后,分配1
2、个MySQL连接,将SQL发往数裾库服务器。然后等待数据库返回杏询结果。当数据库返回结果后,再发给对应的客户端连接。核心的数裾结构是3个PHP数纟II。idle_pool是空闲的数据库连接,当冇SQL请求时从idle_pool中移到busy_pool中。当数扼库返冋结果后从busy_pool巾W移到idle_pool中,以供新的请求使川。当SQL请求到达吋如果没有空闲的数据库连接,那会&动加入到wait_queue屮。一旦冇SQL完成操作,将动从wait_queue屮取出等待的谙求进行处理。如此循环使川。由于整个服务器是异步的单进程单线程所以完全不需要锁
3、。而且是完全异步的,效率非常高。当然本文的代码,如果耍川丁•生产环境,还需做更多的保护机制和压力测试。在此仅抛砖引玉,提供一个解决问题的思路。classDBServer{protected$pool_size=20;protected$idle_pool=array();//空闲连接protected$busy_pool=array();//工作连接protected$wait_queue=array();//等待的请求protected$wait_queue_max=100;//等待队列的最人长度,超过f•将拒绝新的谴求y***@varswoole_s
4、erver*/protected$serv;functionrun()$serv=newswoole_server(,,127.0.0.1"/9509);$serv->set(array(’worker_nunV=>1,));$serv->on(’WorkerStarf,array($this,’onStart1));//$serv->on('ConnecV,array($this,'onConnect'));$serv->on(’Receive’,array($this,'onReceive'));//Sserv^onf'Close^array($th
5、is,’onClose1));$serv->start();}functiononStart($serv){$this->serv=$serv;for($i=0;$i<$this->pool_size;$i++){$db=newmysqli;$db->connect('127.0.0.1',’root’,'root','test');$db_sock=swoole_get_mysqli_sock($db);swoole_event_add($db_sock,array($this,’onSQLReady1”;$this->idle_pool[]=arra
6、y('mysqli'=>$db,’db-Sock1=〉$db_sock,'fd'=>0,);}echo"Server:start.Swooleversionis[".SWOOLE_VERSION."]";}functiononSQLReady($db_sock){$db_res=$this->busy_pool[$db_sock];$mysqli=Sdb^esCmysqli1];$fd=Sdb^esl'fd1];echo_METHOD_.client_sock=$fd
7、db_sock=$db_sock";if($result=$mysqli->r
8、eap_async_query()){$ret=var_export($result->fetch_all(MYSQLI_ASSOC)/true)."";$this->serv->send($fd,$ret);if(is_object($result)){mysqli_free_result($result);}}else{$this->serv->send($fd,sprintf("MySQLiError:%s",mysqli_error($mysqli)));}//releasemysqliobject$this->idle_pool[]=$
9、db_res;unset($this->busy_pool[$db_sock])