当前位置: 首页 > news >正文

Golang实现Redis分布式锁解决秒杀问题

先写一个脚本sql,插入2000个用户

INSERT INTO sys_users (mobile, password)
SELECT numbers.n AS mobile,'$2a$10$zKQfSn/GCcR6MX4nHk3MsOMhJnI0qxN4MFdiufDMH2wzuTaR9G1sq' AS password
FROM (SELECT ones.n + tens.n*10 + hundreds.n*100 + thousands.n*1000 + 1 AS nFROM (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) onesCROSS JOIN (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) tensCROSS JOIN (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) hundredsCROSS JOIN (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) thousandsORDER BY n) numbers
LIMIT 2000;

登录是通过2个字段,一个是mobile,一个是password,生成了mobile从1到2000,密码默认是123456

然后写一个单元测试,实现新注册的2000个用户登录,然后获取token

package systemimport ("encoding/json""fmt""io/ioutil""net/http""os""strings""sync""testing""time"
)func TestBaseApi_TokenNext(t *testing.T) {start := time.Now()var wg sync.WaitGroupch := make(chan string, 2000)for i := 1; i <= 5; i++ {fmt.Println(i)wg.Add(1)mobile := fmt.Sprintf("%d", i)password := "123456"go obtainToken(mobile, password, &wg, ch)}wg.Wait()close(ch)fmt.Println("All tokens obtained:")//tokens := ""i := 0for token := range ch {fmt.Println(i, token)i++err := AppendStringToFile("E:\\Go\\goproject\\LearnExam\\sever\\token.txt", token)if err != nil {fmt.Println(err)}}end := time.Now()latency := end.Sub(start)fmt.Println(fmt.Sprintf(" takes %v", latency))
}
func AppendStringToFile(filePath string, content string) error {file, err := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)if err != nil {return err}defer file.Close()_, err = file.WriteString(content + "\n")if err != nil {return err}return nil
}
func obtainToken(mobile, password string, wg *sync.WaitGroup, ch chan string) {defer wg.Done()type Body struct {Mobile   string `json:"mobile"`Password string `json:"password"`}b := Body{mobile, password,}bodymarshal, err := json.Marshal(&b)if err != nil {return}//再处理一下reqBody := strings.NewReader(string(bodymarshal))req, err := http.NewRequest("POST", "http://127.0.0.1:8888/api/base/login", reqBody)if err != nil {fmt.Printf("Error creating request for user %s: %v\n", mobile, err)return}req.Header.Add("Content-Type", "application/x-www-form-urlencoded")resp, err := http.DefaultClient.Do(req)if err != nil {fmt.Printf("Error sending request for user %s: %v\n", mobile, err)return}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body) //把请求到的body转化成byte[]if err != nil {return}type Result struct {Data struct {Token string `json:"token"`} `json:"data"`}r := Result{}err = json.Unmarshal(body, &r)if err != nil {return}if resp.StatusCode == http.StatusOK {ch <- r.Data.Tokenfmt.Printf("Token obtained for user %s\n", mobile)} else {fmt.Printf("Failed to obtain token for user %s\n", mobile)}}

我们使用有缓冲的通道和sync.WaitGroup信号量,来控制协程的数量在2000个以内

http://www.lryc.cn/news/112620.html

相关文章:

  • 狂神说-通俗易懂的23种设计模式
  • VR实景导航——开启3D可视化实景导航新体验
  • 《HeadFirst设计模式(第二版)》第四章代码——工厂模式
  • 拖拽宫格vue-grid-layout详细应用及案例
  • sanyo三洋摄像机卡有部分坏块恢复案例
  • 【C++】STL——set和map及multiset和multiset的介绍及使用
  • 帕累托森林:IEEE Fellow唐远炎院士出任「儒特科技」首席架构官
  • 数据库大数据
  • 骨传导耳机是怎么工作的?骨传导耳机是智商税产品吗?
  • Java电子招投标采购系统源码-适合于招标代理、政府采购、企业采购、等业务的企业tbms
  • 算法-合并区间
  • 布基纳法索ECTN(BESC)申请流程
  • CDN安全面临的问题及防御架构
  • 【MySQL】MySQL管理 (十四)
  • Mybatis:一对一查询映射处理
  • 九、用 ChatGPT 提高算法和编程能力
  • 【数模】主成分分析PCA
  • 全志F1C200S嵌入式驱动开发(从DDR中截取内存)
  • C++中点云聚类算法的实现与应用探索
  • 大数据Flink(五十六):Standalone伪分布环境(开发测试)
  • Godot 4 源码分析 - 碰撞
  • 前端面试经典算法题
  • ospf减少LSA更新
  • 万字长文解析深度学习中的术语
  • 冠达管理投资前瞻:三星加码机器人领域 大信创建设提速
  • 24届近5年上海交通大学自动化考研院校分析
  • 【PDF密码】PDF文件不能打印,为什么?
  • LeetCode-Java(03)
  • 【Linux命令行与Shell脚本编程】第十六章 Shell函数
  • SpringCloud-Hystrix服务熔断与降级工作原理源码 | 京东物流技术团队