旧架构
新架构
cookie和session的区别
cookie和session的联系
chrome抓包查看 // TODO
普通登录场景下cookie和session的配合使用流程
参考附录1,2
Q: base64最开始的功能
A:
Q: 为什么要使用base64编码,有哪些情景需求?
A: 有2个场景不能传输二进制
1. user_controller.go
登录接口的后端实现。本来登录成功后往只cookie写入了uid字段,为了防止uid被篡改,往cookie中写入了一个验证uid是否被篡改的sign字段。
2. auth.go
验证用户是否登录的中间件。验证uid是否存在。代码不变。
分布式架构
从原理部署在一个机器的一个进程中,改为部署到多个机器的不同进程中。
拆分后的构成: 权限验证(水平扩容)+数量控制(水平扩容)+web服务器+消息队列+mysql
单独部署
. 验证代码从代码中提取处理单独部署
Q: 我们这里为什么需要一致性hash算法
A: 一致性hash算法的主要应用场景是 分布式存储,分布式缓存, 负载均衡。我们这里属于分布式缓存这类应用,注意我们并没有用redis,而是用的内存缓存,每个机器存放不同的用户信息缓存。
数据存储需求: 每台机器(进程)存放uid及其请求时间。比如uid=1,2,3缓存在机器1,uid=4,5,6缓存在机器2,那么uid=1请求机器2时就会去机器1的缓存上去拿数据(内网)
//创建结构体保存一致性hash信息
type Consistent struct {
//hash环,key为哈希值,值存放节点的信息 // TODO k: 请求key或节点的hash值 v: 真实节点或虚拟节点信息(如果有2个真实节点,每个节点20个虚拟节点,那么一共有20个v需要存储,环上其他位置并不需要存放数据)
circle map[uint32]string
//已经排序的节点hash切片 // TODO 排好序的虚拟节点hash值,40个元素,对应2个v。
sortedHashes units
//虚拟节点个数,用来增加hash的平衡性
VirtualNode int
//map 读写锁
sync.RWMutex
}
//设置集群地址,最好内网IP
var hostArray = []string{"192.168.0.1", "192.168.0.2"}
var localHost = "192.168.0.1"
// 创建Consistent结构体
hashConsistent = common.NewConsistent()
// 添加服务器节点
for _, v := range hostArray {
hashConsistent.Add(v)
}
// 作为缓存的结构体
type AccessControl struct {
//用来存放用户想要存放的信息
sourcesArray map[int]interface{}
sync.RWMutex
}
假设使用redis保存商品数量
redis瓶颈原理
redis单机qps 8w。
redis集群qps 整体千万, 但是对单个商品而言也是8w。
突破方法
不用redis保存商品数量,而是直接写在代码,这样只访问go接口,不访问redis和数据库。
测试结果:24w的qps。
wrk
wrk参数和输出结果
修改fronted/web/controllers/product_controller.GetOrder方法
原有方法对数据访问压力很大,每调用一次创建一个订单就要访问几次数据库。
新方法:
channel.Qos
rabbimq相关代码实现
product_controller.go: 在下单接口GetOrder()中生产消息(消息结构体有2个字段: userId+productId)
consumer.go :消费者。流量控制(channel.Qos设置1次取1个消息),手动确认后删除消息 (消费成功,调用msg.Ack(false)使得rabbitmq删除该消息 // TODO 消费失败应该怎么处理)
当前代码存在的问题
没有事务(商品数量减1+生成订单)
原文:https://www.cnblogs.com/yudidi/p/12518529.html