• Spring Cloud Feign 服务消费调用(三)


    序言

    Spring Cloud Netflix的微服务都是以HTTP接口的形式暴露的,所以可以用Apache的HttpClient或Spring的RestTemplate去调用

    Feign是一个使用起来更加方便的HTTP客户端,它用起來就好像调用本地方法一样,完全感觉不到是调用的远程方法 

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

    Feign会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。

    Feign整合了Ribbon和Hystrix(关于Hystrix我们后面再讲),可以让我们不再需要显式地使用这两个组件。 

    总起来说,Feign具有如下特性: 

    • 可插拔的注解支持,包括Feign注解和JAX-RS注解;
    • 支持可插拔的HTTP编码器和解码器;
    • 支持Hystrix和它的Fallback;
    • 支持Ribbon的负载均衡;
    • 支持HTTP请求和响应的压缩。

    https://github.com/Netflix/feign

    微服务提供方注册服务到Eureka实例代码

    pom.xml

    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>

     <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Finchley.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>       
            </dependencies>
        </dependencyManagement>

    资源配置文件

    ## server
    server.port=8082
    
    ##eureka
    eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/
    eureka.instance.instance-id=${spring.application.name}:${server.port}
    # 设置微服务调用地址为IP优先(缺省为false)
    eureka.instance.prefer-ip-address=true
    # 心跳时间,即服务续约间隔时间(缺省为30s)
    eureka.instance.lease-renewal-interval-in-seconds=30
    # 发呆时间,即服务续约到期时间(缺省为90s)
    eureka.instance.lease-expiration-duration-in-seconds=9

    起始文件

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

    接口controller,可以没有facade层的接口,这里是为拉给java其他客户端调用设计的。

    //controller层
    @RestController
    @RequestMapping(value = "/Promotion",method = RequestMethod.GET)
    public class PromotionController implements PromotionFacade {
        @Override
        @RequestMapping(value = "/delete")
        public String releasePromotion(@RequestParam int orderID){
            return orderID+"-- hello!";
        }
    }
    
    //facade层
    public interface PromotionFacade {
        /**
         * 释放门店优惠券
         */
        String releasePromotion(@RequestParam int orderID);
    }

    好啦,这个启动起来之后,就注册到啦eureka中啦,等待被调用吧。

    Feign调用简单示例

    pom.xml

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
     <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Finchley.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>       
            </dependencies>
        </dependencyManagement>

    资源配置文件

    ## server
    server.port=8083
    ##eureka
    eureka.instance.instance-id=${spring.application.name}:${server.port}
    eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/
    #租期更新时间间隔(3)
    eureka.instance.leaseRenewalIntervalInSeconds=30
    #租期到期时间(默认90秒)
    eureka.instance.leaseExpirationDurationInSeconds=90

    起始文件

    @SpringBootApplication
    @EnableFeignClients(basePackages = { "trade.order.remote" })
    @EnableEurekaClient
    public class StartMain {
        public static void main(String[] args) {
            SpringApplication.run(StartMain.class, args);
        }
    }

    调用类

    //remote层
    @FeignClient(name = "trade-promotion")
    public interface PromotionClient {
         @RequestMapping(value = "/Promotion/delete",method = RequestMethod.GET)
         String  releasePromotion(@RequestParam int orderID) ;
    }
    
    //controller 层
    @RestController
    @RequestMapping(value = "/promotion", method = RequestMethod.GET)
    public class PromotionController {
        @Autowired
        PromotionClient promotionClient;
    
        @RequestMapping(value = "/delete")
        public String delete(@RequestParam int orderID) {
            return promotionClient.releasePromotion(orderID);
        }
    }

    note:

    1.上述调用只又remote就可以啦。

    2.注意路由地址大小写规范,不要以为自己很牛逼,一会大一会小,要我说,你很挫,一直小就可以啦。。

    Feign 工作原理

    • 在开发微服务应用时,我们会在主程序入口添加 @EnableFeignClients 注解开启对 Feign Client 扫描加载处理。根据 Feign Client 的开发规范,定义接口并加 @FeignClients 注解。
    • 当程序启动时,会进行包扫描,扫描所有 @FeignClients 的注解的类,并将这些信息注入 Spring IOC 容器中。当定义的 Feign 接口中的方法被调用时,通过JDK的代理的方式,来生成具体的 RequestTemplate。当生成代理时,Feign 会为每个接口方法创建一个 RequetTemplate 对象,该对象封装了 HTTP 请求需要的全部信息,如请求参数名、请求方法等信息都是在这个过程中确定的。
    • 然后由 RequestTemplate 生成 Request,然后把 Request 交给 Client 去处理,这里指的 Client 可以是 JDK 原生的 URLConnection、Apache 的 Http Client 也可以是 Okhttp。最后 Client 被封装到 LoadBalanceclient 类,这个类结合 Ribbon 负载均衡发起服务之间的调用。

    @FeignClient 注解

    • name:指定 Feign Client 的名称,如果项目使用了 Eureka,name 属性会作为微服务的名称,用于服务发现。
    • url:url 一般用于调试,可以手动指定 @FeignClient 调用的地址。
    • decode404:当发生404错误时,如果该字段为 true,会调用 decoder 进行解码,否则抛出 FeignException。
    • configuration:Feign 配置类,可以自定义 Feign 的 Encoder、Decoder、LogLevel、Contract。
    • fallback:定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback 指定的类必须实现 @FeignClient 标记的接口。
    • fallbackFactory:工厂类,用于生成 fallback 类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码。
    • path:定义当前 FeignClient 的统一前缀。

    Feign参数绑定

    @PathVariable

        /**
         * 在服务提供者我们有一个方法是用直接写在链接,SpringMVC中用的@PathVariable
         * 这里边和SpringMVC中有些有一点点出入,SpringMVC中只有一个参数而且参数名的话是不用额外指定参数名的,而feign中必须指定
         */
        @RequestMapping(value = "/greet/{dd}",method = RequestMethod.GET)
        String greetFeign(@PathVariable("dd") String dd);

    @RequestParam

        /**
         * 这里说下@RequestParam 注解和SpringMVC中差别也是不大,我认为区别在于Feign中的是参数进入URL或请求体中,
         * 而SpringMVC中是参数从请求体中到方法中
         * @param ids id串,比如“1,2,3”
         * @return
         */
        @RequestMapping(value = "/users",method = RequestMethod.GET)
        public List<User> getUsersByIds(@RequestParam("ids") List<Long> ids);

    @RequestHeader

     /**
         * 这里是将参数添加到Headers中
         * @param name 参数
         */
        @RequestMapping(value = "/headers")
        String getParamByHeaders(@RequestHeader("name") String name);

    @RequestBody

       /**
         * 调用服务提供者的post方法,接收回来再被服务提供者丢回来
         * @param user User对象
         */
        @RequestMapping(value = "/user", method = RequestMethod.POST)
        User getUserByRequestBody(@RequestBody User user);

    Feign压缩与日志

    1.请求压缩(Feign request/response compression)

    ##这两行即可开启压缩
    feign.compression.request.enabled=true
    feign.compression.response.enabled=true
    ## 配置压缩具体信息
    feign.compression.request.enabled=true
    feign.compression.request.mime-types=text/xml,application/xml,application/json
    feign.compression.request.min-request-size=2048

    2. Feign日志(Feign logging)

    Feign对日志的处理非常灵活,可为每个Feign客户端指定日志记录策略,每个Feign客户端都会创建一个logger。默认情况下,logger的名称是Feigh接口的完整类名。需要注意的是,Feign的日志打印只会对Debug级别做出响应。

    我们可以为每个Feign客户端配置各种的Logger.Level对象,告诉Feign记录哪些日志。Logger.Level的值有以下选择。

    • NONE,无记录(DEFAULT)。
    • BASIC,只记录请求方法和URL以及响应状态代码和执行时间。
    • HEADERS,记录基本信息以及请求和响应标头。
    • FULL,记录请求和响应的头文件,正文和元数据。

    开启记录

    logging.level.com.cnblogs.hellxz.client.EurekaServiceFeign: DEBUG

    总结

    多看文档吧

  • 相关阅读:
    20170612测试
    vijos1453曼哈顿距离
    vijos1153 猫狗大战
    vijos1037搭建双塔
    dijkstra+priority_queue+vector
    BZOJ1507: [NOI2003]Editor
    dinic模板
    旅行-树形DP
    51nod1799-二分答案
    51nod1791-合法括号子段
  • 原文地址:https://www.cnblogs.com/knowledgesea/p/11208013.html
Copyright © 2020-2023  润新知