1.1.背景

当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下,并且显得好傻。

那么有没有更好的解决方案呢?答案是确定的有,Netflix已经为我们提供了一个框架:Feign。

1.2.Feign概述

Feign是Spring Cloud提供的声明式、模板化的HTTP客户端, 它使得调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加一个注解即可。

Spring Cloud集成Feign并对其进行了增强,使Feign支持了Spring MVC注解;Feign默认集成了Ribbon,所以Fegin默认就实现了负载均衡的效果。

1.3.Feign入门

1.3.1.创建服务提供者

1.3.1.1.创建工程

        

1.3.1.2.application.yml

server:

port: 9091

spring:

cloud:

nacos:

discovery:

server-addr: 192.168.128.131:8848 #nacos服务的地址

application:

name: feign-provider #向注册中心注册的名字

 pom文件

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">

springCloud_parent

com.peng

1.0-SNAPSHOT

4.0.0

feign_provider01

8

8

org.springframework.boot

spring-boot-starter-web

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-discovery

com.peng

springcloud_commom

1.0-SNAPSHOT

controller

package com.peng.controller;

import com.peng.pojo.User;

import com.peng.service.UserService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

@RestController

@RequestMapping("/provider")

public class ProviderController {

@Autowired

private UserService userService;

@RequestMapping("/getUserById/{id}")

public User getUserById(@PathVariable Integer id){

return userService.getUserById(id);

}

@RequestMapping("/deleteUserById")

public User deleteUserById(@RequestParam("id") Integer id){

return userService.deleteUserById(id);

}

@RequestMapping("/addUser")

public User addUser(@RequestBody User user){

return userService.addUser(user);

}

}

service

package com.peng.service;

import com.peng.pojo.User;

public interface UserService {

User getUserById(Integer id);

User deleteUserById(Integer id);

User addUser(User user);

}

impl

package com.peng.service.impl;

import com.peng.pojo.User;

import com.peng.service.UserService;

import org.springframework.stereotype.Service;

@Service

public class UserServiceImpl implements UserService {

@Override

public User getUserById(Integer id) {

return new User(id,"张三-01",12);

}

@Override

public User deleteUserById(Integer id) {

return new User(id,"删除了张三-01",12);

}

@Override

public User addUser(User user) {

return new User(22,"新增了张三-01",12);

}

}

启动类

package com.peng;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication

@EnableDiscoveryClient //向注册中心注册该服务,并可以获取其他服务的调用地址

public class SpringCloudProviderApp {

public static void main(String[] args) {

SpringApplication.run(SpringCloudProviderApp.class,args);

}

}

1.3.2.创建feign接口

1.3.2.1.创建工程

pom文件

org.springframework.cloud

spring-cloud-starter-openfeign

com.peng

springcloud_commom

1.0-SNAPSHOT

 

1.3.2.3.feign在接口中使用

1、@RequestMapping表示 拼接请求路径     localhost:80/getUser/1

2、@PathVariable("id") 表示  ?传参                localhost:80/getUser?id=1

3、@RequestBody   对象转JSON传参           localhost:80/getUser?id=1&name=zs     转成JSON

package com.peng.feign;

import com.peng.pojo.User;

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.RequestParam;

@FeignClient("feign-provider") //调用的服务名

@RequestMapping("/provider") //拼接路径

public interface UserServiceFeign {

@RequestMapping("/getUserById/{id}") //拼接url

User getUserById(@PathVariable("id") Integer id); //restful形式拼接参数

@RequestMapping("/deleteUserById") //拼接url

User deleteUserById(@RequestParam("id") Integer id);//?形式拼接参数

@RequestMapping("/addUser") //拼接url

User addUser(@RequestBody User user); //pojo ==> json 把传过来的参数转成json串

}

1.3.3.创建服务消费者

1.3.3.1.创建工程

1.3.3.2.pom.xml

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">

springCloud_parent

com.peng

1.0-SNAPSHOT

4.0.0

feign_consumer

8

8

org.springframework.boot

spring-boot-starter-web

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-discovery

com.peng

feign_interface

1.0-SNAPSHOT

1.3.3.3.application.yml

server:

port: 80

compression:

enabled: true #开启gzip压缩

spring:

cloud:

nacos:

discovery:

server-addr: 192.168.128.131:8848 #向nacos中心注册服务(nacos服务的地址)

application:

name: feign-consumer #给该服务起个名字

1.3.3.4.Controller

package com.peng.controller;

import com.peng.feign.UserServiceFeign;

import com.peng.pojo.User;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

@RestController

@RequestMapping("/consumer")

public class ConsumerController {

//访问Rest服务的客户端

@Autowired

private UserServiceFeign userServiceFeign; //注入代理类

@RequestMapping("/getUserById/{id}")

public User getUserById(@PathVariable Integer id){

//打印代理类的类型

System.out.println(userServiceFeign.getClass());

return userServiceFeign.getUserById(id);

}

@RequestMapping("/deleteUserById")

public User deleteUserById(@RequestParam("id") Integer id){

//打印代理类的类型

System.out.println(userServiceFeign.getClass());

return userServiceFeign.deleteUserById(id);

}

@RequestMapping("/addUser")

public User addUser(User user){

//打印代理类的类型

System.out.println(userServiceFeign.getClass());

return userServiceFeign.addUser(user);

}

}

配置类

package com.peng.config;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.client.RestTemplate;

@Configuration

public class ConfigBean {

@Bean

public RestTemplate restTemplate(){

return new RestTemplate();

}

}

1.3.3.4.app(启动类)

package com.peng;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication

@EnableDiscoveryClient //向Nacos 注册中心注册该服务,并可以获取其他服务的调用地址

@EnableFeignClients //开启feign注解扫描

public class SpringCloudConsumerApp {

public static void main(String[] args) {

SpringApplication.run(SpringCloudConsumerApp.class,args);

}

}

测试:三种方式访问

第一种:对象

第二种:路径传参

第三种:路径拼接传参,key=value

1.4.Feign原理

1.4.1、将feign接口的代理类扫描到Spring容器中:         @EnableFeignClients开启feign注解扫描:FeignClientsRegistrar.registerFeignClients()扫描被 @FeignClient标识的接口生成代理类,         并把接口和代理类交给Spring的容器管理。 1.4.2、为接口的方法创建RequestTemplate         当consumer调用feign代理类时,代理类会调用SynchronousMethodHandler.invoke()创建RequestTemplate(url,参数) 1.4.3、发出请求         代理类会通过RequestTemplate创建Request,然后client(URLConnetct、HttpClient、OkHttp)使用Request发送请求

 1.5feign优化

1.5.1、开启feign日志

        feign:           client:             config:               default:             loggerLevel: full         logging:           level:             com.peng.feign: debug

 

    1.5.2、feign超时

        1、方式一:             ribbon:                ConnectTimeout: 5000 #请求连接的超时时间                ReadTimeout: 5000 #请求处理的超时时间         2、方式二:             feign:               client:                 config:                   feign-provider:                 ConnectTimeout: 5000 #请求连接的超时时间                 ReadTimeout: 5000 #请求处理的超时时间

不配置的话默认是一秒,超过一秒就会抛异常,可以配置连接超时时间,当开启日志时,会忽略连接超时

    1.5.3、http连接池

                     io.github.openfeign             feign-httpclient         

    1.5.4、gzip压缩

         server:           compression:               enabled: true #开启gzip压缩

 

 

 

 

文章来源

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: