一直以来,php一直没有mysql连接池的概念,而在开发中大多数框架也是直接使用了长连接的方式。如Thinkphp就是使用的长连接。对于并发较小的项目来说,长连接确实可以提高查询效率,php不用每次去与mysql服务器建立连接,只要某个php-cgi连接过mysql,那么本次访问结束后,php不会释放与mysql的连接。当下次请求过来的时候,php就可以复用之前的连接,从而消除了建立连接是的额外损耗。
举个栗子:
假如有一台mysql服务器MA允许的最大连接数为50。有一台php-fpm服务器PA,PA常驻的php-cgi进程数量设置为100。
这种方法增加的数量有限,当超过某个数量时,查询效率与建立连接的效率都会大大折扣。具体与mysql服务器的硬件配置高低有关。
使用redis、memcached做缓存层,减少与mysql的连接频率
mycat(国内开源软件)、SMProxy(一款基于swoole的轻量连接池)
读写分离。可部署多台slave服务器。服务器数量越多也就意味着你可建立的最大连接越多。
必须安装php并且安装swoole扩展并把php添加到环境变量中。
git clone https://github.com/louislivi/SMProxy.git
# 或者直接下载源码包解压
https://github.com/louislivi/SMProxy/releases/latest
SMProxy conf目录有两个配置文件,一个是database.json,用于配置mysql数据库信息。另一个是server.json用于配置连接池的一些信息
{
"database": {
# 设置mysql账户信息
"account": {
"master_test": {
"user": "root",
"password": "root123456"
}
},
# 设置数据库host、端口等信息
"serverInfo": {
"server1": {
"write": {
"host": ["172.18.0.4"],
"port": 3306,
"timeout": 2,
"account": "master_test"
}
}
},
# 设置database的名称
"databases": {
"test": {
"serverInfo": "server1",
"startConns": "swoole_cpu_num()*2",
"maxSpareConns": "swoole_cpu_num()*2",
"maxSpareExp": 3600,
"maxConns": "swoole_cpu_num()*2",
"charset": "utf8mb4"
}
}
}
}
{
# 设置代理地址端口、账户密码
"server": {
"user": "sm_proxy",
"password": "123456",
"charset": "utf8mb4",
"host": "172.18.0.8",
"port": "3366",
"mode": "SWOOLE_PROCESS",
"sock_type": "SWOOLE_SOCK_TCP",
"logs": {
"open":true,
"config": {
"system": {
"log_path": "ROOT/logs",
"log_file": "system.log",
"format": "Y/m/d"
},
"mysql": {
"log_path": "ROOT/logs",
"log_file": "mysql.log",
"format": "Y/m/d"
}
}
},
"swoole": {
"worker_num": "swoole_cpu_num()",
"max_coro_num": 6000,
"open_tcp_nodelay": true,
"daemonize": true,
"heartbeat_check_interval": 60,
"heartbeat_idle_time": 600,
"reload_async": true,
"log_file": "ROOT/logs/swoole.log",
"pid_file": "ROOT/logs/pid/server.pid"
},
"swoole_client_setting": {
"package_max_length": 16777215
},
"swoole_client_sock_setting": {
"sock_type": "SWOOLE_SOCK_TCP"
}
}
}
[root@35c65981765f /]# SMProxy start
[root@35c65981765f /]# ps -ef|grep SMProxy
root 12 1 0 06:29 ? 00:00:00 SMProxy master process
root 14 12 0 06:29 ? 00:00:00 SMProxy manager process
root 28 14 0 06:29 ? 00:00:00 SMProxy worker-0 process
root 46 30 0 06:31 pts/1 00:00:00 grep --color=auto SMProxy
我这里使用的是thinkphp5进行的测试
return [
// 数据库类型
'type' => 'mysql',
// 服务器地址
'hostname' => '172.18.0.8',
// 数据库名
'database' => 'test',
// 用户名
'username' => 'sm_proxy',
// 密码
'password' => '123456',
// 端口
'hostport' => '3366',
// 连接dsn
'dsn' => '',
// 数据库连接参数
'params' => [
\PDO::ATTR_CASE => \PDO::CASE_NATURAL,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_ORACLE_NULLS => \PDO::NULL_NATURAL,
\PDO::ATTR_STRINGIFY_FETCHES => false,
\PDO::ATTR_EMULATE_PREPARES => true,
],
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库表前缀
'prefix' => 'think_',
// 数据库调试模式
'debug' => true,
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'deploy' => 0,
// 数据库读写是否分离 主从式有效
'rw_separate' => false,
// 读写分离后 主服务器数量
'master_num' => 1,
// 指定从服务器序号
'slave_no' => '',
// 自动读取主库数据
'read_master' => false,
// 是否严格检查字段是否存在
'fields_strict' => true,
// 数据集返回类型
'resultset_type' => 'array',
// 自动写入时间戳字段
'auto_timestamp' => false,
// 时间字段取出后的默认时间格式
'datetime_format' => 'Y-m-d H:i:s',
// 是否需要进行SQL性能分析
'sql_explain' => true,
];
<?php
/**
* +----------------------------------------------------------------------
* |Created by PhpStorm.
* +----------------------------------------------------------------------
* |User: gongxulei <email:[email protected]>
* +----------------------------------------------------------------------
* |Date: 2020/6/6
* +----------------------------------------------------------------------
* |Time: 5:43 下午
* +----------------------------------------------------------------------
*/
namespace app\index\controller;
use think\Controller;
use think\Db;
class Test extends Controller
{
/**
* SMProxy查询测试
* @access public
* @param mixed $field 字段描述
* @return mixed
**/
public function smProxyAction()
{
$res = Db::table('lock1')->field('*')->select();
return json($res);
}
}
查询结果如下:
[
{
"id": "1",
"name": "1",
"create_time": null
},
{
"id": "2",
"name": "cc",
"create_time": null
},
{
"id": "3",
"name": "cc",
"create_time": null
},
{
"id": "4",
"name": "cc",
"create_time": null
}
]
官方文档地址如下:
https://smproxy.gitee.louislivi.com/#/README