流量路由技术解析

本文涉及的产品
MSE Nacos/ZooKeeper 企业版试用,1600元额度,限量50份
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
简介: Sentinel2.0 将基于 OpenSergo 流量路由规则实现基本的流量路由能力,支持多种流量路由策略、负载均衡策略、虚拟工作负载等。Sentinel2.0 期望支持 Http、RPC、SQL等微服务各种流量的路由能力,并且可以快速被各主流微服务框架所集成。

流量路由,顾名思义就是将具有某些属性特征的流量,路由到指定的目标。流量路由是流量治理中重要的一环,本节内容将会介绍流量路由常见的场景、流量路由技术的原理以及实现。


流量路由的业务场景


我们可以基于流量路由标准来实现各种业务场景,如标签路由、金丝雀发布、同机房优先路由等。


标签路由

标签路由是按照标签为维度对目标负载进行划分,符合条件的流量匹配至对应的目标,从而实现标签路由的能力。当然基于标签路由的能力,赋予标签各种含义我们就可以实现各种流量路由的场景化能力。



image.png



金丝雀发布

金丝雀发布是一种降低在生产中引入新软件版本的风险的技术,方法是在将更改推广到整个基础架构并使其可供所有人使用之前,缓慢地将更改推广到一小部分用户。金丝雀发布是一种在黑与白之间,能够平滑过渡的一种发布方式。让一部分用户继续用旧版本,一部分用户开始用新版本,如果用户对新版本没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到新版本上面来。一直都有听说,安全生产三板斧的概念:可灰度、可观测、可回滚。那么灰度发布能力就是帮助企业软件做到快速迭代验证的必备能力。在K8s中金丝雀发布的最佳实践如下:第一步:新建灰度 Deployment,部署新版本的镜像,打上新版本的标签。第二步:配置针对新版本的标签路由规则。第三步:验证成功,扩大灰度比例。第四步:若验证成功,将稳定版本的应用更新成最新镜像;若验证失败,把灰度的 Deployment 副本数调整到 0 或删除该 Deployment。


全链路灰度

当企业的发展,微服务的数量会逐渐增多。在有一定规模的一定数量的微服务情况下,一次发版可能涉及到的服务数量会比较多,微服务链路也相当较长。全链路灰度可以保证特定的灰度流量可以路由到所有涉及到的灰度版本中。


image.png


同可用区优先路由

当企业的对稳定性的要求变高时,企业的应用会选择部署在多个可用区中提高应用的可用性,避免某个可用区出现问题后导致影响应用的可用性。当应用在不同的可用区部署时,应用间跨可用区调用可能会被因为远距离调用造成的网络延迟影响,同可用区优先路由会让我们的Consumer应用优先调用当前可用区内的Provider应用,可以很好地减少这种远距离调用造成的影响,同时当某个可用区出现问题后,我们只需在流量入口处将当前可用区的流量隔离掉,其他可用区的流量不会访问至当前可用区的节点,可以很好地控制某个可用区出现问题后的影响面。


image.png


流量路由能力实现的场景众多,上面只是列举了一些典型的场景,下面我们将从流量路由原理入手,剖析流量路由的实现与技术细节。


流量路由原理


需要实现上述所提的流量路由的场景,那么对于Consumer应用来说,同一个 Provider 应用的不同节点之间是有一些特殊的标识。金丝雀发布场景来说,新版本代码所部署的节点需要被标上成新版本的标识;同机房优先路由来说,Provider节点要被标识上机房的信息;全链路灰度场景来说,灰度环境的节点需要被带上灰度标。因此,我们需要在Provider服务注册的过程中,就在注册到注册中心的地址信息中带上治理场景所需的标识。


节点打标

首先介绍一下节点打标的能力,我们先看看 Apache Dubbo 的设计,其中 Dubbo 服务节点的地址信息使用 URL 模型来承载。

class URL implements Serializable {
    protected String protocol;
    // by default, host to registry
    protected String host;
    // by default, port to registry
    protected int port;
    protected String path;
    private final Map<String, String> parameters;
}


举个简单的例子,假如 Consumer 收到这样一条 dubbo://10.29.0.102:20880/GreetingService?tag=gray&az=az_1 地址信息,表示 GreetingService 服务使用的是 dubbo 协议,服务绑定的 ip 与 port 分别为  10.29.0.102 跟 20880,该地址携带上了 tag=gray、az=az_1 这样两条元数据信息,分别表示当前节点的标签为灰度,当前节点所处的可用区(az:Availability Zone 为云上的机房的可用区概念)为 az_1 。那么节点打标的能力其实就比较明确了,我们在服务提供者向注册中心注册服务地址之前,我们在当前服务提供者的地址信息上增加需要增加的元数据信息比如 `verion = gray`,比如在 Apache Dubbo 的 URL 中增加 paramters 信息,一般来说元数据信息都是 k-v 的 map 结构,这样框架向注册中心注册该节点时会为其添加需要的标签信息`verison=gray`。


相似的, Spring Cloud 中通过表示服务节点信息的抽象

public class Server {
   public static interface MetaInfo {
        ...
    }
    private String host;
    private int port = 80;
    ...
}


Sentinel2.0 希望作为流量治理能力的实现,考虑到会被较多框架即成,因此需要考虑到各个框架的通用点以及本身设计的易用性,Sentinel2.0 中使用 Instance 模型表示服务节点信息的抽象,并且在其中保留了原有类型的引用。

public class Instance {
  private String host;
  private Integer port;
  private Map<String, String> metadata;
  private Object targetInstance;
}


其中metadata用来存储用于服务治理的元数据,比如AZ标、版本标签等等。


流量路由

到目前为止,我们算是搞明白了 Consumer 收到的 Provider 的地址列表长什么样子。假设 Consumer 收到了 如下图所示 GreetingService 服务的6条地址,那么我们该如何进行选择呢?


image.png


算是进入到正题,我们看一下 Sentinel2.0 是如何实现流量路由能力的。


目前我们在 Sentinel2.0 中分别抽象了InstanceManager、RouterFilter 以及 LoadBalancer 三个对象,并通过 ClusterManager 将它们管理起来。其中 InstanceManager 将地址列表按需进行存储与管理,RouterFilter做为流量路由能力实现的主体,LoadBalancer做为负载均衡能力实现的主体。


image.png


Dubbo 在收到注册中心同步过来的 Provider URL 之后会生成对应的 Invoker ,Invoker 列表我们可以理解为就是可以调用的Provider节点列表的抽象。流量路由则是需要将传入的 Invoker 列表按照路由规则进行路由筛选,筛选出符合路由规则的服务提供者,即符合路由规则的 Invoker 列表。我们如何可以通过 Sentinel2.0 的抽象来实现流量路由的能力呢?当地址通知下来后,我们需要通过instanceManager#storeInstances将地址列表进行缓存。

@Override
public void notify(BitList<Invoker<T>> invokers) {
    super.notify(invokers);
    instanceManager.storeInstances(invokersToInstances(invokers));
}


在流量路由处,我们则调用clusterManager#route实现地址路由。

@Override
protected BitList<Invoker<T>> doRoute(BitList<Invoker<T>> invokers, URL url, Invocation invocation, boolean needToPrintMessage, Holder<RouterSnapshotNode<T>> routerSnapshotNodeHolder, Holder<String> messageHolder) throws RpcException {
    TrafficContext trafficContext = getTrafficContext(invocation);
    List<Instance> instances = clusterManager.route(trafficContext);
    return instancesToInvokers(instances);
}


其中ClusterManager会将路由执行的逻辑交给RouterFiler.route进行执行。

public List<Instance> route(TrafficContext context) {
    List<Instance> instances = instanceManager.getInstances();
    for (RouterFilter routerFilter : routerFilterList) {
        instances = routerFilter.filter(instances, context);
    }
    return instances;
}


每个 RouterFilter 服务路由都可以包含一条路由规则,路由规则决定了服务消费者的调用目标,即规定了服务消费者可调用哪些服务提供者;一次微服务调用的地址列表可以由多个 RouterFilter 服务路由共同影响,比如我们希望当前的 Consumer 流量访问到在同时符合灰度发布以及同可用区优先调用路由规则的节点上。我们可以按照需求增加路由链中的 RouterFilter,并且路由链的 Route 方法是循环调用每个 RouterFilter 的 Route 方法。并且上一个 Router 的输出 Invoker 列表会做为下一个 Router 的输入。介绍到这里,大家可能对下图会有一个更加深刻的理解了。


image.png


路由的整体模型大家已经理解了,我们来重点看一下具体的 RouterFilter 服务路由是如何实现的。

public interface RouterFilter {
  List<Instance> filter(List<Instance> instanceList, TrafficContext context) throws TrafficException;
}


RouterFilter 的 Route 方法会在每次请求调用时被执行,Route 方法有关键的两个入参 InstanceList 跟 TrafficContext,instanceList 是可调用的服务提供者节点列表的抽象。TrafficContext 是当前调用流量的请求上下文的抽象,我们可以从中读到请求中携带着的RouterFilter所关心的一些元数据(比如当前请求的AZ信息、请求参数中指定key的值等内容)。Route 方法会在每次调用时候根据请求中的上下文信息结合路由规则计算出当前请求需要匹配的目标节点特征,并遍历当前的地址列表,根据目标节点特征进行地址过滤。筛选出目标节点的地址列表,是输入地址列表的子集,然后传递给下一个 RouterFilter。


RouterFilter 的 Route 方法逻辑的伪代码如下:

@Override
public List<Instance> filter(List<Instance> instanceList, TrafficContext context) throws TrafficException {
    List<Instance> targetInstances = new ArrayList<>();
    for (Instance instance : instanceList) {
        if (trafficRouteMatch(instance, context)) {
            targetInstances.add(instance);
        }
    }
    return targetInstances;
}


instanceList 为输入地址列表,targetInstances为输出地址列表即当前Router服务路由的结果。


Sentinel2.0 流量路由规划


image.png


Sentinel2.0 将基于 OpenSergo 流量路由规则实现基本的流量路由能力,支持多种流量路由策略、负载均衡策略、虚拟工作负载等。Sentinel2.0 期望支持 Http、RPC、SQL等微服务各种流量的路由能力,并且可以快速被各主流微服务框架所集成。

相关文章
|
8月前
|
传感器 人工智能 物联网
穿戴科技新风尚:智能服装设计与技术全解析
穿戴科技新风尚:智能服装设计与技术全解析
683 85
|
8月前
|
人工智能 API 语音技术
HarmonyOS Next~鸿蒙AI功能开发:Core Speech Kit与Core Vision Kit的技术解析与实践
本文深入解析鸿蒙操作系统(HarmonyOS)中的Core Speech Kit与Core Vision Kit,探讨其在AI功能开发中的核心能力与实践方法。Core Speech Kit聚焦语音交互,提供语音识别、合成等功能,支持多场景应用;Core Vision Kit专注视觉处理,涵盖人脸检测、OCR等技术。文章还分析了两者的协同应用及生态发展趋势,展望未来AI技术与鸿蒙系统结合带来的智能交互新阶段。
539 31
|
8月前
|
编解码 监控 网络协议
RTSP协议规范与SmartMediaKit播放器技术解析
RTSP协议是实时流媒体传输的重要规范,大牛直播SDK的rtsp播放器基于此构建,具备跨平台支持、超低延迟(100-300ms)、多实例播放、高效资源利用、音视频同步等优势。它广泛应用于安防监控、远程教学等领域,提供实时录像、快照等功能,优化网络传输与解码效率,并通过事件回调机制保障稳定性。作为高性能解决方案,它推动了实时流媒体技术的发展。
477 5
|
8月前
|
数据采集 机器学习/深度学习 存储
可穿戴设备如何重塑医疗健康:技术解析与应用实战
可穿戴设备如何重塑医疗健康:技术解析与应用实战
323 4
|
8月前
|
机器学习/深度学习 人工智能 自然语言处理
AI技术如何重塑客服系统?解析合力亿捷AI智能客服系统实践案例
本文探讨了人工智能技术在客服系统中的应用,涵盖技术架构、关键技术和优化策略。通过感知层、认知层、决策层和执行层的协同工作,结合自然语言处理、知识库构建和多模态交互技术,合力亿捷客服系统实现了智能化服务。文章还提出了用户体验优化、服务质量提升和系统性能改进的方法,并展望了未来发展方向,强调其在客户服务领域的核心价值与潜力。
495 6
|
8月前
|
编解码 人工智能 并行计算
基于 Megatron 的多模态大模型训练加速技术解析
Pai-Megatron-Patch 是一款由阿里云人工智能平台PAI 研发的围绕英伟达 Megatron 的大模型训练配套工具,旨在帮助开发者快速上手大模型,打通大模型相关的高效分布式训练、有监督指令微调、下游任务评估等大模型开发链路。本文以 Qwen2-VL 为例,从易用性和训练性能优化两个方面介绍基于 Megatron 构建的 Pai-Megatron-Patch 多模态大模型训练的关键技术
|
8月前
|
监控 负载均衡 安全
静态IP代理与动态IP代理:提升速度与保障隐私的技术解析
本文探讨了静态IP代理和动态IP代理的特性和应用场景。静态IP代理通过高质量服务提供商、网络设置优化、定期更换IP与负载均衡及性能监控提升网络访问速度;动态IP代理则通过隐藏真实IP、增强安全性、绕过封锁和提供独立IP保障用户隐私。结合实际案例与代码示例,展示了两者在不同场景下的优势,帮助用户根据需求选择合适的代理服务以实现高效、安全的网络访问。
295 1
|
8月前
|
机器学习/深度学习 数据采集 自然语言处理
基于Python的情感分析与情绪识别技术深度解析
本文探讨了基于Python的情感分析与情绪识别技术,涵盖基础概念、实现方法及工业应用。文中区分了情感分析与情绪识别的核心差异,阐述了从词典法到深度学习的技术演进,并通过具体代码展示了Transformers架构在细粒度情感分析中的应用,以及多模态情绪识别框架的设计。此外,还介绍了电商评论分析系统的构建与优化策略,包括领域自适应训练和集成学习等方法。未来,随着深度学习和多模态数据的发展,该技术将更加智能与精准。
511 1
|
8月前
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
8月前
|
缓存 算法 Oracle
深度干货 | 如何兼顾性能与可靠性?一文解析YashanDB主备高可用技术
数据库高可用(High Availability,HA)是指在系统遇到故障或异常情况时,能够自动快速地恢复并保持服务可用性的能力。如果数据库只有一个实例,该实例所在的服务器一旦发生故障,那就很难在短时间内恢复服务。长时间的服务中断会造成很大的损失,因此数据库高可用一般通过多实例副本冗余实现,如果一个实例发生故障,则可以将业务转移到另一个实例,快速恢复服务。

热门文章

最新文章

推荐镜像

更多
  • DNS