接上篇《29.Zuul的FallBack回退机制》 Spring Cloud版本为Finchley.SR2版
上一篇我们介绍了有关Zuul回退的相关知识,本篇我们来学习使用Sidecar支持异构平台的微服务,
本部分官方文档:https://cloud.spring.io/spring-cloud-static/Finchley.SR4/single/spring-cloud.html#_polyglot_support_with_sidecar 注:好像Finchley.SR2的文档已经挂了,最新的是Finchley.SR4的文档。
目录
一、Sidecar的作用
二、搭建一个Sidecar服务
三、异构服务对接Sidecar
四、异构服务状态同步
五、Sidecar的不足之处
六、不使用Sidecar引用异构服务
一、Sidecar的作用
我们的微服务系统里面不一定只使用Java这一种语言,有一部分微服务可能是其他语言(如Node.js或PHP等)。此时我们可以使用Sidecar把异构的微服务纳入到Spring Cloud的生态圈中。
Sidecar的灵感来源自“Netflix Prana”,它包含了一个HTTP的API,用于获取给定服务的所有实例(按主机和端口)。说的通俗一点,Sidecar除了实现了Zuul代理网关的作用,还提供了一个HTTP服务,其他非Java语言(或非JVM语言)的服务,可以对接该HTTP服务,实现一个类似健康检查的端点服务。所以Sidecar不仅可以代理异构应用的服务,也可以通过其健康检查服务的调用结果向Eureka报告应用程序是启动还是关闭。
使用Sidecar对接第三方服务的结构如下:
图片摘自:https://www.jianshu.com/p/e970b9a4e61a 在上图中,纯Java架构的online服务,通过访问Sidecar服务,就可以访问第三方服务,这里Sidecar本质就是一个Zuul的网关代理。而第三方程序通过实现健康检查服务,加上注册到Sidecar的配置,Sidecar可以检测第三方程序是否健康。而所有应用都是注册在Eureka服务上,被发现和被调用的。
说白了,Sidecar就是异构服务的一个壳子,来使得异构服务能够接入Spring Cloud的生态圈。
二、搭建一个Sidecar服务
我们需要在应用中实现以下几点,来搭建一个Sidecar服务:
(1)创建一个Maven工程(默认引入Spring Boot、Spring Cloud以及Eureka的依赖),在POM文件中引入Sidecar的依赖
(2)在Spring Boot启动类上添加@EnableSidecar注解,该注解包含了@EnableCircuitBreaker, @EnableDiscoveryClient, 以及@EnableZuulProxy注解,分别实现了Hystrix断路器、Eureka服务发现以及Zuul网关代理的效果。(3)在配置文件中配置应用的端口号、应用名以及Sidecar的服务地址,例如:
注:sidecar.port属性代表非java应用的健康监听端口。
sidecar.health-uri是一个可以在非JVM应用程序上访问的uri,它模拟了一个Spring Boot健康指示器。它应该返回一个类似于以下内容的JSON文档:
即对接Sidecar的非java应用要实现health服务,并在服务正常运行时返回上述内容的JSON串。
完成以上几步就可以实现一个Sidecar服务了。我们下面动手创建一个Sidecar服务。
首先新建一个Maven工程:
然后在POM文件中引入Spring Cloud的父工程和“eureka”、“Sidecar”的依赖:
注意,这里为了便于版本统一管理,该工程的parent父工程和我们User、Movie工程一样,均依赖于microserver-spring-cloud工程(此父工程统一引入了spring-cloud-dependencies的Finchley.SR2版,以及spring-boot-starter-parent-2.0.6.RELEASE的parent,这个在前面的章节已经讲过)。然后编写启动类MicroserverSidecarApplication.java:
这里添加了@EnableSidecar注解以启用Sidecar。
然后在src/main/resource下新建application.yml主配置文件,添加以下配置:
这里我们定义了应用的名称、端口号,对接Eureka注册中心的Url,以及sidecar服务监听的非Java应用的端口号和健康检查地址。
此时我们的一个Sidecar应用就创建好了。
三、异构服务对接Sidecar
我们这里创建一个Node.js的服务,作为一个异构服务来对接Sidecar。
首先我们创建一个node-service.js脚本文件:
注:这里为了方便查看,我直接把脚本文件放在microserver-sidecar工程里了,本来是和microserver-sidecar工程没有关系的。
node-service.js脚本文件编写如下内容:
我们不必学习Node.js的语法,我们只需要知道,该代码会启用一个运行在8060端口的服务,该服务提供两个端点供我们访问,一个是根节点“http://localhost:8060/”,会返回“{"index":"欢迎来到首页"}”的json串;一个是“http://localhost:8060/health.json”健康检查端点,会返回“{"status":"UP"}”的json串。
然后我们安装一下Node服务组件,详情见https://www.runoob.com/nodejs/nodejs-install-setup.html,这里不再赘述。
Node服务组件安装完毕后,启动Node应用的方式很简单,我们打开Windows的控制台,找到node-service.js脚本文件所在的路径,然后使用“node”指令+空格+脚本文件名称,就可以启动:
node node-service.js
当出现“listening on localhost:8060”字样时,证明已经在8060端口启动了一个Node服务了。此时我们访问该Node服务的两个节点(“http://localhost:8060/”和“http://localhost:8060/health.json”):
发现可以成功访问,这里我们的异构服务搭建成功。 此时我们启动Eureka Server工程、Zuul工程、Sidecar工程:
这里我们要提前在Zuul中配置Sidecar的代理配置(如果没有ignored-services,就不用配):
查看Eureka Server主页,确认服务启动成功:
然后访问Zuul的routs端点,查看Zuul是否代理了Sidecar工程:
可以看到这里除了我们之前配置了User服务、文件上传服务的端口,这里还代理了Sidecar的所有端点。然后通过Zuul网关,我们可以通过Zuul网关去访问Sidecar代理的Node服务:
发现访问成功,说明Sidecar成功代理了异构的非Java服务的所有端点。
我们在其它微服务调用异步微服务也很简单,这里我们以使用了Ribbon的Movie工程为例,在MovieController中,创建相关服务,使用restTemplate对象进行访问:
这里的HTTP服务的URI即是Sidecar在Eureka中注册的服务名。
此时启动Movie工程,访问其“/sidecar-test”服务,可以看到也成功访问:
四、异构服务状态同步
Sidecar会根据异构服务的状态,同步自己的状态。
在上面几个服务启动的情况下,我们可以看到Sidecar的应用状态是UP的:
然后我们将node-service.js中的health.json服务返回的status状态从UP,改为DOWN:
重新启动Node服务,注意此时我们没有动Sidecar服务,刷新Eureka Server主页,发现Sidecar的状态也同步变更为DOWN了:
然后我们访问Sidecar服务的health节点,可以看到该服务自己就是DOWN的状态:
这就是Sidecar通过异构服务的health.json服务获知其健康状态,然后更新自己的健康状态,而对于Eureka,只需要感知Sidecar的状态即可。
五、Sidecar的不足之处
1、同一个host问题
目前使用Sidecar的时候,要求Sidecar服务和代理的异构服务必须保持在同一个host下,即在一个域下,部署在同一个服务器上。
如果我们需要实现Sidecar服务和代理的异构服务不在一个host下,就需要配置${eureka.instance.hosthome},具体配置详见官方文档中有关Eureka的“registering_a_secure_application”章节:
https://cloud.spring.io/spring-cloud-static/Finchley.SR4/single/spring-cloud.html#_registering_a_secure_application。
虽然可以解决,但越复杂的配置,坑越多。
2、一个异构服务对应一个Sidecar
在上面的例子中,我们一个异构服务,就需要启动一个Sidecar服务去代理,如果异构服务比较多的话,我们要一个一个启动相同的Sidecar服务去代理每个异构服务,这明显不是一个好的方案。
六、不使用Sidecar引用异构服务
当然,Eureka也提供有不使用Sidecar就能注册至注册中心的方法,即使用Eureka提供的一套RESRful服务来实现:
https://github.com/netflix/eureka/wiki/Eureka-REST-operations 这里就要求异构服务需要实现这些RESRful服务来向Eureka注册。
这里我们需要根据项目实际情况,来决定是否需要使用哪种方式实现。
参考:《51CTO学院Spring Cloud高级视频》
https://www.jianshu.com/p/e970b9a4e61a