微服务间的调用和应用内调用的有啥区别

摘要

目前大部分的系统架构都是微服务架构,就算没有注册中心、服务管理,也肯定是多个服务,单体服务比较少了。
大家平时需要在应用内调用rpc接口也比较多,那么有没有思考过微服务之间的调用和应用内直接调用有什么区别呢?面试时是不是经常被被问到微服务呢,本篇文章针对微服务间的方法调用和应用内方法调用的有啥区别这个很小的点,谈谈我的经验

微服务调用特点

先从单体应用说起

单体应用
单体引用通过一个服务节点直接组装好数据,返回给调用者。所有的方法调用都发生在应用内部。


微服务应用

商品详情服务需要调用商品,营销等多个服务组装好商品详情页的数据

微服务调用和应用内调用不同点在于它是跨进程的,甚至是跨节点的,这意味着什么呢

使用k8s编排微服务时,我们可以让不同的服务放在同一个节点的不同docker container上,但是考虑到网络不可靠,和容灾,
服务之间不可避免会放到不同的节点/机架上,所以下文都以跨节点来讨论

意味着两点

  • 对外部有了依赖
  • 如果是跨节点,就有了网络调用。我们知道网络都是不可靠的

关于网络有几个著名的错误推论

The network is reliable(网络是可靠的)
Latency is zero.(延迟可以为0)
Bandwidth is infinite(带宽是无限的)
The network is secure(网络是安全的)
Topology doesn‘t change(网络拓扑结构不会变)
Transport cost is zero(网络传输耗时为0)
The network is homogeneous(网络是同类的)

我们需要做什么

存在上述两个问题后,那么我们需要在写微服务间方法调用时注意什么的

对外部有了依赖
微服务架构设计中有一条重要的原则叫严出宽进,严出意思就是说你提供给其他服务的东西要尽可能的进行严格的校验。宽进就是你调用别人的接口要宽容,兼容各种情况。比如说你需要考虑别人的节点down了/api超时/api不可用等等因素。

为了解决这个问题,我们必须要针对具体业务,分析依赖类型,是强依赖还是弱依赖,强依赖包装成自己的服务异常返回码/或者直接告诉前端调用不可用。弱依赖,catch所有异常,无论依赖方发生什么,不能影响我的接口返回。

此外,我依赖的服务某段时间内接口错误率很高,调用方还在不停的发送请求,那么就会一直得到错误的结果,这时候这些请求其实是无效的,所以这时候需要客户端熔断,不再去调用服务方,给服务方恢复的时间,等过段时间再去重试,发现服务方可用时,再去调用。

网络调用

网络调用是耗时的,所以我们需要利用池化技术,复用连接,比如在单体应用中我们需要与数据库连接,会利用到数据库连接池来提高数据操作效率。那么微服务调用也是这么个道理,我们与其他服务建议http/tcp连接,也需要建立连接池。另外一个服务可能会依赖多个微服务,不能因为和某个服务之间的连接出了问题,影响到与其他服务的连接,所以需要做连接池隔离。

服务间调用有可能失败,所以我们需要有重试机制,比如因为网络抖动引发的超时问题,我们可以通过重试提高API的可用性。
但是思考一下坏的情况,某段时间网络或者服务端真的有问题了。客户端超时时间设置的很大的话,客户端等待的时间就会很长,然后再加上重试机制,就会将客户端的连接占满,造成客户端相关API不可用。

几个案例

分享几个微服务调用的故障案例,帮助大家进行场景化思考
为啥要分享这些案例呢,因为TMD的这些案例都是血的教训,造成线上故障,不是我的错,却要我背锅

案例1:

新上线了一个产品功能,需要推广,放在另外一个流量比较大的产品模块中,展示一些我们产品功能的数据。

出于某种原因,我们的服务mock了rpc调用数据,返回null。结果其他服务整个前台页面挂了,挂了,挂了。

典型的强弱依赖问题,调用方没有处理好依赖类型,明明是一个弱依赖没有处理,变成了强依赖,造成功能挂了

案例2:

依赖的某个服务需要根据主键List<id>来批量查询,依赖服务内部做分库分表拆分,升级了sdk
在提供的sdk client中做分表路由,将批量id拆分成N个rpc调用。这么做的原因是防止批量查询把数据库连接池打爆。

忽略了网络调用

案例3
别人调我们的服务的某个接口,这个接口RT(耗时时间)P95 < 30ms。但是客户端调用的超时时间设置成了500ms,在某次不知道是什么原因的情况下,调用方的连接大量block,造成线程阻塞,相关API不可用。看服务方监控,该接口返回时间正常,服务方没有任何异常。

没有正确的设置超时时间

总结

微服务调用和应用内调用有很大的区别,我们不能在进行服务间调用时无感知,需要知道它面临的问题

  • 对外部有了依赖,外部是不可靠的
  • 有了网络调用

解法可以精炼为4条

  • 根据业务需要,判断依赖类型,做好对应的降级
  • 设置合理的超时时间
  • 调用方需要对不同的服务调用设置连接池隔离
  • 调用方需要有熔断机制

这些问题看似都很简单,但是根据我的观察,真的有很多人写了无数的rpc调用,还没有意识到这些问题。

关注【方丈的寺院】,与方丈一起开始技术修行之路

原文地址:https://www.cnblogs.com/stoneFang/p/10727191.html

时间: 2024-10-23 16:45:39

微服务间的调用和应用内调用的有啥区别的相关文章

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

摘要使用 Istio 可以很方便地实现微服务间的访问控制.本文演示了使用 Denier 适配器实现拒绝访问,和 Listchecker 适配器实现黑白名单两种方法. 使用场景 有时需要对微服务间的相互访问进行控制,比如使满足某些条件(比如版本)的微服务能够(或不能)调用特定的微服务. 访问控制属于策略范畴,在 Istio 中由 Mixer 组件实现. Mixer拓扑图,来源官方文档 如上图所示,服务的外部请求会被 Envoy 拦截,每个经过 Envoy 的请求都会调用 Mixer,为 Mixer

zuul feign微服务间文件上传

feign传文件 需求 文件微服务负责管理文件,具体的文件上传下载逻辑都在此模块. openAPI负责向app用户提供头像上传的接口,实现具体业务逻辑. zuul是网关,负责路由转发.用户直接访问网关. 头像文件==>zuul==>openAPI==>文件微服务 增加引用包 <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form</

SpringCloud分布式事务实战(七)在微服务1中创建整合函数,调用微服务2

(1) 添加jar pom.xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> (2)在主程序中添加注解@EnableFeignClients (3)编写调用微服务的代码(调用服务2)1 创建theme实体 public class

springcloud 实现微服务间调用

package com.idoipo.ibt.config; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; impo

如何在一分钟内实现微服务系统下的架构可视化

为什么需要架构可视化 随着企业进行微服务架构改造,系统架构复杂度越来越高,架构变化日益频繁,微服务改造后的实际架构模型可能与预期已经产生了巨大差异,架构师或系统运维人员很难准确记忆所有资源实例的构成和交互情况:其次,系统架构在动态演化过程中可能引入了一些不可靠的因素,比如弱依赖变强依赖.局部容量不足.系统耦合过重等,给系统的稳定性带了极大的安全隐患.所以我们每次在面对系统改造.业务大促以及稳定性治理工作之前,都会通过梳理架构图的方式,呈现系统架构中个组件之间的交互方式,架构可视化能够清晰的协助我

创建微服务?请先回答这10个问题

原文地址:http://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&mid=401654497&idx=1&sn=5cac9aa4ae113592e1513c1ff70ea917&scene=21#wechat_redirect 乍一看微服务似乎很容易构建,但是要真正构建微服务,要完成的工作可比在容器里运行一些代码,并在这些代码间使用HTTP请求进行通信,要多得多.在开发新的微服务之前--必须得在新服务部署到生产环境之前--你需要回答

孢子框架-接口访问层、ESB、微服务API GateWay对比

如果从百度去搜索“接口访问层”你会发现主要是.NET里面的技术,叫做IDAL,其实是数据访问层接口.它的主要作用是兼容多种数据库.比如你定义一个标准接口,然后实现改接口的SqlServer访问和Oracle访问,那么利用IDAL就可以自由切换数据库.看.NET DEMO PetShop4,总共有22个项目.大体思想是3层,从Model.DAL.BLL,然后他在各层上又采用了工厂模式,把逻辑与实现想分离,比如以前BLL直接调用DAL就好了,但现在BLL却调用了IDAL,IDAL就是一个接口层,里面

【译文】用Spring Cloud和Docker搭建微服务平台

by Kenny Bastani Sunday, July 12, 2015 转自:http://www.kennybastani.com/2015/07/spring-cloud-docker-microservices.html This blog series will introduce you to some of the foundational concepts of building a microservice-based platform using Spring Cloud

Re:从0开始的微服务架构--(二)快速快速体验微服务架构?--转

原文地址:https://mp.weixin.qq.com/s/QO1QDQWnjHZp8EvGDrxZvw 这是专题的第二篇文章,看看如何搭建一个简单模式的微服务架构. 记得好久之前看到一个大牛说过:如果单体架构都搞不好,就别搞微服务架构.乍一看,这句很有道理,后来发现这句话是不太对的,因为微服务架构的目的就是为了降低系统的复杂性,所以 微服务架构应该比单体架构更简单.更好实践才对. 这篇文章,我们就分享一下如何搭建一个 简单模式 的微服务架构. 什么是微服务架构的简单模式? 相对于大型互联网