Feign默认集成了ribbon,并和Eureka结合,默认实现了负载均衡的效果。
核心代码和配置如下:
- 在application.yml文件,指定程序名为service-feign,端口号8765,指定服务注册地址为http://localhost:8761/eureka/,同时需要开启断路器,代码如下:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8765
spring:
application:
name: service-feign
# Feign是自带断路器的,在D版本的Spring Cloud中,它没有默认打开。
# 需要在配置文件中配置打开它,在配置文件加以下代码
feign:
hystrix:
enabled: true
- 在程序的启动类上加上@EnableFeignClients注解开启Feign的功能:
package com.dalingjia.servicefeign;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* Feign的源码实现的过程如下:
*
* 1, 首先通过@EnableFeignCleints注解开启FeignCleint
* 2, 根据Feign的规则实现接口,并加@FeignCleint注解
* 3, 程序启动后,会进行包扫描,扫描所有的@FeignCleint的注解的类,并将这些信息注入到ioc容器中。
* 4, 当接口的方法被调用,通过jdk的代理,来生成具体的RequestTemplate
* 5, RequestTemplate在生成Request
* 6, Request交给Client去处理,其中Client可以是HttpUrlConnection、HttpClient也可以是Okhttp
* 7, 最后Client被封装到LoadBalanceClient类,这个类结合类Ribbon做到了负载均衡
*
* 在工程的启动类中,通过@EnableDiscoveryClient向服务中心注册
* @EnableFeignClients注解开启Feign的功能
*/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ServiceFeignApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceFeignApplication.class, args);
}
}
- 定义一个接口,通过@FeignClient(“服务名”),来指定调用哪个服务。比如在代码中调用了service-hi服务的“hi”接口,代码如下:
/**
* @author tanhq
* 定义一个feign接口,通过@FeignClient(“服务名”),来指定调用哪个服务。比如在代码中调用了service-hi服务的“/hi”接口
*
* Feign中使用断路器,基于service-feign工程进行改造,只需要在FeignClient的SchedualServiceHi接口的注解中加上fallback的指定类就行了
*/
@FeignClient(value = "service-hi", fallback = SchedualServiceHiHystric.class)
public interface SchedualServiceHi {
@RequestMapping(value = "/hi",method = RequestMethod.GET)
String sayHiFromClientOne(@RequestParam(value = "name") String name);
}
fallback的指定类如下:
package com.dalingjia.servicefeign.service;
import org.springframework.stereotype.Component;
@Component
public class SchedualServiceHiHystric implements SchedualServiceHi {
@Override
public String sayHiFromClientOne(String name) {
return "sorry "+name;
}
}
在Web层的controller层,对外暴露一个"/hi"的API接口,通过上面定义的Feign客户端SchedualServiceHi 来消费服务。
package com.dalingjia.servicefeign.controller;
import com.dalingjia.servicefeign.service.SchedualServiceHi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HiController {
@Autowired
SchedualServiceHi schedualServiceHi;
@RequestMapping(value = "/hi",method = RequestMethod.GET)
public String sayHi(@RequestParam String name){
return schedualServiceHi.sayHiFromClientOne(name);
}
}
启动程序,多次访问http://localhost:8765/hi?name=forezp,浏览器交替显示:
hi forezp,i am from port:8762
hi forezp,i am from port:8763
此时关闭 service-hi 工程,当我们再访问http://localhost:8765/hi?name=forezp,浏览器会显示:
sorry forezp