基于Swoole的Mysql中间件 SMProxy 让你的数据库操作快三倍

最近在学习swoole,偶然间发现了这个数据库中间件:SMPoxy。 项目github地址 https://github.com/louislivi/smproxy

在实际测试中发现使用了数据库连接池以后 查询效率提升了将近一半左右,具体以实际结果为准,接下来一起来看看吧,使用前请确保安装了Swoole 扩展,执行php -m 查看;

SMProxy 是一个基于 MySQL 协议,Swoole 开发的MySQL数据库连接池。
支持读写分离
支持数据库连接池,能够有效解决 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
  • stop 停止服务
  • restart 重启服务
  • status 查询服务运行状态
  • reload 平滑重启
  • -h --help 帮助
  • -v --version 查看当前服务版本
  • -c --config 设置配置项目录
  • --console 前台运行(SMProxy>=1.2.5)
  • -f --force 强制执行(SMProxy>=1.3.0)
配置文件

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

database.json

官方示例:

{
  "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.json

官方示例:

{
  "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框架可能会出现一些未知错误!

蔡关荣博客
请先登录后发表评论
  • latest comments
  • 总共0条评论