简介
Spring Cloud是目前非常流行的微服务化解决方案,它将Spring Boot的便捷开发和Netflix OSS的丰富解决方案结合起来。Spring Cloud不同于Dubbo,使用的是基于HTTP(s)的Rest服务来构建整个服务体系。
那么有没有可能使用一些非JVM语言,例如熟悉的Node.js来开发一些Rest服务呢?当然是可以的。但是如果只有Rest服务,还不能接入Spring Cloud系统。此外,还想使用起Spring Cloud提供的Eureka进行服务发现,使用Config Server做配置管理,使用Ribbon做客户端负载均衡。这个时候Spring sidecar就可以大显身手了。
Sidecar起源于Netflix Prana。它提供了一个可以获取既定服务所有实例的信息(例如host,端口等)的http api。也可以通过一个嵌入的Zuul,代理服务到从Eureka获取的相关路由节点。Spring Cloud Config Server可以直接通过主机查找或通过代理Zuul进行访问。
需要注意的是你所开发的Node.js应用,必须去实现一个健康检查接口,来让Sidecar可以把这个服务实例的健康状况报告给Eureka。
非jvm应用应该实现一个健康检查,Sidecar能够以此来报告给Eureka注册中心该应用是up还是down状态。
使用spring cloud netflix sidecar
为了使用Sidecar,你可以创建一个带有@EnableSidecar注解的Spring Boot程序。在项目中使用Sidecar,需要添加依赖,其group为 org.springframework.cloud ,artifact id为 spring-cloud-netflix-sidecar 。
启用Sidecar,创建一个Spring Boot应用程序,并在在应用主类上加上@EnableSidecar 注解。该注解包含 @EnableCircuitBreaker , @EnableDiscoveryClient 以及 @EnableZuulProxy 。
配置Sidecar,在application.yml中添加 sidecar.port 和 sidecar.health-uri 。 sidecar.port 属性是非jre程序监听的端口号,这就是Sidecar可以正确注册应用到Eureka的原因。
健康检查
sidecar.health-uri 是非jre应用提供的一个对外暴露的可访问uri地址,在该地址对应的接口中需要实现一个模仿Spring Boot健康检查指示器的功能。
DiscoveryClient
API DiscoveryClient.getInstances() 所对应的访问方式是 /hosts/{serviceId} ,这是访问 /hosts/consul-sidecar-myapp 后的响应示例,它返回了一个或多个不同主机上的实例.
|
|
Zuul代理
Zuul代理会自动为每个在Eureka注册中心上的服务添加路由到 /serviceId 上,所以上面那个consul-sidecar-myapp的服务可以通过 /consul-sidecar-myapp 访问。非Jre应用可以通过 http://localhost:port}/consul-sidecar-myapp 来访问Service.
如果你用的不是Eureka,譬如使用了consul, 实现有所不同。
Spring Cloud Consul Sidecar
官方并没有提供spring cloud consul Sidecar, 是因为在大多数情况下,是通过本地代理的方式来连接Consul的,这个本地代理本身就是一个sidecar。这与netflix Eureka是不同的。
下面会讲述一下假如仍然基于consul去打造一个类似于eureka的sidecar,如何定制实现该功能。
直接上代码先。
代码地址:https://github.com/osswangxining/spring-cloud-consul-sidecar/tree/master/spring-cloud-consul-sidecar
使用该Sidecar的例子: https://github.com/osswangxining/spring-cloud-consul-sidecar/tree/master/spring-cloud-consul-sample
下面不打算写太多文字了,直接看代码吧。
实现@EnableSidecar
|
|
Healthcheck
|
|
SidecarConfiguration
|
|
附录1 - RetryLoadBalancerInterceptor
org.springframework.cloud.client.loadbalancer.RetryLoadBalancerInterceptor
|
|