laravel之laravels组件构建Redis连接池

介绍

        laravel框架入门可参见(《laravel入门及技术指南》https://blog.csdn.net/yan_dk/article/details/117375890),laravel结合swoole,可以实现高性能Http服务,提升应用性能。hhxsv5/laravel-s是第三方的组件包,我们可以安装使用。可参见(《laravel之laravel-s组件技术指南》https://blog.csdn.net/yan_dk/article/details/117867961

       我们使用laravel-s组件,结合swoole,构建Redis连接池,在服务器并发请求redis压力增大是,利用连接池,缓存连接资源,避免频繁重新连接的资源消耗,减轻redis压力,提升Redis性能,避免服务器压力过大而缓慢或崩溃。

构建实现

     

环境配置

 laravel框架及laravel-s的安装见介绍,不再多说。

我们需要安装redis,可以采用docker安装redis,配置环境文件.env,config/database.php

config/database.php中redis的连接池相关配置如下,红色的参数是扩展的,后面要用到

'default' => [
    'url' => env('REDIS_URL'),
    'host' => env('REDIS_HOST', '127.0.0.1'),
    'password' => env('REDIS_PASSWORD', null),
    'port' => env('REDIS_PORT', '6379'),
    'database' => env('REDIS_DB', '0'),
    'pool' => [
        'size' => 10
    ],
    'driver' => 'redis'
],

.env中配置redis的连接参数,不再细说。

建立连接池类

CoReis.php:redis连接池底层入口来,主要负责连接池初始化构造,还提供redis操作接口,抽象主控制类。需要在laravel框架的AppServiceProvider中注册引入。

<?php

namespace App\pool\Core;


class CoRedis
{
    /*
     * 池
     */
    protected $pool;

    /*
     * Redis连接
     */
    private $redis;

    public function __construct($pool)
    {
        $this->pool = $pool;
        
    }

    /**
     * @return mixed
     * 从连接池中取得连接
     */
    public function connection()
    {
        return $this->pool->get();
    }

    /*
     * 从池中取得连接给到Redis属性
     */
    public function getRedis()
    {
        return $this->redis = $this->connection();
    }

    public function __call($name, $arguments)
    {
        // TODO: Implement __call() method.
        if (!method_exists($this,$name)){
            throw new \RuntimeException("{$name} Method doesn't exist!");
        }
        call_user_func("getRedis");
        call_user_func_array([$this,$name],$arguments);
    }

   ...
 /*****************redis 操作函数*******************/
}

RedisPool.php:Redis连接池的环境参数初始化,构建连接池实例,使用了Swoole组件提供的RedisConfig、RedisPool,与CoReis类关联的实现类。

<?php


namespace App\pool\Redis;

use Swoole\Database\RedisPool as Pool;
use Swoole\Database\RedisConfig;
use Illuminate\Foundation\Application;

class RedisPool
{
    /**
     * @var Application
     * laravel的应用
     */
    protected $app;

    /*
     *获取Redis的配置
     */
    protected $config;

    /**
     * @var
     * 池
     */
    protected $pool;

    public function  __construct(Application $app)
    {
        $this->app = $app;
        $this->config = $app->make("config");
        $this->init();
    }

    public function init()
    {
        $config = (new RedisConfig())
            ->withHost($this->config->get('database.redis.default.host'))
            ->withPort($this->config->get('database.redis.default.port'))
            ->withAuth($this->config->get('database.redis.default.password'));
        $this->pool = new Pool($config,$this->config->get('database.redis.default.pool.size'));
    }

    public function get()
    {
        return $this->pool->get();
    }

    public function put($redis)
    {
        return $this->pool->put($redis);
    }
}

Redis.php:从Redis连接池中获得连接,这里使用Swoole的协程、通道,高性能稳定可靠。

<?php
namespace App\pool;

use Swoole\Runtime;
use Swoole\Coroutine;
use Swoole\Coroutine\Channel;

class Redis
{
    public static function getDriver()
    {
        return app(app('config')->get("database.redis.default.driver"));
    }

    public static function __callStatic($name, $arguments)
    {
        // TODO: Implement __callStatic() method.
        Runtime::enableCoroutine();
        $chan = new Channel(1);
        Coroutine::create(function () use ($chan,$name,$arguments){
            $redis = self::getDriver();
            $return = $redis->{$name}(...$arguments);
            $chan->push($return);
            return $chan->pop();
        });
    }
}

注册Redis连接池服务

将上述连接池构建实例,注册成应用的服务,框架启动时,启动这个连接池服务。

<?php

namespace App\Providers;

use App\pool\Core\CoRedis;
use App\pool\Redis\RedisPool;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //注册redis连接池 
        $this->app->singleton('redis',function (){
            return new CoRedis(new RedisPool($this->app));
        });
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

建立测试控制器

我们采用dingo组件控制器及路由

# php artisan make:controller Api/V1/ProductController

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    //连接池
    public function pool()    {
        app('redis')->set("name","test222");
        $result =app('redis')->get("name");
        return $result;
    }
}

建立路由

建立路由配置文件 routes/api.php

$api = app('Dingo\Api\Routing\Router');
$api->version('v1',[
    'middleware' => ['bindings'],
    'namespace' => "App\Http\Controllers\Api\V1"
],function ($api){
    $api->post("pool","ProductController@pool")->name("product.pool");
});

测试

服务器启动后,访问相关路由,我们使用postman测试工具,发送请求,如下

这样实现了,成功构建了redis连接池。

猜你喜欢

转载自blog.csdn.net/yan_dk/article/details/117884536
今日推荐