基础版本抖音(字节跳动青训)

抖音基础版(字节跳动青训项目)

一、项目介绍

  • 本抖音项目是基于grpc通讯协议开发的高性能微服务,不仅使用gin作为业务层框架,gorm框架作为持久层框架,还使用预编译sql防止sql注入,同时该项目结合连接池技术来构建连接工厂和复用grpc连接来提高系统的性能,这样可以有效的处理高并发场景下的挑战,还可以通过减少频繁创建和销毁grpc连接带来的性能开销
  • 项目服务地址:https://1024code.com/codecubes/jpyi9rm
  • 项目地址:https://github.com/fineCoderWithLove/douyin-base

二、项目实现

2.1技术选型

  • gin:提供grpc服务使用protobuf进行数据传输。

  • JWT:token生成和权限的校验

  • Gorm:对Mysql执行ORM操作,Go-redis:操作Redis对频繁更改的数据进行缓存以便更快的响应。

  • Redis:对点赞/取消赞,视频的喜欢量/评论量,用户的喜欢量,总点赞量缓存Redis中,设置定时任务,并且使数据同步到数据库中。

  • Zap:高性能日志打印

  • ffmpeg:进行视频取帧,作为视频的封面

  • 七牛云:使用七牛云做对象存储,用来存储视频,图片等静态资源。

  • pprof:使用pprof进行性能测试

    2.2架构设计

    由于项目的耦合度不高,所以采用微服务架构来缓解服务器的压力,项目分为api层,业务服务层,数据层

  • api层负责鉴权和分发请求调用远程服务来返回数据

  • 业务层负责与数据库进行交互和逻辑处理

在这里插入图片描述

2.3代码目录介绍

├─base-service # 基础服务
│  ├─cmd # 启动类  
│  ├─global # 定义全局信息
│  │  └─constant # 定义全局常量
│  ├─handler # 业务处理
│  ├─model # 定义常用结构体
│  │  └─video
│  ├─proto # proto文件
│  │  └─favorite
│  ├─test # 测试类
│  ├─util # 封装工具类
│  └─videoproto # 视频的proto文件
├─douyin-api # 外部网关
│  ├─api # grpc服务调用
│  ├─cmd # 启动类
│  ├─global # 定义全局变量
│  ├─globalinit # 定义全局日志信息
│  │  └─constant
│  ├─proto # proto文件
│  ├─redis # 封装redis工具类
│  ├─router # 加载路由信息
│  └─util # 封装工具类
├─interaction-service # 互动模块
│  ├─dao # gen代码生成器
│  │  └─gen
│  ├─global # 定义全局信息
│  │  └─constant
│  ├─handler # 处理业务信息
│  ├─model # 定义常用结构体
│  ├─proto # proto文件
│  │  ├─comment
│  │  ├─favorite
│  │  ├─user
│  │  └─video
│  └─server # grpc启动类
│      ├─comment
│      └─favorite
├─log # 输入的日志信息
│  └─info
└─social-service # 社交模块├─cmd # 启动类├─global # 定义全局变量├─handler # 处理业务├─proto   # proto文件│  ├─favorite│  ├─message│  ├─relation│  └─user└─util # 封装的工具类

接口文档地址: https://apifox.com/apidoc/shared-09d88f32-0b6c-4157-9d07-a36d32d7a75c/api-50717106

三、测试结果

3.1功能测试

功能项接口名称测试点模块结果
基础接口视频流接口不限制登录状态,返回按投稿时间倒序的视频列表base-service测试通过
基础接口用户注册新用户注册时提供用户名,密码即可,用户名需要保证唯一。创建成功后返回用户 id 和权限tokenbase-service测试通过
基础接口用户登录通过用户名和密码进行登录,登录成功后返回用户 id 和权限 tokenbase-service测试通过
基础接口用户信息获取用户的 id、昵称,如果实现社交部分的功能,还会返回关注数和粉丝数base-service测试通过
基础接口投稿列表登录用户选择视频上传base-service测试通过
基础接口发布列表用户的视频发布列表,直接列出用户所有投稿过的视频base-service测试通过
互动接口赞操作登录用户对视频的点赞和取消点赞操作interaction-servic测试通过
互动接口喜欢列表用户的所有点赞视频interaction-service测试通过
互动接口评论操作登录用户对视频进行评论interaction-service测试通过
互动接口评论列表查看视频的所有评论,按发布时间倒序interaction-service测试通过
社交接口关注操作已登录的用户对其他用户进行关注social-service测试通过
社交接口关注列表已登录的用户查询其他用户的关注列表social-service测试通过
社交接口粉丝列表已登录的用户查询用户的粉丝列表social-service测试通过
社交接口好友列表已登录的用户查询好友列表social-service测试通过
社交接口发送消息已登录的用户给其他用户发送消息social-service测试通过
社交接口聊天记录已登录的用户查询与其他用户的聊天记录social-service测试通过

用户测试样例

用户鉴权失败样例


3.2性能测试

  1. 我们使用pprof进行性能监测,因为每次请求grpc都会产生连接和销毁连接造成服务的性能消耗,思考后我把grpc的连接设置成一个全局变量,后来发现这个全局变量有一个问题,在并发情况下,用同一个全局变量会导致读写错误。
  2. 经过思考,我设置了互斥锁的全局变量,但是性能提升不是很明显。
  3. 经过搜索引擎查询资料,最后利用线程池技术,简单工厂设计模式设计出了一个GrpcFactory工厂,每次只需要调用工厂就可以返回连接配合利用grpc的keep-alive使得grpc的连接开销变小。性能测试图如下:

优化前

在这里插入图片描述

优化后

在这里插入图片描述

四、项目总结与反思

4.1目前存在的问题

  1. 聊天记录存储到mysql中可能导致查询聊天记录mysql压力过大
  2. 敏感词过滤要耗费大量内存。

4.2已经识别的优化项

  1. 判断user和video是否存在的时候,可以直接从redis中判断增加速度
  2. 应该将聊天记录缓存到redis中{token:create_time}的形式,因为前端需要不断获取到最晚消息的发布时间
  3. 上传视频进行异步发送,减少用户等待时间优化用户体验。
  4. 因为迭代次数过多,代码冗余过多,代码内容不清晰,应该进行适当的封装和复用。

4.3架构演进的可能性

  1. 分库分表
  2. 做到数据库的读写分离
  3. 我们会在第七届青训营使用Hertz和Kitex重构代码
  4. 使用Minio做对象存储而不是使用七牛云
  5. 准备用机器学习训练模型加快强感词的过滤效果和速度而不是使用普通算法

4.4项目中的反思和总结

  • 代码应该尽可能优雅的写法,让以后的改动是方便的,应该满足开放封闭原则。
  • 一个优秀的程序员应该让别的程序员更好的工作,我的队友给我提供了很多的工具,让我工作更加高效。
  • 测试是一个项目的重点,没有测试的软件是不合格的,而测试的关键则是边界点的问题。
  • 每一个同步的位置都是并发情况下容易发生错误的地方,都要加上互斥锁。
  • 一个项目应该敢为极致,在自己力所能及的地方做到最好,应该尝试多种可能性,寻找最好的解决办法!

五、部署

  1. 安装ffmpeg环境
  2. 改变每个模块中global的mysql连接和redis连接
  3. 改变base-service下的video中的七牛云密匙和仓库名称
  4. Linux下执行命令./run.sh

六、演示视频

【消失的token作品视频】https://www.bilibili.com/video/BV1634y1T71p?vd_source=04ce138fbcd8dc0d65299e3dccf2b3f1


后续迭代

数据库索引的建立

  1. 用户登录接口索引设置
    用户登录接口,要验证用户名和密码的正确性,所以我们给user表的name和password字段加上了联合索引,避免了回表查询。
  2. 视频流接口索引设置
    视频流接口需要查询晚于某一个时间的视频,所以我们在视频的发布时间需要创建索引,同时考虑到了索引失效的问题,对已经有的sql进行优化。
  3. 关注列表索引设计
    我们的关注表是attention,其中字段只有user_id和touser_id,我们在获取关注列表的时候需要对这两个字段进行查询。
  4. 用户的喜欢列表索引
    用户喜欢的列表需要查询favorites表,我们在user_id,video_id创建了idx_favorites_user_video联合索引。
  5. 软删除评论的索引
  • 我们一开始设置软删除的时候是bool类型,但是这样使得索引效率不高,因为字段只有true和false,区分度低。
  • 最后我们设置一个删除的时间,提高了区分度,使得idx_delete_comment索引使用更高效。
  1. 查询评论的索引
    查询评论是根据视频的id查询的,我们在comments表的video_id创建了idx_select_comment_list 索引。

字典树算法实现敏感词过滤

在第七届,我们会使用机器学习训练模型来处理敏感词。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/133813.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】类和对象(中下)

前言: 上一篇文章,我们了解了类的默认成员函数——构造函数、析构函数、拷贝构造函数,这篇我们让我们接着了解。 一、赋值运算符重载: 1.运算符重载: C为了增强代码的可读性引入了运算符重载,运算符重载是…

【Linux从入门到精通】多线程 | 线程互斥(互斥锁)

上篇文章我们对线程 | 线程介绍&线程控制介绍后,本篇文章将会对多线程中的线程互斥与互斥锁的概念进行详解。同时结合实际例子解释了可重入与不被重入函数、临界资源与临界区和原子性的概念。希望本篇文章会对你有所帮助。 文章目录 引入 一、重入与临界 1、1 可…

HTML显示中文空格字符,emsp;一个中文字符,ensp;半个中文字符

&emsp;一个中文字符 &ensp;半个中文字符 <ul><li class"li">姓&emsp;&emsp;名&#xff1a;<input type"text" /></li><li class"li">手&ensp;机&ensp;号&#xff1a;<input type"…

react ant ice3 实现点击一级菜单自动打开它下面最深的第一个子菜单

1.问题 默认的如果没有你的菜单结构是这样的&#xff1a; [{children: [{name: "通用配置"parentId: "1744857774620672"path: "basic"}],name: "系统管理"parentId: "-1"path: "system"} ]可以看到每层菜单的p…

和数集团:我国区块链行业发展具有广阔前景

区块链技术正在引领全球新一轮技术变革和产业变革&#xff0c;推动“信息互联网”向“价值互联网”变迁。 公开资料显示&#xff0c;区块链是一种由多方共同维护&#xff0c;使用密码学保证传输和访问安全&#xff0c;能够实现数据一致存储、难以篡改、防止抵赖的记账技术&…

视频监控/安防监控/AI视频分析/边缘计算EasyCVR平台如何调取登录接口获取token?

安防视频监控管理平台/视频汇聚/视频云存储平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;实现视频资源的鉴权管理、按需调阅、全网分发、云存储、AI智能分析等&#xff0c;视频监控智能分析平台EasyCVR融合性强、…

Gmail邮箱注册情况及最新动态

在中国大陆地区&#xff0c;对于是否可以注册Gmail邮箱一直存在一定的限制和讨论。准确来说&#xff0c;中国大陆地区的用户目前无法直接访问和注册Gmail邮箱。由于某些政策和技术原因&#xff0c;中国政府对于一些外国的网站和服务实施了网络封锁与限制。因此&#xff0c;中国…

地奥“畅依笙”革故鼎新,新品面市! 呵护肠胃 助力大健康!

根据平安健康发布的《2021国民肠道健康调研报告》&#xff0c;肠道问题逐渐年轻化&#xff0c;约90%的国人都会遇到肠道问题。我国肠胃终端产品持续热销&#xff0c;根据2021年淘宝天猫全年益生菌保健品/功能食品市场规模&#xff0c;销售额达63.2亿元&#xff1b;目前益生菌类…

密码学【一】

前言 在区块链的整个体系中大量使用了密码学算法&#xff0c;比如用于 PoW 的哈希算法&#xff0c;用于完整性验证的 Merkle Tree&#xff0c;用于交易签名与验证的数字签名算法&#xff0c;用于隐私保护的零知识证明等等。 可以说密码学是保证区块链安全的基石&#xff0c;而区…

JDK9特性——语法、API的改变

文章目录 语法层次改变钻石操作符号语法升级try结构语法升级下划线命名标识符的使用限制 API层次的改变接口中的私有方法String底层存储结构变化Stream新增4个APIInputStream新增transferTo方法只读集合创建 语法层次改变 钻石操作符号语法升级 钻石操作符&#xff0c;就是我…

css relative 和absolute布局

1、relative和absolute内部的元素都是相对于父容器&#xff0c;若父容器没有指定为relative&#xff0c;则默认为整个文档视图空间&#xff0c;absolute可以重叠元素&#xff0c;relative则不行。relative意味着元素的任意属性如left和right都是相对于其他元素的。absolute则相…

正确理解芯片解密,解除偏见

正确理解芯片解密&#xff0c;解除偏见 电子半导体技术在当今时代如日中天&#xff0c;许多行业都有着它的应用&#xff0c;芯片解密也不例外。那么什么是芯片解密&#xff1f;芯片解密是一种新兴的逆向工程技术&#xff0c;它利用半导体逆向技术来解密加密后的芯片&#xff0c…

华为开源自研AI框架昇思MindSpore应用案例:消噪的Diffusion扩散模型

目录 一、环境准备1.进入ModelArts官网2.使用CodeLab体验Notebook实例 二、案例实现构建Diffusion模型位置向量ResNet/ConvNeXT块Attention模块组归一化条件U-Net正向扩散数据准备与处理采样训练过程推理过程&#xff08;从模型中采样&#xff09; 本文基于Hugging Face&#x…

数据结构入门 — 树的概念与结构

本文属于数据结构专栏文章&#xff0c;适合数据结构入门者学习&#xff0c;涵盖数据结构基础的知识和内容体系&#xff0c;文章在介绍数据结构时会配合上动图演示&#xff0c;方便初学者在学习数据结构时理解和学习&#xff0c;了解数据结构系列专栏点击下方链接。 博客主页&am…

华为云云耀云服务器L实例评测|基于Docker环境快速部署Halo个人博客实操

目录 一、基本介绍 1.1 云耀云服务器L实例介绍 1.2 实操介绍 二、云耀云服务器的购买及基本使用 2.1 服务器购买流程 2.2 初始化连接流程 2.3 系统环境检查 三、Docker中运行Halo 3.1 Halo基本介绍 3.2 Docker的安装 3.3 使用 Docker 镜像创建容器 四、安装初始化H…

《Linux从练气到飞升》No.22 Linux 基础IO

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…

prize_p1

文章目录 解题过程代码审计思路问题解决数组绕过preg_match__destruct的触发修改phar文件以及签名phar://支持的后缀(其他方法) 题解方法一&#xff08;数组绕过&#xff09;方法二&#xff08;gzip绕过&#xff09; 解题过程 源代码 <META http-equiv"Content-Type&q…

谷歌翻译API接口,翻译API接口,翻译API接口申请指南

Google翻译API是一种可以在多个平台上使用的Web服务&#xff0c;通过使用该API&#xff0c;用户可以将任何文本转换成多种语言&#xff0c;同时也可以将多种语言转换成用户指定的语言。目前Google翻译API支持超过100种语言&#xff0c;涵盖了全球范围内的所有主流语言。 Googl…

Linux C 多线程

为什么会有线程? ————————>>>> 进程实现多任务的缺点&#xff1a; 进程间切换的计算机资源开销很大&#xff0c;切换效率非常低进程间数据共享的开销也很大 线程和进程的关系 线程是进程的一个执行单元&#xff0c;是进程内的调度实体。比进程…

在PHP8中对数组进行排序-PHP8知识详解

在php8中&#xff0c;提供了丰富的排序函数&#xff0c;可以对数组进行排序操作。常见的排序函数如下几个&#xff1a;sort() 函数、rsort() 函数、asort() 函数、arsort() 函数、ksort() 函数、krsort() 函数、natsort()函数和natcascsort()函数。 1、sort() 函数&#xff1a;…