首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
louislivi
V2EX  ›  PHP

SMProxy,让你的项目数据库操作快三倍!

  •  1
     
  •   louislivi · 2018-11-15 14:27:30 +08:00 · 1657 次点击
    这是一个创建于 429 天前的主题,其中的信息可能已经有所发展或是发生改变。

    SMProxy

    GITHUB:https://github.com/louislivi/smproxy

    支持请 star

    swoole msyql proxy 一个基于 mysql 协议,swoole 开发的 mysql 数据库连接池

    数据库连接池

    数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;
    释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。
    这项技术能明显提高对数据库操作的性能。 
    

    特性

    • 支持读写分离
    • 支持数据库连接池,能够有效解决 PHP 带来的数据库连接瓶颈
    • 支持 SQL92 标准
    • 遵守 Mysql 原生协议,跨语言,跨平台的通用中间件代理。
    • 支持多个数据库连接,多个数据库,多个用户,灵活搭配。
    • 支持 mysql 事物
    • 采用协程调度
    • 支持 HandshakeV10 协议版本
    • 完美兼容 mysql5.6-5.7

    设计初衷

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

    环境

    • swoole 2.1+
    • php 7.0+

    安装

    下载的文件直接解压即可。

    运行

    • bin/server start : 运行服务
    • bin/server stop : 停止服务
    • bin/server restart : 重启服务
    • bin/server status : 查询服务运行状态
    • bin/server reload : 平滑重启
    • bin/server -h : 帮助

    SMProxy 连接测试

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

    推荐先采用命令行测试:

    mysql -uroot -p123456 -P3366 -h127.0.0.1

    也可采用工具连接。

    测试

    $start = microtime(true);
    print_r(Db::query('select * from account limit 1'));
    print_r(microtime(true)-$start);
    

    未使用 SMProxy 连接池运行:

    0.17314600944519
    

    使用 SMProxy 连接池运行:

    0.073625087738037
    

    配置文件:

    ROOT 当前 SMProxy 跟目录
    

    database.json

    {
      "database": {
        "account": {
          "root": {
            "user": "root", 
            "password": "123456"
          }
        },
        "serverInfo": {
          "server1": {
            "write": {
              "host": "127.0.0.1",
              "port": 3306,
              "timeout": 0.5,
              "flag": 0,
              "account": "root"
            },
            "read": {
              "host": "127.0.0.1",
              "port": 3306,
              "timeout": 0.5,
              "flag": 0,
              "account": "root"
            }
          }
        },
        "databases": {
          "db1": {
            "serverInfo": "server1",
            "maxSpareConns": 10,
            "maxConns": 20,
            "charset": "utf-8"
          }
        }
      }
    }
    

    | account 账号信息 | serverInfo 服务信息 | databases 数据库连接池信息 | | ------ | ------ | ------ | | account.root 用户标识 与 serverInfo...account.root 对应 | serverInfo.server1 服务标识 与 databases..serverInfo 对应 | databases.db1 数据库名称 | | account..user 用户名 | serverInfo..write 读写分离 write 写库 read 读库 | databases..serverInfo 服务信息 | | account..password 密码 | serverInfo..host 数据库连接地址 | databases..maxSpareConns 最大空闲连接数 | | | serverInfo..prot 数据库端口 | databases..maxConns 最大连接数 | | | serverInfo..timeout 数据库超时时长(秒) | databases..charset 数据库编码格式 | | | serverInfo..flag TCP 类型目前支持 0 阻塞 不支持 1.非阻塞 | | | | serverInfo..account 与 databases.account 对应| |

    server.json

    {
      "server": {
        "user":"root",
        "password":"123456",
        "charset":"utf8mb4",
        "host": "0.0.0.0",
        "port": "3366",
        "mode": 3,
        "sock_type": 1,
        "logs": {
          "open":true,
          "config": {
            "system": {
              "log_path": "/var/www/swoole/swoole-mysql-proxy/logs",
              "log_file": "system.log",
              "format": "Y/m/d"
            },
            "mysql": {
              "log_path": "/var/www/swoole/swoole-mysql-proxy/logs",
              "log_file": "mysql.log",
              "format": "Y/m/d"
            }
          }
        },
        "swoole": {
          "worker_num": 2,
          "max_coro_num": 16000,
          "open_tcp_nodelay": true,
          "daemonize": 0,
          "heartbeat_check_interval": 60,
          "heartbeat_idle_time": 600,
          "reload_async": true,
          "log_file": "/var/www/swoole/swoole-mysql-proxy/logs/error.log",
          "pid_file": "/var/www/swoole/swoole-mysql-proxy/logs/pid/server.pid"
        },
        "swoole_client_setting": {
          "package_max_length": 16777216
        },
        "swoole_client_sock_setting": {
          "sock_type": 1,
          "sync_type": 1
        }
      }
    }
    

    | user 服务用户名 | password 服务密码 | charset 服务编码 | host 链接地址 | port 服务端口 多个以,隔开 | mode | sock_type 1 tcp | logs 日志配置 | swoole swoole 配置 | swoole_client_setting 客户端配置 | swoole_client_sock_setting 客户端 sock 配置 | | ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | | | | | | | | | logs.open 日志开关 | worker_num work 进程数量 | package_max_length 最大包长 | sock_type 1.tcp | | | | | | | | | logs.config 日志配置项 | max_coro_num 最大携程数 | | sync_type 1.异步 | | | | | | | | | 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 目录 | | |

    其他学习资料

    liwanglin12
        1
    liwanglin12   2018-11-17 00:25:49 +08:00
    读写分离妈耶,真香,感觉多地部署数据库问题有解了,因为没办法实现读写分离本来打算试试组复制(多主同步)的,有读写分离的话只需要用主从星状部署就好了_(:з」∠)_希望能实现预期效果,今天白天就试试看
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3163 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 18ms · UTC 04:25 · PVG 12:25 · LAX 20:25 · JFK 23:25
    ♥ Do have faith in what you're doing.