V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
woduzibue
V2EX  ›  程序员

spring cloud 服务调用 问题排查 解决方法求教

  •  
  •   woduzibue · 2021-12-08 10:00:39 +08:00 · 2094 次点击
    这是一个创建于 1063 天前的主题,其中的信息可能已经有所发展或是发生改变。
    C 服务通过网关 调用 A 服务,A 服务(更新数据库后)调用 B 服务,A 服务部署了两个节点。现在 B 服务 log 里面发现 [同一时间点] 有两条 A 服务参数一样的请求导致异常了,求教解决方法

    从 A 服务源头来看有什么方法可以在 A 服务 避免发出 两个一样的请求么?有没有可能是因为网关问题导致 A 服务两个节点同一时刻发出了两个相同的请求。
    我考虑下来 1. redis 锁 2.mysql 行锁,一般使用哪种方法多一点 有什么优劣
    求大佬指教
    20 条回复    2021-12-08 17:52:58 +08:00
    Kyle18Tang
        1
    Kyle18Tang  
       2021-12-08 10:11:22 +08:00   ❤️ 1
    同一时间点是日志时间一模一样? 有没有弄链路追踪通过 TraceId 看看链路呢.
    Saxton
        2
    Saxton  
       2021-12-08 10:11:35 +08:00   ❤️ 1
    内部互调为什么要走网关?
    Saxton
        3
    Saxton  
       2021-12-08 10:15:34 +08:00   ❤️ 1
    应该先从网关开始排查,如果是用 spring cloud gateway 的话随便找个 filter 打个断点就知道了,靠猜想没用,实践才是唯一真理
    woduzibue
        4
    woduzibue  
    OP
       2021-12-08 10:50:51 +08:00
    @Kyle18Tang 不是同一个内部的服务,之前老伙计写的链路追踪不到
    @Saxton 不是内部的服务,B 服务是外部服务,就是偶现的不好排查,我后面试试能不能本地复现

    现在快速解决问题我说的两种加锁方式可行么?有没有什么其他好的时间方法
    javapythongo
        5
    javapythongo  
       2021-12-08 11:10:47 +08:00   ❤️ 1
    每一次请求加上一个随机数吧
    yiheweigui
        6
    yiheweigui  
       2021-12-08 11:28:44 +08:00   ❤️ 1
    cloud 只会发一个请求,既然发了两个,就是调了两次。

    要么就是 a 调了 b 两次,要么就是熔断限流什么的,在补偿的时候多调了一次,估计是用法不当,正常使用也走补偿。
    至于你遇到这种问题就想通过幂等性来解决,要看这个业务是不是适合幂等。
    至于加锁,就别玩了,动不动就锁,高并发的情况下,人家秒杀的需求就是要并发修改同一行。
    搞个分布式,又经常加锁,分布式的意义就是专门花大力气搞得很复杂,只是为了解耦分包开发?什么集群是加倍性能还是减弱性能?
    Saxton
        7
    Saxton  
       2021-12-08 11:41:01 +08:00   ❤️ 1
    @woduzibue 分布式锁能避免就避免,你这场景不是加锁就能解决的,还是解决得实际根本问题
    woduzibue
        8
    woduzibue  
    OP
       2021-12-08 11:41:21 +08:00
    @javapythongo 意思是通过随机数确认是不是同一个请求是吧

    @yiheweigui 我的认知下也觉得请求应该只有一个,可能中间有地方使用错误。当前只是偶现的情况,也不排除是 C 服务同时调用了两次,所以想通过加锁的方式拦截掉相同的请求。当前的业务场景是用户同步一批设置项,数据库里一个用户对应一条记录,之前考虑加锁应该没问题,基本不存在同一个用户同一时间很多次去同步数据库。多谢大佬指点
    Saxton
        9
    Saxton  
       2021-12-08 11:43:33 +08:00   ❤️ 1
    @woduzibue 上幂等就行了
    woduzibue
        10
    woduzibue  
    OP
       2021-12-08 11:44:53 +08:00
    @Saxton 对的,现在就是暂时不清楚是 C [同一时间] 调用了两次 A 导致 A 调用了两次 B , 还是 A 之前写法有问题 这里重复调用了两次 B 。又着急修复,所以想着加锁这种 头痛医脚的方法
    xuanbg
        11
    xuanbg  
       2021-12-08 12:00:41 +08:00   ❤️ 1
    内部调用不用走网关
    Saxton
        12
    Saxton  
       2021-12-08 12:05:32 +08:00   ❤️ 1
    @xuanbg A 域调用 B 域时需要走他们各自的网关,A 域内部自己调用不需要走网关
    woduzibue
        13
    woduzibue  
    OP
       2021-12-08 14:25:03 +08:00
    @Saxton 幂等 一般是根据什么来确定最好使用哪种方式的?有没有详细的资料啥的可以看看,我网上找到的看着好少
    z960112559
        14
    z960112559  
       2021-12-08 16:40:02 +08:00   ❤️ 1
    是不是网关的 ribbon 或者 hystrix 做了重试? hystrix 是不是没设置超时时间(默认 1 秒超时)
    z960112559
        15
    z960112559  
       2021-12-08 16:41:37 +08:00   ❤️ 1
    问题比现的话可以本地 debug 一下
    Amit
        16
    Amit  
       2021-12-08 16:47:59 +08:00   ❤️ 1
    Feign 默认是有重试机制的,但是如果是重试的话时间应该会差个几秒
    woduzibue
        17
    woduzibue  
    OP
       2021-12-08 17:13:34 +08:00
    @z960112559 @Amit 被调用方那边有两条秒数都一样的请求 log 是两个线程的,导致他那边服务崩掉了。 主要还是偶现的,不太好复现,所以想找一种兜底的方法。
    kaz10025
        18
    kaz10025  
       2021-12-08 17:45:44 +08:00   ❤️ 1
    两次请求的时间戳都一样吗?感觉还是得找到源头
    woduzibue
        19
    woduzibue  
    OP
       2021-12-08 17:50:53 +08:00
    @kaz10025 时间戳一毛一样,主要是调用的源头也不在我这,我刚接手 一个多月之前的 log 日志也不太好找。还是偶现的。源头后面等复现了还是要找的。
    cheng6563
        20
    cheng6563  
       2021-12-08 17:52:58 +08:00   ❤️ 1
    如果程序直接写库那就直接用事务加行锁就行了,先把锁都加上解决冲突问题,之后再想办法分离锁提高性能。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5528 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 08:38 · PVG 16:38 · LAX 00:38 · JFK 03:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.