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

百度站长平台官网男的如何自己解决生理问题

百度站长平台官网,男的如何自己解决生理问题,宜宾市建设工程质量监督站网站,网站建设技术主管go 语言以高并发著称。那么在实际的项目中 经常会用到锁的情况。比如说秒杀抢购等等场景。下面主要介绍 redis 布式锁实现的两种高并发抢购场景。其实 高并发 和 分布式锁 是一个互斥的两个状态#xff1a; 方式一 setNX#xff1a; 使用 redis自带的API setNX 来实现。能解决… go 语言以高并发著称。那么在实际的项目中 经常会用到锁的情况。比如说秒杀抢购等等场景。下面主要介绍 redis 布式锁实现的两种高并发抢购场景。其实 高并发 和 分布式锁 是一个互斥的两个状态 方式一 setNX 使用 redis自带的API setNX 来实现。能解决高并发场景下的 绝大多数场景待优化点 锁的续命 和 等待锁 的实现。实现流程 redis setNX 设置键值。如果 键存在则返回 false 反之则为 true使用 setNX 来设置一个键值值为当前协程设置的随机值。当程序运行完成之后 删除该键值  这里只有当减库存成功 抢购流程成功 则返回 410。其余失败则返回 200.  这样就能通过返回码  很容易看到成功抢购的数量 我么使用 postman 模拟 1600 用户点击 十分钟。库存为 一个亿。 // redis分布式锁 方式1自己动手 // 该方案可以解决大多数场景中的 redis 锁的问题 // 还剩余一个 锁续命的问题 极高并发下的微小概率事件 func redisLock_0(c *gin.Context) {// 实现逻辑// 1 先用商品ID为 key, uuid为值, 这一步是防止别人把自己的锁删除// 2 用SetNX 设置一个键值 锁住一个商品并设置超时时间。 当 SetNX key 存在则 返回false, 反之为 truerdb : Rdb()lockKey : product_001newUUID : uuid.New()// 只能删除锁 并切判断是不是自己的锁只有自己的锁才会删除defer func() {keyValue, err : rdb.Get(ctx, lockKey).Result()if err ! nil {fmt.Println(keyValue error:, keyValue, err)c.JSON(http.StatusOK, gin.H{message: 获取锁失败,})return}if keyValue newUUID.String() {rdb.Del(ctx, lockKey)}}()//设置锁30秒过期只有当锁不存在时才会成功设置//设置时间是为了 防止特殊情况所没有成功释放。success, err : rdb.SetNX(ctx, lockKey, newUUID.String(), time.Second*30).Result()if err ! nil {fmt.Println(Error setting lock: %v, err)c.JSON(http.StatusOK, gin.H{message: 设置锁单出错,})return}// 判断是否成功获得锁if success {fmt.Println(Successfully acquired lock:, newUUID)// 执行需要锁保护的操作 获取真实的 库存count, err : strconv.Atoi(rdb.Get(ctx, product_count).Val())if err ! nil {fmt.Println(Error getting product count: %v, err)c.JSON(http.StatusOK, gin.H{message: Error getting product count,})return}if count 1 {stock : count - 1err : rdb.Set(ctx, product_count, strconv.Itoa(stock), 0).Err()if err ! nil {fmt.Println(Error setting product count: %v, err)c.JSON(http.StatusOK, gin.H{message: Error setting product count,})return} else {fmt.Println(减库存操作成功 现在库存为: %v, stock)c.JSON(http.StatusGone, gin.H{message: Hello, World!,})return}} else {fmt.Println(库存为 0 )c.JSON(http.StatusOK, gin.H{message: Hello, World!,})return}} else {///没有获得锁 可以做延迟 轮询处理fmt.Println(Failed to acquire lock. The key already exists.)c.JSON(http.StatusOK, gin.H{message: Hello, World!,})return} } 经过十分钟我们看下数据 该方案整体数据 一共请求了 534,979 次并发 877成功销售 280,367 个商品 即返回值为 410的个数。 方式二 redisson: 使用  go-redisson 库这个 类似 java redisson: go-redisson command - github.com/paceew/go-redisson - Go Packageshttps://pkg.go.dev/github.com/paceew/go-redisson 该方案使用起来就很简单了 我们来测试一样的数据 func redisLock_1(c *gin.Context) {//获取一个锁对象mutex : RedSon().NewMutex(godisson)//尝试加锁 并且设置超时时间和等待时间//如果加锁失败 会阻塞等待或超时 或 加锁成功err : mutex.TryLock(20000, 20000)if err ! nil {log.Println(cant obtained lock)c.JSON(http.StatusOK, gin.H{message: Error cant obtained lock,})return}defer func(mutex *godisson.Mutex) {_, err : mutex.Unlock()if err ! nil {log.Println(cant obtained lock)c.JSON(http.StatusOK, gin.H{message: Error1 cant obtained lock,})}}(mutex)// 执行需要锁保护的操作 获取真实的 库存count, err : strconv.Atoi(rdb.Get(ctx, product_count).Val())if err ! nil {fmt.Println(Error getting product count: %v, err)c.JSON(http.StatusOK, gin.H{message: Error getting product count,})return}if count 1 {stock : count - 1err : rdb.Set(ctx, product_count, strconv.Itoa(stock), 0).Err()if err ! nil {fmt.Println(Error setting product count: %v, err)c.JSON(http.StatusOK, gin.H{message: Error setting product count,})return} else {fmt.Println(减库存操作成功 现在库存为: %v, stock)c.JSON(http.StatusGone, gin.H{message: Hello, World!,})return}} else {fmt.Println(库存为 0 )c.JSON(http.StatusOK, gin.H{message: Hello, World!,})return} }   该方案整体数据 一共请求 528,686并发 868成功销售 343,381 个商品  即返回值为 410的个数。应该是实现了锁等待。所有这个方案比自己实现的抢购 要高。 如何提高吞吐 优化性能问题  分段锁 分段锁的核心思路就是之前的方案都是一个锁处理所有请求。这里呢 开十把锁。那吞吐性能不就 快了 十倍了麽。那么我们就采用redisson 来做十把分段锁 把一个亿的商品库存分成1千万的 十份。然后用 十把锁。这样 func redisLock_2(c *gin.Context) {rand.Seed(time.Now().UnixNano())// 生成包含0和9的随机数num : rand.Intn(10)mutexKey : godisson_ strconv.Itoa(num)product_key : product_count_ strconv.Itoa(num)//获取一个锁对象mutex : RedSon().NewMutex(mutexKey)//尝试加锁 并且设置超时时间和等待时间//如果加锁失败 会阻塞等待或超时 或 加锁成功err : mutex.TryLock(20000, 20000)if err ! nil {log.Println(cant obtained lock)c.JSON(http.StatusOK, gin.H{message: Error cant obtained lock,})return}defer func(mutex *godisson.Mutex) {_, err : mutex.Unlock()if err ! nil {log.Println(cant obtained lock)c.JSON(http.StatusOK, gin.H{message: Error1 cant obtained lock,})}}(mutex)// 执行需要锁保护的操作 获取真实的 库存count, err : strconv.Atoi(rdb.Get(ctx, product_key).Val())if err ! nil {fmt.Println(Error getting product count: %v, err)c.JSON(http.StatusOK, gin.H{message: Error getting product count,})return}if count 1 {stock : count - 1err : rdb.Set(ctx, product_key, strconv.Itoa(stock), 0).Err()if err ! nil {fmt.Println(Error setting product count: %v, err)c.JSON(http.StatusOK, gin.H{message: Error setting product count,})return} else {fmt.Println(减库存操作成功 现在库存为: %v, stock)c.JSON(http.StatusGone, gin.H{message: Hello, World!,})return}} else {fmt.Println(库存为 0 )c.JSON(http.StatusOK, gin.H{message: Hello, World!,})return} }  无超卖情况 测试结果如下 一共请求 523,418并发 858成功销售 404,238 个商品  即返回值为 410的个数 如此看不知道是我 单台机器性能跑满了测试不准确还是其他原因。并没有十倍的性能提升。
http://www.hkea.cn/news/14312484/

相关文章:

  • 网站服务器备案查询网站备案珠江新城网站建设
  • 手机网站设计小程序拿网站的文章做外链
  • 淘宝找做网站wordpress无域名
  • 网站建好了怎么做才赚钱wordpress随机幻灯片
  • 网站怎么自动加水印防伪码做网站的还能没导入吗
  • 营销网站怎样做网站建站平台广告
  • 营销型网站首页模板网站名称怎么起
  • 网站站内链接怎么做网站内容为王
  • 多城市网站开发flash网站代做
  • 常州哪些网站公司做的好一微网站建设公司
  • wordpress 下载站wordpress旅游插件
  • 一分钟建站seo为什么不景气了
  • 广饶网站制作网站建设招标书范本
  • 东庄水利建设公司网站电子商务网站设计流程
  • 北京网站建设itcask企业展示型网站
  • 网站免费推广方法现在做个网站要多少钱
  • 一级a做爰片免费网站中文php网站怎么做自适应
  • 优秀的电商设计网站有哪些内容四川建设网专家库
  • 京东物流网站网络科技有限公司注册资金最低
  • 网站的栏目和版块设计的原则济南企业制作网站
  • 自己想做个网站 费用宁波网站建设按需定制
  • 知道源码做网站西安网易网站建设
  • 电视剧下载网站 免费糖醋蒜怎样做网站优化塔山双喜
  • 微信对接网站群网站策划步骤
  • 用asp.net做的网站模板下载建立网站站点
  • 微信怎么设计分享网站拉新平台
  • 西湖区外贸网站建设手机网站定制建设
  • 手机图片网站模板网站静态和动态区别是什么
  • 个人能建设网站吗王也高清壁纸第三季
  • 好看欧美视频网站模板下载 迅雷下载地址如何建立一个自己的网站啊