SpringCloud实战【五】:声明式服务调用-Feign

目录

1 Feign解决的问题

2 创建Feign实例

3 总结


1 Feign解决的问题

使用RestTemplate调用其他服务的API时,请求参数需要在URL后面拼接,参数少的情况下没有影响,参数多的轻轻下去拼接String效率非常低,操作起来也非常不灵活容易出错,Feign就应运而生解决了这个问题。

Feign是一个声明式的Web Service客户端,是为了让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。

Feign会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix(关于Hystrix我们后面再讲),可以让我们不再需要显式地使用这两个组件。

2 创建Feign实例

创建项目springcloud-feign,引入Feign依赖,会自动引入Hystrix依赖的,pom.xml文件配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud-feign-demo</artifactId>
        <groupId>com.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.springcloud</groupId>
    <artifactId>springcloud-feign</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.4.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>

</project>

application.yml配置如下:

server:
  port: 9006
spring:
  application:
    name: feign-consumer
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/

在提供者spirngcloud-provider1的ProviderController.java修改为:

@RestController
public class ProviderController {
    @RequestMapping("/hello")
    public String hello(){
        System.out.println("访问来1了......");
        return "hello1";
    }

    //新增的方法
    @RequestMapping(value = "/hellol", method= RequestMethod.GET)
    public String hello(@RequestParam String name) {
        return "HelloProvider1 " + name;
    }

    @RequestMapping(value = "/hello2", method= RequestMethod.GET)
    public User hello(@RequestHeader String name, @RequestHeader Integer age) {
        return new User(name, age);
    }

    @RequestMapping(value = "/hello3", method = RequestMethod.POST)
    public String hello (@RequestBody User user) {
        return "HelloProvider1 "+ user. getName () + ", " + user. getAge ();
    }

}

把服务提供者spirngcloud-provider2的ProviderController.java修改为:

@RestController
public class ProviderController {
    @RequestMapping("/hello")
    public String hello(){
        System.out.println("访问来1了......");
        return "HelloProvider2";
    }

    //新增的方法
    @RequestMapping(value = "/hellol", method= RequestMethod.GET)
    public String hello(@RequestParam String name) {
        return "HelloProvider2 " + name;
    }

    @RequestMapping(value = "/hello2", method= RequestMethod.GET)
    public User hello(@RequestHeader String name, @RequestHeader Integer age) {
        return new User(name, age);
    }

    @RequestMapping(value = "/hello3", method = RequestMethod.POST)
    public String hello (@RequestBody User user) {
        return "HelloProvider2 "+ user. getName () + ", " + user. getAge ();
    }

}

在服务提供者springcloud-provider1,springcloud-provider2以及服务消费者springcoud-fegin中分别添加实体类User.java

@Data
public class User {

    private String name;
    private Integer age;

    public User(){

    }
    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

}

使用Feign的@FeignClient映射服务调用:

@FeignClient(value = "hello-service",fallback = FeignFallBack.class)
public interface FeignService {
    //服务中方法的映射路径
    @RequestMapping("/hello")
    String hello();

    @RequestMapping(value = "/hellol", method= RequestMethod.GET)
    String hello(@RequestParam("name") String name) ;

    @RequestMapping(value = "/hello2", method= RequestMethod.GET)
    User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age);

    @RequestMapping(value = "/hello3", method= RequestMethod.POST)
    String hello(@RequestBody User user);
}

处理服务降级:

@Component
public class FeignFallBack implements FeignService {
    //实现的方法是服务调用的降级方法
    @Override
    public String hello() {
        return "error";
    }

    @Override
    public String hello(String name) {
        return "error";
    }

    @Override
    public User hello(String name, Integer age) {
        return new User();
    }

    @Override
    public String hello(User user) {
        return "error";
    }
}

controller层注入接口FeignService进行远程调用:

@RestController
public class ConsumerController {

    @Autowired
    FeignService feignService;

    @RequestMapping("/consumer")
    public String helloConsumer(){
        return feignService.hello();
    }

    @RequestMapping("/consumer2")
    public String helloConsumer2(){
        String result1 = feignService.hello("boy");
        String result2 = feignService.hello("boy", 30).toString();
        String result3 = feignService.hello(new User("boy", 30));
        return result1 + "-----" + result2 + "----" + result3;
    }

}

创建启动类FeignApplication.java,打上eureka客户端的注解@EnableDiscoveryClient,以及Feign客户端的注解@EnableFeignClients

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeignApplication.class, args);
    }
}

启动服务注册中心springcloud-eureka1,springcloud-eureka2;启动服务提供者springcloud-provider1,springcloud-provider2;启动服务消费者springcloud-feign。浏览器访问:

http://localhost:9006/consumer

轮询得到如下结果:

可以看到轮询得到HelloProvider1和HelloProvider1两个结果,浏览器访问:

http://localhost:9006/consumer2

轮询得到如下结果

停掉服务springcloud-provider1,springcloud-provider2,浏览器访问

可以看到调用都进行了服务降级。

3 总结

本文介绍了Feign的使用方法,Feign使用@FeignClient映射服务,大大提升了服务请求的便捷性,在实际的工作中大多数会使用这种方式。本文的源码下载地址:https://github.com/xiaoyususu/springcloud-feign-demo.git

发布了32 篇原创文章 · 获赞 38 · 访问量 5470

猜你喜欢

转载自blog.csdn.net/u010482601/article/details/103440955