前言
之前在SpringCloud(二):服务调用和负载均衡中实现了一个使用 Eureka 注册中心的案例,其中 consumer 使用RestTemplate
进行远程调用。这里使用Spring Cloud Openfeign进行远程调用。
OpenFeign
使用OpenFeign可以很容易实现负载均衡以及服务容错,这里我们创建一个 cloud-feign-service 模块,替代之前的 consumer 模块。
创建新的消费者模块
创建一个 cloud-feign-service 模块,修改pom依赖如下:
<dependencies>
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.10.RELEASE</version>
</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-starter-test</artifactId>
<scope>test</scope>
</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>
</dependencies>
修改配置文件如下:
server:
port: 80
spring:
application:
name: cloud-feign-service
eureka:
client:
register-with-eureka: true # 可以不用注册到服务
fetch-registry: true
service-url:
#设置Eureka Server交互的地址查询服务和注册服务地址
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,
instance:
prefer-ip-address: true
在主启动类上加入@EnableFeignClients
注解,开启Feign功能。
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class FeignServiceMainApplication {
public static void main(String[] args) {
SpringApplication.run(FeignServiceMainApplication.class, args);
}
}
这里我们调用之前 /provider/show 查看对应服务端口号,从而证明负载均衡功能。
OpenFeign为声明式调用,只需要在接口中添加注解FeignClient
即可定义一个Feign客户端,该注解中的 value 属性定义远程调用的服务名(在服务注册中心注册的服务名)。
创建一个 UserService 接口,定义如下功能:
@FeignClient(value = "cloud-payment-service")
public interface UserService {
@GetMapping("/provider/show")
String show();
}
定义 UserController 实现该接口的调用:
@RestController
public class UserController {
@Resource
private UserService userService;
@GetMapping("/consumer/show")
public String show() {
return userService.show();
}
}
启动两个注册中心作为注册中心集群,启动两个服务提供模块和本次创建的模块。首先访问注册中心http://localhost:7001/,查看注册状态:
访问http://localhost/consumer/show看到成功进行远程调用。
刷新会发现端口号交替出现
至此实现了 OpenFeign声明式调用和负载均衡。需要注意新版 OpenFeign已经没有引入 Ribbon,这里实现负载均衡因为 Eureka依赖中包含 LoadBalancer,如果使用别的注册中心,需要手动引入 Ribbon 或 LoadBalancer。
实现服务降级
OpenFeign实现服务降级非常方便,只需要在@FeignClient
中添加对应的降级实现类即可。
首先在配置文件中开启Hystrix功能,不同版本可能配置不同,根据版本选择两个其中一个即可。
feign:
circuitbreaker:
enabled: true # feign中开启hystrix
feign:
hystrix:
enabled: true #在Feign中开启Hystrix
接着为 UserService 接口实现服务降级类
@Component
public class UserServiceFallback implements UserService {
@Override
public String show() {
return "当前服务出现问题,请稍后再试";
}
}
为之前@FeignClient
注解中加入降级类
@FeignClient(value = "cloud-payment-service", fallback = UserServiceFallback.class)
public interface UserService {
@GetMapping("/provider/show")
String show();
}
启动两个注册中心、两个服务提供者模块和本模块。首先正常访问http://localhost/consumer/show,可以看到正常返回。
然后关闭两个服务提供者模块,继续访问http://localhost/consumer/show,可以看到返回降级信息。
开启日志打印
首先在配置文件中配置需要开启日志打印的Feign客户端。
logging:
level:
# feign日志打印的接口已经级别
com.pickup.cloud.service.UserService: debug
可以修改日志打印信息范围,添加如下配置类:
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
日志范围说明:
- NONE:默认的,不显示任何日志;
- BASIC:仅记录请求方法、URL、响应状态码及执行时间;
- HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;
- FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。
启动服务再次访问http://localhost/consumer/show,可以看到控制台打印很多信息。
除了从配置类修改打印日志范围,也可以在配置文件中修改。
feign:
client:
config:
default:
# 建立连接时间
connectTimeout: 1000
# 读取资源时间
readTimeout: 1000
# feign记录日志级别
loggerLevel: FULL
至此实现了使用OpenFeign进行远程调用,并且实现了负载均衡和服务降级。