《SpringCloud篇:003Feign服务之间的通讯》

一、概述

之前实现服务与服务之间的调用,需要使用RestTemplate的对象:

  • 多次的编写关于RestTemplate的信息
  • 维护每一个RestTemplate访问时,使用的路径
  • 使用RestTemplate时,每次发送json参数时,很麻烦

找官方文档
在这里插入图片描述
在这里插入图片描述
在consumer修改pom依赖
在这里插入图片描述

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

在启动类上加注解@EnableFeignClients
编写consumer的ProviderClient接口,映射provider服务

package com.qf.springcloud.consumer.client;

import com.qf.springcloud.consumer.client.factory.ProviderFallbackFactory;
import com.qf.springcloud.consumer.client.fallback.ProviderClientFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

// 映射Provider的服务,
@FeignClient(value = "PROVIDER",fallbackFactory = ProviderFallbackFactory.class)
public interface ProviderClient {


    // 抽象方法,映射目标服务的controller,
    // 映射返回结果和方法参数
    // 用SpringMVC的注解,映射请求路径,注意目标Controller的类上是否有@RequestMapping注解
//    @GetMapping("/provider/test")
    @RequestMapping("/provider/test")
    public String test();



    @GetMapping("/path/{id}")
    public Map path(@PathVariable(value = "id") Integer id);


    @PostMapping("/param")
    public Map param(@RequestParam(name = "name") String name, @RequestParam(value = "age") Integer age);


    @PostMapping("/body")
    public Map body(@RequestBody Map map);
}

在consumer中的controller直接注入刚刚创建的接口

package com.qf.springcloud.consumer.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.qf.springcloud.consumer.client.ProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@RestController
public class ConsumerController {

    /*@Autowired
    private EurekaClient eurekaClient;*/

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ProviderClient providerClient;

    @GetMapping("/consumer/test")
    public String test() throws InterruptedException {
        /*//1. 通过Eureka获取PROVIDER服务的ip和port
        InstanceInfo provider = eurekaClient.getNextServerFromEureka("PROVIDER", false);
        String ip = provider.getIPAddr();
        int port = provider.getPort();

        //2. 通过RestTemplate调用provider的/provider/test
        String result = restTemplate.getForObject("http://" + ip + ":" + port + "/provider/test", String.class);*/

        /*
        //1. 访问目标服务
        String result = restTemplate.getForObject("http://PROVIDER/provider/test", String.class);
        */
        Thread.sleep(2000);
        System.out.println("test:" + Thread.currentThread().getName());
        String result = providerClient.test();
        //3. 返回结果
        return result;
    }
    }

二、Feign传递参数

  • 传参方式:
    • @PathVariable在路径上传递参数。
    • @RequestParam通过key=value的方式传递参数
    • @RequestBody传递json参数
  • 使用时,需要注意的点:
    • @RequestParam和@PathVariable一定要在接口中编写时,指定value属性
    • 传递POJO类或者Map类型的参数时,Feign会自动使用POST请求并且传递JSON数据,请求的方式时POST请求
    • 就时直接将目标服务的controller方法copy过来,删除方法体,如果时@RequestParam和@PathVariable就添加value属性,并且不要忘记Controller类上的路径

三、Feign的Fallback和FallbackFactory(整合hystrix)

当调用者在调用目标服务时,如果出现异常等问题,可以用过Fallback针对某一个功能在出现问题时,执行降级方法,返回托底数据

Fallback:

- 当调用者在调用目标服务时,如果出现异常等问题,可以用过Fallback针对某一个
- 功能在出现问题时,执行降级方法,返回托底数据
- 实现方式:
  - 创建POJO类,实现Feign的Client接口,重写全部抽象方法(降级方法),添加
   @Component
  - 修改Feign的Client接口的@FeignClient注解,添加属性fallback,并且指定
 实现类.class
  - 修改配置文件,开启hystrix.feign.enable=true
- Fallback在执行降级方法后,无法获取到出现的异常信息的,无法处理问题


在消费者consumer中创建一个ProviderClientFallback,继承ProviderClient接口,定义托底数据(调用路径时,哪个路径有问题就找到哪个路径的托底数据(降级方法))

package com.qf.springcloud.consumer.client.fallback;

import com.qf.springcloud.consumer.client.ProviderClient;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
public class ProviderClientFallback implements ProviderClient {

   @Override
   public String test() {
       return null;
   }


   // 降级方法,hystrix
   @Override
   public Map path(Integer id) {
       Map map = new HashMap();
       map.put("msg","服务挤爆了,请稍后再试!");
       return map;  // 托底数据
   }

   @Override
   public Map param(String name, Integer age) {
       return null;
   }

   @Override
   public Map body(Map map) {
       return null;
   }
}

在映射接口ProviderClient中添加FallBack机制

package com.qf.springcloud.consumer.client;

import com.qf.springcloud.consumer.client.factory.ProviderFallbackFactory;
import com.qf.springcloud.consumer.client.fallback.ProviderClientFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

// 映射Provider的服务,
@FeignClient(value = "PROVIDER",fallbackFactory = ProviderFallbackFactory.class)
public interface ProviderClient {


   // 抽象方法,映射目标服务的controller,
   // 映射返回结果和方法参数
   // 用SpringMVC的注解,映射请求路径,注意目标Controller的类上是否有@RequestMapping注解
//    @GetMapping("/provider/test")
   @RequestMapping("/provider/test")
   public String test();



   @GetMapping("/path/{id}")
   public Map path(@PathVariable(value = "id") Integer id);


   @PostMapping("/param")
   public Map param(@RequestParam(name = "name") String name, @RequestParam(value = "age") Integer age);


   @PostMapping("/body")
   public Map body(@RequestBody Map map);



}

由于FallBack是默认关闭的,所以需要在application.yml中修改配置,这个是由(Hystrix - 服务的线程隔离以及断路器)提供的

# 开启hystrix整合feign开关
feign:
  hystrix:
    enabled: true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值