快捷搜索: 长连接 前端 源码 pan

spring-cloud 服务间通信与调用(Feign)

spring-cloud 服务间通信与调用(Feign)

Feign简介 Feign 的主要作用就是简化远程调用 我们可以对比一下使用Eureka做原始HTTP调用,Ribbon调用和Feign调用三种方式

  1. 使用Eureka做原始HTTP调用
  2. Ribbon调用
  3. Feign组件调用 controller service:
  4. feign的简单使用案例 运行条件注册中心启动,服务提供者启动(服务名:eureka-client)

第一步:依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

第二步:启动类

package com.lys.springcloud;

import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * Created with IntelliJ IDEA.
 * User: Administrator
 * Date: 2021/4/19
 * Time: 22:55
 * Description: No Description
 */
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients // 开启feign
public class FeignConsumerApplication {
          
   

    public static void main(String[] args) {
          
   
        new SpringApplicationBuilder(FeignConsumerApplication.class)
                .web(WebApplicationType.SERVLET)
                .run(args);
    }
}

第三步:配置文件

spring.application.name=feign-consumer
server.port=40001

#允许注解重载(解决spring-cloud G版 @FeignClient修饰的接口无法继承的问题)
#spring.main.allow-bean-definition-overriding=true
eureka.client.service-url.defaultZone=http://localhost:20000/eureka/

第四步:声明接口

package com.lys.springcloud;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * Created with IntelliJ IDEA.
 * User: Administrator
 * Date: 2021/4/19
 * Time: 22:59
 * Description: No Description
 */
@FeignClient("eureka-client") //服务提供者的服务名
public interface IService {
          
   

    @GetMapping("/hello")
    String hello();
}

第五步:调用

package com.lys.springcloud;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created with IntelliJ IDEA.
 * User: Administrator
 * Date: 2021/4/19
 * Time: 23:05
 * Description: No Description
 */
@RestController
public class Controller {
          
   

    @Autowired
    private IService iService;

    @GetMapping("/hello")
    public String hello() {
          
   
        return iService.hello();
    }
}

深入学习Feign

  1. Feign的体系架构 feign是如何实现简化远程调用的呢?总体来说就是:声明一个代理接口,服务调用者通过调用这个代理接口来实现远程调用。 Feign 构建请求: 如上图所示,feign自身就引用了Ribbon组件和Hystrix组件,在构建请求时,Feign通过调用Ribbon的负载均衡策略来选定目标机器,通过调用Hystrix的熔断机制来判断是否发起调用
  2. Feign的底层机制

第六步:InvocationHandler类的invoke方法进行拦截

第七步:最终将由SynchronousMethodHandler类的invoke进行请求调用和结果返回

  1. 重试

理想的Feign风格项目结构 基于HTTP的服务治理方案在使用了feign组件之后,确实简化了一大部分的服务间调用代码,但是也出现了冗余的部分。在我们书写调用代码的过程中,有的人可能会发现,使用@FeignClient声明的接口代码中,如路径、post/get等信息,服务提供者已经书写过一遍了,我们要怎么样才能简化代码做到最理想化呢? answer: 当然是分离接口和接口实现,将接口作为一个独立的模块,如果要使用接口, 那么服务提供者可以实现该接口,而服务调用者只需继承该接口即可。 这里会有两种方式: 第一种在抽象的接口模块中加了@FeignClient注解,调用方需注意两点: 1.注意feign版本冲突,如若依赖冲突了可以在pom中使用exclude排除冲突项 2.调用方继承接口可不指定@FeignClient注解,但是需要指定basePackages属性,确保能代理本地接口 3.当然,如果要指定降级策略肯定需要加@FeignClient,然后添加fallback,不过需要注意父接口子自接口的primary属性都等于true的问题 第二种:在抽象的接口模块中没有加@FeignClient注解,调用方需注意两点: 1.调用方继承接口需要指定@FeignClient注解 其他属性视具体调用清空指定。 推荐使用第二种,第二种更灵活,适用性更高。

经验分享 程序员 微信小程序 职场和发展