默认情况下,服务注册到Eureka Server的过程比较慢。在开发或测试时,常常希望能够加速这一过程,从而提升工作效率。
Srping Cloud官方文档详细描述了该问题的原因并提供了解决方案。
服务注册涉及到周期性心跳,默认30秒一次(通过客户端配置的serviceUrl)。只有当实例、服务器端和客户端的本地缓存中的元数据都相同时,服务才能被其他客户端发现(所以可能需要3次心跳)。可以使用参数eureka.instance.leaseRenwalIntervalInSeconds修改时间间隔,从而加快客户端连接到其他服务的过程。在生产环境中最好坚持使用默认值,因为在服务器内部有一些计算,他们会对续约做出假设。
综上,要想解决服务注册慢的问题,只需将eureka.instance.leaseRenwalIntervalInSeconds设成一个更小的值,该配置用于EurekaClient向Eureka Server发送心跳的时间间隔,默认是30,单位是秒。在生产环境中,建议坚持使用默认值。
在开发环境下,常常希望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秒)
值得注意的是,这些配置仅建议在开发或测试时使用,生产环境建议坚持使用默认值。
探讨如何自定义微服务的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:端口的形式。
这样设置后效果如下。
注册信息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的问题。
某些场景下,Feign或Ribbon整合Hystrix后,会出现首次调用失败的问题。
本节将对该问题做一些总结。
Hystrix默认的超时时间是一秒,如果在1秒内得不到响应,就会进入fallback逻辑。由
于Spring的懒加载机制,首次请求往往会比较慢,因此在某些机器(特别是配置低的机器)
上,首次请求需要的时间可能就会大于1秒。
有很多方式解决该问题,以下列举集中比较简单的方案。
方法一:延长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支持。该方式比较极端,一般不建议使用。
在某些版本的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。该解决方案和方法二本质上是一致的。
1.springcloud的配置
Spring Cloud的所有配置都在其官方文档的附录,地址如下:
http://cloud.spring.io/spring-cloud-static/Camden.SR4/#_appendix_compendium_of_configuration_properties
2.原生配置
Spring Cloud整合了很多类库,例如Eureka、Ribbon、Feign等。这些组件自身也有一些配置属性,如下:
排查问题的思路不妨按照以下步骤展开。
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微服务架构实战》