Spring Cloud常见问题与总结

Eureka常见问题

1.Eureka注册服务慢

默认情况下,服务注册到Eureka Server的过程比较慢。在开发或测试时,常常希望能够加速这一过程,从而提升工作效率。

Srping Cloud官方文档详细描述了该问题的原因并提供了解决方案。
服务注册涉及到周期性心跳,默认30秒一次(通过客户端配置的serviceUrl)。只有当实例、服务器端和客户端的本地缓存中的元数据都相同时,服务才能被其他客户端发现(所以可能需要3次心跳)。可以使用参数eureka.instance.leaseRenwalIntervalInSeconds修改时间间隔,从而加快客户端连接到其他服务的过程。在生产环境中最好坚持使用默认值,因为在服务器内部有一些计算,他们会对续约做出假设。
综上,要想解决服务注册慢的问题,只需将eureka.instance.leaseRenwalIntervalInSeconds设成一个更小的值,该配置用于EurekaClient向Eureka Server发送心跳的时间间隔,默认是30,单位是秒。在生产环境中,建议坚持使用默认值。

2.已停止的微服务节点注销慢或不注销

在开发环境下,常常希望Eureka Server能迅速有效地注销已停止的微服务实例。然而,
由于Eureka Server清理无效节点周期长(默认90秒),以及自我保护模式等原因,可能
会遇到微服务注销慢甚至不注销的问题。解决方案如下:

 Eureka Server端:
配置关闭自我保护,并按需设置Eureka Server清理无效节点的时间间隔。
eureka.server.enable-self-preservation
#设置为false,关闭自我保护,从而保证会注销微服务
eureka.server.eviction-interval-timer-in-ms
#清理间隔(单位毫秒,默认是60*1000)

Eureka Client端:
配置开启健康检查,并按需配置持续更新的时间和到期时间。
eureka.client.healthcheck.enabled
#设为true,开启健康检查(需要spring-boot-starter-actuatoryi依赖)
eureka.instance.lease-xepiration-duration-in-seconds
#续约到期时间(默认90秒)

值得注意的是,这些配置仅建议在开发或测试时使用,生产环境建议坚持使用默认值。

3.如何自定义为服务的InstanceID

探讨如何自定义微服务的Instance ID。Instance ID用于唯一标识注册到Eureka Server
上的微服务实例。

在这里插入图片描述

在Spring Cloud中,服务Instance ID默认值是 s p r i n g . c l o u d . c l i e n t . h o s t n a m e : {spring.cloud.client.hostname}: spring.cloud.client.hostname:{
spring.cloud.application.name}:KaTeX parse error: Expected '}', got 'EOF' at end of input: …on.instance_id:{server.port}}。
如果想要自定义这部分的内容,只需在为服务中配置eureka.instance.instance_id属性即可。

这样,就可将微服务microservice-provider-user的Instacnce ID设为IP:端口的形式。
这样设置后效果如下。
在这里插入图片描述

4.Eureka的UNKNOWN问题总结与解决

注册信息UNKNOWN,是新手常会遇到的情况,一种是应用名称UNKNOWN,另一种是应用状态
UNKNOWN。下面分别讨论这两种情况。
在这里插入图片描述

应用名称UNKNOWN
应用名称UNKNOWN显然不合适,首先是微服务的名称不够语义化,无法直观看出这是哪个微服务;
更重要的是,我们常常使用应用名称消费对应微服务的接口。
一般来说有两种情况会导致该问题的发生:
末配置spring.application.name或者eureka.instance.appname属性。如果这两个属性均
不配置,就会导致应用名称UNKNOWN的问题。
某些版本SpringFox会导致该问题,例如SpringFox 2.6.0.建议使用SpringFox 2.6.1或更新版本。

微服务实例状态UNKNOWN
微服务实例状态UNKNOWN同样很麻烦。一般来讲,只会请求状态是UP的微服务。该问题一般由健康检查
所导致。

eureka.client.healthcheck.enabled=true必须设置在application.yml中,而不能设置在
bootstrap.yml中,否则一些场景下会导致应用状态UNKNOW的问题。

Hystrix/Feign整合Hystrix后首次请求失败

某些场景下,Feign或Ribbon整合Hystrix后,会出现首次调用失败的问题。
本节将对该问题做一些总结。

1.原因分析

Hystrix默认的超时时间是一秒,如果在1秒内得不到响应,就会进入fallback逻辑。由
于Spring的懒加载机制,首次请求往往会比较慢,因此在某些机器(特别是配置低的机器)
上,首次请求需要的时间可能就会大于1秒。

2.解决方案

有很多方式解决该问题,以下列举集中比较简单的方案。
方法一:延长Hystrix的超时时间
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
该配置让Hystrix的超时时间改为5秒。
方式二:禁用Hystrix的超时
hystrix.command.default.execution.timeout.enabled: false
方式三:对于Feign,还可为Feign禁用Hystrix
feign.hystrix.enable: false
这样还可为Feign全局禁用Hystrix支持。该方式比较极端,一般不建议使用。

Turbine聚合的数据不够完整

在某些版本的SpringCloud(例如Brixton SR5)中,Turbine会发生该问题。该问题的直观体现是:
使用Turbine聚合了多个微服务,但在Hystrix Dashboard上只能看到部分微服务的监控数据。
例如Turbine配置如下:
turbine:
appConfig: microservice-consumer-movie,microservice-consumer-movie-feign
-hystrix-fallback-stream
clusterNameExpression: “‘default’”

Turbine理应聚合microservice-consumer-movie和microservice-consumer-movie-
feign-hystrix-fallback-stream这两个微服务的监控数据,然而打开Hystrix Dashboard时,
会发现Dashboard上只显示部分微服务的监控数据。
在这里插入图片描述
解决方案
当Turbine聚合的为服务部署在同一台主机上时,就会出现该问题。
解决方案如下:
方法一:为各个微服务配置不同的hostname,并将preferIpAddress设置为false或者不设置。

方式二:设置turbine,combine-host-port = true。

方式三:升级Spring Cloud到Camden或更新版本。当然,也可单独升级Spring Cloud Netflix
到1.2.0或更新版本(一般不建议单独升级Spring Cloud Netflix,因为可能会跟Spring Cloud
其他组件冲突)。
这是因为老版本中的turbine.combine-host-port默认值是false。Spring Cloud已经意识到该
问题,所以在新的版本中将该属性默认值修改为true。该解决方案和方法二本质上是一致的。

Spring Cloud各组件配置属性

1.springcloud的配置
Spring Cloud的所有配置都在其官方文档的附录,地址如下:
http://cloud.spring.io/spring-cloud-static/Camden.SR4/#_appendix_compendium_of_configuration_properties

2.原生配置
Spring Cloud整合了很多类库,例如Eureka、Ribbon、Feign等。这些组件自身也有一些配置属性,如下:
在这里插入图片描述

Spring Cloud定位问题思路总结。

排查问题的思路不妨按照以下步骤展开。
1.排查配置问题
YAML缩进是否正确
曾有朋友发现Spring Cloud应用程序无法正常启动。或配置无法正常加载。
最后发现,仅仅是YAML配置文件缩进不正确。
类似问题应在编码的过程中严格规避。

配置属性是否正确
配置属性写错是个非常常见的问题。尽管该问题很低级。
很多场景下,这类问题可借助IDE的提示功能来排查——当IDE不自动提示或
给出警告时,应格外注意。

配置属性的位置是否正确
想请属性到底是写在application.yml还是bootstrap.yml中。

2.排查环境问题
环境变量
例如Java环境变量、Maven环境变量以及Docker容器环境变量等。当应用无法
正常工作时,应该确保环境变量配置正确。

依赖下载是否完整

网络问题
微服务之间通过网络保持通信,因此,网络常常是排查的关键。

3.排查代码问题
很多时候常常是少了某个注解,或是依赖缺失,而导致了各种异常。

4.排查Spring Cloud自身问题
如果确定不是代码问题,就可Debug一下Spring Cloud的代码了。

本文大部分内容转载自周立的《Spring Cloud与Docker微服务架构实战》

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐