使用EasySwoole3.3.7搭建基础应用框架实现部分功能

Royal
2021-07-30 / 0 评论 / 693 阅读 / 正在检测是否收录...

1. 环境说明

  • 运行环境:LINUX,系统版本centos7
  • PHP运行版本:7.4.21
  • Swoole扩展版本:4.5.7
  • Easyswoole版本:3.3.7
  • mongodb版本:4.4.6
    krq2psd1.png

    2. 实现功能说明

  • 实现入参过滤,入参限制等功能
    EasySwoole的控制器并没有提供类似中间件的说法,EasySwoole 3.4.x 版本之前:可在项目根目录的EasySwooleEvent.php 中看到onRequestonRequest ,所以在onRequestonRequest事件进行验证。
    第一步:在APP目录下生成Libraries自定义类文件夹,建立测试拦截类,防止sql注入,对一些关键词进行屏蔽;
    第二步:在Event中的OnRequest事件进行全局的请求参数过滤或者拦截;
  • 签名校验
    通过RSA加密方式生成一对公私钥,采用私钥加签公钥验签的方式对请求数据进行验签,签名原文生成机制,采用按字段首字母字典升序首尾拼接生成。
    第一步:创建自定义类RsaClient,包含生成公私钥,签名原文,验签等方法;
    第二步:一对公私钥配置在项目配置文件/config/rsa中
    第三步:在Event中的OnRequest事件对请求数据进行验签,验签通过后继续下一步请求;
  • 实现Redis和MySql连接池
    实现MYSQL和REDIS连接池可有效解决减少创建连接的时间,控制资源的使用,达到连接复用的目的。
    第一步:加载依赖包通过composer安装easyswoole/pool通用连接池组件,easyswoole/redis-pool 协程连接池组件,easyswoole/orm 安装orm组件;
    第二步:在配置文件dev中添加配置项包含MySQL连接信息,连接池最小和最大连接数,连接池对象最大闲置时间以及REDIS的连接信息,最大最小连接数等;
    第三步:在EasySwooleEvent.php文件的initialize方法中初始化连接池连接配置信息,日志记录异常;
  • 实现日志处理自定义类
    用ioc重写系统日志类,实现LoggerInterface接口。
    第一步:在自定义类中增加Log文件实现系统日志类接口;
    第二步:项目根目录创建文件 bootstrap.php,IOC覆盖系统日志类,注册自定义日志处理器;

    use App\Log\LogHandler;
    use EasySwoole\Component\Di;
    use EasySwoole\EasySwoole\SysConst;
    //IOC覆盖系统日志类
    Di::getInstance()->set(SysConst::LOGGER_HANDLER, LogHandler::class);
    
  • 实现elasticsearch协程客户端
    通过composer 安装easyswoole/elasticsearch组件
  • 实现mongodb客户端
    通过composer安装easyswoole/sync-invoker组件和mongodb/mongodb组件,定义驱动
    ,客户端调用类定义,在 EasySwoole 全局事件 的 mainServerCreate 事件中进行服务注册。
  • 实现IP限流和IP白名单机制
    使用 Swoole\Table,存储用户访问情况,使用定时器,将前一周期的访问情况清空,统计下一周期。
    第一步:IP 访问统计类,实现了 初始化 Table、统计 IP访问次数、获取一个周期内次数超过一定值的记录;

    class IpList
    {
        use Singleton;
    
        /** @var Table */
        protected $table;
    
        public function __construct()
        {
            TableManager::getInstance()->add('ipList', [
                'ip' => [
                    'type' => Table::TYPE_STRING,
                    'size' => 16
                ],
                'count' => [
                    'type' => Table::TYPE_INT,
                    'size' => 8
                ],
                'lastAccessTime' => [
                    'type' => Table::TYPE_INT,
                    'size' => 8
                ]
            ], 1024 * 128);
            $this->table = TableManager::getInstance()->get('ipList');
        }
    
        public function access(string $ip): int
        {
            $key = substr(md5($ip), 8, 16);
            $info = $this->table->get($key);
    
            if ($info) {
                $this->table->set($key, [
                    'lastAccessTime' => time(),
                    'count' => $info['count'] + 1,
                ]);
                return $info['count'] + 1;
            } else {
                $this->table->set($key, [
                    'ip' => $ip,
                    'lastAccessTime' => time(),
                    'count' => 1,
                ]);
                return 1;
            }
        }
    
        public function clear()
        {
            foreach ($this->table as $key => $item) {
                $this->table->del($key);
            }
        }
    
        public function accessList($count = 10): array
        {
            $ret = [];
            foreach ($this->table as $key => $item) {
                if ($item['count'] >= $count) {
                    $ret[] = $item;
                }
            }
            return $ret;
        }
    }

    第二步:封装完IP统计 的操作之后,我们就可以在 EasySwooleEvent.php 中的 mainServerCreate 回调事件中初始化 IpList 类和定时器,注册 IP 统计自定义进程
    第三步:在 EasySwooleEvent.php 中的 onRequestonRequest 事件中 接着我们在判断和统计IP的访问
    3. 项目地址
    https://gitee.com/sangshuaidong2020/easyswoole

1

评论

博主关闭了当前页面的评论