学习springCloud(七)之Feign接口服务

前面已经简述了Ribbon负载均衡,从Eureka获取服务的实例在通过RestTemplate调用,并转换成需要的对象

 List<Product> list = restTemplate.exchange(PRODUCT_LIST_URL,HttpMethod.GET,new HttpEntity<Object>(httpHeaders), List.class).getBody();

可以发现所有的数据调用和转换都是由用户直接来完成的,我们可能不想直接访问Rest接口,如果转换回来的直接是对象而不需要直接使用RestTemplate进行转换就好了,这个时候就需要使用Feign了

Feign的基本使用

复制【microcloud-consumer】 成一个新的模块【microcloud-consumer-feign】

【microcloud-consumer-feign】修改pom文件,增加对feign的支持

<?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</artifactId>
        <groupId>enjoy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>microcloud-consumer-feign</artifactId>
    <dependencies>
        <dependency>
            <groupId>enjoy</groupId>
            <artifactId>microcloud-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

</project>

注意:这里又有版本问题,如果是Edgware或之前的版本,

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

feign的操作其实需要ribbon的支持

【microcloud-service】,新建立一个microcloud-service模块,这个模块专门定义客户端的调用接口

【microcloud-service】,修改pom文件如下

<?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</artifactId>
        <groupId>enjoy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>microcloud-service</artifactId>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>enjoy</groupId>
            <artifactId>microcloud-api</artifactId>
        </dependency>
    </dependencies>

</project>

【microcloud-service】如果要通过Feign进行远程调用,依然需要安全服务提供方的认证问题,不过在feign里面已经集成了这块功能

package cn.enjoy.feign;
import feign.auth.BasicAuthRequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignClientConfig {
    @Bean
    public BasicAuthRequestInterceptor getBasicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("admin", "enjoy");
    }
}

【microcloud-service】 新建一个IProductClientService接口

package cn.enjoy.service;

import cn.enjoy.feign.FeignClientConfig;
import cn.enjoy.vo.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;
@FeignClient(name = "MICROCLOUD-PROVIDER-PRODUCT",configuration = FeignClientConfig.class)
public interface IProductClientService {
    @RequestMapping("/prodcut/get/{id}")
    public Product getProduct(@PathVariable("id")long id);

    @RequestMapping("/prodcut/list")
    public  List<Product> listProduct() ;

    @RequestMapping("/prodcut/add")
    public boolean addPorduct(Product product) ;

}

【microcloud-consumer-feign】 修改pom文件,引入microcloud-service 包

 <dependency>
            <groupId>enjoy</groupId>
            <artifactId>microcloud-service</artifactId>
        </dependency>

【microcloud-consumer-feign】 由于microcloud-service里面已经做了安全验证,并且后面并不直接使用RestTemplate ,删除RestConfig.java类

//package cn.enjoy.config;
//
//
//import org.springframework.cloud.client.loadbalancer.LoadBalanced;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.http.HttpHeaders;
//import org.springframework.web.client.RestTemplate;
//
//import java.nio.charset.Charset;
//import java.util.Base64;
//
//@Configuration
//public class RestConfig {
//
//    @Bean
//    @LoadBalanced
//    public RestTemplate restTemplate() {
//        return  new RestTemplate();
//    }
//
//    @Bean
//    public HttpHeaders getHeaders() { // 要进行一个Http头信息配置
//        HttpHeaders headers = new HttpHeaders(); // 定义一个HTTP的头信息
//        String auth = "root:enjoy"; // 认证的原始信息
//        byte[] encodedAuth = Base64.getEncoder()
//                .encode(auth.getBytes(Charset.forName("US-ASCII"))); // 进行一个加密的处理
//        String authHeader = "Basic " + new String(encodedAuth);
//        headers.set("Authorization", authHeader);
//        return headers;
//    }
//
//
//}

【microcloud-consumer-feign】 修改ConsumerProductController,这个时候直接使用microcloud-service定义的服务就可以了

package cn.enjoy.controller;
import cn.enjoy.service.IProductClientService;
import cn.enjoy.vo.Product;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/consumer")
public class ConsumerProductController {
    @Resource
    private IProductClientService iProductClientService;

    @RequestMapping("/product/get")
    public Object getProduct(long id) {
        return  iProductClientService.getProduct(id);
    }

    @RequestMapping("/product/list")
    public  Object listProduct() {
        return iProductClientService.listProduct();
    }

    @RequestMapping("/product/add")
    public Object addPorduct(Product product) {
        return  iProductClientService.addPorduct(product);
    }
    
}

可见,这个时候ConsumerProductController的代码已经简洁了不少

【microcloud-consumer-feign】修改程序主类

package cn.enjoy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients("cn.enjoy.service")
public class ConsumerFeignApp {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerFeignApp.class,args);
    }
}

启动测试:
http://localhost/consumer/product/list
可以发现Feign在调用接口的时候自带负载均衡,这也不奇怪,因为Fegin里面内置就使用的Ribbon

可以做个测试,看下是否真的如此
【microcloud-consumer-feign】修改程序主类

package cn.enjoy;

import cn.xiangxue.config.RibbonConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients("cn.enjoy.service")
@RibbonClient(name ="MICROCLOUD-PROVIDER-PRODUCT" ,configuration = RibbonConfig.class)
public class ConsumerFeignApp {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerFeignApp.class,args);
    }
}

启动测试:
http://localhost/consumer/product/list
可以发现,现在的路由规则以及变成了随机访问

其他配置

数据压缩

前面我们已经知道Feign之中最核心的作用就是将Rest服务的信息转化为接口,这其中还有其他的一些地方应该要考虑,比如:数据的压缩
Rest协议更多的传输的是文本,JSON或者XML,如果用户发送的请求很大,这个时候有必要对数据进行压缩处理,好在feign本身就提供了压缩的支持

FeignContentGzipEncodingAutoConfiguration 可以先看下这个类
在这里插入图片描述

虽然Feign支持压缩,但默认是不开启的

再看下FeignClientEncodingProperties,可以根据这里面的属性进行相关压缩的配置

【microcloud-consumer-feign】 修改application.yml配置文件

feign:
 compression:
  request:
    enabled: true
    mime-types: # 可以被压缩的类型
     - text/xml
     - application/xml
     - application/json
    min-request-size: 2048 # 超过2048的字节进行压缩

日志配置

在构建@FeignClient注解修饰的服务客户端时,会为一个客户端都创建一个feign.Logger实例,可以利用日志来分析Feign的请求细节,不过默认 Feign的日志是不开启的。

【microcloud-consumer-feign】 修改 application.yml配置文件,增加日志信息

logging:
 level:
  cn.enjoy.service: DEBUG

只添加上面配置还无法实现对DEBUG日志的输出,以因为Feign客户端默认的logger.level对象定义为none级别,所以不会记录feign调用过程中的信息
在这里插入图片描述
【microcloud-service】修改FeignClientConfig,开启日志输出

package cn.enjoy.feign;
import feign.Logger;
import feign.auth.BasicAuthRequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignClientConfig {

    @Bean
    public Logger.Level getFeignLoggerLevel() {
        return feign.Logger.Level.FULL ;
    }

    @Bean
    public BasicAuthRequestInterceptor getBasicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("admin", "enjoy");
    }
}

访问:localhost/consumer/product/list

  • 当使用 Feign 要通过接口的方法访问 Rest 服务的时候会根据设置的服务类型发出请求,这个请求是发送给 Eureka
  • 随后由于配置了授权处理,所以继续发送授权信息(“Authorization”)
    其实在外面使用RestTemplate的时候也是这么做的,可以对应日志的加密内容和直接访问其实是一样的。
  • 在进行服务调用的时候 Feign 融合了 Ribbon 技术,所以也支持有负载均衡的处理

总结:Feign = RestTempate + HttpHeader + Ribbon + Eureka 综合体,使用feign大大增加了代码的灵活程度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值