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

2021-12-08 10:00:39 +08:00
 woduzibue
C 服务通过网关 调用 A 服务,A 服务(更新数据库后)调用 B 服务,A 服务部署了两个节点。现在 B 服务 log 里面发现 [同一时间点] 有两条 A 服务参数一样的请求导致异常了,求教解决方法

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

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

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

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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/820794

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX