一次超时事件的排查

背景

生产环境中,调用公司封装的kms服务进行解密,偶报超时错误。但是看接口实际耗时只有100多ms。

一开始怀疑是errgroup中的ctx用错了,导致cancel掉了请求。后面确认以后发现不是。

最后查看基础框架封装的源码,默认的请求超时时间被设置成了30ms,真是气死。

当时有两个模块,一个是模块是对端接口,gateway会在ctx里面设置deadline,然后向下传递,这个模块没报错,因为ctx里面有deadline了,就没有用client设置的timeout
    if _, ok := ctx.Deadline(); ok {
        return next
    }

另一个模块是消费kafka回调函数里面的ctx,这个ctx里面没有设置deadline,所以会用client的timeout

grpc-go如何实现超时

通过下面的代码,可以看到grpc-go是通过context实现超时控制的。

import (
    "context"
    "time"

    pb "example.com/example.protobuf"
    "google.golang.org/grpc"
)

func main() {
    // 假设已经设置了连接和客户端
    conn, _ := grpc.Dial("your_grpc_server_address", grpc.WithInsecure()) // 使用实际的连接参数替换
    client := pb.NewYourServiceClient(conn)

    // 设置超时
    timeout := 3 * time.Second
    ctx, cancel := context.WithTimeout(context.Background(), timeout)
    defer cancel()

    // 使用带超时的 context 进行 gRPC 调用
    req := &pb.YourRequest{} // 使用实际的请求结构体替换
    resp, err := client.YourMethod(ctx, req)
    if err != nil {
        // 处理错误,可能是超时导致的
    }
    // 如果调用成功,处理响应
}

基础框架如何把timeout参数和grpc-go的超时机制整合

通过grpc的拦截器【只需要几个拦截器,把拦截器做成自定义hook的形式,方便添加更多的业务逻辑】,在发送请求前,读取请求里面的timeout参数,通过context.WithTimeout注进context来实现超时控制。

通过ctx注进去,然后请求前拿出来设置上去

func WithClientConfig(ctx context.Context, conf settings.ClientConfig) context.Context {
    return context.WithValue(ctx, clientConfigKey{}, conf)
}

设置timeout

func withTimeout(ctx context.Context, next func(context.Context) error) func(context.Context) error {
        //如果是stream类的rpc,则不许呀设置超时
    if rpc.IsStream(ctx) {
        return next
    }

        //如果context自己设置了超时,就不读配置里面的timeout参数去设置context了
    if _, ok := ctx.Deadline(); ok {
        return next
    }

    var timeout int64

    conf := grpcclient.GetClientConfig(ctx)

    timeout = conf.Timeout
    if timeout <= 0 {
        timeout = defaultTimeout
    }

    return func(ctx context.Context) error {
        ctx, cancel := context.WithTimeout(ctx, time.Duration(timeout)*time.Millisecond)
        defer cancel()
        return next(ctx)
    }
}

kms客户端缓存优化

kms客户端可以设置两个缓存,一个是加密的缓存,一个是解密的缓存。

根据uid后2位取模,设置加密的缓存,缓存过期时间为1小时。相同uid后缀的消息,在1小时以内都用相同的密钥加密。过期以后,重新去获取密钥,后面1小时的,又用另外一个密钥加密。

加密获取密钥对以后,把解密的密钥缓存下来,过期时间设置为24小时。这样,新发的消息,在24小时内被拉取,都不需要请求kms去解密,走缓存即可。

效果:加密密钥小时级别变化,解密大概率走缓存,性能好。即保证了安全性,又保证了性能。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • 为什么需要超时控制? 很多连锁故障的场景下的一个常见问题是服务器正在消耗大量资源处理那些早已经超过客户端截止时间的...
    kevwan阅读 637评论 0 5
  • 1、事件还原 昨天下午,收到一个504的告警,显然这是一个超时告警。当时由于手头有其他事情,没在意,就只是瞄了一眼...
    Jackie_Zheng阅读 957评论 0 3
  • 原创文章,转载请务必将下面这段话置于文章开头处(保留超链接)。本文转发自[董泽润 blog],不允许修改题目及内容...
    董泽润阅读 4,662评论 1 7
  • 在工程化的Go语言开发项目中,Go语言的源码复用是建立在包(package)基础之上的。本文介绍了Go语言中如何定...
    雪上霜阅读 241评论 0 0
  • 大家好,我是杜欢,很荣幸能代表滴滴来做分享。我来滴滴的第一件事情就是帮助公司统一技术栈,在服务端我们要把以前拿 P...
    中v中阅读 1,752评论 0 25