资讯专栏INFORMATION COLUMN

Swoole Redis 连接池的实现

Sourcelink / 2261人阅读

摘要:概述这是关于入门学习的第九篇文章连接池的实现。在上篇文章的基础上进行简单调整即可,将实例化的地方,修改成实例化即可,还要注意一些方法的调整。这篇文章仅仅只实现一个连接池,篇幅就太少了,顺便将前几篇整合一下。目录下的文件,在下运行。

概述

这是关于 Swoole 入门学习的第九篇文章:Swoole Redis 连接池的实现。

第八篇:Swoole MySQL 的实现

第七篇:Swoole RPC 的实现

第六篇:Swoole 整合成一个小框架

第五篇:Swoole 多协议 多端口 的应用

第四篇:Swoole HTTP 的应用

第三篇:Swoole WebSocket 的应用

第二篇:Swoole Task 的应用

第一篇:Swoole Timer 的应用

收到读者反馈,“亮哥,文章能多点图片吗?就是将运行结果以图片的形式展示...”

我个人觉得这是比较懒、动手能力差的表现,恩... 要勤快些。

但谁让文章是写给你们看的那,我以后尽量文章写的图文并茂一点。

上篇文章 分享了 MySQL 连接池,这篇文章 咱们来分享下 Redis 连接池。

在上篇文章的基础上进行简单调整即可,将实例化 MySQL 的地方,修改成实例化 Redis 即可,还要注意一些方法的调整。

这篇文章仅仅只实现一个 Redis 连接池,篇幅就太少了,顺便将前几篇整合一下。

大概 Demo 中包含这些点:

实现 MySQL 连接池

实现 MySQL CURD 方法的定义

实现 Redis 连接池

实现 Redis 方法的定义

满足 HTTP、TCP、WebSocket 调用

提供 Demo 供测试

调整 目录结构

HTTP 调用:

实现 读取 MySQL 中数据的 Demo

实现 读取 Redis 中数据的 Demo

TCP 调用:

实现 读取 MySQL 中数据的 Demo

实现 读取 Redis 中数据的 Demo

WebSocket 调用:

实现 每秒展示 API 调用量 Demo

目录结构
├─ client
│  ├─ http
│     ├── mysql.php //测试 MySQL 连接
│     ├── redis.php //测试 Redis 连接
│  ├─ tcp
│     ├── mysql.php //测试 MySQL 连接
│     ├── redis.php //测试 Redis 连接
│  ├─ websocket
│     ├── index.html //实现 API 调用量展示
├─ controller
│  ├─ Order.php     //实现 MySQL CURD
│  ├─ Product.php   //实现 Redis 调用
│  ├─ Statistic.php //模拟 API 调用数据
├─ server
│  ├─ config
│     ├── config.php //默认配置
│     ├── mysql.php  //MySQL 配置
│     ├── redis.php  //Redis 配置
│  ├─ core
│     ├── Common.php //公共方法
│     ├── Core.php   //核心文件
│     ├── HandlerException.php //异常处理
│     ├── callback //回调处理
│         ├── OnRequest.php
│         ├── OnReceive.php
│         ├── OnTask.php
│         ├── ...
│     ├── mysql
│         ├── MysqlDB.php
│         ├── MysqlPool.php
│     ├── redis
│         ├── RedisDB.php
│         ├── RedisPool.php
│  ├─ log  -- 需要 读/写 权限
│     ├── ...
├─ index.php //入口文件
代码 server/core/redis/RedisPool.php
pool)) {
            $this->config = $config;
            $this->pool = new chan($config["master"]["pool_size"]);
            for ($i = 0; $i < $config["master"]["pool_size"]; $i++) {
                go(function() use ($config) {
                    $redis = new RedisDB();
                    $res = $redis->connect($config);
                    if ($res === false) {
                        throw new RuntimeException("Failed to connect redis server");
                    } else {
                        $this->pool->push($redis);
                    }
                });
            }
        }
    }

    public function get()
    {
        if ($this->pool->length() > 0) {
            $redis = $this->pool->pop($this->config["master"]["pool_get_timeout"]);
            if (false === $redis) {
                throw new RuntimeException("Pop redis timeout");
            }
            defer(function () use ($redis) { //释放
                $this->pool->push($redis);
            });
            return $redis;
        } else {
            throw new RuntimeException("Pool length <= 0");
        }
    }
}
server/core/redis/RedisDB.php
_get_usable_db("slave");
        } else {
            $db = $this->_get_usable_db("master");
        }
        $result = call_user_func_array([$db, $name], $arguments);
        return $result;
    }

    public function connect($config)
    {
        //主库
        $master = new SwooleCoroutineRedis();
        $res = $master->connect($config["master"]["host"], $config["master"]["port"]);
        if ($res === false) {
            throw new RuntimeException($master->errCode, $master->errMsg);
        } else {
            $this->master = $master;
        }

        //从库
        $slave = new SwooleCoroutineRedis();
        $res = $slave->connect($config["slave"]["host"], $config["slave"]["port"]);
        if ($res === false) {
            throw new RuntimeException($slave->errCode, $slave->errMsg);
        } else {
            $this->slave = $slave;
        }

        $this->config = $config;
        return $res;
    }

    private function _get_usable_db($type)
    {
        if ($type == "master") {
            if (!$this->master->connected) {
                $master = new SwooleCoroutineRedis();
                $res = $master->connect($this->config["master"]["host"], $this->config["master"]["port"]);
                if ($res === false) {
                    throw new RuntimeException($master->errCode, $master->errMsg);
                } else {
                    $this->master = $master;
                }
            }
            return $this->master;
        } elseif ($type == "slave") {
            if (!$this->slave->connected) {
                $slave = new SwooleCoroutineRedis();
                $res = $slave->connect($this->config["slave"]["host"], $this->config["slave"]["port"]);
                if ($res === false) {
                    throw new RuntimeException($slave->errCode, $slave->errMsg);
                } else {
                    $this->slave = $slave;
                }
            }
            return $this->slave;
        }
    }
}
client/http/redis.php
 "SW",
    "token" => "Bb1R3YLipbkTp5p0",
    "param" => [
        "class"  => "Product",
        "method" => "set",
        "param" => [
            "key"   => "C4649",
            "value" => "订单-C4649"
        ],
    ],
];

$ch = curl_init();
$options = [
    CURLOPT_URL  => "http://10.211.55.4:9509/",
    CURLOPT_POST => 1,
    CURLOPT_POSTFIELDS => json_encode($demo),
];
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);
client/tpc/redis.php
client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);

        $this->client->on("Connect", [$this, "onConnect"]);
        $this->client->on("Receive", [$this, "onReceive"]);
        $this->client->on("Close", [$this, "onClose"]);
        $this->client->on("Error", [$this, "onError"]);
    }

    public function connect() {
        if(!$fp = $this->client->connect("0.0.0.0", 9510, 1)) {
            echo "Error: {$fp->errMsg}[{$fp->errCode}]".PHP_EOL;
            return;
        }
    }

    public function onConnect() {

        fwrite(STDOUT, "测试RPC (Y or N):");
        swoole_event_add(STDIN, function() {
            $msg = trim(fgets(STDIN));
            if ($msg == "y") {
                $this->send();
            }
            fwrite(STDOUT, "测试RPC (Y or N):");
        });
    }

    public function onReceive($cli, $data) {
        echo "[Received]:".$data;
    }

    public function send() {
        $demo = [
            "type"  => "SW",
            "token" => "Bb1R3YLipbkTp5p0",
            "param" => [
                "class"  => "Product",
                "method" => "get",
                "param" => [
                    "code" => "C4649"
                ],
            ],
        ];
        $this->client->send(json_encode($demo));
    }

    public function onClose() {
        echo "Client close connection".PHP_EOL;
    }

    public function onError() {

    }
}

$client = new Client();
$client->connect();
client/websocket/index.html



    
    
    
    
    
    Demo
    
    



还涉及到,OnMessage.php、OnTask.php 、OnWorkerStart.php 等,就不贴代码了。

运行

小框架的启动/关闭/热加载,看看这篇文章: 第六篇:Swoole 整合成一个小框架

里面 Demo 在 client 文件夹下。

http 目录下的文件,放到自己虚拟目录下,用浏览器访问。

tcp 目录下的文件,在 CLI 下运行。

websocket 目录下的文件,直接点击在浏览器访问。

扩展

官方协程 Redis 客户端手册:

https://wiki.swoole.com/wiki/...

大家可以尝试使用官方提供的其他方法。

小结

Demo 代码仅供参考,里面有很多不严谨的地方,根据自己的需要进行修改 ...

上面的 Demo 需要源码的,加我微信。(菜单-> 加我微信-> 扫我)

推荐阅读

系统的讲解 - SSO 单点登录

系统的讲解 - PHP WEB 安全防御

系统的讲解 - PHP 缓存技术

系统的讲解 - PHP 接口签名验证

系统的讲解 - PHP 浮点数高精度运算

本文欢迎转发,转发请注明作者和出处,谢谢!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/37191.html

相关文章

  • swoole通用协程池的实现

    摘要:之前过行代码实现通用协程池今天看了下相关文档,用也实现了一个,由于没有的,所以实现的有点简单,但是实用性还可以,通过工厂函数实现了通用性。官方的协程池是用只能用在。因为协程池代码层耦合了实例化逻辑。 之前过golang40行代码实现通用协程池 今天看了下swoole相关文档,用PHP也实现了一个,由于swoole没有golang的select,所以实现的有点简单,但是实用性还可以,通过...

    wanghui 评论0 收藏0
  • Swoft 源码剖析 - 连接

    摘要:基于扩展实现真正的数据库连接池这种方案中,项目占用的连接数仅仅为。一种是连接暂时不再使用,其占用状态解除,可以从使用者手中交回到空闲队列中这种我们称为连接的归队。源码剖析系列目录 作者:bromine链接:https://www.jianshu.com/p/1a7...來源:简书著作权归作者所有,本文已获得作者授权转载,并对原文进行了重新的排版。Swoft Github: https:...

    rozbo 评论0 收藏0
  • Swoole MySQL 连接池的实现

    摘要:概述这是关于入门学习的第八篇文章连接池的实现。开始今天的文章,这篇文章实现了连接池,代码是在的实现文章的基础上进行开发的。 概述 这是关于 Swoole 入门学习的第八篇文章:Swoole MySQL 连接池的实现。 第七篇:Swoole RPC 的实现 第六篇:Swoole 整合成一个小框架 第五篇:Swoole 多协议 多端口 的应用 第四篇:Swoole HTTP 的应用 第三...

    13651657101 评论0 收藏0
  • Swoole 在 Swoft 中的应用

    摘要:在中的应用官网源码解读号外号外欢迎大家我们开发组定了一个就线下聚一次的小目标上一篇源码解读反响还不错不少同学推荐再加一篇讲解一下中使用到的功能帮助大家开启的实战之旅服务器开发涉及到的相关技术领域的知识非常多不日积月累打好基础是很难真正 date: 2017-12-14 21:34:51title: swoole 在 swoft 中的应用 swoft 官网: https://www.sw...

    EscapedDog 评论0 收藏0
  • 压测 swoole_websocket_server 性能

    摘要:概述这是关于入门学习的第十篇文章压测性能。测试机上安装的虚拟机系统内存数量核数数量大小代码压测脚本并发量请求量压测结果第次第次第次以上是压测结果,供参考。小结通过这个压测结果,表明的执行效率是杠杠的当然还有一些参数是可以调优的,比如等。 概述 这是关于 Swoole 入门学习的第十篇文章:压测 swoole_websocket_server 性能。 第九篇:Swoole Redis ...

    余学文 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<