问题引入
我们在开发的时候,多人开发同一个微服务,都注册到同一个nacos,前端请求的时候,网关Gateway默认轮训请求注册中心的服务,OpenFeign也会轮询请求注册中心的服务,这样就会导致前端有时会误入后台自己正在Debug的服务,导致前端响应失败。
目前解决办法
通过注册多个namespace来区分前端开发的环境,将前端开发环境与后台人员环境分割开来。
每次开发都如此配置会导致配置文件一直增加,后台同时开发相同服务时也需要隔离开来。
优化解决方案
通过自定义路由策略,将多个服务注册到一个namespace下,前端与后台人员点对点联调,多任务并行,默认开发环境会保留一个稳定版本的服务,然后前后端人员点对点进行开发调试。如此一来极大加快开发效率,因为在开发过程中的打包,验证,反馈等时间都可以极大减少。
实现原理
在注册了若干相同服务到nacos的注册中心上后,我们通过配置每个服务的元数据属性来标识每个服务。
1 通过客户端的http请求头带上版本信息来寻找特定服务。
2 网关会通过请求中的serviceId向nacos发送请求。
3 Nacos返回对应ServiceId列表。
4 然后执行我们自定义的负载均衡算法来选择相应的服务。
5 最终网关将对应的请求发送给选择后的实例节点。
核心代码
路由选择 CustomizedReactorServiceInstanceLoadBalancer 继承了 ReactorServiceInstanceLoadBalancer
并重写了其choose方法,该方法即为我们选择服务的策略。如springcloud 下的路由选择策略RandomLoadBalancer和RoundRobinLoadBalancer(默认使用)皆是通过这种方式实现的.
在该方法里定义了两个常量LOADBALANCE_METADATA_KEY 和 LOADBALANCE_METADATA_DEFAULT_VALUE 分别代表标识服务元数据的key,和默认选择值。
然后choose方法->processInstanceResponse->getInstanceResponse
这个代码主要意思就是假如nacos中服务列表为空,抛出异常,若只有一个服务即返回该服务实例即可,最后一种方式即为返回特定路由请求下的服务eg.(route=lmx)。
自动装配
CustomizedRouteBalancerAutoConfiguration,此类为自定义策略装配类。
首先该类绑定了我们的自定义路由策略。
其次该类选择了自定义策略的生效范围,目前该策略只在开发环境上适用。
前后端使用文档
后端配置
在每个需要发布的服务上加上metadata 元数据格式用于表示自己,可见在nacos服务列表中注册了自己本地的服务。(提交代码时不要将本地开发标识带至线上环境)
前端访问
1 正常请求不带header,会默认访问开发环境的default(稳定)服务 2 点对点开发联调 在header 请求中添加route参数进入相应开发后台