1. Feign是什么?
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。
2. 用来做什么?
1.Feign是用来做服务之间的远程调用的,类似于dubbo。
 2.Feign集成了Ribbon,Ribbon是SpringCloud中基于Http/Tcp客户端负载均衡工具。
 3.Feign集成了熔断器,避免了当调用的服务宕机时出现错误。
3. 创建工程
创建一个为server-feign的Maven Model,
 pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http:///POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http:///POM/4.0.0 http:///xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.sakura</groupId>
        <artifactId>basice</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.sakura</groupId>
    <artifactId>server-feign</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>server-feign</name>
    <description>server-feign</description>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--eureka-client-->
        <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-openfeign</artifactId>
        </dependency>
    </dependencies>
    <!--<build>-->
        <!--<plugins>-->
            <!--<plugin>-->
                <!--<groupId>org.springframework.boot</groupId>-->
                <!--<artifactId>spring-boot-maven-plugin</artifactId>-->
            <!--</plugin>-->
        <!--</plugins>-->
    <!--</build>-->
</project>配置Feign
 Application.yml
eureka:
  client:
    register-with-eureka: true #是否注册
    service-url: #服务中心地址
      defaultZone: http://192.168.16.96:10000/eureka/
  instance:
    hostname: 192.168.16.96 #设置当前实例(服务)的主机地址
    lease-expiration-duration-in-seconds: 90 #多久没有上报心跳就移除自己(单位:s)
    lease-renewal-interval-in-seconds: 30  #心跳间隔时间(单位:s)
server:
  port: 10002
spring:
  application:
    name: feign
    
feign: #feign自带的熔断器  启用
  hystrix:
      enabled: true4. 创建远程调用接口
例如我们需要调用之前在eureka-client中的 /hello/port接口
 eureka-client中的接口
package com.sakura.ofmeurekaclient.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/hello")
public class HelloController {
    @Value("${server.port}")
    String port;
    @RequestMapping("/port")
    public String port(@RequestParam("name") String name){
        return "hello"+name+",this is "+port;
    }
}我们在server-feign中创建一个名为HelloRemote的interface和HelloRemoteHSX的实现类 结构如下

 HelloRemote 就是远程调用使用的接口
 HelloRemoteHSX 是远程调用异常 熔断器使用的接口
HelloRemote.java
package com.sakura.serverfeign.remote;
import com.sakura.serverfeign.remote.hystrix.HelloRemoteHSX;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
 * FeignClient注解
 * value:需要调用服务的应用名
 * path:如果服务提供者有contextpath  则需要在path中申明
 * fallback:服务调用失败 熔断器执行的方法类  该类需要实现当前接口 并且注入到IOC容器中
 *
 * 其余部分与Controller层一样
 * 只是都是接口,不需要实现方式 类上的RequestMapping的增加到方法上去 不然启动会异常
 */
@FeignClient(value = "eureka-client",path = "/client",fallback = HelloRemoteHSX.class)
public interface HelloRemote {
    @RequestMapping("/hello/port")
    String port(@RequestParam("name") String name);
}HelloRemoteHSX.java
package com.sakura.serverfeign.remote.hystrix;
import com.sakura.serverfeign.remote.HelloRemote;
import org.springframework.stereotype.Component;
@Component
public class HelloRemoteHSX implements HelloRemote {
    @Override
    public String port(String name) {
        return "server error";
    }
}而后我们在server-feign中创建一个Controller来调用我们的远程接口进行测试
HelloController.java
package com.sakura.servicefeign.controller;
import com.sakura.servicefeign.remote.HelloRmote;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/hello")
public class HelloController {
    @Autowired
    private HelloRmote helloRmote;
    @RequestMapping("/hi")
    public String hi(@RequestParam("name") String name){
        return helloRmote.hi(name);
    }
}然后启动Eureka服务中心
 再在不同的端口分别启动eureka-client两次 (关于idea怎么启动多实例服务请自行百度)
 然后启动server-feign
 在注册中心确认各个模块是否都正常启动了

 可以看到我分别在10008端口和10001端口启动了eureka-client
 然后调用server-feign中的Controller接口
 反复刷新 会得到两个不同的结果(因为我返回了当前服务的启动端口)


 这就说明Feign集成的负载均衡效果生效了此时我们停掉一个eureka-client服务器,再多次刷新


 就会发现熔断器执行了我们实现的方法,说明此时熔断器生效了。
                
 
 
                     
            
        













 
                    

 
                 
                    