OTel可观测性

可观测性 什么是可观测性? 马克·安德森(Marc Andreessen)说过这样一句话:“软件正在吞噬世界 ”。这句话发表于2011年,但是十多年后的今天,我想它更好的演绎应该是“云原生正在吞噬世界,万物皆可上云”。面对云原生这个新赛道,BAT、美团、字节跳动、快手等一线大厂都在加速推进业务的容器化、云原生化。 也正是由于各大厂商对云原生的奔赴,传统的技术架构面临着巨大的冲击,我们的监控对象也由传统的单体结构,变成了分布式的多个微服务。监控,被架到了一个不得不革自己命的位置。在这样的背景之下,可观测性(Observability)脱颖而出。 CNCF 早在定义云原生的概念时就提到了可观测性 ,它声称可观测性是云原生时代的必备能力。而随着可观测性的概念明晰化,相关产品纷纷涌现,“可观测性”越来越成为云原生一个绕不开的话题。 在计算机系统和软件领域,可观测性的含义:它可以从系统和应用对外输出的信息(包括你可能已经知道的指标、日志和链路),来帮助我们了解应用程序的内部系统状态和运行情况。 可观测性能够架起开发人员和运维人员构建合作的桥梁,运维人员使用可观测性来发现问题,给故障现场提供足够的数据让开发人员进行分析,而开发人员可以使用可观测性来指导运维人员定位问题,并使用工具来质疑和验证假设; 从单机电脑时代的Windows任务管理器,Linux一堆Top、PS等命令帮助我们知道操作系统的运行转台;再到局域网时代的C/S架构、互联网时代的B/S架构的网络监控工具;再到如今移动互联网时代,出现了大量的可观测性技术。ELK方案、基于时序数据库的监控软件(如Prometheus、Telegraf + InfluxDB 等,APM 则出现了 ZipKin、Jaeger、Pinpoint、Skywalking 这些软件)然而,如果我们要完整地“观测”一个互联网系统,还是需要将各种形态的开源监控产品组合起来使用。 OpenTelemetry 这个组织的出现标志着业界意识的产生,也就是,我们需要将系统的可观测性变成一种统一的标准和规范。OpenTelemetry 致力于推动更多的应用和服务遵循这一规范,同时也会提供相应的可观测性能力。这也是我们今天这节课的重点 Metrics 指标 是对一段时间内基础设施或应用程序的数值数据的汇总。由于指标最大的特点是聚合性,它生成的数值反映了预定义时间段内系统状态的汇总报告,在此期间处于活动状态的所有请求的行为都会汇总为一个数值,因此缺乏细颗粒度。同时这些指标很可能都是彼此不相关的,没有关联性。 Log 日志 是一种带时间戳的文本记录,可以是结构化,也可以是非结构化的。 结构化日志 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 { "timestamp": "2024-08-04T12:34:56.789Z", "level": "INFO", "service": "user-authentication", "environment": "production", "message": "User login successful", "context": { "userId": "12345", "username": "johndoe", "ipAddress": "192.168.1.1", "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" }, "transactionId": "abcd-efgh-ijkl-mnop", "duration": 200, "request": { "method": "POST", "url": "/api/v1/login", "headers": { "Content-Type": "application/json", "Accept": "application/json" }, "body": { "username": "johndoe", "password": "******" } }, "response": { "statusCode": 200, "body": { "success": true, "token": "jwt-token-here" } } } 非结构化日志 ...

March 8, 2025 · 2 min · 389 words · Whitea

初探微服务架构

先聊聊单体架构吧 在一个项目的最初阶段,只有几个人参与的时候,想着业务能够快速迭代,往往采用单体应用的架构。求快,因此会把不同功能模块耦合在一起,编译打包部署也都在一起。 但是当业务规不断扩大,团队规模不断扩大,问题就慢慢暴露出来了。代码的高耦合,很难进行高效的横向扩展、每次部署上线都要重新部署整个应用、CI/CD和测试也逐渐变得更加耗时且容易因为一个很小的问题就失败… 于是团队为了解决这些问题,做了很细致的技术调研,最后选定了服务化的解决方案,对原有的单体应用架构进行改造,把功能相对独立的模块拆分出去,部署为微服务,分别交给专门的更小的团队来维护。后来我们又引入了Docker容器化,以及Service Mesh等技术,为了更好地适应业务的高速发展。 这就是应用架构经历了经历了单体应用 - 微服务架构 - 容器化应用 - DevOps的发展历程 微服务化拆分 因此当团队出现上述类似的问题时,往往就该考虑将单体架构应用进行拆分。 拆分往往分为横向拆分和纵向拆分 纵向:是从业务维度进行拆分。标准是按照业务的关联程度来决定,关联比较密切的业务适合拆分为一个微服务,而功能相对比较独立的业务适合单独拆分为一个微服务 横向:是从公共且独立功能维度拆分。标准是按照是否有公共的被多个其他服务调用,且依赖的资源独立不与其他业务耦合 但同时从单体架构向微服务的迁移会暴露出更多的问题 服务如何定义 服务如何发布和订阅 服务如何监控 服务如何治理 故障如何定位 微服务架构 总结一下,微服务架构下,服务调用主要依赖下面几个基本组件: 服务描述 注册中心 服务框架 服务监控与追踪 服务治理 服务描述 服务如何对外描述就是当我们对外提供一个服务,服务的服务名叫什么?调用这个服务需要提供哪些信息?调用这个服务返回的结果是什么格式的?该如何解析? 常见的一般是RESTful API,IDL文件等等。前者往往是基于HTTP,可以通过Wiki或者Swagger来管理。后者往往基于RPC,通过IDL文件管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 service ProductCatalogService { rpc AddProduct(AddProductReq) returns (AddProductResp) {} rpc UpdateProduct(UpdateProductReq) returns (UpdateProductResp) {} rpc DeleteProduct(DeleteProductReq) returns (DeleteProductResp) {} rpc OnlineProduct(OnlineProductReq) returns (OnlineProductResp) {} rpc OfflineProduct(OfflineProductReq) returns (OfflineProductResp) {} rpc ListProducts(ListProductsReq) returns (ListProductsResp) {} rpc GetProduct(GetProductReq) returns (GetProductResp) {} rpc BatchGetProducts(BatchGetProductsReq) returns (BatchGetProductsResp) {} rpc SearchProducts(SearchProductsReq) returns (SearchProductsResp) {} rpc GetCategories(GetCategoriesReq) returns (GetCategoriesResp) {} rpc GetCategory(GetCategoryReq) returns (GetCategoryResp) {} rpc DecrStock(DecrStockReq) returns (DecrStockResp) {} rpc IncrStock(IncrStockReq) returns (IncrStockResp) {} } 注册中心 提供了一个服务,如何让外部想调用你的服务的人知道。这个时候就需要一个类似注册中心的角色,服务提供者将自己提供的服务以及地址登记到注册中心,服务消费者则从注册中心查询所需要调用的服务的地址,然后发起请求 ...

February 10, 2025 · 1 min · 140 words · Whitea