SpringCloud服务间内部调用原理
前言
SpringCloud中各个服务分布在不同的服务器上,我们常常使用内部服务调用去调用其他服务,那么他们内部到底是怎么调用的呢?这里我们以一个购物APP为例子:包含商品服务,仓储服务,支付服务,购物车服务;
那么我们这里从商品服务获取了商品,加入了购物车,然后准备支付商品款,再通知仓储进行发货。那么这个过程中就设计到服务间调用。
在说明调用原理之前我们先来屡一下思路:每个服务在不同的服务器上,这些服务直接如何发现彼此?
注册中心
这就引出了注册中心(服务注册与发现);首先每个服务中都会有一个注解@EurekaClient,就是告诉注册中心关于自己服务的信息,而且每个服务都有一个注册中心EurekaServer的地址,(定时)不停地往注册中心发送心跳告诉自己是否中断,注册中心就维护了一张注册表,这张注册表记录了每个服务的IP,监听的端口,服务状态等信息
那么如果购物车服务要调用支付服务,那么它就会问注册中心:支付服务的注册信息是啥?然后购物车拿支付服务注册信息之后就缓存到本地服务中。那么问题又来了,不同服务器之间调用肯定需要通过网络请求到对应服务器上的服务监听端口?那么谁来做这个事情呢?
通常我们在没有使用微服务框架时,都是通过HttpClient去调用请求,传递参数,然后获取到相应结果进行处理,但这样每次都写重复的代码是不是很烦人?那微服务SpringCloud中谁来干这个活呢?这里就引出了Feign这个组件了。
Feign
我们写过微服务的大家应该都知道,我们在实现控制器时,通常都会以实现一个接口,这个接口在服务间进行调用显示写法,那么这个Feign的底层实现原理是啥呢?
我们前面说了要调用不同服务器之间的服务呀就得使用HttpClient形式去调用,Feign就是用来干这个的。
前面我们拿到了支付服务的IP与端口,那么Feign就会将这些信息拼接起来,形成一个网络请求:Http://服务地址:监听端口/服务注册标识/对应的请求MAPPING
Feign实现原理
通常我们都知道加上@FeignClient注解的都是一个接口,其实这个Feign的原理就是使用的动态代理,通过@FeignClient@RequestsMapping@PathValue或者@RequestBody将请求发送到目标HandleMapping上。
这样我们就解决了不同服务器之间通信请求连接的问题,但是我们微服务通常都会实现分布式部署,同一个服务会部署在不同的多个服务器上,那么Feign它又怎么知道我发给那个服务IP上呢?这个工作是谁来做呢?谁来告诉Feign呢?那么这里又引出了一个组件:Ribbon;
Ribbon
没错,Ribbon就是来告诉Feign具体发送到那个Ip上的一个负载均衡组件。根据Ribbon中的负载均衡策略,每次都会返回给Feign一个Ip地址用于服务调用。默认情况下,是均分方式,比如有ip1,ip2,ip3,那么这个时候来了10个请求,那么他就先给Ip1,再给ip2,再给ip3,这种轮询策略将请求分布到不用别的服务器上
那么如果这个时候其中一台服务器的服务挂掉了,会怎么样呢?内部服务调用还能继续吗?内部又会发生什么操作呢?
首先当然本次内部调用肯定会报服务内部错误,因为服务都调不通了嘛。接着出现问题的服务器无法与注册中心进行心跳检查,这个时候注册中心就会将这个注册信息状态改变将其实例下架。然后各客户端就会更新本地注册表。那么当再次内部服务调用时就可以调用到可用的服务器上的服务。
那么如果当一个一个服务器上的服务都崩溃了,这个时候支付服务都没法提供服务了,这个时候又会怎么样呢?那这个时候所有调用该服务的线程都会卡在这个服务的调用无法往下走,这个时候严重时会导致调用该服务的服务也奔溃无法服务。
这个地方显然是不合理的,A服务挂了,关我B服务啥事,最起码不要让我也挂了呀。这个时候就会引入一个新东西:Hystrix(熔断器)
Hystrix服务熔断与降级
我们可以把熔断器想象为一个保险丝,在电路系统中,一般在所有的家电系统连接外部供电的线路中间都会加一个保险丝,当外部电压过高,达到保险丝的熔点时候,保险丝就会被熔断,从而可以切断家电系统与外部电路的联通,进而保障家电系统不会因为电压过高而损坏。
Hystrix提供的熔断器就有类似功能,当在一定时间段内服务调用方调用服务提供方的服务的次数达到设定的阈值,并且出错的次数也达到设置的出错阈值,就会进行服务降级,让服务调用方之间执行本地设置的降级策略,而不再发起远程调用。但是Hystrix提供的熔断器具有自我反馈,自我恢复的功能,Hystrix会根据调用接口的情况,让熔断器在closed,open,half-open三种状态之间自动切换。
open状态说明打开熔断,也就是服务调用方执行本地降级策略,不进行远程调用。
closed状态说明关闭了熔断,这时候服务调用方直接发起远程调用。
half-open状态,则是一个中间状态,当熔断器处于这种状态时候,直接发起远程调用。
使用了熔断器之后,那么服务之间就不会有强耦合,不会导致服务间崩溃连锁反应。从而保证了服务的高可用行,提高了服务的可服务时间。
SpringCloud服务间内部调用原理
原文地址:https://blog.51cto.com/4837471/2513548