zoukankan      html  css  js  c++  java
  • Feign配合Ribbon和Eureka来提供负载均衡的HTTP客户端(四)

    更多内容参见个人技术博客,无广告欢迎关注

    1.1         Feigh

    1.1.1      概念

    Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Ribbon and Eureka to provide a load balanced http client when using Feign.

    Feigh是一个声明式web服务客户端。它能让开发web服务变得容易。使用Feign需要创建一个接口并注解它。它拥有包括Feign注解和JAX-RS注解的可插拔支持。它还支持可插拔的编码器和解码器。Spring Cloud拥有Spring MVC支持,并使用Spring Web中默认同样的HttpMessageConverters。在使用Feign时,Spring Cloud集成了RibbonEureka来提供负载均衡的HTTP客户端。

    总结:Feign简化HttpClient开发,封装了JAX-RSspringmvc的注解,学习成本很低。

    1.1.2      Feign的坑

    不能直接支持接收对象参数,只能一个一个属性接收。如果必须要接收对象参数,可以变相通过@RequestBody,通过json的表单提交来实现。

    对于日期类型支持和json转换间冲突多,还滞后8小时。转为字符串类型,在提供者时,再强制转换为日期,更加方便些。

    1.2         消费者实现Feign

    1.2.1      创建Maven工程

    1.2.2      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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>com.wood</groupId>
    <artifactId>spring-cloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wood</groupId>
    <artifactId>feign-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>feign-client</name>
    <description>Demo project for Spring Boot</description>

    <dependencies>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!-- Feign依赖,声明式开发 -->
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
    <version>1.4.6.RELEASE</version>
    </dependency>
    <!-- Hystrix,Feign是基于Hystrix的,Hystrix下一章节会讲到 -->
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
    <version>1.4.6.RELEASE</version>
    </dependency>
    </dependencies>
    </project>

    1.2.3      application.properties

    server.port=8093
    spring.application.name=feign-client
    eureka.client.serviceUrl.defaultZone=http://localhost:6001/eureka
    # 定义根目录下日志级别
    logging.level.root=INFO

    1.2.4      EurekaServiceFeign.java

    以接口对外暴露,从而封装底层操作。

    package com.wood.feignclient.remote;

    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;

    /**
    * 这个接口相当于把原来的服务提供者项目当成一个Service类
    **/
    @FeignClient(value="provider-user")
    public interface EurekaServiceFeign {
    /**
    * Feign中没有原生的@GetMapping/@PostMapping/@DeleteMapping/@PutMapping
    * 要指定需要用method进行
    * */
    @RequestMapping(value="/hello/{name}",method=RequestMethod.GET)
    String hello(@PathVariable("name") String name);

    }

    1.2.5      HelloController.java

    package com.wood.feignclient.controller;

    import com.wood.feignclient.remote.EurekaServiceFeign;
    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.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;

    @RestController
    public class HelloController {

    @Autowired
    private EurekaServiceFeign eurekaServiceFeign
    ;

    @GetMapping("/hello/{name}")
    @ResponseBody
    public String hello(@PathVariable String name){
    return eurekaServiceFeign.hello(name);
    }
    }

    1.2.6      FeignClientApplication.java

    package com.wood.feignclient;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;

    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients //开启Feign
    public class FeignClientApplication {

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

    }

    1.2.7      常见的坑

    只支持旧的@RequestMapping不支持新的@GetMapping()

    method=RequestMethod.GET 只支持POST方法,GET方法也会自动转到POST方法

    @PathVariable("name") String name 必须写名称“name”,springmvc可以不写

    启动超过1s会报超时,再刷新就可以正常访问,原因在于hystrix断路器的影响,稍差的机器就会发生。

     

    1.2.8      测试

    执行顺序:

    先启动服务端     6001    eureka-server        EurekaServerApplicaiton

    在启动提供者1   8081    provider-a        ProviderAAppcation

    最后启动消费者  8093    feign-client  FeignClientApplication

    访问Eureka控制台:      http://localhost:6001/

     

    访问请求:               http://localhost:8093/hello/wood

    出现服务提供者A:wood ,页面出现,设置断点,发现提供者也进入了,Feign消费者也进入了。

    1.3         拓展:Feign实现降级

    1.3.1      UserFeignFallback

    直接实现消费者的Feign接口,给每个方法设置异常时的处理

    package com.wood.feignclient.remote;

    import org.springframework.stereotype.Component;

    /**
    * Feign实现降级
    * 直接实现消费者的UserFeign接口,给每个方法设置异常时的处理
    */
    @Component // 微服务访问异常则启用降级
    public class UserFeignFallback implements EurekaServiceFeign {
    @Override
    public String hello(String name) {
    return "微服务访问异常则启用降级 hello";
    }
    }

    1.3.2      修改接口EurekaServiceFeign

    @FeignClient(value="provider-user", fallback = UserFeignFallback.class)

    1.3.3      application.properties

    server.port=8093
    spring.application.name=feign-client
    eureka.client.serviceUrl.defaultZone=http://localhost:6001/eureka
    # 定义根目录下日志级别
    logging.level.root=INFO

    #feign集成hystrix必须开启

    feign:

      hystrix:

        enabled: true

    1.4         Feign小结

    1.4.1      调用过程

     

    首先,提供者provider-user和消费者custorm-feign都注册到Eureka中。用户请求feign中的controllerfeign中的controller调用feign定义的接口方法。接口的方法根据注解去找到eureka注册中心中的provider-user地址,然后请求远程provider-user所在服务器的地址,然后调用远程的provider-user提供者的具体服务。提供者响应返回jsonjsonfeign封装传输给“接口”的返回值,“接口”在返回给feigncontroller,最终响应给用户。

    1.4.2      自动创建实现类

    Feign是典型的基于接口,基于动态代理技术自动生成代理对象。

    设置断点,可以清晰的看到这个过程。先访问feign-clientcontroller;观察EurekaServiceFeign接口,如下图其实一个jdk动态代理类。

     

    动态代理类根据配置的注解信息去Eureka中找到对应调用的提供者的链接信息,进行访问,断点就进入到provider-usercontroller中具体执行,执行完成层层返回。

    附上demo spring-clioud-feign.zip 

  • 相关阅读:
    jmeter的断言
    Fiddler(五)设置显式IP地址
    学习pycharm----自动化接口
    fidder重复创建数据+模拟接口响应数据+fidder接口测试
    python网络/并发编程部分简单整理
    python面向对象部分简单整理
    python模块与包简单整理
    python函数部分整理
    Python基础部分整理
    Scheme Implementations对比
  • 原文地址:https://www.cnblogs.com/wood-life/p/10332919.html
Copyright © 2011-2022 走看看