SpringCloud(七):SpringCloud 声明式服务消费 Feign

发布于 2019-08-27 08:10:15

7-1. Feign 是什么

Feign是Netflix公司开发的一个声明式的REST调用客户端; Ribbon负载均衡、Hystrix服务熔断是我们Spring Cloud中进行微服务开发非 常基础的组件,在使用的过程中我们也发现它们一般都是同时出现的,而且配置 也都非常相似,每次开发都有很多相同的代码,因此Spring Cloud基于Netflix Feign整合了Ribbon和Hystrix两个组件,让我们的开发工作变得更加简单, 就像Spring Boot是对 Spring+SpringMVC的简化一样,Spring Cloud Feign 对 Ribbon 负载均衡、Hystrix 服务熔断进行简化,在其基础上进行了进一步的 封装,不仅在配置上大大简化了开发工作,同时还提供了一种声明式的Web服 务客户端定义方式;

7-2. 使用 Feign 实现消费者

使用 Feign 实现消费者,我们通过下面步骤进行:
第一步:创建普通 Spring Boot 工程
首先我们来创建一个普通的 Spring Boot 工程,取名为: 05-springcloud-service-feign;

第二步:添加依赖
要 添 加 的 依 赖 主 要 是 spring-cloud-starter-netflix-eureka-clientspring-cloud-starter-feign,如下:

  <!--Eureka客户端进行服务发现的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>

        <!--SpringCloud  feign的起步依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.4.5.RELEASE</version>
        </dependency>



        <!--Spring Cloud熔断器起步依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>1.4.5.RELEASE</version>
        </dependency>

第三步:添加注解
在项目入口类上添加@EnableFeignClients 注解表示开启 Spring Cloud Feign的支持功能;

第四步:声明服务
定义一个 HelloService 接口,通过@FeignClient 注解来指定服务名称,进而绑定服务,然后再通过 SpringMVC 中提供的注解来绑定服务提供者提供的接口,
如下:

/**
 * 使用Feign可客户端注解,绑定远程服务的名字
 * 远程服务的名字 可以大写 也可以小写
 */
@FeignClient("01-springcloud-service-provider")
public interface HelloService {

    // 声明一个方法,这个方法就是远程服务提供者提供的方法
    @RequestMapping("service/hello")
    public String hello();
}

image.png

这相当于绑定了一个名叫 01-springcloud-service-provider (这里
01-springcloud-service-provider 大小写 01-SPRINGCLOUD-SERVICE-PROVIDER
都可以 ) 的服务提供者提供的/service/hello 接口;
我们服务提供者提供的接口如下:

@RequestMapping("/service/hello")
    public String hello(){
        return "hello,Spring Cloud,Provider1";
    }

第五步:使用 Controller 中调用服务
接着来创建一个 Controller 来调用上面的服务,如下:

@RestController
public class FeignController {

    @Autowired
    private HelloService helloService;

    @RequestMapping("/web/hello")
    public String hello(){
        // 调用声明式接口方法,实现对远程服务的调用
       return helloService.hello();
    }
}

image.png

第六步:属性配置
在 application.properties 中指定服务注册中心、端口号等信息,如下:

server.port=8082
# 配置服务的名称
spring.application.name=05-springcloud-service-feign
# 配置 eureka 注册中心地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka,http://localhost:8762/eureka

第七步:测试

依次启动注册中心、服务提供者和 feign 实现服务消费者,然后访问如下地址:
http://localhost:8082/web/hello

7-3. 使用 Feign 实现消费者的测试

负载均衡:

我们知道,Spring Cloud 提供了 Ribbon 来实现负载均衡,使用 Ribbo 直接注
入一个 RestTemplate 对象即可,RestTemplate 已经做好了负载均衡的配置;
在 Spring Cloud 下,使用 Feign 也是直接可以实现负载均衡的,定义一个注解
有@FeignClient 注解的接口,然后使用@RequestMapping 注解到方法上映
射远程的 REST 服务,此方法也是做好负责均衡配置的。

上面我们写的就是负载均衡的,大家可以自己测试下。

服务熔断:

1、在 application.properties 文件开启 hystrix 功能

feign.hystrix.enabled=true

2、指定熔断回调逻辑

@FeignClient(name="01-springcloud-service-provider", fallback = MyFallback.class)
@Component
public class MyFallback implements HelloService {

    @Override
    public String hello() {
        return "hello远程服务不可用";
    }
}

2-1 新增错误回调类

image.png

2-2 新建MyFallback类,继承HelloService,重写HelloService的方法,重写的内容即为熔断后回调的

image.png

在服务提供着的方法中制造异常

image.png

重启 重启 重启 所有的服务提供者,Eureka服务,feign,在服务提供者2的方法中制造异常

测试结果:
image.png

image.png

服务提供者2发生异常,进入了fallback方法

3、服务熔断获取异常信息:

为@FeignClient 修饰的接口加上 fallback 方法可以实现远程服务发生异常后进
行服务的熔断,但是不能获取到远程服务的异常信息,如果要获取远程服务的异
常信息,怎么办?此时可以使用 fallbackFactory:

@FeignClient(name="01-springcloud-service-provider", fallbackFactory=MyFallbackFactory.class)
@Component
public class MyFallbackFactory  implements FallbackFactory<HelloService> {

    @Override
    public HelloService create(Throwable throwable) {
        return new HelloService() {
            @Override
            public String hello() {
                return throwable.getMessage();
            }
        };
    }
}

上图:电脑端点击可放大至高清

image.png

image.png

0 条评论

发布
问题