本文为阿里云容器服务spring cloud应用开发系列文章的第五篇,讨论如何利用spring cloud 对 netflix zuul支持,完成服务的职能路由功能。
五、服务智能路由(本文)
在手机端完成一个功能有可能需要调用多个后台的服务,如果从手机端完成所有调用,可能造成调用次数很多,通信时间过长。由于手机电量的限制,一般也不建议多次调用后台服务。
一个可行的办法是将所有相关的服务聚合起来,生成一个新的服务。新的服务作为入口点,前端应用只需调用一次,就完成了原来多次调用。并且,对于服务调用的处理也可以在新的服务中完成,更减轻了前端的处理压力。相关的代码在<code>foobar</code>中展示。
我们还可以利用spring cloud zuul构建的一个api gateway将<code>foobar</code>和其它需要对外提供服务的应用暴露出来。我们可以通过zuul的配置文件声明对外的服务的url模式等信息,可以非常简单地将服务对外输出。这部分示例代码为<code>commons/gateway</code>
zuul是多实例的,对zuul也需要负载均衡。在阿里云上,我们可以定义一个slb来实现对zuul的对外输出和负载均衡。相关的部署模版声明在<code>docker-compose.yml</code>中。
<code>gateway</code>服务使用eureka进行服务的发现,所以在build.gradle不但由zuul,还有对eureka的依赖。
在主class上添加<code>@enablezuulproxy</code>,声明该应用使用zuul提供服务路由能力;添加<code>@enablediscoveryclient</code>注解表示该应用内置服务发现客户端。由于在<code>build.gradle</code>中引入了eureka,所以客户端会自动通过eureka发现服务。
application.yml中定义<code>gateway</code>侦听固定的端口<code>8080</code>,在<code>zuul.routes.foobar.path</code>定义所有对本机<code>/acs/***</code>访问都指向<code>foobar</code>服务。
zuul通过eureka发现所有<code>foobar</code>服务,具体eureka的配置和前文相同。
<code>gateway</code>是服务的职能路由,内部的服务可以通过它对外暴露。如果我们想让<code>gateway</code>也是多个实例那么怎么将单一外部访问端点映射到多个<code>gateway</code>实例呢?
使用阿里云的slb负载均衡可以达成这个目标。在阿里云容器服务提供了对docker compose模版的标签扩展,将服务声明为通过slb进行负载均衡。具体方法见<code>docker-compose.yml</code>文件:
阿里云容器服务会解析以<code>aliyun</code>开头的标签,并根据标签的定义执行不同的操作。<code>aliyun.scale</code>表示启动2个实例。
<code>aliyun.lb.port_8080</code>表示将该的所有实例通过slb进行负载均衡,服务端口号(又称为后端端口号)为8080,slb的地址通过随后的url来描述。<code>${slbname}</code>为占位变量,需要替换为对应slb的名字或id。用户可以在部署文件中直接替换这个变量,也可以在部署应用时系统提示输入<code>slbname</code>,用户填入正确值。
url中最后的<code>8080</code>表示slb对外的端口号,在这里也是8080。
本文讨论了如何利用zuul实现服务智能路由,以及对外通过阿里云slb实现对zuul的负载均衡。