资讯专栏INFORMATION COLUMN

扩展Zuul实现敏捷开发的小小技巧

shadowbook / 787人阅读

摘要:生产环境可以借助集合来实现灰度发布代码请参考微服务权限框架的灰度发布功能,已经全部开源关于基于开发基于前后分离的开发平台,支持账号短信等多种登录,提供配套视频开发教程。

分析下目前遇到的痛点

你在开发工作的是否遇到这个问题,微服务模块划分过细,基础模块依赖的比较多?
比如你要进行微服务开发则需要启动以下基础模块

注册中心(eureka)

配置中心(spring cloud config)

网关(zuul)

认证中心(oauth)

...

如上图红色标注的服务模块,而你需要编码或者需要的只有那么一个业务微服务模块,本地启动这么微服务模块对开发机器的要求性能较高,并且影响开发效率。
为了解决这种问题,团队一般都会把通用的基础模块部,提供统一的开发环境,方便大家开发,如上图 只需要考虑你的业务模块(serviceA、serviceB) 即可,提高开发效率。
这种统一开发基础环境问题存在小小的问题,比如当开发A维护serviceA,开发B维护serviceB 不会出现冲突;如果开发A、B同时维护一个模块时候,就会出现冲突如下图所示:A的本地请求会被路由到B正在开发的biz-service,而不是目标的A的biz-service,因为zuul 是更具服务名称进行路由的

解决原理

重写网关的转发规则,其实就是重写ribbon的路由规则,根据客户端不同的用户请求(可以根据入参不同区分)路由到对应的微服务上,所以对应的微服务上要打上标签。biz-service A开发版本,biz-service B开发版本

代码实现 1. 在微服务的eureka客户端声明版本所属

</>复制代码

  1. eureka:
  2. instance:
  3. metadata-map:
  4. version: v1.0 # A的开发版本
2. 自定义ribbon 的断言

</>复制代码

  1. /**
  2. * @author lengleng
  3. * @date 2018/10/16
  4. *

  5. * 路由微服务断言
  6. *

  7. * 1. eureka metadata 存在版本定义时候进行判断
  8. * 2. 不存在 metadata 直接返回true
  9. */
  10. @Slf4j
  11. public class MetadataCanaryRuleHandler extends ZoneAvoidanceRule {
  12. @Override
  13. public AbstractServerPredicate getPredicate() {
  14. return new AbstractServerPredicate() {
  15. @Override
  16. public boolean apply(PredicateKey predicateKey) {
  17. String targetVersion = RibbonVersionHolder.getContext();
  18. RibbonVersionHolder.clearContext();
  19. if (StrUtil.isBlank(targetVersion)) {
  20. log.debug("客户端未配置目标版本直接路由");
  21. return true;
  22. }
  23. DiscoveryEnabledServer server = (DiscoveryEnabledServer) predicateKey.getServer();
  24. final Map metadata = server.getInstanceInfo().getMetadata();
  25. if (StrUtil.isBlank(metadata.get(SecurityConstants.VERSION))) {
  26. log.debug("当前微服务{} 未配置版本直接路由");
  27. return true;
  28. }
  29. if (metadata.get(SecurityConstants.VERSION).equals(targetVersion)) {
  30. return true;
  31. } else {
  32. log.debug("当前微服务{} 版本为{},目标版本{} 匹配失败", server.getInstanceInfo().getAppName()
  33. , metadata.get(SecurityConstants.VERSION), targetVersion);
  34. return false;
  35. }
  36. }
  37. };
  38. }
  39. }
3. 版本上下文TTL

</>复制代码

  1. public class RibbonVersionHolder {
  2. private static final ThreadLocal context = new TransmittableThreadLocal<>();
  3. public static String getContext() {
  4. return context.get();
  5. }
  6. public static void setContext(String value) {
  7. context.set(value);
  8. }
  9. public static void clearContext() {
  10. context.remove();
  11. }
  12. }
4. 初始化ribbon 路由配置

</>复制代码

  1. @Configuration
  2. @ConditionalOnClass(DiscoveryEnabledNIWSServerList.class)
  3. @AutoConfigureBefore(RibbonClientConfiguration.class)
  4. @ConditionalOnProperty(value = "zuul.ribbon.metadata.enabled")
  5. public class RibbonMetaFilterAutoConfiguration {
  6. @Bean
  7. @ConditionalOnMissingBean
  8. @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
  9. public ZoneAvoidanceRule metadataAwareRule() {
  10. return new MetadataCanaryRuleHandler();
  11. }
  12. }
5. 客户端调用时 header 传入版本,以 axios 为例

</>复制代码

  1. axios.interceptors.request.use(config => {
  2. NProgress.start() // start progress bar
  3. if (store.getters.access_token) {
  4. config.headers["Authorization"] = "Bearer " + token
  5. config.headers["version"] = "v1.0" // 开发人员自己的版本标志,对应eureka metadata 配置
  6. }
  7. return config
  8. }
总结

扩展ribbon 的路由规则,根据客户端来去不同版本的服务,也可以理解为灰度发布。

生产环境可以借助Kong、Traefik 集合zuul 来实现灰度发布

代码请参考微服务权限框架pig的灰度发布功能,已经全部开源

关于pig:

基于Spring Cloud、oAuth2.0开发基于Vue前后分离的开发平台,支持账号、短信、SSO等多种登录,提供配套视频开发教程。
https://gitee.com/log4j/pig

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/27505.html

相关文章

  • 扩展Zuul实现敏捷开发小小技巧

    摘要:生产环境可以借助集合来实现灰度发布代码请参考微服务权限框架的灰度发布功能,已经全部开源关于基于开发基于前后分离的开发平台,支持账号短信等多种登录,提供配套视频开发教程。 showImg(https://segmentfault.com/img/remote/1460000016809362); 分析下目前遇到的痛点 你在开发工作的是否遇到这个问题,微服务模块划分过细,基础模块依赖的比较...

    baihe 评论0 收藏0
  • 重构:一项常常被忽略基本功

    摘要:无论如何,单元测试一直是一中非常重要却常常被忽视的技能。在实践中,重构的要求是很高的它需要有足够详尽的单元测试,需要有持续集成的环境,需要随时随地在小步伐地永远让代码处于可工作状态下去进行改善。 showImg(https://segmentfault.com/img/bVbttWF?w=1000&h=528); 五月初的时候朋友和我说《重构》出第 2 版了,我才兴冲冲地下单,花了一个...

    idealcn 评论0 收藏0
  • 这次要是讲不明白Spring Cloud核心组件,那我就白编这故事了

    摘要:我不听,我就是这么命名。任何服务启动以后,都会把自己注册到的注册表中当服务死亡的时候,也会通知。服务拿到结果后,会把结果缓存在本地的注册表里。根据负载均衡策略,从注册表中选择一个真正的实例地址。 原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。 这几天可真是热啊,泡个海澡是再好不过了。玩的正起劲,突然脚底绊上一股暗流,然后我就一直在水里旋转旋转旋转...终于...

    stdying 评论0 收藏0
  • SpringCloud之zuul

    摘要:洞察和监控在边缘跟踪有意义的数据和统计数据,以便为我们提供准确的生产视图。压力测试逐步增加集群的流量,以评估性能。减少负载为每种类型的请求分配容量,并删除超过限制的请求。在路由到源之前执行,可以用于身份验证路由和装饰请求。 showImg(https://segmentfault.com/img/remote/1460000018826272); 简介 Zuul是所有从设备和web站点...

    Youngdze 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<