北极星是什么
- 1: 简介
- 2: 功能特性
- 3: 接入方式
- 3.1: 使用 SDK
- 3.2: 使用开发框架
- 3.3: 使用 Java Agent
- 3.4: 使用 K8s 和网格代理
1 - 简介
北极星是腾讯开源的服务治理平台,致力于解决分布式和微服务架构中的服务管理、流量管理、配置管理、故障容错和可观测性问题,针对不同的技术栈和环境提供服务治理的标准方案和最佳实践。下面介绍北极星的应用场景、功能特性、系统组件和常见问题。
背景
应用架构经历了从单体到分布式服务或者微服务的演进,但是演进并不是替代,每种架构各有优劣。
单体架构
单体架构的全部代码都在一个应用里,适合小型业务系统的研发。如果应用的复杂度低,单体架构易于开发、测试、部署和伸缩。但是,随着功能模块和研发人员的增加,单体架构面临众多问题:
-
故障扩散:如果某些功能模块发生异常,可能影响其他的功能模块。
-
扩展性差:只能扩展整个应用,不能单独扩展某些热点功能,存在资源浪费。
-
迭代效率低:不同功能无法独立迭代,任何改动都影响整个应用,增加开发、测试和发布成本。
-
技术栈单一:全部功能只能采用相同的技术栈开发,引入新技术和升级新版本的难度太大。
微服务架构
对于中型以上规模的业务系统来说,更适合采用分布式服务架构,例如:微信支付这种超大型系统涉及上百个功能模块和上千名研发人员,采用单体架构简直是个灾难。因此,需要将不同的功能拆成分布式服务,每个服务由少量研发人员独立维护。
分布式服务可以解决单体架构的问题,但是用起来并不容易,需要配套的基础设施:
-
本地函数调用变成远程服务调用,需要高效的网络请求框架。
-
网络请求需要解决服务寻址、故障容错和各种应用场景中的流量调度问题。
-
应用数量大幅增加,需要 CICD 流水线和发布平台简化应用的测试和运维工作。
微服务和分布式服务没有本质的区别,微服务更强调服务的粒度要细。在落地过程中,服务的粒度其实没有绝对的标准,要从实际问题出发选择合理方案,不要盲目追求微服务。
北极星致力于打造一个支持多语言、多框架的服务治理平台,帮助用户解决分布式服务或者微服务架构中的服务管理、流量管理、配置管理、故障容错和可观测性问题。
北极星具备哪些功能
北极星具备服务管理、流量管理、故障容错、配置管理和可观测性五大功能:
-
服务管理
:包含服务发现、服务注册、健康检查和元数据管理。- 服务发现:支持 HTTP、SDK 和 DNS 服务发现方式。
- 服务注册:支持 HTTP、SDK、控制台操作和 K8s 服务注册方式。
- 健康检查:支持服务实例上报心跳,通过心跳判断实例是否健康,及时剔除异常实例。
- 元数据管理:支持在服务和实例上配置协议、版本和位置等标签,实现动态路由等功能。
-
流量管理
:包含动态路由、负载均衡和访问限流。- 动态路由:支持自定义路由策略,将服务的部分请求路由到部分实例,用于灰度发布等应用场景。
- 负载均衡:支持权重轮训、权重随机和权重一致性 Hash 等负载均衡算法。
- 访问限流:支持本地和分布式两种模式,被限流的请求支持排队和自定义响应。
-
故障容错
:包含服务熔断和节点熔断。- 服务熔断:对服务或者接口进行熔断,如果服务或者接口发生熔断,返回自定义响应。
- 节点熔断:对服务实例进行熔断,不会将请求路由到熔断的服务实例,降低请求失败率。
- 主动探测:服务和节点熔断除了被动探测,还支持主动探测,进一步降低请求失败率。
-
配置管理
:包含配置变更、配置校验、版本管理和灰度发布等功能。 -
可观测性
:提供业务流量、系统事件和操作记录等监控视图。
北极星的功能需要控制面和数据面配合实现:
-
控制面
:负责服务和配置数据的管理和下发,负责流量管理和熔断降级策略的管理和下发。 -
数据面
:负责全部服务发现和治理功能的客户端实现,采用插件化设计,支持按需加载和使用。
数据面功能分为三个部分:
-
服务作为被调
:当一个服务被其他服务调用时,可以使用服务注册、上报心跳、访问限流和访问鉴权功能。 -
服务作为主调
:当一个服务调用其他服务时,可以使用服务发现、动态路由、负载均衡和熔断降级功能。 -
公共部分
:支持拉取配置数据和上报监控数据。
北极星包含哪些组件
北极星的系统组件分为控制台、控制面和数据面三个部分:
-
控制台
:提供简单易用的管理页面,支持用户和权限管理。 -
控制面
:包含核心组件 Polaris 和可选的功能组件,核心组件可以满足绝大部分业务需求,可选的功能组件按需部署。 -
数据面
:提供多语言 SDK、开发框架、Java Agent 和网格代理四种形态的实现,满足不同的业务场景和开发模式,支持异构服务的互联互通和统一治理。
控制面组件:
-
Polaris
:支持各种形态的数据面接入,支持服务和配置数据的管理和下发,支持流量管理和熔断降级策略的管理和下发,可以覆盖服务注册中心、服务网格控制面和配置中心的功能。 -
Polaris Controller
:可选的功能组件,支持 K8s 服务同步和网格代理注入。K8s 服务同步将 K8s 服务按需同步到北极星,用户不需要在应用程序里显式地注册服务。网格代理注入按需在应用程序 Pod 里注入北极星 Sidecar,以流量代理的方式实现服务发现和治理功能。
数据面组件:
-
SDK
:北极星提供轻量级的多语言 SDK,使用方法和绝大部分客户端软件类似,用户在应用程序里引入北极星 SDK。这种数据面形态以无流量代理的方式实现服务发现和治理功能,没有额外的性能和资源损耗,不会增加现网运维和问题定位的成本。 -
开发框架
:北极星 SDK 可以被集成到开发框架内部,如果用户使用开发框架,不需要显式地引入北极星 SDK。对于 Spring Cloud、Dubbo 和 gRPC 等开发框架,北极星提供可以无缝集成的依赖包。另外,go-micro、go-kratos、go-zero、GoFrame 和 CloudWeGo 等开发框架社区也提供北极星插件。 -
Java Agent
:对于 Spring Cloud 和 Dubbo 等 Java 开发框架,北极星支持 Java 生态常用的 Agent 接入模式。用户只需要在应用程序的启动命令中引入 Polaris Java Agent,即可将北极星的服务发现和治理功能引入应用程序,不需要改动任何代码和配置文件。 -
网格代理
:北极星网格代理在应用程序 Pod 里注入 Polaris Sidecar 和 Proxy,前者通过劫持 DNS 解析将请求转到后者,后者通过流量代理实现服务发现和治理功能。这种数据面形态适合性能和资源损耗不敏感的业务,要求业务具备网格代理的运维能力。
常见问题
腾讯业务都在使用北极星吗?
北极星是腾讯内部协同共建的新一代服务发现和治理平台,已整合和替代 L5 等名字服务和负载均衡系统。截止2021年底,超过90%的业务部门使用北极星,接入节点数量超过千万。
北极星开源版和内部版相同吗?
开源版和内部版的主体功能和代码相同,但是部署架构不同。开源版提供单机和集群两种部署架构,集群架构支持百万级的节点接入。内部版通过插件的方式实现了更为复杂的部署架构,支持千万级的节点接入。
北极星和 TARS 是什么关系?
北极星和 TARS 都是腾讯在微服务领域的重点开源项目。曾经,腾讯内部存在多套服务开发框架、注册中心和治理组件,使用不同开发框架的服务难以互相调用和统一管理。为了解决这个问题,腾讯内部协同共建了北极星,整合了服务注册中心和治理组件,TARS 内部版的开发框架部分已接入北极星。北极星和 TARS 开源社区也会尝试更多合作。
2 - 功能特性
2.1 - 服务管理
服务注册
服务注册指的是被调方按照服务模型将自身的服务数据注册到北极星,以供主调方进行服务发现。
服务数据主要包括以下部分:
- 服务名:服务的唯一标识,区分大小写。
- 服务元数据:服务的标签信息,KV格式,可对服务进行分类,可用于过滤。
- 服务实例:提供服务的节点列表,以IP:PORT的方式提供。
- 服务实例元数据:服务实例的标签信息,KV格式,通常用于描述节点的集群、版本等,用于后续流量治理等操作。
服务注册的方式
北极星支持以下4种服务注册方式:
通过SDK注册
北极星提供了多语言SDK,服务可以通过集成SDK,调用registerInstance接口完成服务注册。
通过服务框架注册
服务框架会提供通用的服务注册接口,供应用在拉起的时候,自动往注册中心注册。
北极星对主流的服务框架(SpringCloud,Dubbo,gRPC)做了适配,用户无需修改业务逻辑代码,只需引入北极星的框架扩展库,即可实现自动注册。
通过k8s同步的方式注册
用户通过k8s部署服务,并注册为k8s的service,北极星通过controller的机制,从k8s中将service和endpoint信息同步到北极星,完成服务注册。
通过OpenAPI注册
北极星控制面提供基于Rest标准的OpenAPI,用户可通过OpenAPI完成服务注册的操作。
服务发现
服务发现指的主调方是根据服务名标识,拉取服务实例列表,以供后续进行服务调用的操作。
服务发现的方式
北极星支持以下4种方式进行服务发现:
通过SDK进行服务发现
北极星提供了多语言SDK,SDK通过ConsumerAPI提供3个接口进行服务发现:
- getAllInstances:获取服务下全量的服务实例列表,不做任何过滤。
- getHealthyInstances:获取服务下健康的服务实例列表,只包含健康实例,不包含被熔断、不健康、隔离、权重为0的实例。
- getOneInstances:针对健康的服务实例列表,进行动态路由和负载均衡,返回单个可用的服务实例。
通过服务框架进行服务发现
服务框架会提供通用的服务发现接口,应用在RPC之前,会自动进行服务发现,获取到可用的实例进行RPC调用。
北极星对主流的服务框架(SpringCloud,Dubbo,gRPC)做了适配,用户无需修改业务逻辑代码,只需引入北极星的框架扩展库,即可实现自动发现。
使用DNS进行服务发现
北极星通过polaris-sidecar提供DNS功能,用户程序可以通过DNS域名访问的方式,实现无侵入的服务发现。
使用OpenAPI服务发现
北极星控制面提供基于Rest标准的OpenAPI,用户可通过OpenAPI完成服务发现的操作。
健康检查
健康检查提供了一种机制,使得控制面可以在一定时间段内,感知服务实例出现异常,从而将异常节点剔除,并通知给所有的消费者。健康检查支持以下实现形式:
心跳上报
服务实例持续上报心跳给控制面,并与控制面约定TTL的时间段,控制面检查服务实例的心跳上报时间点,当发现当前时间相比实例最后一次上报时间已经超过3*TTL
,就将实例标记为不健康,并通知给该服务的消费者。
2.2 - 流量管理
动态路由
通常一个服务包含多个实例。在简单场景下,每个实例是对等的,通过负载均衡组件访问任意一个即可。
但是,在绝大部分场景下,每个实例具有逻辑属性和物理属性:
- 逻辑属性:版本、协议、业务Set、特性环境等。北极星允许用户为每个实例设置自定义标签
- 物理属性:地理位置。比如实例所属的地域-城市-园区的位置信息。
对于某个服务的全部实例,可以根据逻辑和物理属性将其划分成为多个分组或者集群,如下图所示:
服务主调方/消费者发送请求,客户端根据请求和主调方节点属性,将不同节点的不同请求路由到不同实例分组或者集群。
串联式路由插件
北极星动态路由组件采用插件化、可配置的方式实现。北极星默认内置以下路由插件:
- 前置路由插件:默认在插件链的最前面执行,用于剔除隔离和权重为0的实例。
- 规则路由插件:按照控制台配置的路由规则,根据用户请求参数执行路由规则进行服务实例的过滤。
- 元数据路由插件:直接根据传入的实例元数据对服务实例进行过滤。
- 就近路由插件:根据应用自身所属的地域信息,与实例的地域信息进行匹配,筛选出就近的服务实例。
- 后置路由插件:剔除健康状态异常和故障熔断的实例。如果被剔除的节点数超过一定比例,返回前一个插件的筛选结果,防止因网络分区原因导致的误剔除。
当调用GetOneInstance接口时,会调用路由插件,执行动态路由进行实例筛选,执行流程如下图所示:
插件链中路由插件的执行顺序可以由用户自行编排,同时用户也可以定制自己的路由插件。
负载均衡
从满足本次转发要求的服务实例集中, 通过一定的均衡策略,选取一个实例返回给主调方,供主调方进行服务请求发送。
分类
负载均衡策略一般分为2类:
无状态负载均衡
无状态负载均衡策略,主要特点是每次负载均衡获取到的结果是由具体的负载均衡算法决定。目的是让负载均匀的分发到后端节点。
主要负载均衡策略包括:权重随机,权重轮询等
对于无状态的业务逻辑,为了保证后端节点能够均衡分配请求,此时应该选择权重随机负载均衡策略
有状态负载均衡
有状态负载均衡策略,除了要达到让负载均衡分散到节点的目标以外,还需要实现将同一对象的请求分发到同一个节点。例如业务场景需要将同一个用户的全部请求发送到后端同一个节点处理的情况。
主要负载均衡策略是一致性hash
算法
权重随机
权重随机负载均衡策略,利用区间算法,基于伪随机因子取模的方式选择对应服务实例。
对于有状态的业务逻辑(比如通过用户ID或者请求ID进行hash分区的),为了保证同key请求能够持续命中同一个物理节点,此时应该选择一致性hash负载均衡策略。
权重一致性hash(ringhash算法)
该负载均衡策略基于ketama环算法,每一个服务实例会按照权重分裂成若干个虚拟节点。虚拟节点通过取hash值的方式,映射到长度为2^32的hash环中。
发起查询时,北极星会基于用户传入的hashKey,计算出具体的hash值,然后到环中寻找hash值刚刚好大于传入数据hash值的虚拟节点,并返回其对应的服务实例
权重一致性hash(maglev算法)
该负载均衡策略基于maglev算法(https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/44824.pdf)进行节点分配。
首先为实例集创建一个长度为质数65537的向量表,算法根据节点的权重,将向量表进行填充,直到向量表全部被节点所占满。取节点时则根据用户传值的hashValue取摸的方式,返回对应下标的节点。
算法优点:由于是直接取模寻址,因此算法性能相比ketama环要高(官方数据是在256K个插槽的情况下,性能是5X到10X的差距)。
算法缺点:当节点下线后,导致迁移的节点数量相比ketama环要多(官方数据为迁移节点数量是ketama的两倍)
权重设计
北极星的每个服务实例,都可以设置权重,请求会根据权重,按比例进行分配。权重分为静态权重和动态权重两类:
静态权重
用户可以通过界面配置或者实例注册的方式,调整服务实例的权重,由控制面推送给所有的数据面生效。
动态权重
数据面在运行过程中,定时上报负载数据给控制面,目前支持capacity&used两个指标, 被调方定时(一般2s)上报两个指标的数值到控制面,控制面根据负载信息,调整权重数据。主调方定时拉取最新的权重数据,实时更新以前的静态权重字段,复用老的weightrandom算法。
访问限流
限流能力是高并发系统中,对于服务提供方的一种保护手段。通过限流功能,我们可以通过控制QPS的方式,以避免被瞬时的流量高峰冲垮,从而保障系统的高可用性。
访问限流主要有如下两个应用场景:
- 过载保护:保护业务不被突发流量打垮
- 业务防刷:防止恶意用户发送过多流量影响其他正常用户
北极星为被调端服务提供2种类型的访问限流能力:
单机限流:针对单个被调实例的级别的限流,流量限额只针对当前被调实例生效,不共享。
分布式限流:针对服务下所有实例级别的限流,多个服务实例共享同一个全局流量限额。
两种限流模式如何选择?
- 单机限流:一般适用于保护服务自身不被打垮,按照每个服务集群单机的容量来计算配额。
- 分布式限流:一般适用于保护第三方服务或者公共服务(比如保护数据库);或者是在网关层进行限流,对通过网关接入的后端服务进行保护。
访问鉴权
访问鉴权包含以下3部分功能:
- 认证:检验服务调用双方的身份真实性
- 加密:对服务调用通讯数据进行加密
- 鉴权:校验请求是否有访问服务接口的权限
访问鉴权可以有效地保护服务调用过程,防止中间人攻击、敏感数据泄露、数据越权访问等问题。
整体架构
Polaris支持使用mTLS来对服务调用进行认证与加密,整体架构如下所示:
- polaris-security是Polaris的安全组件,在mTLS场景下,它支持作为中间证书签发机构(Intermediate Certificate Authority)使用。
- Polaris Controller监测到用户服务启用mTLS功能后,会向Pod内自动注入所有启用mTLS功能需要的环境。
- Polaris xDS Server会给启用mTLS的服务对应的Envoy sidecar下发相应的额外配置。
- Polaris Sidecar中会额外启动mTLS agent组件,通过Unix Domain Socket通讯向Envoy提供SDS(Secret Discovery Service)能力。
- mTLS agent组件会自动生成服务使用的身份证书及私钥,并自动进行轮转(rotate)。
- 每当身份证书接近过期时,mTLS会向polaris-security发送CSR(证书签名请求)来进行更新。
证书签名及轮转原理
启动阶段
- 用户启用mTLS功能之前,需要先在k8s集群中部署两个secret
- polaris-security会读取polaris-security-secret,并为自身签发service certificate,用于在TLS握手中自证身份。
- mTLS agent会读取polaris-sidecar-secret,用于TLS握手中验证polaris-security的身份。
证书签名
- mTLS agent向polaris-security发起TLS保护的certificate signing request,polaris-security会提供自身的service certiface给mTLS agent验证。
- 成功后,polaris-security从请求的header中提取出mTLS agent的Service Account Token,并使用Token Review请求的方式发送给Kubernetes API Server进行验证。
- 验证成功后,正式进入证书签名流程,polaris-security会按CSR中的参数要求,使用CA私钥加密摘要,并将所有材料整合成已签名的证书,连同证书链一起返回给mTLS Agent。
- mTLS Agent可以使用返回的材料来提供SDS服务,已签名的证书可以用作证明workload的身份;证书链可以用作验证对端workload的身份。
证书轮转
- mTLS agent的Rotater类会负责证书轮转,它其实就是一个定时任务执行器,每隔一定时间间隔就会执行一次CSR发送任务,并根据返回结果更新SDS材料,请求失败则会自动重试。
- 轮转时间间隔默认值为30分钟,证书TTL默认值为1小时,自动重试间隔默认为1秒。
- polaris-security是一个无状态的组件,可以进行适当的水平扩展来保证高可用。
mTLS实现原理
Polaris提供三种不同的服务粒度模式供用户选择:
模式 | 解释 |
---|---|
Permissive | 宽容模式,服务接受纯文本/mTLS服务调用;发起服务调用时,根据对端接受状况自动选择发起mTLS或纯文本服务调用 |
Strict | 严格模式,服务仅接受/发起mTLS服务调用 |
None | 无加密模式(为默认选项),服务仅接受/发起纯文本服务调用 |
sidecar注入
- mTLS的开关是用户服务的
metadata
中的polarismesh.cn/tls-mode
键对应的label
。 - 服务注册回调时,Polaris Controller的injector发现上述label的值为strict或permissve时,就会渲染出额外的注入配置:挂载secret及uds路径、开启iptables入流量拦截、为polaris-bootstrap-writer设置特殊的环境变量等。
- polaris-bootstrap-writer检测到mTLS相关的环境变量被设置后,会使用一份mTLS专用的Envoy配置模版来进行渲染,这份模版中设置了sds的相关配置与特殊的node metadata,polaris控制面就是使用这个特殊的metadata来区分服务网格中的各个服务是否启用mTLS功能。
xDS
- polaris控制面在给各个Envoy sidecar下发配置时,会根据node metadata中的mTLS相关信息来决定下发哪种配置。
- 对于permissve模式,下发的listener会加入一个TLS Inspector filter配置,TLS Inspector能根据请求的头几字节自动判断这是纯文本请求或是mTLS请求,然后进行不同处理;下发的cluster会加入一个额外的Match条件,在对端endpoint拥有
acceptMTLS
metadata时,会使用tls transport socket,否则就使用默认的raw buffer transport socket。 - 对于strict模式,下发的listener仅接受mTLS服务调用;而下发的cluster仅会使用tls transport socket来连接对端endpoint。
2.3 - 熔断降级
熔断降级
故障熔断,指的是当下游因过载或者BUG等原因,出现请求错误后,为了防止故障级联扩散导致整个链路出现异常,从而对请求进行拒绝或者重试的一种机制。
熔断模型
熔断模型的设计遵循业界标准的熔断器模型设计。熔断器有3类状态:
- 关闭:所有请求皆可访问下游资源,无任何限制。
- 打开:限制访问下游资源的请求,不允许任何请求的访问。
- 半开:限制访问下游资源的请求,只允许部分请求达到下游。
熔断场景
熔断一般会发生在以下场景下:
硬件环境出现故障
服务在运营过程中,因为一些不可抗力的因素,可能会出现机器故障、机器重启、机房断电、网络中断等问题。通过熔断机制,对服务实例或者机房分组的快速熔断,可以避免业务请求持续失败。
版本上线引入BUG
版本新特性开发上线后,因为漏测等原因,某些分支触发了BUG,导致部分的业务逻辑出现故障。常见的是部分方法在遇到某些入参的时候,会出现进程报错或者高负载的问题,影响其他方法的请求处理。通过熔断机制,将故障方法进行屏蔽,可以避免其他业务请求受到影响。
服务出现过载
因为路由不均或者峰值流量的到来,导致被调服务出现了高负载,导致请求的时延增大,成功率降低。通过熔断机制,合理的拒绝一部分请求,可以降低服务负载,恢复正常的运行状态。
熔断级别
接口级熔断
应用与服务之间的调用都是针对接口进行调用,为避免调用故障接口导致业务整体时延较大,加剧后端的压力。用户可以设置熔断规则,按照整个服务或者服务下某个接口的粒度设置熔断阈值,并统计在调用过程中的错误率时延等数据,达到阈值后会进行熔断(熔断器打开)。熔断后,访问该服务或特定接口的请求都会返回失败或者走降级逻辑。
接口级熔断生效在接口调用前,主调服务访问接口前需要判断接口的熔断状态。
实例级熔断
一般用于远程服务调用(RPC)的场景,针对某个节点或者分组(具备相同标签的节点集)设置熔断阈值,实例级熔断往往按照具体的服务实例进行熔断统计,并统计在调用过程中的错误率时延等数据,达到阈值后会进行熔断。熔断后,该实例会被屏蔽,不会有请求路由进来,直到恢复。
接口级熔断生效在接口调用中,在负载均衡过程中完成对熔断状态实例的剔除。
触发熔断条件
连续错误数熔断
请求调用时,统计周期内,出现连续错误数目超过阈值之后,资源进入熔断状态。
错误率熔断
熔断器按照滑窗对请求总数及成功数进行统计,并汇总时间段内的总错误率,一旦超过阈值,资源进入熔断状态。
错误判断条件
系统需要通过错误请求的统计来判断是否需要触发熔断,请求的错误一般会表现出以下2个方面的特性:
返回的状态码
对于标准协议的请求,比如HTTP Response,常见的5XX等状态码,代表着后端出现异常(比如数据库异常)导致业务请求失败。
时延
对于交易系统等对时延比较敏感的系统,当出现后端数据库等负载过高的情况,导致部分请求可以正常处理,但是时延普遍过高,此时仍可认为这部分请求是失败请求,触发熔断处理。
熔断恢复
当资源的错误请求统计达到一定阈值后,资源会进入熔断状态,在接下来的一段时间内,该资源将会被屏蔽(不会有请求路由到该资源),渡过屏蔽期后,资源会进入半开状态,此时系统会放少部分业务请求给该资源,并记录请求的处理结果。假如请求全部处理成功,则资源恢复成功(熔断器关闭),取消屏蔽并正常处理业务请求。
但是,假如业务请求扔存在处理失败,则该资源会重新进入熔断状态,继续保持隔离。
如何使用
2.4 - 配置管理
配置中心
流程设计
客户端视角
应用启动时,同步从服务端拉取一次配置,获取最新的配置内容。
把第一步拉取到的所有的配置文件生成 List
当收到配置文件的推送消息时,向服务端拉取最新的配置文件。
配置服务端视角
先检查客户端 List
如果客户端配置文件版本号都是最新的,则在内存里维护 File -> List
发布推送配置简化流程
用户在界面点击发布按钮,服务端更新数据库里配置发布表的数据。配置发布表的核心字段:file, version, content, mtime
每个北极星服务端实例,都会定时1s扫描配置发布表,根据 mtime 捞出最近 1s 内变更过的数据
北极星服务端实例扫描到最新变更的数据之后
- 重新加载内存缓存
- 向内存里的消息发布管道里写入一条消息
推送协程从消息发布管道里获取到消息,并消费消息。通过 File -> List
3 - 接入方式
3.1 - 使用 SDK
功能简介
北极星网格提供多语言 SDK 作为高性能接入方式:
以插件化和配置化的方式实现服务发现和治理功能:
- 被调方功能:服务注册、上报心跳、限流
- 主调方功能:服务发现、动态路由、负载均衡、熔断降级
- 观测性功能:服务调用、熔断降级和限流的监控统计
接口说明
被调方功能接口
Register
功能:注册服务实例
描述:将实例注册到某个服务下,实例信息包含地址和元数据
Deregister
功能:反注册服务实例
描述:将某个服务下的实例反注册
Heartbeat
功能:上报心跳
描述:如果在注册服务实例时,开启服务端健康检查功能,需要定期上报心跳到服务端,不然服务实例状态异常
GetLimitQuota
功能:获取请求处理配额
描述:如果使用限流功能,在每次处理请求之前,获取请求处理配额。若有配额,则处理请求,否则拒绝处理请求
主调方功能接口
GetAllInstances
功能:获取全部实例
描述:获取注册到某个服务下的全部实例,包含健康、异常和隔离的实例。本接口只使用服务发现功能模块
GetOneInstance
功能:获取一个可用实例
描述:在每次服务调用之前,获取一个可用实例。本接口使用服务发现、动态路由、负载均衡和熔断降级功能模块
备注:几个功能模块采用插件化设计,默认插件配置适用于基本场景,可以根据业务场景调整插件配置
UpdateServiceCallResult
功能:上报服务调用结果
描述:在每次服务调用之后,上报本次服务调用的结果。服务调用结果用于熔断降级和监控统计
接口使用说明
服务被调方
// 在应用启动阶段,注册服务实例
Register(namespace, service, instance)
// 如果使用服务端健康检查功能,在应用运行阶段,需要定期上报心跳到服务端
{
Heartbeat(namespace, service, instance)
}
// 如果使用限流功能,在每次处理请求之前,获取请求处理配额
{
if( GetLimitQuota(limiter) ) {
Handle(request)
} else {
Refuse(request)
}
}
// 在应用停止阶段,反注册服务实例
Deregister(namespace, service, instance)
服务主调方
// 发起一次服务调用
{
// 获取本次服务调用的实例
instance = GetOneInstance(namespace, service)
// 发起服务调用
response = ServiceCall(instance.address, request)
// 上报本次服务调用的结果
UpdateServiceCallResult(instance.id, response.code, response.delay)
}
快速入门示例
各语言 SDK 的快速入门示例:
Java语言
Go语言
C++语言
PHP语言
3.2 - 使用开发框架
功能简介
北极星 SDK 可以被集成到开发框架内部,如果用户使用开发框架,不需要显式地引入北极星 SDK,只需要依赖北极星相关的框架插件即可接入北极星。
当前支持以下框架的扩展接入:
开发框架如何集成北极星
北极星会基于服务框架原生的扩展接口之上,封装北极星的多语言SDK,接入北极星服务端实现服务发现、服务治理、配置管理等能力。
下图是SpringCloud框架集成的示意图,北极星只对原生的SpringCloud接口进行扩展,业务逻辑不感知这部分扩展,只需要通过修改POM引入相关的扩展依赖即可。
<dependencies>
<!-- 示例:引入spring-cloud-starter-tencent-polaris-discovery插件,即可接入北极星服务注册发现功能-->
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
</dependencies>
3.3 - 使用 Java Agent
功能简介
对于Java应用,北极星 SDK 可以被通过字节码注入的方式,集成到开发框架内部,如果用户使用开发框架,不需要显式地引入北极星 SDK,只需要在启动时,通过-javaagent的指令加载使用JavaAgent,即可无缝接入北极星。
当前支持以下框架的JavaAgent扩展:
JavaAgent如何集成北极星
北极星会通过字节码注入的方式,将北极星的SDK,作为插件注入到服务框架原生的扩展接口之上,从而接入北极星服务端实现服务发现、服务治理、配置管理等能力。
用户无需修改POM,只需要在启动Java程序时,加入javaagent的JVM启动参数就可以。
java -javaagent:polaris-java-agent-bootstrap-${version}.jar -jar xxx.jar
3.4 - 使用 K8s 和网格代理
随着容器化的普及,越来越多用户使用 K8s 部署应用,北极星支持 K8s 服务注册和健康检查。另外,Linkerd 和 Istio 等服务网格通过流量劫持的方式实现大部分服务治理功能,北极星也支持这种接入方式。
K8s服务同步
架构原理
北极星提供polaris-controller,基于kubernetes的controller机制,监听service&pod事件,将K8s Namespace, Service以及Endpoint,实时同步成北极星对应的命名空间、服务、服务实例列表。
用户无需依赖任何SDK及框架,即可实现基于POD的服务实例注册、反注册和健康检查。
应用场景
北极星是一个计算与存储分离的系统,具备极强的可扩展性,一个北极星集群可以支持多个k8s集群同时接入。接入到同一个北极星的集群的多个k8s集群中的应用,可以共享同一份服务数据,实现集群间的无感知调用。
网格代理
架构原理
北极星支持Proxy网格模式,envoy数据面可以直接接入北极星控制面实现服务发现和治理。北极星支持自动注入envoy代理,用户程序无需做任何改动,即可实现自动往POD中注入envoy。
应用场景
北极星提供了多种框架的适配插件,可以支持当下比较流行的proxyless网格模式的接入。SpringCloud、Dubbo的应用可以零改造接入服务网格,共享统一的服务治理模型,与使用Envoy代理的应用无缝互通。