架构师如何选型分布式业务网关
Posted 35岁程序员那些事
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构师如何选型分布式业务网关相关的知识,希望对你有一定的参考价值。
在日常工作中,不同的场合下,我们可能都会听说网关的概念,当然通常是指业务网关(API网关),负责API的输入和输出。有了业务网关之后,各个API服务提供者可以专注于自己的业务逻辑处理,而API网关更专注于安全、流量、路由等问题。从功能层次我们又会联想到一个概念——代理。网关与代理的区别:代理本质是数据的透传,协议不会发生变化;网关在数据透传的背景下,还会涉及协议的转换,比如从HTTP到Dubbo。
那么作为一名架构师,我们该如何选型“业务网关”呢?我们自己先要学会做技术选型,自己预期有一个技术成本的预判,比如我推荐使用Spring Cloud Alibaba+Spring Gateway,就是我自己作为一个架构师的技术预判。
Zuul
Zuul是Netflix开源的微服务网关,可以和Eureka、Ribbon、Hystrix等组件配合使用,Spring Cloud对Zuul进行了整合与增强,Zuul总共有两个大的版本:Zuul1.0和Zuul2.0,目前最新的版本为v2.2.0,Zuul1.0和Zuul2.0版本之间功能差异性非常大。
Netflix的Zuul包含如下功能:
身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求;
审查与监控:在边缘位置追踪有意义的数据和统计结果;
动态路由:动态地将请求路由到不同的后端集群;
压力测试:逐渐增加指向集群的流量,以了解性能;
负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求;
静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到内部集群;
多区域弹性:跨越AWS Region进行请求路由,旨在实现ELB(Elastic Load Balancing)使用的多样化和以及让系统的边缘更贴近系统的使用者。
以上介绍来自Zuul官方文档,但其实开源版本的Zuul以上功能一个都没有——开源的Zuul只是几个Jar包而已,以上能力指的应该是Netflix官方自用的Zuul的能力;Netflix自用的Zuul能力是比较强大的,可使用Groovy编写过滤器,并且可动态加载/卸载、修改规则,而且使用Cassandra作为数据库,然而开源版本这些一个都没有;Spring Cloud中,Zuul绝大部分功能都是Spring Cloud团队为Zuul开发的;所以Zuul 2.x的开源进度延后一年,Spring Cloud团队开发了自己的SCG,并宣布Spring Cloud不打算支持Zuul 2.x,你还觉得意外吗?看到这里,很多人可能没有动力学习Zuul了,个人认为还是可以了解一下的,后面讲到SCG时,你会发现很多设计理念是相通的。
既然说到了Spring Cloud对Zuul的封装,那么我们来简单的分析下Spring Cloud与Zuul的关系。Spring Cloud通过Spring Cloud Netflix 1.X来封装Zuul1.0,1.X的最后一个版本是v1.4.7.RELEASE,对应的Zuul版本是1.3.1。Spring Cloud Netflix从3.X开始就没有封装Zuul网关,包括Zuul1.0和Zuul2.0,也就是说开发者想要通过Spring Cloud来复用Zuul,只能使用Zuul1.0,暂时不能复用Zuul2.0。
Zuul目前在github上的star数为10.2k,fork数为2k,也就是说还是有很多开源爱好者会基于Zuul来定制化业务网关。
除了开源的Spring Cloud定制化Zuul,开源微服务框架jhipster也参与了定制,并集成到它的生态中。Jhipster主要包含generator-jhipster和jhipster-registry,前者star数微17.7k,fork数为3.5k,后者star数为604,fork为607。
Zuul1.0整体架构设计如图所示。
Zuul2.0整体架构设计如图所示。
Spring Cloud Gateway
SCG是基于Spring Framework 5.0和Spring Boot 2.0构建的API网关,提供路由等功能。其旨在提供一种简单而有效的方法路由到API,并为它们提供跨领域的关注点,例如:安全性、监视/指标和弹性。
主要特性:
Java8
Spring Framework5
Spring Boot2
动态路由
Spring Handler Mapping内置的路由匹配
HTTP请求的路由匹配(路径、方法、Header、主机等)
过滤器限定范围以匹配路由
过滤器可以修改下游HTTP请求和HTTP响应(添加、删除Header、添加/删除参数、重写路径、设置路径等)
API或配置驱动
支持Spring Cloud Discovery Client配置路由
SCG的专业术语包括:
路由:它是基本构建模块,主要包含ID、URI、断言集合以及过滤器集合,如果能够匹配断言就会执行路由;
断言:主要是指Java8的函数式断言,输入类型是Spring Framework的ServerWebExchange,基于断言可以匹配基于headers或者parameters的http请求;
过滤器:它是通过特殊的工厂方法构造的基于Spring Framework GatewayFilter的实现,通过过滤器开发者可以在http请求下行之前修改请求响应参数,在请求响应返回之后可以修改响应的结果。
SCG整体架构设计如图所示。
自研网关
一个API网关的基本功能包括统一接入、协议适配、流量管控与容错,以及安全防护,这个四大基本功能构成了网关的核心能力。网关首要的功能是负责统一接入,然后将请求的协议转换成内部的接口协议,在调用的过程中还要限流、降级和熔断等容错的方式来保护网关的整体稳定,同时网关还要做到基本的安全防护(防刷控制),以及黑白名单(比如IP地址白名单)等基本的安全措施,主要包括:统一标准接入,具备高性能、高并发和高可靠性,具备负载均衡的能力;
除了基本的四个功能,网关运行良好的环境还包括注册中心(比如通过Nacos读取已经发布的API接口的动态配置)。为了实现高性能,将数据全部异构到缓存(比如Redis)中,同时还可以配合本机缓存来进一步的提高网关系统的性能。为了提高网关的吞吐率,可以使用NIO+Servlet3异步的方式,还可以利用Servlet3的异步特性将请求线程与业务处理线程分开,为后续的线程池隔离做好基本的支撑。访问日志的存储我们可以放到Hbase或者ES中,如果要作为开放网关使用,那么需要一个支持OAuth2.0协议的授权中心,同时还可以引入nginx+Lua的方式,将一些基本的校验判断前置到应用系统之上,这样可以更加轻量级的处理网关接入的问题。
主要包括接入层,开发者可以通过Nginx和Lua脚本,解决限流、黑白名单、路由、负载均衡、长短连接以及容灾切换的问题。网关需要保证服务的稳定性,需要接入注册中心,因为本书是Spring Cloud Alibaba的布道书籍,所以强烈推荐使用Nacos作为注册中心和配置中心。统一的鉴权中心,主要是统一解决网关为各个API服务的鉴权问题,当然可以按照服务维度做隔离,自定义鉴权规则。统一用户中心主要是解决用户登录问题,确保微服务调用的安全性。
自研网关还需要有泛化功能,使用者在调用提供者的接口的时候,不再需要API提供者的客户端JAR包,因此也就没有了POJO,通过泛化的方式进行远程调用。一般情况下我们要通过RPC调用接口提供方的服务,首先在系统中嵌入接口提供者的JAR包,然后使用JAR包里面的类和方法。对于一个网关系统来说,如果要调用N个接口,就需要N个JAR包,这样的网关是很难维护的,当然Dubbo RPC是支持泛化的。
网关要具备时间校验、方法校验、版本校验和签名校验等功能,当然网关还需要具备服务降级、日志记录以及监控与告警功能。
对比以上三种网关
网关 | 限流 | 鉴权 | 监控 | 易用性 | 可维护性 | 成熟度 |
SCG | 可以通过IP,用户,集群限流,提供了相应的接口进行扩展 | 普通鉴权auth2.0 | Gateway Metrics Filter | 简单易用 | Spring系列可扩展强,易配置和可维护性好 | Spring社区成熟,但Gateway资源少。 |
Zuul2 | 可以通过配置文件配置集群限流和单服务器限流,也可以通过filter实现限流扩展 | filter中实现 | Filter中实现 | 参考资料比较少 | 可维护性差 | 开源不就资源少。 |
Zuul1 | 同上 | 同上 | 同上 | 同上 | 同上 | 同上 |
自研网关 | 需要开发 | 需要开发 | 需要开发 | 需要开发 | 可维护性极高 | 需要开发 |
总结
推荐使用Spring Cloud Alibaba+Spring Cloud Gateway,可以更加高效的利用Spring Cloud ALibaba的服务治理能力去融合网关API的治理,从而提升业务服务API的系统稳定性。
公众号初衷
知识输出是笔者的初衷,借助知识输出,能够认识更多的牛人,能够和牛人沟通,也是自己技术提升的一个机会。
本人微信ID,如有需要惠请联系
一路向北
人间灯火无不休,爱与山水与春
----无题
架构师如何技术选型-全链路监控
1、如何技术选型,应该是架构师必须具备的技能
技术预研
技术调研
项目风险模型
2、场景项目(全链路监控)
2.1 项目背景调研某公司的技术研发团队的现状
监控埋点项目太多,不统一
业务稳定性凝聚力不够
大中台小前台
微服务化
高效和赋能
人力资源匮乏
结果和关系导向
技术选型范围:Openzipkin、Pinpoint、Incubator-skywalking、Lightstep、Appdash、Jaeger。
2.2.1 AppdashAppdash是Go的应用程序跟踪系统,基于Google的Dapper和Twitter的Zipkin。
Appdash允许您跟踪应用程序中请求和操作的端到端处理(用于执行和调试)。它显示每个步骤的计时和特定于应用程序的元数据,并显示每个请求及其子项的树和时间轴。要使用appdash,您必须通过调用appdash录音机来检测应用程序。 您可以记录任何类型的事件或操作。 求及其子项的树和时间轴。要使用appdash,您必须通过调用appdash录音机来检测应用程序。 您可以记录任何类型的事件或操作。 提供了HTTP(客户端和服务器)和SQL的记录器和模式,可以编写自己的记录器和模式。
Appdash遵循Google Dapper的设计和命名惯例。 如果您对某些架构选择的原因感到好奇,那么您应该阅读该论文。 项目基础组件:
Spans
跨度是指一个操作及其所有子节点。 例如,HTTP处理程序通过调用系统中的其他组件来处理请求,而这些组件又会进行各种API和DB调用。 HTTP处理程序的范围包括所有下游操作及其后代; 同样,每个下游业务都是自己的跨度,并有自己的后代。 通过这种方式,Appdash构造了在处理HTTP请求期间发生的所有操作的树。
Event
应用程序将其执行的各种操作(在处理请求的过程中)记录为事件。 事件可以是任意消息或元数据,也可以是由Go类型定义的结构化事件类型(例如HTTP ServerEvent或SQLEvent)
Recoder
应用程序使用Recorder将事件发送给收集器,每个记录器与处理特定请求的操作树中的特定跨度相关联,并且通过记录器发送的所有事件自动与 该上下文相关联。
Collector
收集器接收记录器发送的注释(事件的编码形式)。 通常,应用程序的Recorder与本地收集器(使用NewRemoteCollector创建)进行通信。此本地收集器将数据转发到远程appdash服务器(使用Ne wServer创建,该服务器组合了构成应用程序的所有服务的跟踪appdash服务器依次运行收集器,在网络上侦听此数据,然后存储它接收的内容。Appdash支持语言: Go、Rubby、Python,Appdash支持OpenTracing API及规范。
Lightstep全链路解决方案非常完整,整体解决方案和微服务架构生态完美的匹配,如果技术栈匹配,可以开箱即用,维护一个稳定的基线版本,Lightstep学习成本较高,可以复用Lightstep的架构思想,自研全链路框架。
Lightstep特性:
Lightstep全链路的宗旨,在几秒钟内诊断出异常情况,包括网络,移动设备,整体设备和微服务。
实时的监控每个请求, 无论基础架构如何设置,都可以在Web,移动设备,微服务和整体磁盘上进行
Lightstep支持SLA(服务等级协议)
在分布式环境中,延迟暂停或故障的根本原因通常是在远程进程中。 LightStep有助于更广泛地理解系统范围内的相互依赖性以及每个组件对其他组件的影响
Lightstep支持语言:Java、Js、Go、Python、Object-c、Ruby,Lightstep支持OpenTracing API及规范。
2.2.3 JaegerJaeger支持语言:Java、Go、Node、Python和C++,Jaeger支持OpenTracingAPI及规范, Jaeger是Uber开源的全链路监控框架,解决方案的完整性的程度和Lightstep差不多,整体学习成本要低,提供了丰富的探针客户端。
Jaeger用于基于微服务的分布式系统监控和排错,包括:
分布式上下文传播
分布式事务监控
根本原因分析
服务依赖性分析
性能/延迟优化
Jaeger支持高可扩展性,Jaeger后端旨在不会出现单点故障,并可根据业务需求进行扩展。 例如,Uber的任何给定Jaeger安装通常每天处理数十亿个跨度。Jaeger后端,Web UI和仪器库的设计初衷是为了支持OpenTracing标准。
通过跨度参考将跟踪表示为有向非循环图(不仅仅是树)
支持强类型span标记和结构化日志
通过baggage支持通用分布式上下文传播机制
Jaeger支持两种流行的开源NoSQL数据库作为跟踪存储后端:Cassandra 3.4+和Elasticsearch 5.x / 6.x. 正在进行使用其他数据库的社区实验,例如ScyllaDB,InfluxDB,AmazonDynamoDB。 Jaeger还提供了一个简单的内存存储器,用于测试设置。
Jaeger Web UI使用流行的开源框架(如React)在Javascript中实现。 在v1.0中已经发布了几项性能改进,以允许UI有效地处理大量数据,并显示具有数万个跨度的跟踪(例如,我们尝试了80,000跨度的跟踪)。
Jaeger后端作为Docker镜像的集合分发。 二进制文件支持各种配置方法,包括命令行选项,环境变量和多种格式的配置文件(yaml等)Kubernete s模板和Helm图表协助部署到Kubernetes集群。如何公司需要自研全链路,则可以参考Jaeger和Lightstep,优选Jaeger,Jaeger底层支持Zipkin标 准,可以无缝迁移,公司链路底层如果是采用Zipkin,可以完整的切入到新的自研的链路系统。所有Jaeger后端组件都默认公开Prometheus指标( 也支持其他指标后端)。 使用结构化日志库zap将日志写入标准输出。Jaeger兼容Zipkin,虽然我们建议使用OpenTracing API检测应用程序并绑定到Jaeger客户端库,以便从其他地方没有的高级功能中受益,但如果您的组织已经使用Zipkin库投资了检测,则不必重写所 有代码。 Jaeger通过HTTP接受Zipkin格式(Thrift或JSON v1 / v2)的跨度,向Zipkin提供向后兼容性。 从Zipkin后端切换只需将Zipkin库中的流量路由到Jaeger后端。
2.2.4 Incubator-skywalkingSkyWalking是一个开源的APM系统,包括监控,跟踪,诊断Cloud Native架构中分布式系统的功能。 核心功能如下:
服务,服务实例,端点指标分析
根本原因分析
服务拓扑图分析
服务,服务实例和端点依赖性分析
检测到缓慢的服务和端点
性能优化
分布式跟踪和上下文传播
报警
SkyWalking支持从不同来源收集遥测(痕迹和指标)数据,以便为不同的场景提供更多选项。SkyWalking探针覆盖率几乎达到100%,几乎覆盖了 所有的技术栈,全链路监控,探针覆盖率也是一个比较重要的指标。
2.2.4 Openzipkin微服务框架SpringCloud已经整合了openzipkin,有现成的链路解决方案,底层框架直接使用Springboot,如果是为了节约开发成本,可以直接截取S pring-Cloud-Sleuth某一个里程碑版本,维护起来,并架构演化为自研链路框架。
Spring Cloud Sleuth为Spring Cloud实施分布式跟踪解决方案,大量借用Dapper,Zipkin和HTrace。 对于大多数用户来说,探针应该是无感知的,并且所有与外部系统的交互都应该自动进行检测。 您可以简单地在日志中捕获数据,也可以将数据发送到远程收集器服务。
Span是基本工作单元。 例如,发送RPC是一个新的跨度,就像RPC发送响应一样。 跨度由跨度的唯一64位ID和跨度为其一部分的跟踪的另一个64位ID标识。 Spans还有其他数据,例如描述,键值注释,导致它们的跨度的ID以及进程ID(通常是IP地址)。 跨度启动和停止,他们跟踪他们的时间信息。 创建跨度后,必须在将来的某个时刻停止它。 一组跨度形成一个称为Trace的树状结构。 例如,如果您正在运行分布式大数据存储,则可能会由put请求形成跟踪。将跟踪和跨度ID添加到Slf4J MDC,因此您可以从日志聚合器中的给定跟踪或跨度中提取所有日志;提供对常见分布式跟踪数据模型的抽象:跟踪,跨距(形成DAG),注释, 键值注释。 松散地基于HTrace,但兼容Zipkin(Dapper);探针常见的入口和出口点来自Spring应用程序(servlet过滤器,休息模板,预定动作,消息通道, zuul过滤器,假装客户端);如果spring-cloud-sleuth-zipkin可用,则该应用程序将通过HTTP生成并收集与Zipkin兼容的跟踪。 默认情况下,它将它们发送到localhost(端口9411)上的Zipkin收集器服务。 使用spring.zipkin.baseUrl配置服务的位置
2.2.4 PinpointTwitter的 Zipkin 使用修改过的类库和它自己的容器(Finagle)来提供分布式事务跟踪的功能。但是,它要求在需要时修改代码。我们期望功能可以不修改代码就工作 并希望得到代码级别的可见性。为了解决这个问题,pinpoint中使用了字节码增强技术。Pinpoint agent干预发起RPC的代码以此来自动处理标签信息。
字节码增强在手工方法和自动方法两者之间属于自动方法:
手工方法: 开发人员使用ponpoint提供的API在关键点开发记录数据的代码
自动方法: 开发人员不需要代码改动,因为pinpoint决定了哪些API要调节和开发 每个方法的优缺点
跟踪方式 | 优点 | 缺点 |
---|---|---|
手工跟踪 | 1. 要求更少开发资源 2. API可以更简单并最终减少bug的数量 | 1. 开发人员必须修改代码 2. 跟踪级别低 |
自动跟踪 | 1. 开发人员不需要修改代码 2. 可以收集到更多精确的数据因为有字节码中的 更多信息 | 1. 在开发pinpoint时,和实现一个手工方法相比 ,需要10倍开销来实现一个自动方法 2. 需要更高能力的开发人员,可以立即识别需要 跟踪的类库代码并决定跟踪点 3. 增加bug发生的可能性,因为使用了如字节码 增强这样的高级开发技巧 |
字节码增强是一种高难度和高风险的技术。但是,综合考虑使用这种技术开发需要的资源和难度,使用它仍然有很多的益处。虽然它需要大量的开发资源,在开发服务上它需要很少的资源。
字节码增强的价值:
隐藏API
容易启用或者禁用
由于字节码增强技术处理java字节码, 有增加开发风险的趋势,同时会降低效率。另外,开发人员更容易犯错。在pinpoint,我们通过抽象出拦截器(interceptor)来改进效率和可达性(acc essibility)。pinpoint在类装载时通过介入应用代码为分布式事务和性能信息注入必要的跟踪代码。这会提升性能,因为代码注入是在应用代码中直 接实施的。在pinpoint中,拦截器API在性能数据被记录的地方分开(separated)。为了跟踪,我们添加拦截器到目标方法使得before()方法和after() 方法被调用,并在before()方法和after()方法中实现了部分性能数据的记录。使用字节码增强,pinpoint agent可以记录需要方法的数据,只有这样采样数据的大小才能变小。
2.3 项目优势项目开发的生命周期和上线之后维护的生命周期是否活跃,主要取决于项目立项之初的项目优势,假想项目优势如下:
高效落地
业务无侵入
符合2-8原则(投入与产出)
探针覆盖率高
平台可扩展性
数据可定制开发
社区活跃度高
技术栈匹配(技术二次投入调研成本低)
整洁架构
技术调研耗时:一人/5d,调研开源的主流的APM框架,考究是否支持OPENTRACING规范,以及技术借鉴成本。
2.4.2 技术方案设计成本可以落地的技术方案设计成本:预估一人/5d 可以落地链路设计的基础架构搭建,以及预评估的可用插件的植入(不包含全部)
2.4.3 技术方案评审成本技术方案评审讨论:头脑风暴、集思广益,结合业务场景的最佳解决方案,预估2d
2.4.4 技术方案落地成本技术方案一期落地成本:按照以前做全链路的经验,全职开发前后端配合,60d
2.4.5 技术方案落地成本项目实施成本主要是部门沟通和链路项目上线对业务系统影响面的评估
2.4.6 项目推广成本分享和布道成本
2.5 项目风险开发人力资源分配成本风险
项目协调沟通成本风险
方案落地成本风险
框架模块功能:
Instrumented-client-plugin 主要包括日志采集探针模块:比如Dubbo、Redis、Http、Mysql、Rocketmq、Rabbitmq等插件
Instrumented-server-plugin 主要包括日志采集通道模块:比如Http、Netty、Grpc、Kafka等插件
Collector模块主要包括:Http、Netty、Grpc、Kafka服务端组件以及存储服务端插件
Server模块:存储客户端插件,查询聚合模块
Agent方案主要是将Instrumented-client-plugin和Instrumented-server-plugin和业务解耦,全部植入到agent组件中,对业务完全无感知。 整体设计如下:
模块功能:
Collector:服务端通道模块、存储插件模块
Server:前后端分离(UI、Query)
Application:探针、agent、client 调研的公司目前的链路系统,应该是采用agent方案,可能数据传输通道和收集器逻辑可能有点不太一样,看针对原有的架构设计,从架构层面是否有优化的空间
基于openTracing规范: trace和traceId:trace是全局监控系统的一次跟踪(用traceId标示一次跟踪,贯穿整个跨进程请求),多个span信息,及其关系信息。
trace和traceId:trace是全局监控系统的一次跟踪(用traceId标示一次跟踪,贯穿整个跨进程请求),多个span信息,及其关系信息。
span:一个span代表系统中具有开始时间和执行时长的逻辑运行单元。span之间通过嵌套或者顺序排列建立逻辑因果关系,包含logs和tags。
Logs:每个span可以进行多次Logs操作,每一次Logs操作,都需要一个带时间戳的时间名称,以及可选的任意大小的存储结构。
tags: 每个span可以有多个键值对(key:value)形式的Tags,Tags是没有时间戳的,支持简单的对span进行注解和补充,在一个span的生命周期 有效不能跨越span传递。
SpanContext: SpanContext跨越进程边界,传递到下级span的状态。(例如,包含traceid, spanid, sampled、baggage等数据),并用于封装Baggage.
Baggage: 存储在SpanContext中的一个键值对集合,在整个trace链路生命周期有效,可以跨越span、跨越进程进行传递.
ActiveSpan: 当前线程的活跃Span,对Span做了封装,也可以理解为一个Span的指针.
inject: SpanContext要做跨进程(如RPC)传输的时候,把SpanContext中的数据序列化到传输协议中。
extract: 与inject对应,从传输协议里,抽取数据反序列化成SpanContext。
设计描述:
探针主要是要植入opentracing-api到宿主组件,并形成树形链路
探针的复杂性在于,每个组件都要封装,并且应用探针的覆盖率也是一个重要的考量指标
2.8.1.1 dubbo
重写dubbo filter,为每个应用包装ConsumerFilter和ProviderFilter,植入opentracing-api到dubbo,串联dubbo链路
2.8.1.2 SpringMvc
AOP切面,拦截注解@Controller和@ResetController,植入opentracing-api,拦截before和after,串联SpringMvc链路
2.8.1.3 SpringService
AOP切面,拦截注解@Service,植入opentracing-api,拦截before和after,串联SpringService链路
2.8.1.4 线程池和线程
统一线程和平台线程池,通过方法重载和反射植入opentracing-api,拦截before和after,串联线程链路
2.8.1.5 消息中间件
AOP侵入客户端
2.8.1.6 agent
agent也需要探针,只是探针逻辑被封装到了 agent,作为agent的个性化模块,独立于agent的基础模块之上。
agent设计原则:
agent针对应用和插件组合级别设置日志级别
采样率可以细化到应用和插件的组合级别
采样率可以细化到应用和插件的组合级别
agent探针开关细化到应用和插件级别,探针开关细化,可以灵活的控制高并发流量下,某些探针流量在应用级别负载过高,但是容易造成 链路信息缺失,查询聚合会形成断路,在极端情况下,可以打开细粒度开关,保证业务的高可用
agent重新造轮子的技术成本是蛮高的,可以复用开源的agent解决方案,避免重复造轮子,agent需要开发字节码框架,兼容不同的java版 本的差异性,需要对java字节码及虚拟机底层有更加深入的研究
分析公司现有业务场景:云上项目和内部项目占比,评估项目流量,数据量日存储达到TB级别以上(实际机 器的整体性能评估),可以切换为拉模式,数据量不是特别大的系统采用消息推模式,实时性比较高。拉模式:解 决方案是在埋点时输出日志到本地,通过日志Agent读取日志,然后再通过实时计算的处理层主动拉取日志再进 行处理。该方案直接复用应用机器存储日志,并且采用拉模式防止流量冲击过大。 推送模式:解决方案利用消息队 列的方式,埋点层主动发送消息,消息队列对消息进行存储,数据处理层从消息队列上订阅消息。这种方案可做 到数据不丢,且主动推送可以提高实时性,环境适应性强,但这种解决方案的成本是比较高的。拉推模式的灵活 切换,从流量入口确保高并发和高流量场景下,链路数据的整体完整性,从技术层面确保链路数据不丢失。
链路数据丢失业务场景:不管是推/拉模式都不能确保数据完全不丢失,软件故障或者硬件故障都可能造成数 据丢失。设计解决方案:1) 硬件故障,数据丢失不可恢复,可以定期进行日志异步备份,保证数据不是完全丢失,可以恢复一部分,agent 读取可以动态路由到备份硬盘,拉取冗余数据,恢复丢失链路。2)软件故障,比如,网络抖动,在通道层面消 息丢失,导致链路完整性(因果关系)被破坏,链路因果关系缺失,极端情况会导致本来属于一个作用域(Trac eId)的span,被分割成不同的作用域,数据完全被隔离,特别是异步业务场景,如果都出现软件故障,如上问 题必现。
agent和应用耦合在一台机器,或者是同一个虚拟机下面,对运维的技术考究成本比较低,就是做CI/DI自动化部署(包括docker化),要在每台 机器上安装agent比较麻烦。 存在如下缺陷:1)如果应用是物理机隔离,再集群化,这样agent设计比较简单 2)如果针对应用是虚拟机隔离(docker也可以进行虚拟机隔离),agent考究兼容性 3)如果应用是云上部署,云上和内部系统之间agent的兼容性,也要考究。其实agent和应该耦合在一块,需要考究的技术成本也是蛮高的。 agent做负载,agent分布式部署技术门槛比较高,技术考究主要是在二次通信的性能损耗上,比如从application→agent切换为application-->RPC- ->agent,需要评估RPC的性能损耗和agent集群化之后,集群的整体吞吐量以及对业务性能的影响因子之间的总体对比和考究,还有agent是否会成 为数据流转的性能瓶颈的考究,以及集群部署之后的agent的路由规则,约定大于配置,这个只要和业务约定好,把麻烦留给框架,把傻瓜式配置留 给业务。
引入链路全流程排查引擎,快速定位和回溯问题源。 全流程排查引擎:实际业务异常问题排查,比如线上某次系统调用异常,业务方需要追踪到具体的某一笔订单以及某一笔订单操作的某一个服务实 例的具体某一个探针方法,更变态的是要追踪到这笔异常订单是否由公司的某一个供应商的商品的具体某一个sku属性引起的,或者是正常情况下, 商品运营针对异常订单关联商品的操作链路追踪。在实际问题排查中经常会遇到如上描述的问题,这些问题都具有明确的业务含义,这些问题尽管 看上去和调用链并无关系,但可以用调用链得到很好的解决。在实际排查问题时,最有价值的切入点在于先从业务问题出发,再进一步在调用链中 确认问题所在之处。 我们可以根据业务时间ID反查调用链,从而顺藤摸瓜找到更多的上下游业务信息。例如一个交易订单(2135897412389123)发现存在问题,我们 可以根据订单号查到与之绑定的TraceId,根据TraceId不仅可以查看系统调用的事件,还可以看到与业务相关的事件,如用户下单、当前库存情况 等,也就是说根据交易ID可以在调用链上查看交易、商品库存以及支付等信息,大大提升错误排查速度。
全流程排查引擎的关键在于:业务主键id与TraceId/RpcId的双向绑定。(提供个性化装饰器入口给业务,让业务自定义排查引擎主键,主键最好 唯一,也可以组合唯一,业务探针解决方案)
常见的双向绑定有三种实现方式:
在调用链的Tags 或UserData 中放入业务事件id,从而建立调用链到业务事件id 的关联;
打通TraceId 到数据库的数据变更的关联,从而建立调用链到每次数据变更的关联;
在业务日志中记录TraceId、业务事件id 等信息,从而建立调用链与业务事件日志的关联。(估计现在公司使用的这种方式)
全流程排查引擎。核心部分是链路最初覆盖的的后端系统,包括服务、消息和缓存;在前端层面涉及前端用户访问日志,具有关联TraceId的能力 ;在移动端也具有关联TraceId的能力;通过对TraceId进行关联,可以打通用户访问日志;在数据库层面,通过SQL语句将TraceId传到数据库的binl og中,在数据复制和数据分发时可以非常容易获取到每次数据变更的记录与TraceId的关联;另外,业务通过自身的业务日志和异常堆栈也可以打印 TraceId;这样一来,业务层、移动端、前端、数据层所有的组件都与TraceId进行了关联,再关联上业务中的订单号、用户号、商品号、物流单号 、交易单号,最后形成一个非常强大的生态——从一个调用链可以看到上下游相关的订单、用户的详细信息,同时可以根据订单查到与该订单相关 的业务ID,再根据业务ID扩展到与其相关的更多ID,甚至是TraceId,最后形成TraceId-->业务ID-->新的TraceId的网状结构,将排查问题转化为从 网状结构中寻找需要的整段信息。
2.9.4 如何减少渠道通信的性能开销渠道通信性能开销点:数据传输格式、序列化框架、承载数据的RPC框架,异步kafka和Rocketmq
2.9.5 如何减少application和agent之间的通信开销通信由TCP→UDP,提高吞吐量。
2.9.6 提高系统的QPS和TPS,底层服务端改用go语言,go天生的并发神器语言,要比java简单缺少技术栈储备,难点比较大。
2.9.6 链路从支持单一的树状结构到DAG(有向无环图)支持并行链路数据结构的存储链路模型支持树和有向无环图两种数据结构。
2.9.7 RectUI不能重复造轮子,第一期版本可以参照https://github.com/jaegertracing/jaeger-ui.git,将开源项目维护起来变为自研。
2.10 项目实施方案项目内部系统功能测试和压力测试通过之后,就要考虑项目如何在业务系统中实施,初步计划方案如下:
全链路系统部署必须申请单独的机器,与业务系统隔离
如果用到kafka,线上要单独部署,以及部署单独的zk集群,与业务隔离
es集群,如果条件允许,要单独部署,日志采集,属于高流量业务场景,对es的冲击量很大,必须要与核心业务的隔离,必须保证业务的 高可用
大数据流式实时计算,比如按应用名称+时间域,预先聚合数据,不要直接通过es在内存中聚合计算,耗时耗资源
collector服务无状态,如果条件允许可以docker化,做到线上弹性伸缩,可以节省机器资源和提高日志采集的高可用和高并发性能
链路实施必须要加全局开关,防止链路系统冲垮业务系统
线上链路系统采样率必须要动态可配置,灵活的根据业务流量动态切换
项目版本演化
初始化测试开发版本1.0.0.SNAPSHOT,线上发布版本1.0.0.RELEASE
git issues统计并记录,并与感兴趣的参与者贡献代码
里程碑版本
建立全链路推广钉钉群,定期同步版本发布信息,以及业务方使用的问题反馈,提高全链路的业务用户体现。
新特性和新插件,统一同步到度量系统,并指定链路系统的开发负责人以及问题解决人。
前期投入大量的人力研发全链路监控框架,推广其实是项目落地的最后手段。
推广阶段
全链路知识体系普及分享,讲解全链路项目的优势以及能够解决的业务痛点
全链路接入方案和部署方案讲解,接入和部署透明化,让业务知道可能存在的风险点
链路压测报告输出,并同步给各个部门leader 试点项目,评估全链路项目的用户体验,以及对业务排查问题的效能是否已经提高
度量系统,度量全链路系统的用户体验,可视化,输出同步给业务线负责人
大批量接入应用,评估链路系统的存储模块性能和React UI的聚合查询性能指标
新特性版本演化
以上是关于架构师如何选型分布式业务网关的主要内容,如果未能解决你的问题,请参考以下文章