SpringCloud的远程调用,一篇文章带你了解什么是远程调用,以及相关的种种问题

1.什么是远程调用

        远程调用组件是SpringCloud核心组件之一。

        远程调用(Remote Procedure Call, RPC)是指一个服务通过网络调用另一个服务的接口,以实现跨进程或跨机器的通信。在微服务架构中,服务之间通常通过远程调用来实现业务逻辑的协作。

2.SpringCloud远程调用的实现方式

2.1.RestTemplate

定义:RestTemplate 是 Spring 提供的一个同步 HTTP 客户端,用于调用 RESTful 服务

特点

(1)简单易用,适合简单的 HTTP 调用

(2)支持与 Ribbon 集成,实现客户端负载均衡

示例

@Bean
@LoadBalanced // 开启负载均衡
public RestTemplate restTemplate() {
    return new RestTemplate();
}

@Autowired
private RestTemplate restTemplate;

public String callService() {
    return restTemplate.getForObject("http://service-name/api", String.class);
}

2.2.Feign

描述:Feign 是一个声明式的 HTTP 客户端,通过接口和注解的方式定义远程调用。

特点

(1)代码简洁,易于维护。

(1)支持与 Ribbon 和 Hystrix 集成,实现负载均衡和熔断。

示例:

@FeignClient(name = "service-name")
public interface ServiceClient {
    @GetMapping("/api")
    String callService();
}

@Autowired
private ServiceClient serviceClient;

public String callService() {
    return serviceClient.callService();
}

2.3.OpenFeign

描述:OpenFeign 是 Feign 的社区增强版,支持更多功能和扩展

特点

(1)支持 Spring Cloud LoadBalancer(替代 Ribbon)。

(2)支持响应式编程(Reactive)。

示例

@FeignClient(name = "service-name")
public interface ServiceClient {
    @GetMapping("/api")
    String callService();
}

2.4.Spring Cloud Stream

描述:用于消息驱动的微服务,通过消息中间件(如 Kafka、RabbitMQ)实现服务间通信

特点:

(1)适合异步通信场景。

(2)解耦服务间的直接依赖。

2.5.gRPC

描述:gRPC 是一个高性能的 RPC 框架,基于 HTTP/2 和 Protocol Buffers

特点

(1)性能高,适合对性能要求较高的场景。

(2)支持多语言。

3.SpringCloud远程调用的核心特征

(1)负载均衡

  • Spring Cloud 通过集成 Ribbon 或 Spring Cloud LoadBalancer,实现了客户端负载均衡
  • 服务消费者可以从多个服务提供者实例中选择一个进行调用

(2)熔断与降级

  • 通过集成 Hystrix 或 Spring Cloud CircuitBreaker,实现了服务的熔断和降级。

  • 当服务调用失败或超时时,可以快速失败或返回降级结果,避免雪崩效应。

(3)服务发现

  • 通过集成注册中心(如 Eureka、Nacos),实现了服务的动态发现。

  • 服务消费者无需硬编码服务提供者的地址,而是从注册中心获取可用的服务实例。

(4)声明式调用

  • Feign 和 OpenFeign 提供了声明式的远程调用方式,通过接口和注解定义调用逻辑,代码简洁易读。

4.SpringCloud远程调用的优势

(1)简化开发:通过声明式调用(如 Feign)和自动化配置,开发者可以快速实现服务间通信。

(2)提高可用性:通过负载均衡、熔断和降级机制,确保服务的高可用性。

(3)动态扩展:结合注册中心,支持服务的动态发现和扩展。

(4)性能优化:支持多种通信协议(如 HTTP、gRPC),满足不同场景的性能需求。

5.实际应用经验

  • 在项目中,我使用 Feign 实现了服务间的远程调用,结合 Ribbon 实现了负载均衡,并通过 Hystrix 实现了熔断和降级。

  • 通过 Nacos 作为注册中心,实现了服务的动态发现和调用。

  • 在高并发场景下,使用 gRPC 替代 HTTP,显著提升了服务调用的性能。

6.进阶

6.1.HTTP与RPC的区别

  • 严格来讲,HTTP 和RPC不是一个层面上的东西,可以说RPC包含HTTP,也可以说RPC在HTTP之上
  • HTTP(Hypertex Transfer Protocol)是一种应用层协议,主要强调的是网络通信
  • RPC(Remote Procedure Call,远程过程调用)是一种用于分布式系统之间通信的协议,强调的是服务之间的远程会调用
  • 一些RPC框架,比如gRPC,底层传输协议其实也是用的HTTP2,包括Dubbo3,也兼容了gRPC,使用了HTTO2作为传输层的一层协议
  • 在微服务体系里,基于HTTP风格的远程调用通常使用框架如Feign来实现,基于RPC的远程调用通常使用框架如Dubbo来实现

如果硬要说区别的话:

6.2.Feign和Dubbo的区别

这两个才是适合比较的东西:


       要注意的时,Feign和Dubbo并不是互斥的关系。实际上,Dubbo可以使用HTTP协议作为通信方式,而Feign也可以继承RPC协议进行远程调用。选择使用哪种远程调用方式取决于具体的业务需求和技术栈的选择

6.3.Feign和OpenFeign的区别

来源与维护

  • Feign 最初由 Netflix 开发,是 Netflix OSS 的一部分,后来被 Spring Cloud 集成到其生态系统中。它是一个独立的库,主要用于声明式的 REST 客户端开发。
  • OpenFeign 是 Feign 的社区维护版本,由 OpenFeign 社区主导开发。它是对 Feign 的增强和扩展,提供了更多的功能和更好的兼容性。

功能增强

Feign:功能相对基础,支持声明式接口、负载均衡(与 Ribbon 集成)、请求拦截等。

OpenFeign:在Feign的基础上增加了很多功能:

  • 更好的 Spring 生态集成(如 Spring MVC 注解支持)
  • 支持 Spring Cloud LoadBalancer(替代 Ribbon)
  • 更灵活的扩展机制。
  • 支持响应式编程(Reactive)
  • 提供更丰富的注解和配置选项

与 Spring Cloud 的集成:

  • 早期 Spring Cloud 使用的是 Netflix Feign,但 Netflix 已经停止维护 Feign,因此 Spring Cloud 逐渐转向 OpenFeign。
  • 目前 Spring Cloud 官方推荐使用 OpenFeign,它与 Spring Cloud 的集成更加紧密,支持最新的 Spring Cloud 特性(如 Spring Cloud LoadBalancer)

依赖关系:

Feign:适用于早期的 Spring Cloud 项目,或者不需要最新特性的场景

OpenFeign:适用于新项目或需要更多功能和更好兼容性的场景,尤其与 Spring Cloud 2020.x 及以上版本集成时

总结

同:

  • Feign和OpenFeign作用一样,都是进行远程调用的组件。
  • 里面都内置了Ribbon。
  • 都是加在消费端的注解,让消费端可以调用其他生产者的服务。

  • 依赖不同,一个是spring-cloud-starter-feign,一个是spring-cloud-starter-openfeign。
  • 使用方式不同,Feign直接加在接口上并且不支持SpringBoot注解。OpenFeign支持@RequestMapping("/demo/test")这种注解。

6.4.Feign怎么做负载均衡

在Feign中,负载均衡时通过继承Ribbon来实现的

       Ribbon在发起请求前,会从“服务中心”获取服务列表(清单),然后按照一定的负载均衡策略去发起请求,从而实现客户端的负载均衡。Ribbon本身也维护者“服务提供者”清单的有效性。如果它发现“服务提供者”不可用,则会重新从“服务中心”获取有效的“服务提供者”清单来及时更新

6.5.为什么Feign第一次调用耗时很长

       主要原因是由于Ribbon的懒加载机制,当第一次调用发生时,Feign会触发Ribbon的加载过程,包括从服务注册中心获取服务列表,建立连接池等操作,这个加载过程会增加首次调用的耗时

ribbon:
  eager-load:
    enabled: true
      clients: service-1

那怎么解决这个问题呢?

       可以在应用启动时预热Feign客户端,自动触发一次无关紧要的调用,来提前加载Ribbon和其他相关组件。这样,就相当于提前进行了一次调用/

6.6.Feign怎么实现认证传递

       比较常见的一个做法是,使用拦截器传递认证信息。可以通过实现Requestlnterceptor接口来定义拦截器,在拦截器里,把认证信息添加到请求头中,然后将其注册到Feign配置中

代码示例

@Configuration
public class FeignClientConfig {

    @Bean
    public RequestInterceptor requestInterceptor() {
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate template) {
                // 添加认证信息到请求头中
                template.header("Authorization", "Bearer " + getToken());
            }
        };
    }

    private String getToken() {
        // 获取认证信息的逻辑,可以从SecurityContext或其他地方获取
        // 返回认证信息的字符串形式
        return "your_token";
    }
}

6.7.服务端负载均衡和客户端负载均衡的区别

服务端

客户端:

       客户端负载均衡器的实现原理时通过注册中心,如Nacos,将可用的服务列表拉取到本地(客户端),再通过客户端负载均衡器(设置的负载均衡策略)获取到某个服务器端具体ip和端口,然后通过HTTP框架请求服务并得到结果

 7.关联文章

       如此等等的资料我都已经整理到了思维导图中,本篇属于SpringCloud篇,有需要的可以去看一下,喜欢的就留个三连再走吧~

SpringCloud:https://blog.youkuaiyun.com/TLOVEYOUTOO/article/details/145532603?spm=1001.2014.3001.5502

Spring全家桶:

https://blog.youkuaiyun.com/TLOVEYOUTOO/article/details/145532922?spm=1001.2014.3001.5502

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值