1.记一次线上SpringCloud-Feign请求服务超时异常排查
2.SpringCloud组件:Eureka服务注册是看源采用主机名还是IP地址?
3.SpringCloud(3):使用Ribbon进行负载均衡配置,以及遇坑指南
记一次线上SpringCloud-Feign请求服务超时异常排查
线上系统因单量暴涨,码e码第三方反馈部分工单业务查询处理失败,看源排查发现是码e码通过FeignClient调用下游系统出现超时失败现象,异常代码已记录。看源
系统慢请求捕捉拦截显示,码e码-5.5源码尽管请求仅耗时毫秒,看源却触发了“Read timed out”超时错误。码e码项目与下游项目均在Eureka上注册,看源对此现象感到困惑,码e码开始查阅Feign底层源码。看源
跟踪代码发现,码e码Feign.Request内部类Options构造函数默认配置连接超时秒,看源-103的源码反码读超时秒。码e码然而请求耗时1秒左右即被掐断,看源提示超时错误。初步判断默认超时配置并未生效。
回顾Feign调用流程,分为Hystrix、Ribbon两层,高版本的Hystrix默认关闭(本项目Hystrix默认关闭),转向分析Ribbon层调用配置信息。
发现RibbonClientConfiguration默认配置的读超时和连接超时时间毫秒,即1秒。在未配置超时情况下,foobar源码输出hdmi符合本次调用超时错误的触发。
在FeignLoadBalancer的execute方法中,当IClientConfig为空时,会覆盖超时时间,默认使用Ribbon的超时时间,而非Feign Options默认的超时时间。
若application.properties文件中配置超时时间,则使用配置的超时时间;否则使用Ribbon的默认超时时间,即1秒。若服务响应时间超过1秒,会相应报错。
实际业务中,handsome源码网盘根据服务响应情况可配置相应的超时时间。提供properties和yml版本的配置示例,以适应不同业务场景需求。
SpringCloud组件:Eureka服务注册是采用主机名还是IP地址?
1. 在微服务架构中,Eureka 服务注册通常涉及服务提供者和服务注册中心之间的交互。服务提供者在启动时会向 Eureka Server 注册自己,这个过程可以指定使用主机名或 IP 地址。
2. 在本节的示例中,我们复制了 SpringCloud 组件的源码,并修改了项目名称,同时对 `application.yml` 配置文件进行了简单的调整。
3. 配置文件中并未明确指定注册方式,在线源码java因此服务会使用默认设置进行注册。默认情况下,Eureka Client 倾向于使用 IP 地址进行注册。
4. 我们通过搭建一个 Eureka Server 实例,来探索服务注册的实际行为。当我们访问一个注册的服务时,默认情况下会被重定向到服务的监控信息界面,这里显示的 URL 表明了注册时使用的地址是 IP 地址。
5. 如果我们希望服务使用主机名进行注册,可以在 `application.yml` 文件中修改 `eureka.instance.hostname` 配置。
6. 在 Linux 系统中,我们需要更新 `/etc/hosts` 文件以包含主机名和 IP 地址的映射。对于 Windows 系统,则需编辑 `C:\Windows\System\drivers\etc\hosts` 文件。
7. 修改配置后,观察到访问路径从 IP 地址变为了主机名,证实了服务已经使用主机名进行了注册。
8. 如果你希望服务优先使用 IP 地址注册,可以通过设置 `eureka.instance.prefer-ip-address` 参数为 `true`。
9. 如果我们想要服务使用一个特定的 IP 地址进行注册,可以设置 `eureka.instance.ip-address` 参数。
. 完成配置文件修改后,进行测试以确保新的设置有效。我们发现访问地址已经反映了我们为服务设置的指定 IP 地址。
. 本节详细介绍了 Eureka Client 注册时使用的不同服务名称方式,并指出了它们之间的优先级顺序。下一节将深入分析这些注册方式的内部机制和优先级。
. 本文的源码已上传至恒宇少年的码云账户,建议结合源码进行学习,感谢您的阅读。
SpringCloud(3):使用Ribbon进行负载均衡配置,以及遇坑指南
使用Ribbon进行负载均衡配置是Spring Cloud体系中的一种关键实践。由于Eureka中已经集成了Ribbon,因此无需额外引入依赖。启动多个服务提供方时,在服务消费方的启动类中启用@LoadBalanced注解来激活负载均衡机制。将@LoadBalanced注解添加到消费方的RestTemplate方法上,即可实现通过服务名调用提供方的服务。
在配置过程中,服务消费方通常使用DiscoveryClient来获取提供方的服务列表,并通过该列表指定具体的服务实例及其主机和端口。然而,开启负载均衡后,系统会自动选择合适的服务实例,无需人工指定,以提升服务调用的效率和可用性。
值得注意的是,一旦使用了@LoadBalanced注解,直接访问提供方的特定主机名和端口号会引发异常(如java.lang.IllegalStateException: No instances available for localhost)。同时,服务名中应避免使用下划线,否则可能会遇到请求URI格式错误(如Request URI does not contain a valid hostname: service_provider/user/4...)的问题。
在消费方控制器中,实现远程服务调用时,负载均衡效果通过LoadBalancerInterceptor和RibbonLoadBalancerClient类的源码展现。RibbonLoadBalancerClient通过默认的轮询策略分配服务实例,而其他策略如随机策略则可以在消费方配置文件中进行指定。重新运行测试用例后,负载均衡策略的切换效果明显。
深入RibbonLoadBalancerClient源码,可以观察到通过BaseLoadBalancer类的chooseServer方法调用rule接口以执行负载均衡策略,其中轮询策略(RoundRobinRule)是默认设置。除了轮询策略之外,随机策略等其他负载均衡策略也可通过配置文件进行选择,以适应不同场景的需求。在实践过程中,通过测试和调整配置,可以有效提升服务调用的负载均衡效果。