参考视频:
Web架构设计的演进
Web架构设计总结
GoWeb网站优化——mysql&redis&CDN&OSS&Nginx&分布式session验证&rabbitMQ&秒杀&安全优化
0 总结
1 架构与查询流程
2 并发优化——数据层优化1
数据库设计与查询优化
2.0 为什么慢查询
- 数据量大
- 变化量大,数据承载能力低,响应不及时
2.1 表结构设计
2.1.1 范式与反范式
2.1.2 表结构与数据类型的优化
- 表拆解的粒度和表信息的便捷性
- 取小子段、短子段,简单子段
- 避免过多的子段
- 不易拆的太碎
- 避免关联查询
2.2 索引优化
2.2.1 建立索引
2.2.2 独立索引&多列索引
2.3 查询优化
2.3.1 切分查询,limit重要性
2.3.2 分解复杂的关联查询
将多个jion查询分解为多个简单查询,将结果合并
3 并发优化——数据层优化2
Go读书社区web开发与高性能架构优化
MySQL的分片分表分库分区
3.1 池化 数据库连接池
golang sql连接池的实现解析
借Go语言database/sql包谈数据库驱动和连接池设计
3.2 主从读写分离
主从复制
ubuntu18.04上基于Docker搭建MySQL主从复制
读写分离
代码实现
- 增删改采用写主库
- 查询采用读从库
3.3 分表
分表经验:
MySQL数据库表如何水平拆分和垂直拆分
数据库拆分:垂直拆分与水平拆分六大原则
3.3.1 水平分表
步骤:
通过取模或者哈希取模,差分拆分多个结构相同的表。
- 如图,按照book_id拆分:
- 取模分表
- 重构代码,通过取模,之前的sql语句返回不同的表
3.3.2 垂直分表
把常用字段建立一张,不常用的建立一张
Mysql的垂直分表-新建
3. 4 分库
- 将较为独立,耦合性不高的属性拆到另一个数据库,减少数据库读取的压力
- 把不同业务逻辑的表分开存储在在不同的数据库。
3.5 搜索模块接入Elastisearch
4 并发优化之缓存层优化
4.1 页面静态化
- os库的openfile函数生成静态html文件
go页面静态化
Go实现页面静态化
页面缓存优化(页面静态化和动态缓存)
大型网站的页面静态化
静态化的实现方式
前后端分离就不用静态化
页面静态化与伪静态化
4.2 动态缓存
- 页面静态化存储在磁盘
- 动态缓存存在内存,所以有节制的使用内存空间
4.3 go实现redis
redigo操作
GoRedis连接池
golang开发:类库篇(二) Redis连接池的使用
Go的json解析:Marshal与Unmarshal
- 对struct、list、string数据进行缓存
- 将对应类型json.marshal编码,再以string类型作为k_value保存到redis
- 读取时,可以采用传入引用,读取key对应的value,unmarshal解码成数据,存入引用类型。
- 在具体存储中,如我们查询图书详情,则首先往redis读key,不存在则err=nil,此时从新从mysql读,然后再写入redis,如图
4.4 CDN&OSS 下载优化
- 就近拉取文件
- 后端,页面层面的静态化缓存,基于数据层的redis动态缓存
- oss看做服务器网盘
4.4.1 ESC
4.4.2 OSS
- CDN 源站,如果cdn没有资源,则到oss上拉取
4.4.3 CDN
- 解析CDN域名
- 配置CDN回源OSS
4.4.4 go操作oss中的bucket
- 设定获取oss的配置信息
- go初始化oss
- 通过配置信息,go获取oss上的bucket
正式运行:
- 通过获取oss上的bucket,将本地图片等资源上次至oss
- 也可将html中图片路径改为oss上存储的url
- 通过cdn绑定的域名即可回源到oss上获取图片
使用阿里云OSS+CDN部署前端页面与加速静态资源
阿里云 CDN+Oss 解决方案
- 图书的详情页资料显示,为静态资源html,部署到oss
- 直接进入oss显示,文件下载,需要绑定自定义域名,则变为数据显示或者页面显示
https://help.aliyun.com/knowledge_detail/39656.html - 也可以cdn为ip加速,直接到web服务器
5 并发优化之服务层优化
5.1 Nginx
统一域名转到负载均衡服务器
- 反向代理、负载均衡、动静分离
用户请求->Nginx反向代理服务器->负载均衡到多个go服务器
5.2 分布式session验证
- goweb读书社区: 将session存入redis,注销则清除缓存
- go秒杀:session通过ase加密,将加密结果存入cookie,每次验证,cookie中的加密串经过解密,是否与数据库存储的session相同,判断用户。
6 秒杀
- 基于一致性哈希的分布式权限验证
- 判断数量接口,验证是否超卖
- 通过http响应码,判断是否有权限购买,并获取cookie中的order与user,并将该信息publish进消息队列
- 消息队列设置为simple,消费一个手动应答一个,防止爆库;使用锁防止多个隧道被强占,使用互斥锁,加锁解锁,保证当前channel被一个进程所使用(我的理解,你还没生产完就被另一个并发请求占用)(channel会出现资源抢占的情况,通过加锁)
- 从队列取出一个,生成订单,并在数据库中减少商品数量
- 完成秒杀
7 安全优化
- html限流: 前段未登录-跳转登陆-每买一次,购买按钮灰色5秒,并显示购买冷却倒计时-计时结束,显示按钮
- 黑名单设置:比如每个用户限购10个,可以计数10个之后,将该用户购买加入黑名单;每次购买前先检查用户是否在黑名单里
- 防止for循环请求:检查用户不在黑名单,则可以购买,每次购买,冷却5s才能继续购买等
- 添加图像验证码
- 漏桶限流
- 令牌限流
- 限定时间段进行秒杀(非秒杀时间则灰色按钮)
- 非限定时间,进制服务请求等等