博客
关于我
微服务间的调用和应用内调用有啥区别
阅读量:555 次
发布时间:2019-03-09

本文共 1610 字,大约阅读时间需要 5 分钟。

微服务间方法调用与应用内方法调用的区别及优化建议

在当今的系统架构中,微服务架构已经成为主流。尽管没有注册中心和服务管理,单体服务也很少见,多个服务之间的协作是常态化的。开发者在日常工作中经常需要处理跨服务的RPC调用,同时也需要处理应用内部的方法调用。很多人可能没有深入思考这两者之间的区别,更不用说在面试中如何深入回答相关问题了。本文将从微服务调用的特点、问题分析以及解决方案等方面,谈谈我的经验和思考。


微服务调用特点

单体应用与微服务应用的对比

在单体应用中,所有的方法调用都发生在应用内部,通过一个服务节点直接组装好数据并返回给调用者。这种方式简单直观,但随着服务数量的增加,单体应用难以应对复杂的业务需求。

而在微服务架构中,一个服务可能需要调用多个其他服务(如商品服务、营销服务等)来组装完整的业务数据。这种跨服务调用的特性意味着:

  • 跨进程甚至跨节点:使用K8s编排微服务时,服务可能部署在不同的节点上。网络连接不可靠,容灾机制也无法保证服务始终可用。

  • 对外部的依赖:服务之间的调用依赖于外部网络,这使得网络传输耗时、不稳定。


  • 网络传输的不可靠性

    网络传输存在一些著名的错误假设,例如:

    • 网络是可靠的
    • 延迟可以为0
    • 带宽是无限的
    • 网络拓扑结构不变
    • 传输耗时为0
    • 网络是同类的

    这些假设在实际应用中往往不成立。网络传输可能会受到延迟、带宽限制、连接中断等因素的影响,这些都会对微服务调用的可靠性产生影响。


    我们需要做什么

    在设计和实现微服务间的方法调用时,需要特别注意以下几点:

    1. 依赖管理

    • 严出宽进原则:提供给其他服务的数据要经过严格校验,但对外部服务的调用则要宽容处理。需要根据业务需求分析依赖类型,是强依赖还是弱依赖。

      • 强依赖:需要对依赖服务的异常进行处理,例如返回特定的错误码或告知调用方服务不可用。
      • 弱依赖:对依赖服务的异常不做处理,避免影响到主业务的正常运行。
    • 熔断机制:如果依赖服务接口错误率很高,调用方应暂停调用,等待服务恢复后再重新尝试。

    2. 网络调用的优化

    • 连接池隔离:每个微服务之间建立独立的HTTP/TCB连接池,防止一个服务的连接问题影响到其他服务。
    • 重试机制:设置合理的超时时间和重试策略,避免因网络抖动或服务不可用导致接口不可用。

    3. 超时设置

    • 合理设置超时时间:超时时间要根据业务需求来确定,避免因等待超时而占用资源。例如,RT(平均响应时间)和P95(95%的请求在P95时间内完成)的指标可以帮助优化超时设置。

    微服务调用的典型问题案例

    案例1:服务间强依赖未处理

    • 背景:新上线的功能需要调用其他服务的数据作为展示内容。
    • 问题:服务的RPC调用的数据返回null,导致前台页面挂了。
    • 原因:服务间的依赖类型未明确,导致弱依赖未处理,变成了强依赖。

    案例2:批量查询分表拆分

    • 背景:依赖服务采用分库分表策略,使用SDK进行批量查询。
    • 问题:未正确处理网络调用,导致批量查询转换为多个RPC调用,增加了网络负载。
    • 原因:忽略了网络调用的并发性和延迟问题。

    案例3:超时设置不当

    • 背景:依赖服务的接口RT(P95)小于30ms,但客户端设置了500ms超时。
    • 问题:调用方线程被占满,导致相关API不可用。
    • 原因:超时时间设置不合理,没有考虑到网络延迟和并发度。

    总结

    微服务间的方法调用与应用内的方法调用在架构、调用的特性、网络依赖等方面有显著的不同。我们需要清醒认识到这些差异,并在实际开发中采取相应的优化措施。

    解决方案建议

  • 依赖管理:根据业务需求明确依赖类型,设置合理的错误处理机制。
  • 网络调优:使用连接池和重试机制,避免网络问题对整体系统造成影响。
  • 超时优化:结合业务指标,合理设置超时时间,避免资源占用和性能问题。
  • 这些问题看似简单,但根据我的观察,很多开发者在写RPC调用时还没有意识到这些问题。希望通过本文的分享,能够帮助大家在实际开发中避免类似的痛点。

    转载地址:http://hiasz.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现regular-expression-matching正则表达式匹配算法(附完整源码)
    查看>>
    Objective-C实现relu线性整流函数算法(附完整源码)
    查看>>
    Objective-C实现restful api服务(附完整源码)
    查看>>
    Objective-C实现reverse letters反向字母算法(附完整源码)
    查看>>
    Objective-C实现ReverseNumber反转数字算法 (附完整源码)
    查看>>
    Objective-C实现ripple adder涟波加法器算法(附完整源码)
    查看>>
    Objective-C实现RKM匹配(附完整源码)
    查看>>
    Objective-C实现RodCutting棒材切割最大利润算法(附完整源码)
    查看>>
    Objective-C实现roman numerals罗马数字算法(附完整源码)
    查看>>
    Objective-C实现Romberg算法(附完整源码)
    查看>>
    Objective-C实现ROT13密码算法(附完整源码)
    查看>>
    Objective-C实现rotate matrix旋转矩阵算法(附完整源码)
    查看>>
    Objective-C实现round robin循环赛算法(附完整源码)
    查看>>
    Objective-C实现RRT路径搜索(附完整源码)
    查看>>
    Objective-C实现RS485通信接收数据(附完整源码)
    查看>>
    Objective-C实现rsa 密钥生成器算法(附完整源码)
    查看>>
    Objective-C实现RSA密码算法(附完整源码)
    查看>>
    Objective-C实现RSA素因子算法(附完整源码)
    查看>>
    Objective-C实现runge kutta龙格-库塔法算法(附完整源码)
    查看>>
    Objective-C实现Sarsa算法(附完整源码)
    查看>>