写点什么

Java 踩坑 2|Feign Client 访问到 Consul 脏节点 / 故障节点

作者:itschenxiang
  • 2023-07-19
    广东
  • 本文字数:1475 字

    阅读完需:约 5 分钟

Java 踩坑 2|Feign Client 访问到 Consul 脏节点/故障节点

背景

系统所有服务模块都注册到 consul,上游服务 service-a 通过 feign api 调用同样注册在 consul 上的 service-b,出现 Connection timeout 异常,在 consul 上发现 service-b 的 2 个节点 health check 一个正常一个异常,当把 service-b 的异常节点剔除后服务调用正常。

场景复现

1)启动服务注册中心 consul

对于 macos 来说很简单,本地启动命令:

brew tap hashicorp/tapbrew install hashicorp/tap/consulconsul agent -dev
复制代码

然后通过 http://localhost:8500/ 访问。

2)定义下游服务

定义下游 Feign API:

@FeignClient(        name = "downstream-service")public interface DownStreamServiceApi {
@PostMapping("/serviceName") public String getServiceName();
}
复制代码

为了 mock 下游服务 service checks failing,可以采用如下配置:

spring:  application:    name: downstream-service  cloud:    consul:      discovery:        service-name: downstream-service        heartbeat:          # mock service checks failing          enabled: false
复制代码

代码链接:https://github.com/itschenxiang/spring-boot-examples/tree/main/downstream-service

3)定义下游服务

引入下游 Feign API 并调用:

public class UpstreamServiceApplication {
// other code @Autowired private DownStreamServiceApi downStreamServiceApi;
@Bean public CommandLineRunner commandLineRunner() { return new CommandLineRunner() { @Override public void run(String... args) throws Exception { Executors.newSingleThreadScheduledExecutor() .scheduleAtFixedRate(() -> { log.info(downStreamServiceApi.getServiceName()); },5 ,5, TimeUnit.SECONDS); } }; }
}
复制代码

代码链接:https://github.com/itschenxiang/spring-boot-examples/tree/main/upstream-service

4)启动 2 个下游服务:1 个健康 1 个异常

# 通过配置文件分别启动 service checks 正常和异常服务java -jar target/downstream-service-0.0.1-SNAPSHOT.jar --spring.profiles.active=unhealthjava -jar target/downstream-service-0.0.1-SNAPSHOT.jar --spring.profiles.active=health
复制代码

Consul 上注册情况如下图所示(这里的例子不是真正服务不可用,而是模拟 service checks failing):

5)启动上游服务并调用下游服务,验证结果

下游服务实现中返回了服务端口,可以看到 service checks failing 的节点也被路由到。

2023-07-19 00:13:04.783  INFO 21574 --- [pool-2-thread-1] c.i.u.UpstreamServiceApplication         : downstream-service:80822023-07-19 00:13:09.728  INFO 21574 --- [pool-2-thread-1] c.i.u.UpstreamServiceApplication         : downstream-service:8081
复制代码

根因分析

问题的根因这里作者没有去追溯,只是从现象得到结论。欢迎熟悉 consul 和 feign 负载均衡原理的小伙伴在评论区给出见解。

解决方案

可以看到注册在 consul 上,service checks failing 的节点也可能被访问到,因此在下游服务出现脏节点的情况下可能导致上游服务出现问题。

解决方案:

  1. 在 downstream-service 前加一层负载均衡层(类似反向代理),ip 保持不变,保证路由到的都是服务健康节点。

参考链接

发布于: 刚刚阅读数: 4
用户头像

itschenxiang

关注

还未添加个人签名 2019-05-04 加入

还未添加个人简介

评论

发布
暂无评论
Java 踩坑 2|Feign Client 访问到 Consul 脏节点/故障节点_Java_itschenxiang_InfoQ写作社区