Press "Enter" to skip to content

EasySwoole+ElasticSearch打造高性能小视频服务系统

导学

EasySwoole是基于Swoole开发的一个常驻内存型的分布式PHP框架

使用高性能搜索服务ElasticSearch

技术点:http server,多进程,异步任务,消息队列,全局事件注册,定时器连接池协程,框架底层源码分析

业务层技术点:拦截器,全局错误处理,代码高度复用,高性能yaconf服务引入,应对高并发大数据场景,静态缓存redis缓存引入,nginx+lua+easyswoole,前后端分离VUE+EasySwoole

EasySwoole简介

  • 基于Swoole扩展的一个PHP框架
  • 可以先看下官网文档

环境准备以及课程技术点介绍

环境:基于linux,php需要高于7.2,基于swoole,mysql,redis,ElasticSearch

技术点:高性能Swoole API,高性能分布式检索-es

easyswoole安装以及结构分析

安装composer,通过composer进行安装

php easyswoole start 开启服务

easyswoole基本使用

php easyswoole start--d 守护进程方式开启

可以使用smaba进行文件共享

为了代码可读性建议在以后一行加return

修改easyswoole中的消息返回方法

格式为status,message,result

讲接口代码放到Api目录

通过$this->request()->getRequestParam()

easyswoole深入使用

php easyswoole --p 8444 监听新端口

源码中有各种关于命令的控制项

每次都需要声明index方法不友好,使用Base控制器实现index方法

在onRequest中做权限校验写在父类中

在onException中做异常处理

void不需要return

EasySwoole结合Mysql使用

  • DB库安装
  • 检查是否有mysqli扩展
  • 基本使用

需要安装mysql,使用composer安装mysqli和orm

性能测试介绍

写一些自动化脚本进行测试

使用ab工具测试

Ab工具安装以及详细讲解

  • 工具的安装 yum -y install httpd-tools

QBS很关键

  • 使用 ab -n 1000 -c 100 https://www.baidu.com

为什么要学习消息队列

生产者 - Broker - 消费者

生产者发送消息,Broker处理数据,发送给消费者进行业务处理,主要用于异步数据处理
  • 常用消息队列 kafka rabbitmq redis

Redis准备工作

安装redis和php-redis扩展

Redis底层类库封装

在lib文件夹中进行封装Redis类库

单例模式,直接使用Singleton中的单例方法

Redis底层类库封装优化

在EasySwooleEvent的mainServerCreate中增加Di注册,就可以通过单例模式的方式去使用了

通过Config类获取到配置有利于后期维护

引入高性能配置文件服务

配置文件读取消耗性能使用Yaconf

前后端分离介绍

原始的前后端分配工作不均匀,开发效率低

前端环境安装以及页面部署

安装NodeJS

npm install

npm run dev

修改config服务域名

前端页面构建以及让Nginx请求转发到swoole服务器

编译后将dist目录拷贝到网站目录即可

修改nginx指向目录

增加重定向配置

if (!-e $request_filename){
    proxy_pass http://127.0.0.1:8000
}

小视频服务平台整体架构

视频存到七牛云或者本地

接口尽量使用静态化API,数据缓存Redis

通过消息队列实现视频点赞

视频搜索使用Elasticsearch

nginx创建集群做转发逻辑,easyswoole和redis和mysql也可以搭建集群

小视频介绍

视频上传-源视频存储-转码分发-加速播放

满足多终端多清晰度播放

使用本地和第三方做视频存储

视频上传到本地

通过$this->request()->getUploadFile方法获取视频

通过moveTo方法将视频放入目录

视频上传到本地优化方案

增加公共上传视频类库

通过构造方法获取request对象,通过SwooleRequest->files,通过array_keys() 获取键名,通过键名的第一个属性获取到文件的类型

根据getSize获取文件大小并判断

根据getClientFileName获取真实名称

根据getClientMediaType获取格式

校验视频大小,校验视频格式,上传视频

视频封面图功能上传

复制Lib下upload的子类,不同的方法校验要重写

根据文件类型实例化不同的类

利用反射机制优化处理上传文件思想

定义反射类,保存类的路径及k

使用initClass方法判断类文件是否存在,增加参数和是否示例化

如果需要实例化则使用ReflectionClass实例化对象否则返回类名

视频基本数据入库

通过getRequestParam方法获取参数

通过ORM增加和获取数据,通过STATUS获取常用状态码

增加验证器校验,增加日志校验

第三方上传视频介绍

遇到多分布式服务器会出现视频不同步的情况

阿里云第三方视频服务提供的功能很多,如果是大量的视频上传可以使用阿里云服务

阿里云SDK获取以及基本使用

下载SDK,购买资源包

阿里云视频点播服务底层类库封装

引入sdk,填入配置信息

根据文档增加上传图片和视频的方法,根据返回参数做判断

获取数据通过base64解析后获取对应参数通过oss的uploadFile方法上传

首页视频页面技术点介绍

将本地上传改为上传视频到阿里云

利用easyswoole开发首页视频API业务

具有条件和分页

getLastQuery获取原生SQL

增加where条件和order排序以及分页参数

遍历时进行时间转换

增加基类控制器,将初始化参数写在里面方便调用

性能优化静态化API

  • 什么是静态化API 把数据存储在本地
  • 为什么要做静态化API 提高性能
  • 如何做 easyswoole+crontab定时获取数据或者使用easyswoole的定时器 定时生成数据

此处定时器的使用方法和视频不一样,参考下文档

性能优化 – 静态化API 定时备份基础库编写

通过定时任务生成静态化数据,用户访问后优先获取静态化数据

创建App\Lib\Cache文件夹存储缓存

增加根据分类取出对应视频数据,将返回的数据存入文件,如果写入文件失败通过短信方式或邮件报警

性能优化 – 静态化API业务层逻辑替换

判断文件是否存在,读取文件

获取总条数,总分页数根据ceil($count/$size)获取

性能优化 – 静态化API easyswoole定时器完美解决方案

在mainServerCreate增加Time类,使用loop方法

高性能easyswoole table方案

使用缓存存储数据,如果easyswoole中断数据则不会存在,需要看下数据落地相关文档

性能优化 – redis解决方案

重新封装redis,设置过期时间,有时间参数的使用setex保存

代码高度复用 – 底层cache基础库优化

应用层不处理判断逻辑

使用switch判断配置参数决定使用file或cache或redis保存数据

通过getCache方法获取不同参数保存的数据

API缓存总结

通过 --help查看easyswoole命令

视频播放页面基本信息

直接使用model自带的获取单条数据的方法获取即可

播放数统计 – 高性能swooletask异步任务引入

task用于处理耗时较长的任务,可以在后台执行

播放数记录到redis中

播放数统计 – 高性能redis有序集合服务引入

zincrby 将指定id去进行自增

ZREVRANGE video_play 0 -1 withscores用于查看列表

视频排行榜 – 总排行,今日排行,本周排行

根据不同的Key值去记录即可实现

zrevrange改版了,最后一个根据分数排序传true

代码高度优化

redis类库的方法重复性太高,使用__call方法覆写

__call($name, $arguments)

...$arguments 所有参数

基于redis的视频点赞逻辑开发以及预留给大家的作业

记录用户点赞到redis

elasticsearch简介

搜索快,比mysql搜索效率高

elasticsearch安装 – es单机安装

需要安装java jdk,官网下载es

首次启动需要配置

    xpack.ml.enabled: false
    network.host: 0.0.0.0
    http.port: 8301

    bootstrap.memory_lock: false
    bootstrap.system_call_filter: false

head插件安装

可视化操作es

需要有node,修改端口号,修改app.js里的端口号

修改配置
http.cors.enabled: true
http.cors.allow-origin: '*'

elasticsearch分布式处理

cluster.name: 集群名称

node.name: 集群名称1
node.master : true 是否为主,搭建集群需要

discovery.zen.ping.unicast.hosts: ['127.0.0.1']

由于内存不够故跳过

elasticsearch索引精讲

索引中增加索引

可以创建结构化索引

文档的新增操作

在Elasticsearch-Head中的信息位置增加数据

文档的查询操作

在基本查询中查询即可

也可在复合查询中输入query参数

easyswoole-php底层基础类库安装和部署

使用sdk做关于es的相关操作

使用composer安装

easyswoole集合elasticsearch初探

使用ClientBuilder类查询

利用easyswoole底层DI容器对es底层基础类库封装

和Redis的封装类似,采用单例模式,使用__call方法调用底层方法

遇到的问题:Specifying types in urls has been deprecated at file - es7.0后启用

视频搜索底层类库封装

由于搜索vide需要传入对应模板的配置故封装一个类库用于保存参数

视频搜索底层类库封装优化

封装公共类库保存公共方法

应用层大数据搜索API逻辑开发

增加Search控制器 增加from和size参数使用分页

遍历数据格式化

应用层大数据下搜索API逻辑开发优化方案以及IK分词器介绍

es的性能很强大,可将视频数据直接插入到es,或者先插入到mysql再同步到es

深度分页不利于性能,但一般用户用不到

可以给一个最大分页加以限制,如果检索非常多使用IK分词器

本章调优概括

  • swoole升级
  • easyswoole升级
  • 全协程升级
  • Nginx负载均衡
  • 分布式
  • Linux性能调优

Swoole的升级

easyswoole2.X升级到easyswoole3

让业务代码轻松适配easyswoole3.x

性能优化-swoole协诚连接池

基础类库用到了原生SWOOLE的协程

性能调优大体介绍以及openresty工具的介绍

高并发性能调优 – 负载均衡

使用流量转发

配置不同服务器

课程总结

  • 拦截器
  • 全局错误处理
  • 代码高度复用
  • 高性能yaconf服务引入
  • 应对高并发,大数据场景
  • 静态缓存 redis缓存引入
  • nginx lua easyswoole
  • 前后端分离VUE EasySwoole