关于openfeign
可以认为OpenFeign是Feign的增强版,不同的是OpenFeign支持Spring MVC注解。OpenFeign和Feign底层都内置了Ribbon负载均衡组件,在导入OpenFeign依赖后无需专门导入Ribbon依赖,用做客户端负载均衡,去调用注册中心服务。
关于hystrix
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,可以保证一个服务出现故障时,不会导致整个系统出现雪崩效应,以提高分布式系统弹性;
作为“断路器”,在一个服务出现故障时,可以通过短路器监控,返回一个可以处理的响应结果,保证服务调用线程不会长时间被占用,避免故障蔓延。
openfeign微服务接口调用
本项目使用nacos 作为注册中心,实现了一个服务提供者:user-service 和一个服务调用者(客户端)open-feign ,整体调用流程如图所示:
服务提供方
- 创建模块:microservice-user
- 引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
server:
port: 9001
servlet:
context-path: /user-service
spring:
application:
name: user-service
cloud:
nacos:
discovery:
enabled: true
server-addr: 192.168.56.101:8848
namespace: f687d65c-41a5-44b8-8e0c-80188f8a6ba5
- 编写service(省略)
- 编写controller
@RestController
public class UserController {
@Autowired
UserService userService;
@GetMapping("/users")
List<User> getUsers(){
return userService.getUsers();
}
@GetMapping("/user/{id}")
public User getUserById(@PathVariable Integer id){
return userService.getUserById(id);
}
}
- 启动项目,测试接口
浏览器访问:http://localhost:9001/user-service/user/3
服务调用方
- 创建模块:microservice-openfeign
- 添加依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>com.laoxu.java</groupId>
<artifactId>microservice-common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
server:
port: 8000
servlet:
context-path: /open-feign
spring:
application:
name: open-feign
cloud:
nacos:
discovery:
enabled: true
server-addr: 192.168.56.101:8848
namespace: f687d65c-41a5-44b8-8e0c-80188f8a6ba5
metadata:
management:
context-path: ${server.servlet.context-path}/actuator
feign:
hystrix:
enabled: true
okhttp:
enabled: true
httpclient:
enabled: false
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class OpenFeignApp {
public static void main(String[] args) {
SpringApplication.run(OpenFeignApp.class);
}
}
主要配置了Feign调用时的接口打印信息、接口调用超时时间配置。
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLogger() {
return Logger.Level.FULL;
}
@Bean
public Retryer feignRetryer() {
return new Retryer.Default(
100,
SECONDS.toMillis(1),
5
);
}
public static final int CONNECT_TIMEOUT_MILLS = 5000;
public static final int READ_TIMEOUT_MILLS = 5000;
@Bean
public Request.Options options() {
return new Request.Options(
CONNECT_TIMEOUT_MILLS, TimeUnit.MICROSECONDS,
READ_TIMEOUT_MILLS, TimeUnit.MILLISECONDS,
true
);
}
}
- 编写feign客户端
用于调用user-service提供的用户服务接口 ,其实就是个接口,代码很简单。 其中path 参数为统一调用路径的前缀,value 为注册中心中服务提供方的服务名。fallback 为指定的hystrix后备策略类。
@FeignClient(value = "user-service",path = "user-service",fallback = UserClientFallback.class)
public interface UserClient {
@GetMapping(value = "/users")
List<User> getUsers();
@GetMapping(value = "/user/{id}")
User getUserById(@PathVariable("id") Integer id);
}
有了上一步中创建的Feign客户端,在controller中可以通过@Autowired注入使用
@RestController
@RequestMapping("/userapi")
public class UserController {
@Autowired
UserClient userClient;
@GetMapping("/users")
public List<User> getUsers(){
return userClient.getUsers();
}
@GetMapping("/user/{id}")
public User getUserById(@PathVariable("id") Integer id){
return userClient.getUserById(id);
}
}
- 启动项目,进行测试
浏览器输入:http://localhost:8000/open-feign/userapi/users 说明可以正常通过feign客户端实现微服务接口调用。
与hystrix集成实现后备策略
当openfeign接口调用出现异常,例如接口调用超时,去执行预先设置好的代码逻辑。
创建后备策略类
当feign客户端接口调用异常时,执行对应方法。此处均返回空。
@Slf4j
@Component
public class UserClientFallback implements UserClient {
@Override
public List<User> getUsers() {
log.info("userclient getUsers接口调用失败,执行回退方法");
return null;
}
@Override
public User getUserById(Integer id) {
log.info("userclient getUserById接口调用失败,执行回退方法");
return null;
}
}
模拟调用超时
注意: 因为hystrix默认超时时间为1s,此处我们将服务提供方接口响应时间设置只要大于1s均能模拟接口超时。
- 修改服务提供方
UserController 接口 在获取用户列表方法中添加睡眠4s逻辑代码:
启用hystrix
在服务调用方bootstrap.yml文件中添加以下配置即可:
feign:
hystrix:
enabled: true
重启项目,测试
浏览器输入:http://localhost:8000/open-feign/userapi/users 此时观察浏览器输出为空:
项目控制台打印日志,说明成功执行了后备代码。
项目代码
https://gitee.com/indexman/microservice-learn
|