最近在学习swoole,偶然间发现了这个数据库中间件:SMPoxy。 项目github地址 https://github.com/louislivi/smproxy
在实际测试中发现使用了数据库连接池以后 查询效率提升了将近一半左右,具体以实际结果为准,接下来一起来看看吧,使用前请确保安装了Swoole 扩展,执行php -m
查看;
支持读写分离
支持数据库连接池,能够有效解决 PHP 带来的数据库连接瓶颈
支持 SQL92 标准
采用协程调度
支持多个数据库连接,多个数据库,多个用户,灵活搭配
遵守 MySQL 原生协议,跨语言,跨平台的通用中间件代理
支持 MySQL 事务
支持 HandshakeV10 协议版本
完美兼容 MySQL5.5 - 8.0
兼容各大框架,无缝提升性能
1、(推荐)直接下载最新发行版的 PHAR 文件,解压即用:
https://github.com/louislivi/SMProxy/releases/latest
2、使用git
git clone https://github.com/louislivi/SMProxy.git
composer install
SMProxy [ start | stop | restart | status | reload ] [ -c | --config <configuration_path> | --console | -f | --force ]
SMProxy -h | --help
SMProxy -v | --versio
配置文件位于 smproxy/conf 目录中,其中大写 ROOT 代表当前 SMProxy 根目录。
官方示例:
{
"database": {
"account": {
"自定义用户名": {
"user": "必选,数据库账户",
"password": "必选,数据库密码"
},
"...": "必选1个,自定义用户名 与serverInfo中的account相对应"
},
"serverInfo": {
"自定义数据库连接信息": {
"write": {
"host": "必选,写库地址 多个用[]表示",
"port": "必选,写库端口",
"timeout": "必选,写库连接超时时间(秒)",
"account": "必选,自定义用户名 与 account中的自定义用户名相对应",
"maxConns": "重载,对应databases",
"maxSpareConns": "重载,对应databases",
"startConns": "重载,对应databases",
"maxSpareExp": "重载,对应databases"
},
"read": {
"host": "可选,读库地址 多个用[]表示",
"port": "可选,读库端口",
"timeout": "可选,读库连接超时时间(秒)",
"account": "可选,自定义用户名 与 account中的自定义用户名相对应",
"maxConns": "重载,对应databases",
"maxSpareConns": "重载,对应databases",
"startConns": "重载,对应databases",
"maxSpareExp": "重载,对应databases"
}
},
"...": "必选1个,自定义数据库连接信息 与databases中的serverInfo相对应,read读库可不配置"
},
"databases": {
"数据库别名": {
"databaseName": "可选,指定真实链接数据库名称(默认不指定与别名相同)",
"serverInfo": "必选,自定义数据库连接信息 与serverInfo中的自定义数据库连接信息相对应",
"maxConns": "必选,该库服务最大连接数,支持计算",
"maxSpareConns": "必选,该库服务最大空闲连接数,支持计算",
"startConns": "可选,该库服务默认启动连接数,支持计算",
"maxSpareExp": "可选,该库服务空闲连接数最大空闲时间(秒),默认为0,支持计算",
"charset": "可选,该库编码格式"
},
"...": "必选1个,数据库名称 多个数据库配置多个"
}
}
}
测试示例:这里我使用的测试数据库为阿里云RDS数据库,如果你在本地测试将server1 host 改为127.0.0.1 即可
{
"database": {
"account": {
"root": {
"user": "数据库登录账户",
"password": "数据库密码"
}
},
"serverInfo": {
"server1": {
"write": {
"host": ["rm-wz9j08l21i7o07w7dno.mysql.rds.aliyuncs.com"],
"port": 3306,
"timeout": 2,
"account": "root"
},
"read": {
"host": ["rm-wz9j08l21i7o07w7dno.mysql.rds.aliyuncs.com"],
"port": 3306,
"timeout": 2,
"account": "root",
"startConns": "swoole_cpu_num()*10",
"maxSpareConns": "swoole_cpu_num()*10",
"maxSpareExp": 3600,
"maxConns": "swoole_cpu_num()*20"
}
}
},
"databases": {
"small_shop": {
"serverInfo": "server1",
"startConns": "swoole_cpu_num()*2",
"maxSpareConns": "swoole_cpu_num()*2",
"maxSpareExp": 3600,
"maxConns": "swoole_cpu_num()*2",
"charset": "utf8mb4"
}
}
}
}
官方示例:
{
"server": {
"user": "必选,SMProxy服务用户",
"password": "必选,SMProxy服务密码",
"charset": "可选,SMProxy编码,默认utf8mb4",
"host": "可选,SMProxy地址,默认0.0.0.0",
"port": "可选,SMProxy端口,默认3366 如需多个以`,`隔开",
"mode": "可选,SMProxy运行模式,SWOOLE_PROCESS多进程模式(默认),SWOOLE_BASE基本模式",
"sock_type": "可选,sock类型,SWOOLE_SOCK_TCP tcp",
"logs": {
"open":"必选,日志开关,true 开 false 关",
"config": {
"system": {
"log_path": "必选,SMProxy系统日志目录",
"log_file": "必选,SMProxy系统日志文件名",
"format": "必选,SMProxy系统日志目录日期格式"
},
"mysql": {
"log_path": "必选,SMProxyMySQL日志目录",
"log_file": "必选,SMProxyMySQL日志文件名",
"format": "必选,SMProxyMySQL日志目录日期格式"
}
}
},
"swoole": {
"worker_num": "必选,SWOOLE worker进程数,支持计算",
"max_coro_num": "必选,SWOOLE 协程数,推荐不低于3000",
"pid_file": "必选,worker进程和manager进程pid目录",
"open_tcp_nodelay": "可选,关闭Nagle合并算法",
"daemonize": "可选,守护进程化,true 为守护进程 false 关闭守护进程",
"heartbeat_check_interval": "可选,心跳检测",
"heartbeat_idle_time": "可选,心跳检测最大空闲时间",
"reload_async": "可选,异步重启,true 开启异步重启 false 关闭异步重启",
"log_file": "可选,SWOOLE日志目录"
},
"swoole_client_setting": {
"package_max_length": "可选,SWOOLE Client 最大包长,默认16777216MySQL最大支持包长"
},
"swoole_client_sock_setting": {
"sock_type": "可选,SWOOLE Client sock 类型,默认tcp 仅支持tcp"
}
}
}
测试示例:这里配置的账户就是在项目中连接数据库的配置了
{
"server": {
"user": "root",
"password": "123456",
"charset": "utf8mb4",
"host": "0.0.0.0",
"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"
}
}
}
我使用的是thinkphp v6.0.3 测试的,配置文件示例:
APP_DEBUG = true
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
[DATABASE]
TYPE = mysql
HOSTNAME = 0.0.0.0
DATABASE = test_db
USERNAME = root
PASSWORD = 123456
HOSTPORT = 3366
CHARSET = utf8
DEBUG = true
[LANG]
default_lang = zh-c
Index.php 控制器
<?php
namespace app\controller;
use app\BaseController;
use think\facade\Db;
class Index extends BaseController
{
public function index(){
$start = microtime(true);
print_r(Db::query('select * from shop_goods limit 1'));
print_r(microtime(true)-$start);
}
}
通过浏览器访问测试项目,从tp 自带的trace面板可以看到执行效率
1、使用了数据库连接池
2、框架直接连接阿里云RDS数据库
在实际测试过程中tp框架可能会出现一些未知错误!
本文为蔡关荣原创文章,转载无需和我联系,但请注明来自蔡关荣博客https://caiguanrong.com
最新评论