Edge Service是ServiceComb提供的JAVA网关服务。Edge Service做为整个微服务系统对外的接口,向最终用户提供服务,接入RESTful请求,转发给内部微服务。Edge Service以开发框架的形式提供,开发者能够很是简单的搭建一个Edge Service服务,经过简单的配置就能够定义路由转发规则。同时Edge Service支持强大的扩展能力,服务映射、请求解析、加密解密、鉴权等逻辑均可以经过扩展实现。前端
Edge Service自己也是一个微服务,需遵照全部微服务开发的规则。其自己能够部署为多实例,前端使用负载均衡装置进行负载分发;也能够部署为主备,直接接入用户请求。开发者能够根据Edge Service承载的逻辑和业务访问量、组网状况来规划。java
开发微服务网关react
搭建框架git
使用ServiceComb的内置Edge Service边缘服务github
3步完成搭建微服务网关web
↓↓↓正则表达式
•配置依赖关系spring
在项目中加入edge-core的依赖,就能够启动Edge Service的功能。Edge Service在请求转发的时候,会通过处理链,所以还能够加入相关的处理链的模块的依赖,下面的实例增长的负载均衡的处理链,这个是必须的。数据库
•定义启动类apache
和开发普通微服务同样,能够经过加载Spring的方式将服务拉起来。
•增长配置文件microservie.yaml
Edge Service自己也是一个微服务,遵循微服务查找的规则,本身也会进行注册。注意APPLICAIONT_ID与须要转发的微服务相同。在下面的配置中,指定了Edge Service监听的地址,处理链等信息。其中auth处理链是DEMO项目中自定义的处理链,用于实现认证。同时auth服务自己,不通过这个处理链,至关于不鉴权。
定制路由规则
使用Edge Service的核心工做是配置路由规则。场景不一样,规则也不一样。 路由规则由一系列AbstractEdgeDispatcher组成。Edge Service提供了几个常见的Dispatcher,经过配置便可启用,若是这些Dispatcher不知足业务场景须要,还能够自定义。
•使用DefaultEdgeDispatcher
DefaultEdgeDispatcher是一个很是简单、容易管理的Dispatcher,使用这个Dispatcher,用户不用动态管理转发规则,应用于实际的业务场景很是方便,这个也是推荐的一种管理机制。它包含以下几个配置项:
常见的这些配置项的示例及含义以下:
•[prefix=rest;withVersion=true;prefixSegmentCount=1]微服务xService提供的URL为: /xService/v1/abc,经过Edge访问的地址为/rest/xService/v1/abc,请求只转发到[1.0.0-2.0.0)版本的微服务实例。
•[prefix=rest;withVersion=true;prefixSegmentCount=2]微服务xService提供的URL为: /v1/abc,经过Edge访问的地址为/rest/xService/v1/abc,请求只转发到[1.0.0-2.0.0)版本的微服务实例。
•[prefix=rest;withVersion=true;prefixSegmentCount=3]微服务xService提供的URL为: /abc,经过Edge访问的地址为/rest/xService/v1/abc,请求只转发到[1.0.0-2.0.0)版本的微服务实例。
•[prefix=rest;withVersion=false;prefixSegmentCount=1]微服务xService提供的URL为: /xService/v1/abc,经过Edge访问的地址为/rest/xService/v1/abc,请求可能转发到任意微服务实例。•[prefix=rest;withVersion=false;prefixSegmentCount=2]微服务xService提供的URL为: /v1/abc,经过Edge访问的地址为/rest/xService/v1/abc,,请求可能转发到任意微服务实例。
•[prefix=rest;withVersion=false;prefixSegmentCount=2]微服务xService提供的URL为: /abc,经过Edge访问的地址为/rest/xService/abc,,请求可能转发到任意微服务实例。
withVersion配置项提供了客户端灰度规则,可让客户端指定访问的服务端版本。Edge Service还包含根据接口兼容性自动路由的功能,请求会转发到包含了该接口的实例。假设某微服务,兼容规划为全部高版本必须兼容低版本,部署了如下版本实例:
1.0.0,提供了operation1
1.1.0,提供了operation一、operation2
Edge Service在转发operation1时,会自动使用1.0.0+的规则来过滤实例
Edge Service在转发operation2时,会自动使用1.1.0+的规则来过滤实例
以上过程用户没必要作任何干预,全自动完成,以免将新版本的operation转发到旧版本的实例中去。
•使用URLMappedEdgeDispatcher
URLMappedEdgeDispatcher容许用户配置URL和微服务的映射关系。使用它能够很是灵活的定义哪些URL转发到哪些微服务。它包含以下几个配置项:
businessV1配置项表示的含义是将请求路径为/usr/business/v1/.的请求,转发到business这个微服务,而且只转发到版本号为1.0.0-2.0.0的实例(不含2.0.0)。转发的时候URL为/business/v1/.。path使用的是JDK的正则表达式,能够查看Pattern类的说明。prefixSegmentCount表示前缀的URL Segment数量,前缀不包含在转发的URL路径中。
有三种形式的versionRule能够指定。2.0.0-3.0.0表示版本范围,含2.0.0,但不含3.0.0;2.0.0+表示大于2.0.0的版本,含2.0.0;2.0.0表示只转发到2.0.0版本。2,2.0等价于2.0.0。从上面的配置能够看出,URLMappedEdgeDispatcher也支持客户端灰度。固然配置项会比DefaultEdgeDispatcher多。URLMappedEdgeDispatcher支持经过配置中心动态的修改配置,调整路由规则。
•自定义Dispatcher
自定义Dispatcher包含两个步骤:
1.实现AbstractEdgeDispatcher
2.经过SPI发布:增长文件META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher,并写入实现类
详细的代码细节能够参考下面的章节"DEMO功能说明"。开发者也能够参考DefaultEdgeDispatcher等代码来定义本身的Dispatcher。
•进行认证鉴权和其余业务处理
经过Edge Servie工做流程能够看出,能够经过多种方式来扩展Edge Service的功能,包括Dispatcher、HttpServerFilter、Handler、HttpClientFilter等。比较经常使用和简单的是经过Handler来扩展。DEMO里面展现了如何经过Handler扩展来实现鉴权。详细的代码细节能够参考下面的章节"DEMO功能说明"。
工做原理
工做流程
Edge Service的工做流程以下
蓝色背景部分在Eventloop线程中执行,黄色背景部分:
•若是工做于reactive模式,则直接在Eventloop线程执行
•若是工做于线程池模式,则在线程池的线程中执行
工做模式
reactive (默认)
Edge Service默认工做于高性能的reactive模式,此模式要求工做于Edge Service转发流程中的业务代码不能有任何的阻塞操做,包括不限于:
•远程同步调用,好比同步查询数据库、同步调用微服务,或是同步查询远程缓存等等
•任何的sleep调用
•任何的wait调用
•超大的循环
Edge Service的底层是基于netty的vertx,以上约束便是netty的reactive模式约束。
线程池
若是业务模型没法知足reactive要求,则须要使用线程池模式。
此时须要在Edge Service的microservice.yaml中配置:
这里的servicecomb.executor.groupThreadPool是ServiceComb内置的默认线程池对应的spring bean的beanId;业务能够定制本身的线程池,并声明为一个bean,其beanId也能够配置到这里。
DEMO功能说明
请参考github上的edge service demo:
https://github.com/ServiceComb/ServiceComb-Java-Chassis/tree/master/demo/demo-edge
该demo包含如下工程:
authentication:微服务:鉴权服务器
edge-service
hiboard-business-1.0.0微服务:business,1.0.0版本,operation add
hiboard-business-1.1.0微服务:business,1.1.0版本,operation add/dec
hiboard-business-2.0.0微服务:business,2.0.0版本,operation add/dec
hiboard-consumer做为一个普通的httpclient,而不是servicecomb consumer
hiboard-model非微服务,仅仅是一些公共的model
经过edge-service访问微服务business的不一样版本,并确认是由正确的实例处理的。
1.注册Dispatcher
实现接口org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher,或从org.apache.servicecomb.edge.core.AbstractEdgeDispatcher继承,实现本身的dispatcher功能。
实现类经过java标准的SPI机制注册到系统中去。
Dispatcher须要实现2个方法:
•getOrder
Dispatcher须要向vertx注入路由规则,路由规则之间是有优先级顺序关系的。
系统中全部的Dispatcher按照getOrder的返回值按从小到大的方式排序,按顺序初始化。
若是2个Dispatcher的getOrder返回值相同,则2者的顺序不可预知。
•init
init方法入参为vertx框架中的io.vertx.ext.web.Router,须要经过该对象实现路由规则的定制。
能够指定知足要求的url,是否须要处理cookie、是否须要处理body、使用哪一个自定义方法处理收到的请求等等
更多路由规则细节请参考vertx官方文档:vertx路由机制https://vertx.io/docs/vertx-web/java/#_routing_by_exact_path
提示:
多个Dispatcher能够设置路由规则,覆盖到相同的url。
假设Dispatcher A和B均可以处理同一个url,而且A优先级更高,则:
•若是A处理完,既没应答,也没有调用RoutingContext.next(),则属于bug,本次请求挂死了
•若是A处理完,而后调用了RoutingContext.next(),则会将请求转移给B处理
2.转发请求
注册路由时,指定了使用哪一个方法来处理请求(下面使用onRequest来指代该方法),在onRequest中实现转发逻辑。
方法原型为:
系统封装了org.apache.servicecomb.edge.core.EdgeInvocation来实现转发功能,至少须要准备如下参数:
•microserviceName,业务自行制定规则,能够在url传入,或是根据url查找等等
•context,即onRequest的入参
•path,转发目标的url
•httpServerFilters,Dispatcher父类已经初始化好的成员变量
edgeInvoke调用内部,会做为ServiceComb标准consumer去转发调用。
做为标准consumer,意味着ServiceComb全部标准的治理能力在这里都是生效的。
3.设置兼容规则
不一样的业务可能有不一样的兼容规划,servicecomb默认的兼容规则,要求全部新版本兼容旧版本。若是知足这个要求,则没必要作任何特殊的设置。
还有一种典型的规划:
1.0.0-2.0.0内部兼容,url为/microserviceName/v1/….的形式
2.0.0-3.0.0内部兼容,url为/microserviceName/v2/….的形式
……
各大版本之间不兼容
此时,开发人员须要针对EdgeInvocation设置兼容规则:
versionMapper的做用是将v1或是v2这样的串,转为1.0.0-2.0.0或2.0.0-3.0.0这样的兼容规则。
注意:
接口不兼容会致使很是多的问题。java chassis要求高版本服务兼容低版本服务,只容许增长接口不容许删除接口。在增长接口后,必须增长微服务的版本号。在开发阶段,接口变动频繁,开发者每每忘记这个规则。当这个约束被打破的时候,须要清理服务中心微服务的信息,并重启微服务和Edge Service(以及依赖于该微服务的其余服务)。不然可能出现请求转发失败等状况。
4.鉴权
Edge Service是系统的边界,对于不少请求须要执行鉴权逻辑。
基于标准的ServiceComb机制,能够经过handler来实现这个功能。
最简单的示意代码以下:
Auth表示是鉴权微服务提供的接口,Invoker.createProxy("auth", "auth", Auth.class)是透明RPC开发模式中consumer的底层api,与@ReferenceRpc是等效,只不过不须要依赖spring bean机制。
Auth接口彻底由业务定义,这里只是一个示例。
Handler开发完成后,配置到edge service的microservice.yaml中:
这个例子,表示转发请求给全部的微服务都必须通过鉴权,可是调用鉴权微服务时不须要鉴权。
文末小结
本文向社区读者从使用角度阐述了使用Edge Service作边缘服务。
咱们也很是欢迎爱好者们向社区提问和贡献代码。
下章咱们将介绍ServiceComb+Zipkin使用篇。
若是在阅读代码时有任何疑问想交流,欢迎扫码加入进微信群。
期待志同道合的朋友们加入
ServiceComb的大门为大家敞开~
用心作开源,不忘初衷
前期阅读: