LWN:Rust 另一些对 kernel 有用的特性!

The beginning of the 6.19 merge window Linux 6.19内核合并窗口前半段已合并4,124个非合并提交,涉及多项重要改进:新增AMD智能数据缓存注入和Intel LASS支持;优化TCP传输性能达300%;BPF程序支持间接跳转;FUSE增强大folio缓冲读取;新增listns()系统调用管理命名空间;重构rseq实现提升性能;支持RFC5837改进路由追踪;内核加密库新增SHA-3和BLAKE2b算法。后续还将有8,000+提交等待合并,预计12月14日完成窗口关闭。 阅读详情

关注了就能看到更多这么棒的文章哦~

More Rust concepts for the kernel

By Jonathan Corbet
September 20, 2021
Kangrejos
DeepL assisted translation
https://lwn.net/Articles/869428/

Kangrejos(Rust for Linux)会议的第一天介绍了这个项目以及它所要实现的目标;第二天介绍了一些 Rust 的核心概念以及跟内核开发有什么关系。第三天,也是最后一天的时候,Wedson Almeida Filho 深入探讨了如何让 Rust 在 Linux 内核中用起来,他介绍了目前为止已经学到的一些经验,并与一些内核开发人员讨论了下一步的工作。

Almeida 首先指出,他不是 Rust 语言的开发者,也不觉得这种语言是完美的。但他确实相信,Rust 可以解决内核中的一些问题。他是安卓平台安全团队的工程师,一直在寻找改善该平台的方法,特别是减少攻击面(reduce attack surface)。他认为 Rust 可以做到这一点,并且它还有助于提高正确性,提供一个超出 C 语言能提供的 expressive type system(类型系统)。

Ownership

他继续介绍了 Rust 中的一个重要概念,那就是数据所有权(data ownership)。Rust 程序中的每个数值都仅有一个所有者。这个所有权会随着程序的执行而转交给别人,但绝不会共享。当一个对象的所有者不再存在时,该对象就会被释放掉(free)。所有权是具有独占性的,但是当然还是要有办法可以将数据进行搬移和转交的。在 Rust 中,这是用引用(reference)来实现的。mutable reference (可变引用)允许其持有者来修改数据,注意 mutable reference 是独占的,不可以存在对该对象的其他引用。而 shared reference (共享引用)则是非排他性的(non-exclusive),并且是只读的。

aa6ef484306672a880937bcf5c06ea5a.png

但是上述规则有几种例外情况。Almeida 简要提到了内部可变性(interior mutability)的想法,但并没有深入探讨细节。Rust 也支持原始指针(raw pointer),但是只有在 unsafe 代码中才支持。

Rust 的所有权规则带来的一个结果是,在用 safe Rust 编写的代码中不会出现 data race。因为要产生 data race 的话,就必须要有至少两个 CPU 在以未同步好的方式(unsynchronized manner)访问共享数据,并且至少有一个在进行写入。由于 mutable reference 是独占式的,使得这种情况根本不可能出现。

这些规则也使得编译器可以对那些编译器无法直接看到的代码进行优化。例如下面这样的代码:

*x = 32
some_function()
return *x

编译器可以完全放心地只返回 32。变量 x 不会有别名,所以 some_function()不可能会对它的值进行改动。

那么,这个所有权规则在内核代码中该如何使用呢?Almeida 提出了一个例子,就是在许多内核结构中都有的 private_data 字段。这个字段一般是由子系统来将自己的特有数据填入到由系统中更高一层代码所管理的结构中。一般情况此字段是一个 void * 指针,当其被真正使用起来时会被转换为相应的类型。根据 Rust 标准,这不是安全的用法(not safe usage)。下面以 struct file (在内核中用其来表示一个打开的文件)为例来解释。

在 Rust 代码中,开发者会写一个 open() 函数,该函数会创建某种内部状态,通常会通过 private_data 来存放这些数据。这些内部状态信息将被返回给调用者,并且这个状态对象的所有权也被返回回去。如果用户空间在打开的文件上调用 ioctl(),那么 ioctl 处理程序将得到一个对此状态对象的共享引用(shared reference)。这个引用必须是共享的,因为这些调用可能是并发出现的。相反,当文件被关闭时,release() 函数就可以获得这个状态数据的所有权,然后就可以释放掉。所有这些都可以使用 Rust 的 type 规则来提供类型安全以及并发安全(type and concurrency safety)。

Device IDs, locks, and more

另一个例子是整个驱动程序子系统中的 device-ID table。这些表中每个数组元素都包含了一个 ID 以及一个无类型的可选参数,并且必须是用 null-terminated。Almeida 用 Rust 编写了一个 PL061(GPIO)驱动,来实现了内核中的相应 C 驱动的功能,并创建了一个新的 device-ID table 抽象来配合使用。开发者必须要确定这里可选参数的类型,并且提供来的所有数据都必须是这个类型的。也没有必要再将 list 用 null-terminate 了,这就消除了驱动程序作者经常犯的一个错误。因此,整个机制就是类型安全的(type-safe),并且也更容易使用。

锁(locking)是内核中很多复杂问题和混乱的来源之一。在 C 语言代码中,锁通常被声明为某个结构中的一个字段,而且往往不清楚某个特定的锁到底是在保护什么数据。而在 Rust 中,数据是直接跟保护它的锁关联起来的,这样一来,如果不先获得锁就没法编写访问该数据的代码。至少得满足这个条件之后编译器才会帮开发者完成编译。所有的检查工作都可以在编译时完成。

Almeida 简要地提到了代号 CVE-2021-26708 的漏洞,这是在 mainline 内核中一个可以被恶意攻击利用的 race condition,就是在获得保护数据的锁之前访问数据而造成的问题。他认为 Rust 就可以防止这个漏洞的发生。锁在定义的时候就会确保在没有获得该锁的情况下不能触及相关数据。但是,如果开发者没有意识到首先需要一个锁,会发生什么?在这种情况下,Rust 的所有权规则会起到效果,因为试图修改未受保护的数据会因为使用了错误的引用类型而失败。

Laurent Pinchart 跳出来说,他喜欢这种把数据和保护它的锁捆绑在一起的想法。但他比较担心开发者明知道不需要锁的那些情况,比如初始化部分的代码就属于这样的情况。看起来如果编译器知道对有关对象只能有一个引用,那么锁就没有必要了,例如,当对象刚刚被创建时就会是这种情况。Almeida 说,如果所有其他办法都没法用的话,开发者总是可以使用 "unsafe escape hatch" (意思是写 unsafe 代码来绕过编译器的限制)。

另一个需要注意的抽象概念是文件描述符(file descriptors),这些描述符在创建时首先需要获得对底层相应的文件结构的引用,然后才能分配描述符编号。如果分配失败的话,代码必须要记着放弃(drop)对文件的引用。Rust 的生命周期管理功能可以让错误处理自动就完成,减少了很多八股文一样的代码。内核代码中经常出现的那种 "goto out; " 的写法在 Rust 中是没有必要的。

Almeida 指出 CVE-2019-15971 就是由于未能增加文件的引用计数而产生的 use-after-free 漏洞。在 Rust 中如果犯了这种错误的话,一定会收到编译器的友好提示信息的。

继续谈论到错误路径(error path),Almeida 重复强调说,他认为在内核代码中看到的大多数复杂和容易出错的错误处理,在使用 Rust 时都可以消失了。在大多数情况下,对象会在超出 scope (生效范围)的时候就会直接被清理掉,根本不需要显式去进行处理。对于开发者需要更多的控制权的那些情况,可以使用 scopeguard 对象。这个对象在初始化时会使用相应的 error-handling 信息,如果一切顺利的话,不需要调用这些 error-handling 代码,那么它的 dismiss() 方法会被调用到。否则,如果该对象超出了生效范围之后的时候会直接执行相应的 error handling 错误处理。

此外会议上还讨论了其他一些内核抽象概念,包括 task 结构、红黑树,以及对 memory-mapped I/O 区域的访问。不过,Almeida 想讲的观点在此时应该已经很清楚了。Rust 语言能够处理内核层面的编程工作,这比用 C 语言完成同样的任务要安全得多。

Discussion

Julia Lawall 首先询问了在 Rust 中有哪些缺点?有什么突出的缺点?Almeida 回答说,在 Rust 中,所有的对象在内存中都是可移动的(movable),这对那些会自己引用自己(self-referential)的数据结构来说可能是个问题。解决办法是钉住(pinning),但这就需要编写 unsafe 的代码了。他说,现有的 Rust 驱动中的很多 unsafe 代码都源于这个问题。另一个问题是 Rust 要求所有数据都要被初始化,这对 mutex 来说尤其是一个问题。要解决这个问题的话主要是要找到并使用正确的抽象概念。

d236879fda7fa794b07b4e5929e73383.png

Pinchart 对 Rust 开发者所采取的渐进式方法提出质疑,这个问题在讨论中也多次出现。他说,正确的做法是把内核子系统的维护者关在一个房间里,要求他们学习 Rust,并在过渡期间为这些维护者提供大量的帮助。如果维护者被一个与 Rust 有关的问题所阻碍了,那么他们应该能够立即得到帮助来解决这个问题。否则的话,Rust 开发者将遇到大量的反抗。

Ojeda 质疑是不是真的会碰到反抗。他说,没有人要剥夺使用 C 语言来编写驱动程序的权利。Pinchart 回答说,在未来某个时刻,维护者可能不接受这些驱动程序。Ojeda 说,这可能是五年或十年后的事情了,不会那么快。他认为有必要期望内核开发者们来学习一些 Rust 知识。safe 模式下的工作并不困难。他承认 unsafe 的 Rust 模式确实比较难,毕竟又会出现那些对未定义行为的担忧了,而且文档也没有那么好。

Pinchart 又提出了另一个有很多人提到的担心,那就是内核开发者必须要能够使用整个源码 tree 来进行工作,很少有开发者是从来不去查看自己子系统之外的代码的。这样一来,我们很难在早期就将 Rust 在内核中的影响降到最低,毕竟会有无数开发者可能会读到 Rust 部分的代码。Ojeda 认为现有计划是只在已经了解了 Rust 的维护者相应的子系统中引入 Rust,但 Pinchart 回答说,不应该指望其他开发者就不会受到这些 Rust 代码的影响了。开发人员几乎肯定也是要用 unsafe Rust 来工作的。Mark Brown 补充说,关于 Rust 的引入,可能会有某个标志性的一天,在那一天之后所有维护者们将不得不在某种程度上了解这种语言。

Almeida 问道,在这种过渡开始之前,需要有多少比例的内核开发人员要懂得 Rust?Jonathan Cameron 回答说:"a lot"。我从引进 ReStructured Text 语言文档支持的过程中得到了一些经验,那就是这个过程要比预期的要长,这个过程中遇到了一些激烈的(和持续的)阻力,并且现在仍然没有全部完成。如果没有被分开发社区中相当多的人所接受的话,它就不可能会达到今天的这种成功。Rust 的引入要比这个复杂得多,因此它被接受的时间只会更长。因此是必须要努力让大家广泛能够接受的。Pinchart 说,现在大多数开发者似乎都对 Rust 的价值感兴趣,但其中许多人在担心将其引入内核带来的成本是不是过高。

Ojeda 说,Linux 的 Rust 开发者需要能说服足够多的开发者来相信 Rust 的价值,这样 Linus Torvalds 就会给这个改动给予祝福,否则就可以干脆结束这些讨论了。他期待着即将举行的 Linux Plumbers Conference 和 Kernel Summit 的讨论,能够帮助把更多的开发者带入这个过程。我对他过于依赖 Torvalds 祝福的想法表示了一些担忧,因为这是一个必要条件,但远远不是充分条件。

Greg Kroah-Hartman 说,他喜欢将 Rust 引入内核开发的想法,但也认为这项工作还有很长的路要走。设备驱动(也就是 Rust 开发者初期的目标领域)必须要与内核的许多部分互动,包括 driver model、sysfs 和其他各种子系统,而能够实现这种交互的 Rust 功能还没有出现。围绕着 Rust 的引入,会有社会、政治和技术问题,而目前甚至连技术问题本身都还没有处理好。尽管如此,他还是赞扬了 Rust 开发者到目前为止所取得的进展。

会议时间快要不够了,Kroah-Hartman 说,至少在五年内不可能要求开发者用 Rust 编写。Pinchart 问道,是否有人想过,社区愿意在这次转型中失去多少开发者,实际肯定会有一些开发者因此离去的。Ojeda 最后说,让 Rust 进入内核的过程是对这一点来说最重要的一个因素,他的下一步将是在 Linux Plumbers 大会上进行讨论。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

6e9eef93f79e2dff41cea6994b2ed94c.png

如何使用 rust 写内核模块 近年来,Rust 语言以内存安全、高可靠性、零抽象等能力获得大量开发者关注,而这些特性恰好是内核编程中所需要的,所以我们看下如何用rust来写Linux内核模块。 阅读详情

相关推荐

rust-kernel:一个小的多任务卵石启发了用Rust编写的内核

x86 Rust内核 这是用Rust编写的x86多线程内核的实现。 内核当前支持内核级线程,虚拟文件​​系统(受Linux启发)和原始驱动程序框架(受Windows启发)。 去做: IDE驱动程序。 ELF解析器。 用户空间加载器。 系统调用。 进程生命周期(fork / exec / wait /消失)。 调度(收益/调度/ make_runnable /睡眠)。 内存管理(mmap / munmap)。 IPC(???)。 安全性得到改善(去除包装纸等)。 动态加载,内核模块。 建造 内核必须由使用夜间配置构建的1.1.0之后的Rust编译器构建,以支持不稳定的功能和drop_in_place函数。 该构建链接到lib目录中预编译的libcore版本。 如果编译器的版本与用于编译libcore的版本不同,则可能会出现恐慌。 如果发生这种情况,请重新编译libc

11. Linux驱动 - Rust编写Linux驱动

Linux 中设备通常被分为三类,每个驱动模块通常实现为这三类中的其中一种: 字符设备。通常是指可以当作一个字节流来存取的设备(比如文件)。 块设备。通常是可以驻有文件系统的设备(比如磁盘),和字符设备类似,但块设备有一个请求缓冲区,因此它们可以选择响应请求的最佳顺序。 网络设备。通常是指能与其他主机交换数据的设备。 我们以编写一个简单的字符设备驱动为例,展示如何用 Rust 来编写内核驱动。 R4L 开发环境准备 为了方便,我们把 Rust for Linux 简称为 R4L。 首先,下载 Rust

笨笨D幸福 - 后花园 4549

别再怕DRIVER_VERIFIER_DMA_VIOLATION蓝屏:手把手教你用WinDbg分析IOMMU与驱动冲突

本文深入解析DRIVER_VERIFIER_DMA_VIOLATION蓝屏错误,从IOMMU原理到实战排错,手把手教你使用WinDbg分析驱动冲突。通过理解DMA与IOMMU的核心机制、搭建分析环境、解读DMAR表与设备拓扑,最终定位问题驱动并提供解决方案,帮助开发者和IT运维人员有效应对此类系统崩溃问题。

weixin_30298497的博客 802

LWN: Linux kernel 中的Rust!

关注了就能看到更多这么棒的文章哦~The Rust for Linux projectBy Jonathan CorbetSeptember 16, 2021KangrejosDeepL ...

Linux News搬运工 838

手把手教你搞定Pattern Recognition期刊的LaTeX投稿(附完整模板下载与避坑指南)

本文详细指导如何在Pattern Recognition期刊上使用LaTeX进行投稿,包括模板下载、环境配置、核心排版规范及投稿材料准备。特别强调期刊对格式的严格要求,如数学符号、图像引用等细节,并提供实用技巧和避坑指南,帮助作者高效完成投稿流程。

weixin_30876945的博客 394

Cadence17.2 > OrCAD Capture CIS > 设计规则检查(Design Rule Check)DRC学习记录详解

选中设计完成的DSN文件,选择Tool->Design Rule Check,弹出下面对话框,详解如下。 一、Design Rule Check对话框选项详解 Design Rules Options tab Set the scope, mode and type of design rule (electrical and / or physical) test options for the design rules check. 为

DL_62532的专栏 1万+

LWN:学习Rust内核开发的可用资源!

关注了就能看到更多这么棒的文章哦~Resources for learning Rust for kernel developmentBy Daroc AldenSeptember 23, 2024Kangrejos 2024Gemini-1.5-flash translationhttps://lwn.net/Articles/990619/Dirk Behme 在 Kangrejos 2024...

Linux News搬运工 1456

神经进化实践:用遗传算法替代反向传播优化神经网络

神经进化用来定义应用于深度学习的特定优化模式。在本节中,我们通过遗传算法优化简单深度学习网络的权重/参数,替换在误差反向传播训练过程中的所用优化器。

盼小辉丶的博客 3592

ScopeGuard 项目常见问题解决方案

ScopeGuard 项目常见问题解决方案 项目基础介绍 ScopeGuard 是一个 Rust 语言编写的开源项目,旨在提供一个方便的 RAII(Resource Acquisition Is Initialization)作用域守卫机制。RAII 是一种编程技术,确保资源在作用域结束时被正确释放,即使在代码执行过程中发生异常(如 panic)。ScopeGuard 通过宏和守卫机制,使得在 R...

gitblog_00601的博客 905

嵌入式NuttX RTOS面试题及参考答案

NuttX 的板级支持包(BSP)是一组软件组件,用于将 NuttX 操作系统适配到特定的硬件平台上。BSP 提供了硬件抽象层,使得 NuttX 能够与硬件进行交互,包括初始化硬件设备、提供设备驱动程序等。BSP 的主要作用是隐藏硬件细节,为上层应用程序和操作系统内核提供统一的接口,从而提高软件的可移植性和可维护性。开发 NuttX 的 BSP 通常需要以下步骤:硬件分析:首先需要对目标硬件平台进行详细的分析,了解硬件的架构、处理器类型、外设接口等信息。

大模型大数据攻城狮的专栏 1302

群晖如何安装软路由OpenWrt/iStoreOS作为旁路由(含网络设置、设置密码、还原出厂设置等linux命令ipk包)

openwrt的固件。

XiaoqiangClub的博客 7016

LWN:使用Rust进行Linux kernel开发!

Supporting Linux kernel development in RustAugust 31, 2020This article was contributed by Nel...

Linux News搬运工 1085

无迹卡尔曼滤波 (UKF, Unscented Kalman Filter) 算法详解及案例分析

无迹卡尔曼滤波是一种用于估计非线性系统状态的递归算法。其目标是通过结合系统模型和观测数据,估计系统的最优状态。

闲人编程的博客 2625

LWN: Rust 中对于Linux kernel有用的关键特性!

关注了就能看到更多这么棒的文章哦~Key Rust concepts for the kernelBy Jonathan CorbetSeptember 17, 2021Kangrejos...

Linux News搬运工 518

黑猫带你学eMMC协议第29篇:eMMC设备锁详解(CMD42)

通过cmd42命令,可以给emmc设置密码,并且锁定emmc。这时候就不能对emmc的user分区进行读写数据访问了。设备锁在V4.3版本后的emmc里面,就只能保护user area分区,因此,被锁定的emmc,依旧可以正常访问BOOT\RPMB\GPP分区。emmc内部有128 bit PWD寄存器,用来存放密码,以及有8bit PWD_LEN寄存器,用来密码长度。这两个寄存器非易失性,掉电也不会丢失。

黑猫奥利奥的博客 3236

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

LWN: kernel 快要有 Rust 了?

关注了就能看到更多这么棒的文章哦~Rust heads into the kernel?By Jake EdgeApril 21, 2021DeepL assisted translati...

Linux News搬运工 411

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

LWN:6.2合并窗口的第二部分!

关注了就能看到更多这么棒的文章哦~The rest of the 6.2 merge windowBy Jonathan CorbetDecember 27, 2022DeepL assisted translationhttps://lwn.net/Articles/918146/今年,世界收到了从 Linus Torvalds 来的一份特殊的圣诞礼物:6.2-rc1 kernel prepat...

Linux News搬运工 569

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

C语言为何仍是操作系统内核开发的首选?内存管理与硬件交互的绝对优势

在计算机系统编程领域,内存管理和硬件交互是两大核心基础概念。内存管理涉及程序如何分配、使用和释放内存资源,直接关系到程序的性能和稳定性;硬件交互则决定了软件能否直接、高效地控制底层硬件设备。这些底层技术原理构成了操作系统、驱动程序和嵌入式系统等关键基础设施的基石,其技术价值在于实现对计算资源的极致控制和高效利用。在操作系统内核、嵌入式固件、高性能中间件等对性能、资源消耗和确定性要求极高的应用场景中,开发者需要一种能够提供直接内存访问、最小运行时开销和高效硬件抽象的语言。C语言凭借其指针操作、内存布局控制和贴

android_mylove的专栏 442

LWN:如何在 kernel 里写 Rust 代码:第一部分!

尽管 GCC 上对 Rust 的支持正在迎头赶上,并且 `rustc_codegen_gcc` 代码生成后端现在能够编译内核的 Rust 组件,但 Rust for Linux 项目目前仅支持使用纯粹的 `rustc` 进行构建。Rust 开发者可能还应该安装 Clippy(Rust 的代码 Lint 工具),rustdoc(Rust 的文档构建工具)和 rust-analyzer(Rust 的 语言服务器),但这些并非严格必需。构建和测试 Rust 代码是审查 Rust 代码的必要条件,但并非充分条件。

Linux News搬运工 1649

开源项目 `scopeguard` 使用教程

开源项目 scopeguard 使用教程 1. 项目的目录结构及介绍 scopeguard 是一个轻量级的 C++ 库,用于实现作用域守卫(ScopeGuard)模式。以下是该项目的目录结构及其介绍: scopeguard/ ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src/ └── lib.rs...

gitblog_00804的博客 490

Rust in Linux Kernel:第一手贡献者经验分享,避开90%新人踩过的坑

掌握Rust语言在Linux内核贡献中的实际应用,避开新手常见陷阱。分享真实开发经验,涵盖模块编写、内存安全优化与编译集成核心方法,提升代码合入效率。适用于驱动开发与内核新功能实现,值得收藏。

VarIsle的博客 834

Linux内核引入Rust的5大关键原因(深度技术解析)

深入解析Linux内核引入Rust的5大动因,揭示Rust在内存安全、并发控制等方面对Linux内核贡献的技术突破。涵盖驱动开发、模块集成等应用场景,提升系统稳定性与安全性,值得收藏。

DeepNest的博客 1237

用Rust写操作系统(2)最小Rust内核

最小Rust内核 原文 https://os.phil-opp.com/minimal-rust-kernel/ 原作者 phil-opp 译者 readlnh 翻译项目地址 https://github.com/readlnh/Writing-an-OS-in-Rust-Second-Edition-zh_CN 在这篇文章里我们将在x86架构上创建一个最小的64位Rust内核。我们将在上一篇...

readlnh的博客 4233

Windows Kernel in Rust 开源项目教程

Windows Kernel in Rust 开源项目教程 项目介绍 Windows Kernel in Rust 是一个开源项目,旨在使用 Rust 语言编写 Windows 内核模块。该项目由 Stephan van Schaik 发起,利用 Rust 的安全性和性能优势,为 Windows 内核开发提供了一种新的选择。通过这个项目,开发者可以学习如何在 Windows 内核环境中使用 Rus...

gitblog_00767的博客 908

Rust进入Linux内核的1024个关键瞬间,每一位开发者都该了解的历史进程

掌握Rust Linux内核开发的演进之路,解析1024贡献案例背后的技术突破与安全优势,涵盖内存安全、并发控制在操作系统中的实践方法。了解Rust如何赋能内核开发,提升系统稳定性与开发效率,值得收藏。

VarChat的博客 471

Spring AI + GPT-5.5 + Ollama 配置教程:Base URL、超时与流式调用

由于不同 Spring AI、Spring Boot 小版本之间仍可能存在差异,创建项目时应检查 Spring Initializr、Spring AI BOM 和官方兼容矩阵,不要直接复制旧教程中的 Starter 名称和版本号。多人项目最好隔离不同客户端,并在脱敏前提下记录最终 URL、状态码、请求耗时、请求 ID 和模型 ID。Spring AI 接入模型 API,至少要同时确认 Starter、Base URL、请求路径、API Key、模型 ID、连接超时、读取超时和流式客户端这 8 项。

2601_95893075的博客 219
上一篇: LWN: Rust 中对于Linux kernel有用的关键特性!
下一篇: LWN:9月份LPC上关于folio的一次讨论!
LinuxNews搬运工
博客等级 码龄7年 438粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值