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

平昌网站建设潍坊+网站建设

平昌网站建设,潍坊+网站建设,类似互推商盟的推广平台,做汽配网站文章目录 前言起因#xff1a;日志告警引发的思考什么是contextcontext的作用context超时之后继续执行 or 中断 最后 前言 公司运行的服务代码中#xff0c;随处可见各种各样的日志信息#xff0c;其中大多数是用来记录各种异常的日志#xff0c;一方面#xff0c;当出现… 文章目录 前言起因日志告警引发的思考什么是contextcontext的作用context超时之后继续执行 or 中断 最后 前言 公司运行的服务代码中随处可见各种各样的日志信息其中大多数是用来记录各种异常的日志一方面当出现问题时通过日志我们可以快速的定位引发问题的原因另外我们可以通过日志平台对一些错误级别比较高的日志进行监控从而能够快速响应系统可能会出现的问题。 起因日志告警引发的思考 虽然日志告警很有用但如果告警次数过于频繁反而会降低开发人员对于系统异常的敏感度使得告警变得毫无意义。因此我们需要对告警进行治理。最近由于一次治理线上频发的超时告警使得笔者开始思考起context deadline exceed异常的问题。 什么是context 在Go语言中Context是一个非常重要的概念它存在于一个完整的业务生命周期内Context类型是一个接口类型它定义了四个方法Deadline()、Done()、Err()和Value()。其中Deadline()方法返回context的截止日期Done()方法返回一个只读的channel当Context被取消或超时时该channel会被关闭Err()方法返回Context被取消的原因Value()方法返回Context中与key相关联的值。 context的作用 在实际应用中我们可以使用Context包来传递请求的元数据例如请求ID、超时信息等等。此外我们还可以使用context包来控制goroutine的生命周期最常见的例如在HTTP请求处理程序中我们可以使用context包来取消正在处理的请求。 可以说我们的服务里随处可见携带context参数的方法。 context超时之后 先来看一段例子 package mainimport (contextfmttime )func timeConsuming(ctx context.Context, costTime int) {ctx.Done()for i : 1; i costTime; i {// 模拟一些耗时操作time.Sleep(1 * time.Second)fmt.Printf(协程正在运行第%v次...\n, i)} }func main() {// 创建一个父级 context设置超时时间为 5 秒钟parentCtx, cancel : context.WithTimeout(context.Background(), 10*time.Second)defer cancel()// 创建一个子级 context用于控制协程childCtx, childCancel : context.WithCancel(parentCtx)defer childCancel()costTime : 5 // 模拟耗时 5 秒钟// 启动一个协程go func(ctx context.Context) {for {select {case -ctx.Done():// 如果收到取消信号退出协程fmt.Println(协程退出)returncase -time.After(15 * time.Second):fmt.Println(协程超时)default:timeConsuming(childCtx, costTime)}}}(childCtx)// 等待 3 秒钟然后取消子级 contexttime.Sleep(3 * time.Second)fmt.Println(取消协程)childCancel()// 继续等待 3 秒钟模拟主协程的一些其他操作time.Sleep(3 * time.Second)fmt.Println(主协程退出) }上面代码的执行结果如下 协程正在运行第1次... 协程正在运行第2次... 取消协程 协程正在运行第3次... 协程正在运行第4次... 协程正在运行第5次... 协程退出 主协程退出虽然说Context可以用来管理goroutine但是可以看到Context超时之后goroutine仍然在执行完成之后才会退出Context无法真正做到强制杀死goroutine 回到文章最开始提到的线上超时告警频发的问题经过排查我们发现一波超时告警的出现实际上只是几条请求引起的都是同一个trace_id。究其原因是我们下游的服务在单次业务请求中会与很多第三方接口发生交互在本篇文章的case是并发调用redis而在业务执行到并发调用redis之前业务逻辑就已经发生了超时。 超时后上游调用端不再继续等待响应直接返回了超时异常。 前面已经提到过goroutine是无法强制杀死的此时goroutine携带着已经超时的context依旧在执行着业务逻辑在执行到并发调用redis时由于context已经超时调用无一例外的全部抛出超时错误实际上并未真正发生调用redisredis客户端代码在调用前判断了context的状态, 从而导致个位数的超时请求却引起了大量日志的超时告警。 ... //If Done is not yet closed, Err returns nil. // If Done is closed, Err returns a non-nil error explaining why: // Canceled if the context was canceled // or DeadlineExceeded if the contexts deadline passed. // After Err returns a non-nil error, successive calls to Err return the same error. if ctx.Err() ! nil { // 这里抛出了context deadline exceeded 异常return nil, ctx.Err() } ...继续执行 or 中断 知道了问题其实处理起来就比较容易了我们将context的状态的判断改写到了合适的位置在一些耗时的节点之间判断了context的状态如果判断超时则直接结束后续的业务流程 日志告警清净了 但是这样的处理方式具有普适性吗可以思考一下在某些超时的情况中即便上游已经返回了超时异常我们仍然希望下游能够将这次业务完整的执行完。 举一个例子下游在执行完返回之前会将本次执行的结果进行缓存。而上游在调用下游之前也会去取缓存取到了就直接返回假设上下游服务共用一套缓存集群。假如某些请求耗时比较久而且我们在判断请求超时之后直接中断下游任务的执行那么缓存将永远不会生成上游后续的调用依旧会超时。这种情况下即便是超时了我们也希望下游任务能够完整执行并生成缓存后续上游就可以直接拿到业务结果返回避免大量耗时的调用。 最后 本篇描述的本身是一个极为常见的问题及处理方案。但是在平时处理问题的过程中如果勤加思考仍然会有所收获和提升。 提个题外话现在是2023年5月21日今年或许从去年开始的形势确实不太好。小伙伴们或多或少能够感受到就业形势的严峻有前同事因各种各样的原因10个月没有找到新工作。越是这样的情况下越是要好好打磨提升自己以应对未来的艰难险阻 共勉之
http://www.dnsts.com.cn/news/263304.html

相关文章:

  • 注册网站名称西安黄页88网企业名录
  • 网站开发w亿玛酷1专注免费网站商城模板
  • 个人做流量大的网站网站备案网站前置审批
  • 做网站最小的字体是多少钱百度为什么不收录网站的某个版块
  • 个人建站项目黄冈市建设银行网站
  • logo模板下载网站推荐无锡网站建设价格费用
  • 网页设计网站模板素材网站建设财务上做什么费用
  • 做安利能开个人网站怎么做宣传
  • 电商网站设计教程报价表
  • 做个外贸网站大概多少钱金塔精神文明建设网站
  • 教育网站建设毕业设计说明书做720全景好的网站
  • 建设农产品网站的背景深圳最新项目
  • 设计公司 网站新2代理网址
  • 古腾堡布局的网站房产中介网站开发模板
  • 网站营销教程网站建设的主要流程步骤
  • 网站源码大全免费公众号登录微信公众号登录
  • 石家庄网站建设推广报价wordpress获取php变量给模板
  • 小型企业建站公司asp网站后台管理系统下载
  • 上海建设小学网站高质量免费的网站
  • 长春网站排名优化公司提供网站空间服务器
  • 微商城网站建设信息换友网站
  • 网站内容页设计网站开发感受
  • 网站好做吗甘肃省作风建设年活动有网站
  • 赣州网站推广公司网站建设需求有哪些
  • 厦门商场网站建设专业电商网站开发
  • 免费建站免费网站申请松原网站建设公司
  • 免费下载网站软件商圈数据app
  • 济宁网站建设的公司哪个网站可以做加工
  • 门户网站设计要求ui设计介绍
  • 威海西郊建设集团网站国内域名注册平台