本文系零起点开发高性能服务之首篇文章,欢迎大家持续关注,也非常欢迎点题。
在本文中,使用了区区20行代码不到,即构建了一个具备核心功能的高性能MySQL Proxy,简便易行,还不快快动手试一试!
本文速读:
1. PHP与MySQL:相知相爱执子之手与子共进
2. connect与pconnect:两种连接方式,各有所长
3. MySQL的运行流程:知晓原理,理解问题
4. MySQL连接池:解决问题的关键
5. MySQL Proxy:真的零起点开发出来了
正文:
1. PHP与MySQL
PHP与MySQL相生相爱,和Linux Nginx/Apache组成威力无比的Lnmp/Lamp组合,在互联网界打下了一大片江山。但人红事非多,有说PHP本身的性能比较低下,关于这个问题,大都是跟风者的无脑喷子而已,这里不讨论了,也有人说PHP没有MySQL连接池,这明显是想挑拔PHP和MySQL已合体的关系嘛,然并卵,不过这里作者就要和各位看官好好来讨论一下PHP与MySQL连接池了
2. connect与pconnect
mysqli 是目前用的比较多的 PHP内核自带的MySQL扩展,在PHP里通过mysqli和mysql数据库连接,有两种方式:connect, pconnect, 他们有何异同,一起来简单分析一下:
connect: 每个进程在每次请求结束之后,会关闭连接
pconnect: 每个进程在请求结束之后,不关闭连接,可以再当前进程内复用
connect会产生几个弊端:
1) 每次请求,都要重新连接,影响效率
2) 频繁的连接、关闭,会产生大量的TIME_WAIT, 大高并发的场景会迅速影响系统的连接能力(不仅仅是MySQL,而是影响整个系统所有的服务)
pconnect会产生的弊端:
1) 持久连接如果产生无法释放数据表锁,会导致相同连接的脚本将会被持久的阻塞,进而拖跨整个应用
2) 如果连接数超过MySQL连接数,会导致mysql gone away
那究竟选用哪种方式, 这里推荐用pconnect, 原因就是效率,但如何来避免pconnect的弊端呢?那得从MySQL的执行流程说起.
3. MySQL的运行流程
在这动不动高并发,单机百万连接的年代,MySQL连接数还是有限的,这是因为MySQL本身的机制造成的,MySQL是一个单进程的服务,对于每一个请求都是用线程来响应的。这就需要一个连接器来处理新用户的请求、相应,以及销毁。所以连接数在MySQL中是有限的(my.cnf里有相关的配置),回过头来看PHP, 我们一般都配置有几百个fpm的进程,每个fpm进程都和MySQL保持一个持久连接,当我们只有一两台机器的时候,一般没有什么问题 (fpm进程总数小于MySQL最大连接数就ok),但随着我们的业务大增,PHP的机器增加到10台机器以上,每台机器都和mysql pconnect,那么fpm进程数就远远大于MySQL的最大连接数了,这个时候就会出现问题,针对这类的问题,通常的解决方案是引入连接池
4. MySQL连接池
上面提到,当有众多机器和MySQL进行pconnect,这导致超过了MySQL的最大连接数,但实际的场景中,并不是每个fpm都同时在工作,真正的并发连接很少,所以这引入了连接池的新技术,顾名思义,连接池就是预先建立好足够多的mysql连接, 当有需要的时候,从连接池里拿出一个空闲连接处理,处理完成之后,把连接放回池子,供下次使用, 而PHP本身的执行流程导致做不了这件事,需要依赖于第三方的插件, 这个插件称之为MySQL Proxy
5. MySQL Proxy
从上面的分析,我们可以得出,MySQL Proxy需要作两方面的核心事情:
1) 对于连接池需求方(PHP),能维持海量的连接数
2) 能预先建立好和MySQL的持久连接
那这需要Proxy首先是一个长驻内存的服务,并且能维护大量的连接数,由于PHP运行流程,导致PHP不适合做这样的服务,所以就出现文章开头的吐嘈,但是PHP神油Swoole的出现,成功解决了这个问题。所以我们用Swoole来实现一个简单可靠的MySQL Proxy。如果你还没听说过Swoole,说明你突突突突out了,快看:http://www.swoole.com/
(小编画外音:嗦了半天,终于步入正题了)
show me the code:
proxy.php
Tag标签: