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

rpc 调用,通常怎么保证一致性?

  •  
  •   JinTianYi456 · 2023-11-06 14:48:55 +08:00 · 2238 次点击
    这是一个创建于 367 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如你用 dubbo rpc 调用,执行通常有 3 种结果

    • 获得了响应,并且响应结果为,对方处理成功了
    • 获得了响应,并且响应结果为,对方处理失败了或者你的入参不对等等之类
    • 未获得响应,常见的 如 timeout
      • 通常怎么处理?
    14 条回复    2023-11-07 16:50:30 +08:00
    NelsonZhao
        1
    NelsonZhao  
       2023-11-06 14:54:04 +08:00
    有响应的话,保持一致性一般需要服务提供方来做接口幂等性.
    没响应,例如 timeout 这中就没办法,只能自己在代码里做一场判断.
    weizhen199
        2
    weizhen199  
       2023-11-06 14:55:54 +08:00
    分布式事务三件套
    同步返回,异步回调,消息队列检查,定时作业核算。
    dzdh
        3
    dzdh  
       2023-11-06 14:56:41 +08:00
    应答机制 + 队列检查
    wkong
        4
    wkong  
       2023-11-06 15:13:20 +08:00
    重试 + 幂等
    Plutooo
        5
    Plutooo  
       2023-11-06 15:17:03 +08:00
    分布式事务的范畴,看业务是否要保证强一致性
    GeekGao
        6
    GeekGao  
       2023-11-06 17:16:05 +08:00
    如果一致性要求可以接受最终一致性,可以把同步调用改成异步,异步任务队列中排队处理
    dlmy
        7
    dlmy  
       2023-11-06 18:01:36 +08:00
    服务调用方进行查询重试,被调用方做好幂等。每个服务都需要提供一个对外查询的接口,用来向外部输出操作执行的状态。

    场景举例:A 调用 B

    前置要求:A 跟 B 都需要各自提供一个对外查询的接口,对外输出操作执行的状态

    失败场景:
    1. A 调用 B 超时或无响应,A 一般要进行重试,并且在重试前调用 B 所提供的对外查询接口,检查 B 的执行状态,如果 B 的执行状态显示 ok ,就不再发起重试调用,并把 A 的调用改为成功
    2. A 调用 B 直接返回异常,A 进行重试,重试间隔时间可以用指数退避算法计算差值,直至达到重试阈值,触发告警后进行人工处理

    在 B 处理请求时,可以先回调 A 所提供的对外查询接口,判断 A 操作的执行状态,从而进行不同的逻辑处理

    幂等场景:在有业务状态的场景下,可以用业务状态做好幂等;在无业务状态的场景下,用业务唯一 ID 保证幂等

    个人建议:
    1. 耗时较长,并且用户对响应没有特殊要求的操作可以进行异步化调用,这样可以减少核心链路的层级,释放系统压力
    2. 能用同步解决的问题,就别用异步
    lolizeppelin
        8
    lolizeppelin  
       2023-11-06 18:12:14 +08:00
    我说一个....用 ntp 保证各个服务器时间一致,ntp 一搬能保证 128 毫秒以内

    所有 rpc 执行数据带上 overtime 时间, 客户端确认超时的时间比 overtime 时间多个 15~30 秒

    执行服务器可以通过 overtime 来确认超时
    lolizeppelin
        9
    lolizeppelin  
       2023-11-06 18:13:19 +08:00
    简单来说用 overtime 来控制超时,而不是用 timeout 来控制超时
    PungentSauce
        10
    PungentSauce  
       2023-11-06 18:16:01 +08:00
    不用考虑 rpc ,考虑一些和涉及到第三方调用的问题就好,处理方式都差不多。而且很多写操作都是收敛了。大多数还是查询操作
    JinTianYi456
        11
    JinTianYi456  
    OP
       2023-11-07 00:25:46 +08:00
    @NelsonZhao #1 `服务提供方来做接口幂等`,通常接口会设计成如何响应?比如第一次调用,响应成功(执行成功了)。第二次调用,响应同第一次(但代表之前已做过,直接告诉你成功)。还是说,第二次调用,换种响应(就告诉你之前已做过,这次重复调了)
    RedBeanIce
        12
    RedBeanIce  
       2023-11-07 11:22:00 +08:00
    @JinTianYi456
    视具体业务而定

    一般情况下,

    假如要修改一条数据,,,第一次调用进行中,第二次调用,应该直接报错。
    JinTianYi456
        13
    JinTianYi456  
    OP
       2023-11-07 11:44:41 +08:00
    @RedBeanIce #12 哦,我是说另一种

    1. 第一次调用
    2. 第二次调用
    2.1 第一次还在进行中,出错响应
    2.2 第一次已经结束了
    2.2.1 响应同第一次(但代表之前已做过,直接告诉你成功)
    2.2.2 换种响应(就告诉你之前已做过,这次重复调了)
    NelsonZhao
        14
    NelsonZhao  
       2023-11-07 16:50:30 +08:00
    @JinTianYi456 强一致的话,第二次就直接返回调用成功,如果业务有需要就响应为已经调用过.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1092 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 22:40 · PVG 06:40 · LAX 14:40 · JFK 17:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.