前言
Ribbon负载均衡链接
一、概述
1、概述
Feign是一个声明式的Web服务客户端,使得编写Web服务客户端变得非常容易,只需要创建一个接口,然后在上面添加注解即可。
2、Feign作用
Feign旨在使编写Java Http客户端变得更容易。
前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,
往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用
。所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可)
,即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。
3、Feign集成了Ribbon
利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,
通过Feign只需要定义服务绑定接口且以声明式的方法
,优雅而简单的实现了服务调用。
4、OpenFeign
OpenFeign是SpringCloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
二、OpenFeign使用步骤
1、新建一个Module
项目名:cloud-consumer-feign-order80
2、pom.xml
<dependencies>
<!--openfeign相关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</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-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.itan</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
3、yml配置
server:
port: 80
eureka:
# 设置服务名称信息(自定义)并设置访问路径可以显示 IP 地址
instance:
instance-id: feign80
prefer-ip-address: true
client:
# 表示是否将自己注册进EurekaServer默认为true
register-with-eureka: false
# 是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
# 客户端注册进 eureka 服务列表内
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
logging:
level:
com.itan.feign.ProviderFeignClient: debug
4、主启动类
@SpringBootApplication
@EnableFeignClients
public class Feign80 {
public static void main(String[] args) {
SpringApplication.run(Feign80.class,args);
}
}
5、Feign接口
通过使用
@FeignClient
注解调用Provider服务,新建一个feign包,用来存放feign接口
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE",configuration = {ProviderFeignClient.ProviderFeignClientConfigure.class})
public interface ProviderFeignClient {
@PostMapping("payment/getOne")
CommonResult getOne(Payment payment);
class ProviderFeignClientConfigure{
//设置超时时间
@Bean
Request.Options options(){
return new Request.Options(30000,60000);
}
}
}
6、控制层
@Slf4j
@RestController
@RequestMapping("feign")
public class Feign80Controller {
@Resource
private ProviderFeignClient providerFeignClient;
@PostMapping("getOne")
public CommonResult getOne(@RequestBody Payment payment){
log.info("入参:" + JSON.toJSONString(payment));
CommonResult result = providerFeignClient.getOne(payment);
log.info("出参:" + JSON.toJSONString(result));
return result;
}
}
7、测试
1、先启动服务注册中心7001、7002
2、再启动服务提供者8001、8002
3、最后启动cloud-consumer-feign-order80服务消费者
4、在postman中调用接口发现端口交替出现,达到负载均衡的效果
三、OpenFeign超时控制
1、概述
默认Feign客户端只等待一秒钟
,但是服务端处理有可能会超过一秒钟,导致Feign客户端不想等待了,直接返回报错,为了避免这样的情况,有时候就需要设置Feign客户端的超时控制。
2、测试延迟一秒钟
1、在8001服务提供者中,新建一个超时等待方法
@PostMapping("timeout")
public String timeout(){
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e){
e.printStackTrace();
}
return port;
}
2、在Feign80消费服务中添加调用方法
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE"/**,configuration = {ProviderFeignClient.ProviderFeignClientConfigure.class}**/)
public interface ProviderFeignClient {
@PostMapping("payment/getOne")
CommonResult getOne(Payment payment);
@PostMapping("payment/timeout")
String timeout();
// 将此内部类注释,是为了更好的验证超时一秒钟报错的情况
// class ProviderFeignClientConfigure{
// //设置超时时间
// @Bean
// Request.Options options(){
// return new Request.Options(30000,60000);
// }
// }
}
3、控制层
@PostMapping("timeout")
public CommonResult timeout(){
//openFeign-ribbon,客户端一般默认等待1秒钟
CommonResult result = CommonResult.success(providerFeignClient.timeout());
return result;
}
4、测试
由于在之前启动了服务,此处只用启动修改的服务8001和feign80服务即可。
在postman中调用接口,发现超时错误,即验证成功,默认Feign客户端只等待一秒。
3、解决方法
1、由于OpenFiegn默认支持Ribbon,所以可以在yml文件配置
ribbon:
# 指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间
ReadTimeout: 10000
# 指的是建立连接后服务器读取到可用资源的所用时间
ConnectTimeout: 10000
2、可以在Fiegn接口中设置超时时间
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE",configuration = {ProviderFeignClient.ProviderFeignClientConfigure.class})
public interface ProviderFeignClient {
@PostMapping("payment/getOne")
CommonResult getOne(Payment payment);
@PostMapping("payment/timeout")
String timeout();
class ProviderFeignClientConfigure{
//设置超时时间
@Bean
Request.Options options(){
return new Request.Options(30000,60000);
}
}
}
3、重启服务发现可以正常调用
四、OpenFeign日志功能
1、概述
Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中Http请求的细节,说白了就是
对Feign接口调用情况进行监控和输出
。
2、日志级别
NONE:默认的,不显示任何日志。
BASIC:仅记录请求方法、URL、响应状态码及执行时间。
HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息。
FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。
3、配置日志Bean
在Feign80中新建一个配置包config并配置
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel(){
//设置日志的级别
return Logger.Level.FULL;
}
}
4、开启Feign日志
需要在配置文件中开启Feign客户端的日志
logging:
level:
com.itan.feign.ProviderFeignClient: debug
5、测试
重启服务调用接口查看后台即可看到日志信息