feign的性能优化、Feign的使用、feign超时-最佳优化两种方案

---------------------------声明式服务调用Feign--------------------------
一、feign介绍

1、什么是feign?
    feign是spring cloud提供的声明式的http客户端,工作在consumer端
    feign支持springmvc注解
    feign集成ribbon也支持负载均衡(restTemplate+ribbon=feign)
2、feign启动器
    spring-cloud-starter-openfeign

二、feign入门案例

1、 创建服务提供者feign_provider
       需要spring-*-web和spring-*-nacos-discovery依赖
       服务提供者仅仅需要向nacos中注册即可  需要再启动类上面加上@EnableDiscoveryClient即可

     1. pom.xml
	      <dependencies>
		 <dependency>
		   <groupId>org.springframework.boot</groupId>
		   <artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	       <dependency>
		    <groupId>com.bjpowernode</groupId>
		    <artifactId>springcloud_common</artifactId>
		    <version>1.0-SNAPSHOT</version>
		 </dependency>
		 <!--nacos客户端-->
		  <dependency>
		    <groupId>com.alibaba.cloud</groupId>
		    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
		  </dependency>
	     </dependencies>

     2.application.yml
           server:
             port: 8090
                spring:
                    cloud:
                       nacos:
                         discovery:
                              server-addr: 192.168.126.132 #注册中心的地址
                    application:
                       name: feign-provider #注册到nacos的服务名

    3.controller

		@RestController
		@RequestMapping("/provider")
		public class ProviderController {

		    @Autowired
		    private UserService userService;

		    @RequestMapping("/getUserById/{id}")
		    public User getUserById(@PathVariable Integer id){

			return userService.getUserById(id);
			    }
			}
         4.service

          1) UserService

	  public interface UserService {
		    User getUserById(Integer id);
		}

	  2) UserServiceImpl

		@Service
		public class UserServiceImpl implements UserService {

		    @Override
		    public User getUserById(Integer id){
			return new User(id,"张三--2",19);
		    }
		}
		
         5.启动类(App)
		@SpringBootApplication
		@EnableDiscoveryClient
		public class FeignPerviderApp {
		    public static void main(String[] args) {
			SpringApplication.run(FeignPerviderApp.class,args);
		    }
		}


2、创建feign_interface接口

	  接口需要openfeign依赖  然后开放注册到nacos中的provider的某一个接口
	  仅仅需要再interface上面添加一个@feignclient(注册到nacos的服务名)即可 

    1、pom.xml
	    <dependencies>
	<!--Spring Cloud OpenFeign Starter -->
	<dependency>
	    <groupId>org.springframework.cloud</groupId>
	    <artifactId>spring-cloud-starter-openfeign</artifactId>
	</dependency>
	<dependency>
	    <groupId>com.bjpowernode</groupId>
	    <artifactId>springcloud_common</artifactId>
	    <version>1.0-SNAPSHOT</version>
	</dependency>
    </dependencies>

    2、feign接口 (UserFeign)
    
	@FeignClient("feign-provider")//这个名字需要跟前面注册到nacos中的provoder的注册服务名字保持一致
	@RequestMapping("/provider")//保持与provider一致
	public interface UserFeign {
	    @RequestMapping("/getUserById/{id}")
	    public User getUserById(@PathVariable("id") Integer id);
	}


3、创建服务的消费者feign_consumer
      需要spring-*-web和spring-*-nacos-discovery依赖  同时还要将interface类引入依赖
    服务消费者需要向nacos中注册同时还需要 扫描onterface包 需要再启动
    类上面加上@EnableDiscoveryClient和@EnableFeignClients

    1、pom.xml
	    <dependencies>
	<dependency>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
	    <groupId>com.alibaba.cloud</groupId>
	    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
	</dependency>
	<dependency>
	    <groupId>com.bjpowernode</groupId>
	    <artifactId>feign_interface</artifactId>
	    <version>1.0-SNAPSHOT</version>
	</dependency>
    </dependencies>


    2、application.yml
      server:
	  port: 80
	spring:
	  cloud:
	    nacos:
	      discovery:
		server-addr: 192.168.126.132:8848 #注册中心地址
	  application:
	    name: feign-consumer #注册到nacos的服务名


    3、controller
	    @RestController
	    @RequestMapping("/consumer")
	    public class ConsumerController {

	    @Autowired
	    private UserFeign userFeign;

	    @RequestMapping("/getUserById/{id}")
	    public User getUserById(@PathVariable Integer id){
		System.out.println(userFeign.getClass());//代理类
		return userFeign.getUserById(id);
	    }
	}


    4、启动类App
	@SpringBootApplication
	@EnableDiscoveryClient
	@EnableFeignClients //开启feign接口扫描  注意consumer与interface里面的包名保持一致
	public class FeignConsumerApp {
	    public static void main(String[] args) {
		SpringApplication.run(FeignConsumerApp.class,args);
	    }
	}

三、feign原理

      @EnableFeignClients===》@ FeignClient ===》接口中方法上的注
  解 @RequestMapping("/getUserById/{id}") // @RequestMapping 作用:拼接参数

 1、扫描feign接口生成代理类并交给spring容器管理
    当服务消费者的启动类启动时,通过注解 @EnableFeignClients 的这个类
    (FeignClientsRegistrar )中的  (registerFeignClients)这个方法,扫
    描被@ FeignClient标识的接口生成代理类, 然后放入 spring ioc容器中 
      
     2、为接口的方法创建RequestTemplate
         当controller调用定义的Feign接口中的方法时,通过JDK的代理方式为Feign接口生成了一个动态代理类,
        【代理类会调用SynchronousMethodHandler.invoke()创建RequestTemplate(url、requestMethod、body)】
         当生成代理时,Feign会为每个接口方法创建一个RequestTemplate。该对象封装了HTTP请求需要的
         全部信息,如请url、参数,请求方式等信息都是在这个过程中确定的。

    3、发起请求
接着通过RequestTemplate创建Request,然后client(HttpClient、OkHttp、URLConnection)使用Request发送请求

四、feign接口三种传参方式

	   controller层 传参时 不需要写 @RequestParam 和 @RequestBody 这两个注解否则会报错
	   接口中三个注解必须都要写
	      
	    1、?传参
		@RequestParam("id") //拼接参数   url?=123  
	    2、restful传参
		@PathVariable("id")  //拼接参数   url/123
	    3、pojo传参
		@RequestBody   把对象转成串 

五、feign优化

feign优化的原因:
      Feign的HTTP客户端支持3种框架:HttpURLConnection、HttpClient、OkHttp,底层默认使用
  的是URLConnection,这是jdk自带的发送http请求的包,不支持连接池;
  这样在发送http请求时,每次都要建立连接(三次握手),发送数据,断开
  连接(四次挥手),比较浪费性能、消耗时间。所以使用Apache HttpClient底层实
  现;日志级别推荐设置full,

1、开启feign日志(feign_consumer==》application.yml)
          feign的日志级别包含下面几个:
            NONE:不输出日志
            BASIC:输出请求方法及url,响应的状态码及响应时间
            HEADERS:输出请求和响应的头信息
            FULL:输出请求和响应的请求头,消息体及元数据

    feign:
      client:
        config:
          default:
            loggerLevel: full #feign显示日志

	  首先需要设置属性logging.level.+包名:debug。
	  打开这个属性的原因?
	  因为feign的logger实现类Slf4jLogger在调用log方法时,
	  会判断是否开启了debug。

   logging:
      level:
        com.bjpowernode.feign: debug  #log4j的日志级别  这个包下com.bjpowernode.feign


2、GZIP压缩
      使用GZIP的原因:
      当 Gzip 压缩到一个纯文本文件时,效果是非常明显的,大约可以减
      少 70% 以上的文件大小,网络数据经过压缩后实际上降低了网络传
      输的字节数,最明显的好处就是可 以加快网页加载的速度。网页加载
      速度加快的好处不言而喻,除了节省流量,改善用户的浏 览体验外,
      另一个潜在的好处是 Gzip 与搜索引擎的抓取工具有着更好的关系。
      例如 Google 就可以通过直接读取 gzip 文件来比普通手工抓取 更快地检索网页。

   在spring-cloud-openfeign-core.jar文件中.默认对请求和响应
   压缩是禁用的,需要我们手动开启

 application.yml
	server:
	  compression:
	    enabled: true #开启浏览器<----->consumer的gzip压缩
	feign:
	  compression:
	    request:
	      enabled: true #开启feign<---->provider的gzip压缩
	    response:
	      enabled: true
	      #配置支持压缩的文本 使用默认的即可   deflate这个属性表示算法
	      mime-types



3、http连接池

在消费者consumer中引入依赖,
pom.xml

    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-httpclient</artifactId>
    </dependency>

4、feign超时
   方式一:
   application.yml
        ribbon:
          ConnectionTimeout: 5000 #请求连接的超时时间
          ReadTimeout: 5000 #请求处理的超时时间


    方式二:

测试:给指定的方法睡眠3000毫秒
     @Service
public class UserServiceImpl implements UserService {

 @Override
 public List<User> addUsers(List<User> userList) {
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return userList;
   }
}

application.yml
        feign:
          client:
            config:
              feign-provider:  # feign-provider:指定的服务 default:也可以是所有的服务
                ConnectionTimeout: 5000 #请求连接的超时时间
                ReadTimeout: 5000 #请求处理的超时时间
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值