子山 / smproxy


README.md

中文 | English

  /$$$$$$  /$$      /$$ /$$$$$$$                                        
 /$$__  $$| $$$    /$$$| $$__  $$                                       
| $$  \__/| $$$$  /$$$$| $$  \ $$ /$$$$$$   /$$$$$$  /$$   /$$ /$$   /$$
|  $$$$$$ | $$ $$/$$ $$| $$$$$$$//$$__  $$ /$$__  $$|  $$ /$$/| $$  | $$
 \____  $$| $$  $$$| $$| $$____/| $$  \__/| $$  \ $$ \  $$$$/ | $$  | $$
 /$$  \ $$| $$\  $ | $$| $$     | $$      | $$  | $$  >$$  $$ | $$  | $$
|  $$$$$$/| $$ \/  | $$| $$     | $$      |  $$$$$$/ /$$/\  $$|  $$$$$$$
 \______/ |__/     |__/|__/     |__/       \______/ |__/  \__/ \____  $$
                                                               /$$  | $$
                                                              |  $$$$$$/
                                                               \______/

SMProxy

release forks stars Build Status Gitter license smproxy

Swoole MySQL Proxy

一个基于 MySQL 协议,Swoole 开发的MySQL数据库连接池。

原理

将数据库连接作为对象存储在内存中,当用户需要访问数据库时,首次会建立连接,后面并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。 使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。

同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。 也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。超出最大连接数会采用协程挂起,等到有连接关闭再恢复协程继续操作。

特性

  • 支持读写分离
  • 支持数据库连接池,能够有效解决 PHP 带来的数据库连接瓶颈
  • 支持 SQL92 标准
  • 采用协程调度
  • 支持多个数据库连接,多个数据库,多个用户,灵活搭配
  • 遵守 MySQL 原生协议,跨语言,跨平台的通用中间件代理
  • 支持 MySQL 事物
  • 支持 HandshakeV10 协议版本
  • 完美兼容 MySQL4.1 – 8.0
  • 兼容各大框架,无缝提升性能

设计初衷

PHP 没有连接池,所以高并发时数据库会出现连接打满的情况,Mycat 等数据库中间件会出现部分 SQL 无法使用,例如不支持批量添加等,而且过于臃肿。 所以就自己编写了这个仅支持连接池和读写分离的轻量级中间件,使用 Swoole 协程调度 HandshakeV10 协议转发使程序更加稳定,不用像 Mycat 一样解析所有 SQL 包体,增加复杂度。

环境

  • Swoole 2.1+ swoole_version
  • PHP 7.0+ php_version

安装

(推荐)直接下载最新发行版的 PHAR 文件,解压即用:

https://github.com/louislivi/smproxy/releases/latest

或者使用 Git 切换任意版本:

git clone https://github.com/louislivi/smproxy.git
composer install --no-dev # 如果你想贡献你的代码,请不要使用 --no-dev 参数。

运行

需要给予 bin/server 执行权限。

  SMProxy [ start | stop | restart | status | reload ] [ -c | --config <configuration_path> ]
  SMProxy -h | --help
  SMProxy -v | --version

Options:

  • start 运行服务
  • stop 停止服务
  • restart 重启服务
  • status 查询服务运行状态
  • reload 平滑重启
  • -h –help 帮助
  • -v –version 查看当前服务版本
  • -c –config <configuration_path> 设置配置项目录

SMProxy连接测试

测试SMProxy与测试MySQL完全一致,MySQL怎么连接,SMProxy就怎么连接。

推荐先采用命令行测试:

mysql -uroot -p123456 -P3366 -h127.0.0.1

也可采用工具连接。

没用框架的 PHP 7.2.6

PHP7.2.6

没用:0.15148401260376,用了:0.040808916091919

未使用连接池: 0.15148401260376

ab

使用连接池: 0.040808916091919

ab

ThinkPHP 5.0

ThinkPHP5

未使用连接池:

ab

使用连接池:

ab

Laravel 5.7

Laravel5.7

未使用连接池:

ab

使用连接池:

ab

MySQL 连接数

未使用连接池:

MySQL

使用连接池:

MySQL

请以实际压测为准,根数据量,网络环境,数据库配置有关。 测试中因超出最大连接数会采用协程挂起 等到有连接关闭再恢复协程继续操作, 所有并发量与配置文件maxConns设置的不合适,会导致比原链接慢,主要是为了控制连接数。

交流

QQ群:722124111

配置文件

配置文件位于 smproxy/conf 目录中,其中大写 ROOT 代表当前 SMProxy 根目录。

database.json

account 账号信息 serverInfo 服务信息 databases 数据库连接池信息
account.root 用户标识 与 serverInfo…account.root 对应 serverInfo.server1 服务标识 与 databases..serverInfo 对应 databases.dbname 数据库名称
account..user 用户名 serverInfo..write 读写分离 write 写库 read 读库 databases..serverInfo 服务信息
account..password 密码 serverInfo..host 数据库连接地址[数组:多读多写] databases..maxSpareConns 最大空闲连接数
serverInfo..prot 数据库端口 databases..maxConns 最大连接数
serverInfo..timeout 数据库超时时长(秒) databases..charset 数据库编码格式
serverInfo..account 与 databases.account 对应 databases..maxSpareExp 最大空闲时间
databases..startConns 服务启动连接数

server.json

user 服务用户名 password 服务密码 charset 服务编码 host 链接地址 port 服务端口 多个以,隔开 mode 运行模式 sock_type SWOOLE_SOCK_TCP tcp logs 日志配置 swoole swoole配置 swoole_client_setting 客户端配置 swoole_client_sock_setting 客户端sock配置
SWOOLE_PROCESS多进程模式(默认),SWOOLE_BASE基本模式 logs.open 日志开关 worker_num work进程数量 package_max_length 最大包长 sock_type SWOOLE_SOCK_TCP tcp
logs.config 日志配置项 max_coro_num 最大携程数 sync_type SWOOLE_SOCK_SYNC 同步,SWOOLE_SOCK_ASYNC 异步
logs.system or MySQL 配置模块 open_tcp_nodelay 关闭Nagle合并算法
logs..log_path 日志目录 daemonize 守护进程化
logs..log_file 日志文件名 heartbeat_check_interval 心跳检测
logs..format 日志日期格式 heartbeat_idle_time 最大空闲时间
reload_async 异步重启
log_file 日志目录
pid_file 主进程pid目录

MySQL8.0

MySQL-8.0默认使用了安全性更强的caching_sha2_password插件, 如果是从5.x升级上来的, 可以直接使用所有MySQL功能, 如是新建的MySQL, 需要进入MySQL命令行执行以下操作来兼容:

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
flush privileges;

将语句中的 'root'@'%' 替换成你所使用的用户, password 替换成其密码.

如仍无法使用, 应在my.cnf中设置 default_authentication_plugin = mysql_native_password

其他学习资料