分布式链路追踪-02-Dapper 论文介绍
开源项目
auto-log 自动日志输出
概要
现代互联网服务通常被实现为复杂的、大规模的分布式系统。
这些应用程序是由软件模块的集合构建的,这些模块可能由不同的团队使用不同的编程语言开发,并且可以跨越多个物理设施的数千台机器。
在这样的环境中,有助于理解系统行为和推理性能问题的工具是非常宝贵的。
在这里,我们介绍了 Google 的生产分布式系统跟踪基础设施 Dapper 的设计,并描述了如何满足我们的低开销、应用程序级透明性以及在超大规模系统上普遍部署的设计目标。
Dapper 与其他跟踪系统(特别是 Magpie [3] 和 X-Trace [12])在概念上有相似之处,但做出的某些设计选择对其在我们的环境中取得成功至关重要,例如使用采样并将仪器限制为 相当少量的公共库。
本文的主要目标是报告我们两年多来构建、部署和使用该系统的经验,因为 Dapper 成功的最重要衡量标准是它对开发人员和运营团队的有用性。
Dapper 最初是一个独立的跟踪工具,但后来发展成为一个监控平台,支持创建许多不同的工具,其中一些工具是其设计者没有预料到的。
我们描述了一些使用 Dapper 构建的分析工具,分享了有关其在 Google 内部使用情况的统计数据,展示了一些示例用例,并讨论了迄今为止学到的经验教训。
1 简介-Introduction
我们构建 Dapper 是为了向 Google 开发人员提供有关复杂分布式系统行为的更多信息。
此类系统特别令人感兴趣,因为大量小型服务器的集合对于互联网服务工作负载来说是一个特别经济高效的平台[4]。
了解这种情况下的系统行为需要观察许多不同程序和机器上的相关活动。
网络搜索示例将说明此类系统需要解决的一些挑战。
前端服务可能会将 Web 查询分发给数百个查询服务器,每个服务器都在自己的索引部分中进行搜索。
该查询还可以被发送到许多其他子系统,这些子系统可以处理广告、检查拼写或查找专门的结果,包括图像、视频、新闻等。
所有这些服务的结果都会有选择地组合在结果页面中; 我们将此模型称为“通用搜索”[6]。
总共可能需要数千台机器和许多不同的服务来处理一个通用搜索查询。
此外,网络搜索用户对延迟很敏感,这可能是由任何子系统的性能不佳引起的。
仅查看总体延迟的工程师可能知道存在问题,但可能无法猜测哪个服务出现问题,也无法猜测为什么它表现不佳。
首先,工程师可能无法准确地知道正在使用哪些服务; 新的服务和部件可能会每周添加和修改,以添加用户可见的功能并改进性能或安全性等其他方面。
其次,工程师不会是每项服务内部的专家; 每一个都是由不同的团队构建和维护的。
第三,服务和机器可能由许多不同的客户端同时共享,因此性能工件可能是由于另一个应用程序的行为造成的。
例如,前端可以处理许多不同的请求类型,或者诸如 Bigtable [8] 之类的存储系统在跨多个应用程序共享时可能是最有效的。
上述场景对 Dapper 提出了两个基本要求:无处不在的部署和持续监控。
普遍性很重要,因为即使系统的一小部分没有受到监控,跟踪基础设施的实用性也会受到严重影响。
此外,应始终打开监视,因为通常情况下,异常或其他值得注意的系统行为很难或不可能重现。
这些要求产生了三个具体的设计目标:
• 低开销:跟踪系统对正在运行的服务的性能影响应该可以忽略不计。 在一些高度优化的服务中,即使很小的监控开销也很容易被注意到,并且可能迫使部署团队关闭跟踪系统。
• 应用程序级透明度:程序员不需要了解跟踪系统。 依赖于应用程序级开发人员的积极协作才能发挥作用的跟踪基础设施变得极其脆弱,并且经常由于仪器错误或遗漏而被破坏,因此违反了普遍性要求。 这在像我们这样的快节奏的开发环境中尤其重要。
• 可扩展性:至少需要在未来几年内处理 Google 服务和集群的规模。
另一个设计目标是跟踪数据在生成后能够快速用于分析:最好在一分钟内。
尽管基于数小时前的数据运行的跟踪分析系统仍然非常有价值,但新鲜信息的可用性可以使对生产异常做出更快的反应。
真正的应用程序级透明度,可能是我们最具挑战性的设计目标,是通过将 Dapper 的核心跟踪工具限制在一个由普遍存在的线程、控制流和 RPC 库代码组成的小语料库中来实现的。
通过使用自适应采样,可以使系统具有可扩展性并降低性能开销,这将在 4.4 节中进行描述。
生成的系统还包括用于收集跟踪的代码、用于可视化跟踪的工具以及用于分析大量跟踪的库和 API(应用程序编程接口)。
尽管 Dapper 有时足以让开发人员识别性能异常的根源,但它并不打算取代所有其他工具。
我们发现 Dapper 的系统范围数据通常侧重于性能调查,以便可以在本地应用其他工具。
1.1 贡献总结 Summary of contributions
分布式系统跟踪工具的设计空间已经在之前的许多优秀文章中进行了探讨,其中与 Dapper 关系最密切的是 Pinpoint [9]、Magpie [3] 和 X-Trace [12]。
这些系统往往在其开发的早期阶段就在研究文献中进行描述,然后才有机会清楚地评估重要的设计选择。
由于 Dapper 已经大规模生产和运营多年,我们认为最合适的做法是将本文的重点放在 Dapper 的部署教会了我们什么、我们的设计决策如何发挥作用以及它在哪些方面最有用。
Dapper 作为性能分析工具开发平台的价值,以及其本身的监控工具的价值,是我们在回顾性评估中可以识别的少数意外结果之一。
尽管 Dapper 与 Pinpoint 和 Magpie 等系统共享许多高级思想,但我们的实现在该领域包含许多新的贡献。
例如,我们发现采样对于降低开销是必要的,特别是在高度优化的 Web 服务中,这些服务往往对延迟非常敏感。
也许更令人惊讶的是,我们发现数千个请求中的一个样本就可以为跟踪数据的许多常见用途提供足够的信息。
我们系统的另一个重要特征是我们能够实现的应用程序级透明度。
我们的仪器被限制在软件堆栈中足够低的水平,即使是像谷歌网络搜索这样的大规模分布式系统也可以在没有额外注释的情况下被追踪。
虽然这更容易实现,因为我们的部署环境具有一定程度的同质性,但我们这样做的结果表明了实现这种透明度的一些充分条件。
2 Dapper 中的分布式跟踪
分布式服务的跟踪基础设施需要记录有关代表给定发起者在系统中完成的所有工作的信息。
例如,图 1 显示了具有 5 台服务器的服务:一个前端 (A)、两个中间层(B 和 C)以及两个后端(D 和 E)。
当用户请求(在本例中为发起者)到达前端时,它会向服务器 B 和 C 发送两个 RPC。
B 可以立即响应,但 C 需要后端 D 和 E 的工作才能回复 A,而 A 又响应原始请求。
此请求的一个简单但有用的分布式跟踪是每个服务器发送和接收的每条消息的消息标识符和时间戳事件的集合。
已经提出了两类解决方案来聚合这些信息,以便可以将所有记录条目与给定的发起者(例如图 1 中的 RequestX)、黑盒和基于注释的监控方案相关联。
黑盒(Black-box)方案 [1,15,2] 假设除了上述消息记录之外没有其他信息,并使用统计回归技术来推断该关联。
基于注释(Annotation-based)的方案 [3,12,9,16] 依赖应用程序或中间件使用全局标识符显式标记每个记录,将这些消息记录链接回原始请求。
虽然黑盒方案比基于注释的方法更易于移植,但由于它们依赖于统计推断,因此需要更多数据才能获得足够的准确性。
显然,基于注释的方法的主要缺点是需要对程序进行检测。
在我们的环境中,由于所有应用程序都使用相同的线程模型、控制流和 RPC 系统,因此我们发现可以将检测限制为一小组公共库,并实现对应用程序开发人员有效透明的监控系统。
我们倾向于将 Dapper 跟踪视为嵌套 RPC 树。
然而,我们的核心数据模型并不局限于我们特定的 RPC 框架; 我们还跟踪 Gmail 中的 SMTP 会话、来自外部世界的 HTTP 请求以及对 SQL 服务器的出站查询等活动。
正式地,我们使用树(trees)、跨度(spans)和注释(annotations)对 Dapper 跟踪进行建模。
2.1 追踪树和跨度
在 Dapper 跟踪树中,树节点是基本工作单元,我们将其称为跨度。
边指示跨度与其父跨度之间的关系(casual relationship)。
然而,无论它在更大的跟踪树中的位置如何,跨度也是带时间戳的记录的简单日志,这些记录对跨度的开始和结束时间、任何 RPC 计时数据以及零个或多个特定于应用程序的注释进行编码,如第 2.3 节中所述。
我们在图 2 中说明了跨度如何形成较大迹线的结构。
Dapper 记录每个跨度的人类可读的跨度名称,以及跨度 ID 和父 ID,以便重建单个分布式跟踪中各个跨度之间的因果关系。
没有父 ID 创建的 Span 称为根 Span。
与特定跟踪关联的所有跨度也共享一个公共跟踪 ID(图中未显示)。
所有这些 id 都是概率上唯一的 64 位整数。
ps: 这里的 id 如果只是唯一,那么算法会更加灵活一下。
在典型的 Dapper 跟踪中,我们期望为每个 RPC 找到一个跨度,并且每个额外的基础设施层都会为跟踪树添加一个额外的深度级别。
图 3 提供了典型 Dapper 跟踪范围中记录的事件的更详细视图。
这个特定的跨度描述了图 2 中两个“Helper.Call”RPC 中较长的一个。
Span 的开始和结束时间以及任何 RPC 计时信息均由 Dapper 的 RPC 库工具记录。
如果应用程序所有者选择使用自己的注释来增强跟踪(如图中的“foo”注释),这些注释也会与跨度数据的其余部分一起记录。
需要注意的是,一个跨度可以包含来自多个主机的信息; 事实上,每个 RPC 跨度都包含来自客户端和服务器进程的注释,这使得双主机跨度成为最常见的跨度。
由于客户端和服务器上的时间戳来自不同的主机,因此我们必须注意时钟偏差。
在我们的分析工具中,我们利用了这样一个事实:RPC 客户端总是在服务器接收请求之前发送请求,反之亦然,对于服务器响应也是如此。
这样,我们就有了 RPC 服务器端跨度时间戳的下限和上限。
2.2 检测点(Instrumentation points)
Dapper 几乎完全依赖于一些通用库的检测,能够遵循分布式控制路径,应用程序开发人员几乎零干预:
• 当线程处理跟踪的控制路径时,Dapper 将跟踪上下文附加到线程本地存储。
跟踪上下文是一个小型且易于复制的跨度属性(例如跟踪和跨度 ID)容器。
• 当计算延迟或异步时,大多数Google 开发人员使用通用控制流库来构造回调并将其安排在线程池或其他执行器中。
Dapper 确保所有此类回调存储其创建者的跟踪上下文,并且在调用回调时此跟踪上下文与适当的线程关联。
通过这种方式,用于跟踪重建的 Dapper id 能够透明地遵循异步控制路径。
• 几乎所有 Google 进程间通信都是围绕单个 RPC 框架构建的,并绑定了 C++ 和 Java。
我们已经对该框架进行了检测,以定义所有 RPC 的跨度。
对于跟踪的 RPC,跨度和跟踪 ID 从客户端传输到服务器。
对于基于 RPC 的系统(例如 Google 广泛使用的系统),这是一个重要的检测点。
我们计划随着非 RPC 通信框架的发展和找到用户群而对其进行检测。
Dapper 跟踪数据与语言无关,生产中的许多跟踪组合了来自用 C++ 和 Java 编写的流程的数据。
在第 3.2 节中,我们讨论了我们在实践中能够实现的应用程序透明度水平。
2.3 注释(Annotations)
上述检测点足以导出复杂分布式系统的详细跟踪,使核心 Dapper 功能可用于其他未经修改的 Google 应用程序。
然而,Dapper 还允许应用程序开发人员使用附加信息来丰富 Dapper 跟踪,这些信息可能有助于监视更高级别的系统行为或帮助调试问题。
我们允许用户通过一个简单的 API 定义带时间戳的注释,其核心如图 4 所示。
这些注释可以具有任意内容。
为了保护 Dapper 用户免受意外的过度记录,各个跟踪范围的总注释量有一个可配置的上限。
无论应用程序行为如何,应用程序级注释都无法取代结构跨度或 RPC 信息。
除了简单的文本注释之外,Dapper 还支持键值注释映射,为开发人员提供更多跟踪能力,例如维护计数器、记录二进制消息以及在进程内传输任意用户定义的数据以及跟踪请求。
这些键值注释用于在分布式跟踪的上下文中定义特定于应用程序的等价类。
2.4 采样(Sampling)
低开销是 Dapper 的一个关键设计目标,因为如果服务运营商对性能有任何重大影响,那么服务运营商将不愿意部署尚未证实价值的新工具,这是可以理解的。
此外,我们希望允许开发人员使用注释 API,而不必担心额外的开销。
我们还发现某些类别的 Web 服务确实对检测开销很敏感。
因此,除了使 Dapper 集合的基本检测开销尽可能小之外,我们还通过仅记录所有跟踪的一小部分来进一步控制开销。
我们在 4.4 节中更详细地讨论了这种跟踪采样方案。
2.5 痕迹收集(Trace collection)
Dapper 跟踪日志记录和收集管道是一个三阶段过程(参见图 5)。
首先,将跨度数据写入 (1) 到本地日志文件。
然后,Dapper 守护进程和收集基础设施将其从所有生产主机中拉出 (2),最后将其写入 (3) 到几个区域 Dapper Bigtable [8] 存储库之一的单元中。
跟踪被布置为单个 Bigtable 行,每列对应一个跨度。
Bigtable 对稀疏表布局的支持在这里很有用,因为各个跟踪可以具有任意数量的跨度。
跟踪数据收集的中值延迟(即数据从检测的应用程序二进制文件传播到中央存储库所需的时间)小于 15 秒。
随着时间的推移,第 98 个百分位数的延迟本身是双峰的; 大约 75% 的时间,第 98 个百分点的收集延迟小于两分钟,但其他大约 25% 的时间可能会增长到几个小时。
Dapper 还提供了一个 API 来简化对我们存储库中跟踪数据的访问。
Google 的开发人员使用此 API 来构建通用和特定于应用程序的分析工具。
5.1 节包含迄今为止有关其用法的更多信息。
2.5.1 带外跟踪收集(Out-of-band trace collection)
所描述的 Dapper 系统使用请求树本身执行带外跟踪记录和收集。
这样做是出于两个不相关的原因。
首先,带内收集方案(其中跟踪数据在 RPC 响应标头内发送回)可能会影响应用程序网络动态。
在 Google 的许多大型系统中,找到具有数千个跨度的痕迹并不罕见。
然而,RPC 响应(即使在如此大的分布式跟踪的根附近)仍然相对较小:通常小于 10 KB。
在此类情况下,带内 Dapper 跟踪数据会使应用程序数据相形见绌,并使后续分析的结果产生偏差。
其次,带内收集方案假设所有 RPC 都是完美嵌套的。
我们发现有许多中间件系统在它们自己的所有后端返回最终结果之前就将结果返回给调用者。
带内(in-band)收集系统无法解释这种非嵌套分布式执行模式
2.6 安全和隐私考虑
记录一定量的 RPC 有效负载信息将丰富 Dapper 跟踪,因为分析工具可能能够在有效负载数据中找到可以解释性能异常的模式。
然而,在某些情况下,有效负载数据可能包含不应向未经授权的内部用户(包括从事性能调试的工程师)透露的信息。
由于安全和隐私问题是不容协商的,Dapper 存储 RPC 方法的名称,但此时不记录任何有效负载数据。
相反,应用程序级注释提供了一种方便的选择加入机制:应用程序开发人员可以选择将其认为对以后分析有用的任何数据与跨度相关联。
Dapper 还提供了一些其设计者没有预料到的安全优势。
例如,通过跟踪公共安全协议参数,Dapper 用于监控应用程序是否通过适当级别的身份验证或加密来满足安全策略。
Dapper 还可以提供信息以确保按预期实施基于策略的系统隔离,例如承载敏感数据的应用程序不会与未经授权的系统组件交互。
这些类型的测量比源代码审计提供了更大的保证。
小结
希望本文对你有所帮助,如果喜欢,欢迎点赞收藏转发一波。
我是老马,期待与你的下次相遇。
相关文章:
分布式链路追踪-02-Dapper 论文介绍
开源项目 auto-log 自动日志输出 概要 现代互联网服务通常被实现为复杂的、大规模的分布式系统。 这些应用程序是由软件模块的集合构建的,这些模块可能由不同的团队使用不同的编程语言开发,并且可以跨越多个物理设施的数千台机器。 在这样的环境中&…...
python:用 sklearn 构建线性回归模型,并评价
编写 test_sklearn_6.py 如下 # -*- coding: utf-8 -*- """ 使用 sklearn 估计器构建线性回归模型 """ import numpy as np import pandas as pd import matplotlib.pyplot as plt from matplotlib import rcParamsfrom sklearn import dataset…...
CTFHUB 信息泄露 备份文件下载-网站源码
根据提示应是猜测网站源码的备份文件,可以采用bp拼接文件名和后缀 开启bp抓包后设置第一个攻击点导入文件名 第二个攻击点导入后缀 开始暴力破解,有成功响应的 拼接到网站后缀后可以直接下载 解压缩后记事本的名字就是flag 总结: …...
Java String详解(三)
上一篇博客:Java String详解(二) 写在前面:大家好!我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正,感谢大家的不吝赐教。我的唯一博客更新地址是:https://ac-fun.blo…...
在pycharm2024.3.1中配置anaconda3-2024-06环境
version: anaconda3-2024.06-1 pycharm-community-2024.3.1 1、安装anaconda和pycharm 最新版最详细Anaconda新手安装配置环境创建教程_anaconda配置-CSDN博客 【2024最新版】超详细Pycharm安装保姆级教程,Pycharm环境配置和使用指南,看完这一篇就够了…...
从0到1实现vue3+vite++elementuiPlus+ts的后台管理系统(一)
前言:从这篇文章开始实现vue3vite的后台管理系统,记录下自己搭建后台系统图的过程。 这篇文章完成项目的初始化和基本配置,这一步可以直接跟着vue3官网进行。整个系列只有前端部分,不涉及后端。 vue3官网:https://cn.…...
升级thinkphp8最新版本,升级后发现版本不变
升级thinkphp8.0.3最新版本8.1.1,升级后发现版本不变, 更新TP有两个方法 1 全部更新(所有插件都一起更新) composer update 2 只更新TP框架核心 composer update topthink/framework 造成可能有两个原因,一是缓存问题,二是更新…...
PPP协议
PPP是一种常见的广域网数据链路层协议,主要用于在全双工的链路上进行点到点的数据传输封装,支持同步传输和异步传输,通常用于VPN和拨号上网 PPP 概述 PPP一般运行在serial串口上,是一种广域网协议,PPP建立分为LCP&a…...
JAVA基础:数据类型
JAVA基础:数据类型 强类型语言 强类型语言(Strongly Typed Language)是指在编程语言中,每个变量都必须有一个明确的类型,并且在编译时会进行类型检查。 JAVA是强类型语言,所有变量必须先定义后使用。 弱类型语言 弱类型语言(Weakly Typed Language)是指在编程中类…...
ElasticSearch 数据聚合与运算
1、数据聚合 聚合(aggregations)可以让我们极其方便的实现数据的统计、分析和运算。实现这些统计功能的比数据库的 SQL 要方便的多,而且查询速度非常快,可以实现近实时搜索效果。 注意: 参加聚合的字段必须是 keywor…...
Nacos 3.0 Alpha 发布,在安全、泛用、云原生更进一步
自 2021 年发布以来,Nacos 2.0 在社区的支持下已走过近三年,期间取得了诸多成就。在高性能与易扩展性方面,Nacos 2.0 取得了显著进展,同时在易用性和安全性上也不断提升。想了解更多详细信息,欢迎阅读我们之前发布的回…...
GeoIP介绍
文章目录 GeoIP1. GeoIP的详细介绍2. 在Go语言中使用GeoIP GeoIP GeoIP是一种技术,它允许通过IP地址来查询地理位置信息,如国家、地区、城市等。这种技术在网络安全、内容分发、市场分析等领域有着广泛的应用。 1. GeoIP的详细介绍 原理: …...
详述 BigDecimal 的错误计算
摘要 详细阐述在使用 Java 的 BigDecimal 类时,可能产生的错误计算。 据 java中BigDecimal的介绍及使用,BigDecimal格式化,BigDecimal常见问题-CSDN博客 介绍:“BigDecimal 的执行顺序不能调换(乘法交换律失效&am…...
3D Gaussian Splatting for Real-Time Radiance Field Rendering-简洁版
1. 研究背景与问题 传统的3D场景表示方法,如网格和点云,适合GPU加速的光栅化操作,但缺乏灵活性。而基于神经辐射场(NeRF)的表示方式,尽管质量高,但需要高成本的训练和渲染时间。此外࿰…...
(三)PyQT5+QGIS+python使用经验——解决各版本不兼容问题
一、问题描述 基础环境:Windows10(64) PyCharm2024 QGIS 3.22。 目的:解决之前python版本多,pyqt5以及QT Designer交互使用存在环境变量冲突矛盾,以及QGIS安装时自带python、pyqt5等问题。 尤其是在QT …...
uniapp navigateTo、redirectTo、reLaunch等页面路由跳转方法的区别
uni.switchTab 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 // app.json {"tabBar": {"list": [{"pagePath": "index","text": "首页"},{"pagePath": "other","text&…...
[创业之路-198]:华为的成立发展与新中国的建立与发展路径的相似性比较
目录 一、公司比较 1、创业初期的艰难与挑战 2、坚持自主创新与研发 3、市场拓展与国际化战略 4、企业文化与社会责任 5、面临的挑战与应对策略 二、任正非管理企业的思想大量借鉴了毛泽东建国的思想 1、矛盾论与企业管理 2、群众路线与企业文化 3、战略思维与长远发…...
[Unity Shader]【图形渲染】【游戏开发】 Unity Shader与原始Shader的区别
在Unity中,Shader是用于控制如何渲染图形的程序,通常涉及到对图形管线的自定义操作。尽管所有的着色器都遵循基本的图形渲染流程,但Unity Shader和原始Shader(通常指OpenGL/DirectX等底层API的Shader)之间存在显著差异。理解这些区别能帮助开发者更好地在Unity环境下进行图…...
JAVA学习日记(二十七)反射
一、反射的概述 二、获取Class对象的三种方式 import testpackage.Student;public class Main {public static void main(String[] args) throws ClassNotFoundException {//获取.class对象的三种方式//1. Class.forName("全类名")//2. 类名.class//3. 对象.getClas…...
PyTorch中apex的安装方式
apex是NVIDIA开发的基于PyTorch的混合精度训练加速神器,能够增加运算速度,并且减少显存的占用。 Github地址:https://github.com/NVIDIA/apex官方教程:https://nvidia.github.io/apex/ 安装方式 需要注意的是apex的安装不能通过…...
JavaScript网络请求( XMLHttpRequest 对象,进度事件, 跨源资源共享)
一、 XMLHttpRequest 对象 IE5 是第一个引入 XHR 对象的浏览器。这个对象是通过 ActiveX 对象实现并包含在 MSXML 库中 的。为此, XHR 对象的 3 个版本在浏览器中分别被暴露为 MSXML2.XMLHttp 、 MSXML2.XMLHttp.3.0 和 MXSML2.XMLHttp.6.0 。 所有现代…...
Android Studio、JDK、AGP、Gradle、kotlin-gradle-plugin 兼容性问题
文章目录 问题:解决办法:gradle与 java的版本兼容AGP与Gradle的版本兼容kotlin 与 jvm 的版本兼容KGP、Gradle、AGP兼容关系kotlin 与 java 的编译版本配置 问题: 你从githb上clone了一个项目,本地跑的时候,各种报错。…...
滑动窗口(定长窗口)
题目一:找到字符串中所有字母异位词 438. 找到字符串中所有字母异位词 - 力扣(LeetCode) 分析 异位次,就是通过排序之后可以跟哪个单词一样,例如 hello 跟 lleho 这是定长窗口, 窗口维护在p的…...
Vue Web开发(九)
1. 用户管理 1.1. user页面下的diolog表单 本节课完成user页面下的diolog表单,表单里的元素都是动态渲染,以一个CommonForm组件的形式放入user页面。 运用Element ui Form表单。 1.1.1. CommonForm组件 在src/components下新建CommonForm.vue组件&am…...
go语言zero框架下的日志记录的sdk实战案例
在 Go 语言中,构建一个日志 SDK 是常见的开发任务,尤其是当你希望将日志记录集中管理时。一个好的日志 SDK 可以帮助你规范化日志记录的方式,并将日志存储到不同的地方(例如:控制台、文件、数据库、远程日志服务等&…...
【Unity基础】Unity中拖拽3D物体的过程分析和实现方法
我们先来分析一下Unity中拖拽物体的过程: 第一步:先检测拖拽的输入方式,可以鼠标,触摸,可以用InputManager输入,也可以 使用InputSystem输入 第二步:获取触碰点的位置,并计算offse…...
深入了解Spring
目录 Spring基础 什么是Spring框架? Spring 包含的模块有哪些? Core Container AOP Data Access/Integration Spring Web Messaging Spring Test Spring,Spring MVC,Spring Boot 之间什么关系? Spring基础 什么是Spring框架? Sp…...
vue3修改elementui-plus的默认样式的几种方法
#创作灵感 今天写vue的前端项目,因为需要去修改elementui-plus中drawer的默认样式,所以刚好将修改步骤记录下来。 一共提供了三种方法,但亲测第二种最好用。 使用第二种是可以无视自己的代码中是否定义了该盒子,因为有时候盒子的…...
免费开源!推荐一款网页版数据库管理工具!
免费开源!推荐一款网页版数据库管理工具! DBGate 是一个开源的数据库管理工具,DBGate 的最大特点是可以 Web 访问!,轻松实现一台机器部署,所有人使用! 无论是 MySQL、PostgreSQL、SQLite 还是…...
Ubuntu22.04切换gcc版本教程
在编译安装程序的时候,由于gcc版本过高,导致编译无法通过,需要降低gcc版本。 一、安装gcc版本 根据自己的需求安装gcc版本。 sudo apt update sudo apt install gcc-10 g++-10二、切换gcc版本 sudo update-alternatives --install /usr/bin/gcc gcc...
OpenCV相机标定与3D重建(24)计算两个二维点集之间的最佳仿射变换矩阵(2x3)函数estimateAffine2D()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 计算两个二维点集之间的最优仿射变换,它计算 [ x y ] [ a 11 a 12 a 21 a 22 ] [ X Y ] [ b 1 b 2 ] \begin{bmatrix} x\\ y\\ \en…...
并发修改导致MVCC脏写问题
并发修改导致MVCC脏写问题 一、概要 1.1 业务场景 数据库表结构设计: 一个主档数据,通过一个字段,逗号分隔的方式去关联其他明细信息的id。 如主档数据A,有3条明细数据与A关联,其id分别是1,2,3,那么其存…...
webSokect安卓和web适配的Bug 适用实时语音场景
❌BUG: Failed to construct WebSocket: The URLs scheme must be either ws or wss. https is not allowed.WebSocket 协议在创建连接时,规定其 URL 的协议头(scheme)必须是 ws(用于非加密的普通 WebSocket 连接&…...
Linux系列之如何更换Centos yum源?
环境 Centos7Xshell7 问题描述 最近安装了一个虚拟机,准备用来学习,不过使用yum命令安装一些软件,不过使用这个命令时候,提示 Cannot find a valid baseurl for repo: base/7/x86_64,Could not retrieve mirrorlis…...
微知-C语言如何指定弱符号?(#define WEAK __attribute__((weak)); WEAK int foo(void))
背景 在C语言中,弱符号是一种特殊的符号,它可以被重定义,但在链接时,只会使用被重定义的符号。 在某些情况下,我们需要在多个文件中定义相同的函数,但只使用其中一个函数。本文将介绍如何在C语言中实现弱符…...
三极管功能
1 三极管的结构 2 三极管开关电路设计注意事项 1 三极管进入饱和状态 电机:500毫安 2 判断三级什么状态:电压法 3 判断三级什么状态:电流法 4 求IB的电阻 5 当三极管用作开关时,通常N型三极管控制负载的gnd端,P型…...
Python的3D可视化库【vedo】2-5 (plotter模块) 坐标转换、场景导出、添加控件
文章目录 4 Plotter类的方法4.7 屏幕和场景中的坐标点转换4.7.1 屏幕坐标转为世界坐标4.7.2 世界坐标转为屏幕坐标4.7.3 屏幕坐标取颜色 4.8 导出4.8.1 导出2D图片4.8.2 导出3D文件 4.9 添加控件4.9.1 添加内嵌子窗口4.9.2 添加选择区4.9.3 添加比例尺4.9.4 为对象添加弹出提示…...
定时/延时任务-万字解析Spring定时任务原理
文章目录 1. 概要2. EnableScheduling 注解3. Scheduled 注解4. postProcessAfterInitialization 解析4.1 createRunnable 5. 任务 Task 和子类6. ScheduledTaskRegistrar6.1 添加任务的逻辑6.2 调度器初始化6.3 调用时机 7. taskScheduler 类型7.1 ConcurrentTaskScheduler7.2…...
Android上传到Minio本地存储
Minio简介 MinIO是一个对象存储解决方案,它提供了与Amazon Web Services S3兼容的API,并支持所有核心S3功能。 MinIO有能力在任何地方部署 - 公有云或私有云,裸金属基础设施,编排环境,以及边缘基础设施。author: https…...
海量数据-Vastbase G100数据库安装
海量数据-Vastbase G100数据库安装 文章目录 海量数据-Vastbase G100数据库安装前期准备防火墙配置方案一:关闭防火墙方案二:开放数据库端口 SELINUX配置时间同步IPC参数配置 单机安装设置主机名创建数据库安装用户和目录(可选)修改资源限制 字符安装&am…...
Python | 对于DataFrame中所有行数据比较的几种方法
在数据分析中,比较DataFrame数据框中的行是一项基本操作,可应用于多种场景,包括: 查找重复项:标识所有相似或包含相同数据的行。相似性检查:确定某些选定因子的不相似行的相似程度。成对分析:非…...
React:闭包陷阱产生和解决
在 React 中,闭包陷阱是一个常见的问题,尤其是在处理异步操作、事件处理器、或是定时器时。理解闭包的工作原理以及它在 React 中如何与状态和渲染交互,可以帮助你避免陷入一些常见的错误。 一、闭包陷阱的产生 1、什么是闭包陷阱࿱…...
图的遍历|深度优先搜索|广度优先搜索(C)
图的基本操作 图的基本操作是独立于图的存储结构的。而对于不同的存储方式,操作算法的具体实现会有着不同的性能。在设计具体算法的实现时,应考虑采用何种存储方式的算法效率会更高。 图的基本操作主要包括(仅抽象地考虑,所以忽略…...
Pytest-Bdd vs Behave:选择最适合的 Python BDD 框架
Pytest-Bdd vs Behave:选择最适合的 Python BDD 框架 Pytest BDD vs Behave:选择最适合的 Python BDD 框架BDD 介绍Python BDD 框架列表Python BehavePytest BDDPytest BDD vs Behave:关键区别Pytest BDD vs Behave:最佳应用场景结…...
python文字转语音
一、安装对应的包 pip install pyttsx3 二、代码实现 import pyttsx3# 初始化tts引擎 engine pyttsx3.init()# 设置要转换的文本 text "你好"# 设置语速,范围从-1到1,1是正常速度,-1是最慢速度 rate engine.getProperty(rate…...
【安全研究】某黑产网站后台滲透与逆向分析
文章目录 x01. 前言x02. 分析 【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与…...
XSLT 编辑 XML
XSLT 编辑 XML 介绍 XSLT(可扩展样式表语言转换)是一种用于转换XML文档的语言。它允许开发人员将XML数据转换为其他格式,如HTML、PDF或纯文本。XSLT通过使用XPath查询来定位XML文档中的元素,并对这些元素应用转换规则。在本教程…...
计算机网络信息系统安全问题及解决策略
目 录 摘 要 前 言 一、计算机网络信息系统研究现状及安全技术 (一)计算机网络信息系统研究现状 (二)计算机网络信息系统全技术概述 二、计算机网络信息系统安全问题 (一)环境危害引发的安全问…...
112.【C语言】数据结构之排序(详解插入排序)
目录 1.排序定义 2.插入排序 "插入"的含义 代码 函数框架 函数设计思路 以升序为例,分析插入的三种可能 单趟排序代码 优化后 将单趟排序代码嵌入到循环中 错误代码 两种改法 运行结果 时间复杂度 1.排序定义 使一串记录,按照其中的某个或某些关键字的…...
洞察:OpenAI 全球宕机,企业应该如何应对 LLM 的不稳定性?
北京时间12月12日上午,OpenAI证实其聊天机器人ChatGPT正经历全球范围的宕机,ChatGPT、Sora及API受到影响。 OpenAI 更新事故报告称,已查明宕机原因,正努力以最快速度恢复正常服务,并对宕机表示歉意。 此次 OpenAI 故障…...