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

发布广东建设工程信息网站河北省住房城乡建设局网站

发布广东建设工程信息网站,河北省住房城乡建设局网站,作业设计模板,上海网站建设外包在 go 的 sync 包中#xff0c;有一个 singleflight 包#xff0c;里面有一个 singleflight.go 文件#xff0c;代码加注释#xff0c;一共 200 行出头。内容包括以下几块儿#xff1a; Group 结构体管理一组相关的函数调用工作,它包含一个互斥锁和一个 map,map 的 key 是…在 go 的 sync 包中有一个 singleflight 包里面有一个 singleflight.go 文件代码加注释一共 200 行出头。内容包括以下几块儿 Group 结构体管理一组相关的函数调用工作,它包含一个互斥锁和一个 map,map 的 key 是函数的名称,value 是对应的 call 结构体。call 结构体表示一个 inflight 或已完成的函数调用,包含等待组件 WaitGroup、调用结果 val 和 err、调用次数 dups 和通知通道 chans。Do 方法接收一个 key 和函数 fn,它会先查看 map 中是否已经有这个 key 的调用在 inflight,如果有则等待并返回已有结果,如果没有则新建一个 call 并执行函数调用。DoChan 类似 Do 但返回一个 channel 来接收结果。doCall 方法包含了具体处理调用的逻辑,它会在函数调用前后添加 defer 来 recover panic 和区分正常 return 与 runtime.Goexit。如果发生 panic,会将 panicwraps 成错误返回给等待的 channel,如果是 goexit 会直接退出。正常 return 时会将结果发送到所有通知 channel。Forget 方法可以忘记一个 key 的调用,下次 Do 时会重新执行函数。 这个包通过互斥锁和 map 实现了对相同 key 的函数调用去重,可以避免对已有调用的重复计算,同时通过 channel 机制可以通知调用者函数执行结果。在一些需要确保单次执行的场景中可以使用这个包中的方法。 通过 singleflight 可以很容易实现缓存和去重的效果避免重复计算接下来我们来模拟一下并发请求可能导致的缓存穿透场景,以及如何用 singleflight 包来解决这个问题 package mainimport (contextfmtgolang.org/x/sync/singleflightsync/atomictime)type Result string // 模拟查询数据库 func find(ctx context.Context, query string) (Result, error) {return Result(fmt.Sprintf(result for %q, query)), nil }func main() {var g singleflight.Groupconst n 200waited : int32(n)done : make(chan struct{})key : this is keyfor i : 0; i n; i {go func(j int) {v, _, shared : g.Do(key, func() (interface{}, error) {ret, err : find(context.Background(), key)return ret, err})if atomic.AddInt32(waited, -1) 0 {close(done)}fmt.Printf(index: %d, val: %v, shared: %v\n, j, v, shared)}(i)}select {case -done:case -time.After(time.Second):fmt.Println(Do hangs)}time.Sleep(time.Second * 4) }在这段程序中如果重复使用查询结果shared 会返回 true穿透查询会返回 false 上面的设计中还有一个问题就是在 Do 阻塞时所有请求都会阻塞内存可能会出现大的问题。 此时Do 可以更换为DoChan两者实现上完全一样不同的是DoChan() 通过 channel 返回结果。因此可以使用 select 语句实现超时控制 ch : g.DoChan(key, func() (interface{}, error) {ret, err : find(context.Background(), key)return ret, err }) // Create our timeout timeout : time.After(500 * time.Millisecond)var ret singleflight.Result select { case -timeout: // Timeout elapsedfmt.Println(Timeout)return case ret -ch: // Received result from channelfmt.Printf(index: %d, val: %v, shared: %v\n, j, ret.Val, ret.Shared) }在超时时主动返回不阻塞。 此时又引入了另一个问题这样的每一次的请求并不是高可用的成功率是无法保证的。这时候可以增加一定的请求饱和度来保证业务的最终成功率此时一次请求还是多次请求对于下游服务而言并没有太大区别此时使用  singleflight  只是为了降低请求的数量级那么可以使用 Forget() 来提高下游请求的并发。 ch : g.DoChan(key, func() (interface{}, error) {go func() {time.Sleep(10 * time.Millisecond)fmt.Printf(Deleting key: %v\n, key)g.Forget(key)}()ret, err : find(context.Background(), key)return ret, err })当然这种做法依然无法保证100%的成功如果单次的失败无法容忍在高并发的场景下需要使用更好的处理方案比如牺牲一部分实时性、完全使用缓存查询 异步更新等。
http://www.huolong8.cn/news/278166/

相关文章:

  • 河南做网站公司报价网上商城可行性分析报告
  • 想做一个公司的网站去哪可以做做网站网页的人是不是思维
  • 门户网站维护方案wordpress的密码
  • 化妆品应如何网站建设定位网站建设 天猫 保证金
  • 外贸网站平台有哪些什么是h5网站
  • 网站的佣金怎么做会计分录app网站建设软件
  • 大连市建设工程老网站百度快照和做网站有关系吗
  • 网站内页可以做关键词优化吗怎么开发一个直播app
  • 建设部网站投诉核查企业名单南通网站建设方案开发
  • 网站服务器搭建XP如何给网店做推广
  • 烟台市未成年思想道德建设网站婚纱摄影网页设计
  • 手机wap网站建站系统网站301重定向 权重转移
  • 松山湖网站建设合肥网络推广优惠设想科技
  • 网站开发公司的选择网络营销与推广的概念
  • 电商网站前端源码wordpress 出名主题
  • 网站优化提升速度制作网页一般用什么来设计分割页面
  • 行业网站做不下去网站建站哪家公司好一点
  • 凡科网站建设平台好么大型网站开发经典框架
  • 优秀的定制网站建设制作商展示类网站开发费用
  • 网站建设版面分几页合适网站开发一般用的什么架构
  • 重庆市建设项目环境影响评价网站软件下载网站排行榜前十名
  • 做电力公司网站玛酷机器人少儿编程加盟
  • dw做的网站如何让文字换行dedecms视频网站模板
  • 如何建立网站数据库连接公众号登录手机版
  • 建设标准 免费下载网站企业logo设计合同
  • 保定企业免费建站wordpress 语言选择器
  • 企业网站建设成本费用有和wind一样做用网站
  • 做知识产权相关的网站宁波网站建设兼职
  • 网站建设什么打王思聪网站返利二维码怎么做
  • 还有用asp做网站的吗网站开发蓝云