From 299db21cd8b3d56403bed175702d95dfc749a22e Mon Sep 17 00:00:00 2001 From: sunface Date: Sun, 23 Jan 2022 16:47:54 +0800 Subject: [PATCH] =?UTF-8?q?add=20tokio=E7=AE=80=E4=BB=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- book/contents/SUMMARY.md | 11 ++-- book/contents/img/tokio-01.png | Bin 0 -> 54185 bytes book/contents/tokio/intro.md | 7 ++- book/contents/tokio/overview.md | 75 +++++++++++++++++++++++++++ book/writing-material/posts/tokio.md | 3 ++ 5 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 book/contents/img/tokio-01.png create mode 100644 book/contents/tokio/overview.md create mode 100644 book/writing-material/posts/tokio.md diff --git a/book/contents/SUMMARY.md b/book/contents/SUMMARY.md index b9f21b68..2df43393 100644 --- a/book/contents/SUMMARY.md +++ b/book/contents/SUMMARY.md @@ -93,18 +93,19 @@ - [高阶特征约束(HRTB) todo](advance/hrtb.md) ## 专题内容,每个专题都配套一个小型项目进行实践 -- [async/await异步编程 doing](async/intro.md) +- [async/await异步编程](async/intro.md) - [async编程入门](async/getting-started.md) - [底层探秘: Future执行与任务调度](async/future-excuting.md) - [定海神针Pin和Unpin](async/pin-unpin.md) - - [async、await和Stream流处理](async/async-await.md) + - [async/await和Stream流处理](async/async-await.md) - [同时运行多个Future](async/multi-futures-simultaneous.md) - [一些疑难问题的解决办法](async/pain-points-and-workarounds.md) - [实践应用:Async Web服务器](async/web-server.md) -- [tokio使用指南](tokio/intro.md) - - [基本用法](tokio/basic.md) - - [异步消息流](tokio/stream.md)) +- [tokio使用指南 doing](tokio/intro.md) + - [tokio简介](tokio/overview.md) + - [Rust最佳实践 doing](practice/intro.md) - [日常开发三方库精选](practice/third-party-libs.md) diff --git a/book/contents/img/tokio-01.png b/book/contents/img/tokio-01.png new file mode 100644 index 0000000000000000000000000000000000000000..051483922d5fde64bf8f81d4334deeb48e1a69bd GIT binary patch literal 54185 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 GMgI%nvtQZ( literal 0 HcmV?d00001 diff --git a/book/contents/tokio/intro.md b/book/contents/tokio/intro.md index f2e3444a..06f1508e 100644 --- a/book/contents/tokio/intro.md +++ b/book/contents/tokio/intro.md @@ -1 +1,6 @@ -# tokio使用指南 +# Tokio使用指南 +在上一个章节中,我们提到了 Rust 异步编程的限制,其中之一就是你必须引入社区提供的异步运行时,其中最有名的就是 `tokio`。 + +在本章中,我们一起来看看 `tokio` 到底有什么优势,以及该如何使用它。 + +> 本章在内容上大量借鉴和翻译了tokio官方文档[Tokio Tutorial](https://tokio.rs/tokio/tutorial), 但是重新组织了内容形式并融入了很多自己的见解和感悟,给大家提供更好的可读性和知识扩展性 \ No newline at end of file diff --git a/book/contents/tokio/overview.md b/book/contents/tokio/overview.md new file mode 100644 index 00000000..af0a587a --- /dev/null +++ b/book/contents/tokio/overview.md @@ -0,0 +1,75 @@ +# tokio简介 +对于 Async Rust,最最重要的莫过于底层的异步运行时,它提供了执行器、任务调度、异步API等核心服务。简单来说,使用 Rust 提供的 `async/.await` 特性编写的异步代码要运行起来,就必须依赖于异步运行时,否则这些代码将毫无用处。 + +## 异步运行时 +Rust 语言本身只提供了异步编程所需的基本特性,例如 `async/.await` 关键字,标准库中的 `Future` 特征,官方提供的 `futures` 实用库,这些特性单独使用没有任何用处,因此我们需要一个运行时来将这些特性实现的代码运行起来。 + +异步运行时是由 Rust 社区提供的,它们的核心是一个 `reactor` 和一个或多个 `executor`(执行器): + +- `reactor` 用于提供外部事件的订阅机制,例如 `I/O` 、进程间通信、定时器等 +- `executor` 在上一章我们有过深入介绍,它用于调度和执行相应的任务( `Future` ) + +目前最受欢迎的几个运行时有: + +- [`tokio`](https://github.com/tokio-rs/tokio),目前最受欢迎的异步运行时,功能强大,还提供了异步所需的各种工具(例如 tracing )、网络协议框架(例如 HTTP,gRPC )等等 +- [`async-std`](https://github.com/async-rs/async-std),最大的优点就是跟标准库兼容性较强 +- [`smol`](https://github.com/smol-rs/smol), 一个小巧的异步运行时 + +但是,大浪淘沙,留下的才是金子,随着时间的流逝,`tokio`越来越亮眼,无论是性能、功能还是社区、文档,它在各个方面都异常优秀,时至今日,可以说已成为事实上的标准。 + +#### 异步运行时的兼容性 +为何选择异步运行时这么重要?不仅仅是它们在功能、性能上存在区别,更重要的是当你选择了一个,往往就无法切换到另外一个,除非异步代码很少。 + +使用异步运行时,往往伴随着对它相关的生态系统的深入使用,因此耦合性会越来越强,直至最后你很难切换到另一个运行时,例如 `tokio` 和 `async-std` ,就存在这种问题。 + +如果你实在有这种需求,可以考虑使用 [`async-compat`](https://github.com/smol-rs/async-compat),该包提供了一个中间层,用于兼容 `tokio` 和其它运行时。 + +#### 结论 +相信大家看到现在,心中应该有一个结论了。首先,运行时之间的不兼容性,让我们必须提前选择一个运行时,并且在未来坚持用下去,那这个运行时就应该是最优秀、最成熟的那个,`tokio` 几乎成了不二选择,当然 `tokio` 也有自己的问题:更难上手和运行时之间的兼容性。 + +如果你只用 `tokio` ,那兼容性自然不是问题,至于难以上手,Rust 这么难,我们都学到现在了,何况区区一个异步运行时,在本书的帮忙下,这些都不再是个问题:) + +## tokio简介 +Tokio是一个纸醉金迷之地,只要有钱就可以为所欲为,哦,抱歉,走错片场了。`Tokio` 是 Rust 最优秀的异步运行时框架,它提供了写异步网络服务所需的几乎所有功能,不仅仅适用于大型服务器,还适用于小型嵌入式设备,它主要由以下组件构成: + +- 多线程版本的异步运行时,可以运行使用 `async/.await` 编写的代码 +- 标准库中阻塞API的异步版本,例如`thread::sleep`会阻塞当前线程,`tokio`中就提供了相应的异步实现版本 +- 构建异步编程所需的生态,甚至还提供了 [`tracing`](https://github.com/tokio-rs/tracing) 用于日志和分布式追踪, 提供 [`console`](https://github.com/tokio-rs/console) 用于 Debug 异步编程 + +### 优势 +下面一起来看看使用 `tokio` 能给你提供哪些优势。 + +**高性能** + +因为快所以快,前者是 Rust 快,后者是 `tokio` 快。 `tokio` 在编写时充分利用了 Rust 提供的各种零抽象和高性能特性,而且贯彻了 Rust 的牛逼思想:如果你选择手写代码,那么最好的结果就是跟 `tokio` 一样快! + +以下是一张官方提供的性能参考图,大致能体现出 `tokio` 的性能之恐怖: +tokio performance + +**高可靠** + +Rust 语言的安全可靠性顺理成章的影响了 `tokio` 的可靠性,曾经有一个调查给出了令人乍舌的[结论](https://www.zdnet.com/article/microsoft-70-percent-of-all-security-bugs-are-memory-safety-issues/):软件系统70%的高危漏洞都是由内存不安全性导致的。 + +在 Rust 提供的安全性之外,`tokio` 还致力于提供一致性的行为表现:无论你何时运行系统,它的预期表现和性能都是一致的,例如不会出现莫名其妙的请求延迟或响应时间大幅增加。 + +**简单易用** + +通过 Rust 提供的 `async/await` 特性,编写异步程序的复杂性相比当初已经大幅降低,同时 `tokio` 还为我们提供了丰富的生态,进一步大幅降低了其复杂性。 + +同时 `tokio` 遵循了标准库的命名规则,让熟悉标准库的用户可以很快习惯于 `tokio` 的语法,再借助于 Rust 强大的类型系统,用户可以轻松地编写和交付正确的代码。 + +**使用灵活性** +`tokio` 支持你灵活的定制自己想要的运行时,例如你可以选择多线程 + 任务盗取模式的复杂运行时,也可以选择单线程的轻量级运行时。总之,几乎你的每一种需求在 `tokio` 中都能寻找到支持(画外音:强大的灵活性需要一定的复杂性来换取,并不是免费的午餐)。 + +### 劣势 +虽然 `tokio` 对于大多数需要并发的项目都是非常适合的,但是确实有一些场景它并不适合使用: + +- 并行运行CPU密集型的任务,`tokio` 非常适合于IO密集型任务,这些IO任务的绝大多数时间都用于阻塞等待IO的结果,而不是刷刷刷的单烤CPU。如果你的应用是CPU密集型(例如并行计算),建议使用 [`rayon`](https://github.com/rayon-rs/rayon),当然,对于其中的IO任务部分,你依然可以混用 `tokio` +- 读取大量的文件, 读取文件的瓶颈主要在于操作系统,因为OS没有提供异步文件读取接口,大量的并发并不会提升文件读取的并行性能,反而可能会造成不可忽视的性能损耗,因此建议使用线程(或线程池)的方式 +- 发送HTTP请求,`tokio` 的优势是给予你并发处理大量任务的能力,对于这种轻量级 HTTP 请求场景,`tokio` 除了增加你的代码复杂性,并无法带来什么额外的优势。因此,对于这种场景,你可以使用 [`reqwest`](https://github.com/seanmonstar/reqwest) 库,它会更加简单易用。 + + +## 总结 +离开三方开源社区提供的异步运行时, `async/await` 什么都不是,甚至还不如一堆破铜烂铁,除非你选择根据自己的需求手撸一个。 + +而 `tokio` 就是那颗皇冠上的夜明珠,也是值得我们投入时间去深入学习的开源库,它的设计原理和代码实现都异常优秀,在之后的章节中,我们将对其进行深入学习和剖析,敬请期待。 \ No newline at end of file diff --git a/book/writing-material/posts/tokio.md b/book/writing-material/posts/tokio.md new file mode 100644 index 00000000..daaf35b7 --- /dev/null +++ b/book/writing-material/posts/tokio.md @@ -0,0 +1,3 @@ +## 性能 + +https://www.reddit.com/r/rust/comments/lg0a7b/benchmarking_tokio_tasks_and_goroutines/ \ No newline at end of file