Compare commits

...

5 Commits

Author SHA1 Message Date
徐涛
1bda27cca6 post:增加记录在ubuntu中安装nerdctl的文章。 2022-08-04 10:37:25 +08:00
徐涛
a48ff3432f post:增加Rust中关于使用类型选择的文章。 2022-08-04 09:45:36 +08:00
徐涛
e8f31beccb enhance:增加React工具书中的Zustand章节。 2022-06-20 09:51:14 +08:00
徐涛
835b08135f fix:补充React工具书内容。 2022-05-19 14:55:16 +08:00
徐涛
ed0482b5af fix:修改书名。 2022-05-17 16:28:12 +08:00
3 changed files with 181 additions and 2 deletions

View File

@ -0,0 +1,90 @@
---
title: 在Ubuntu LTS中启用CGroup v2并安装nerdctl
tags:
- Linux
- 容器化
- Ubuntu
- systemd
- cgroup
categories:
- - DevOps
- 系统管理
keywords: 'ubuntu,containerd,nerdctl,cgroup'
date: 2022-08-04 10:36:50
---
如果云主机采用了Ubuntu 21.04或以下的版本时默认开启的是CGroup v1如果要使容器系统能够使用CGroup v2来管理资源就必须手动开启CGroup v2。本文将记录如何在Ubuntu 21.04及以下系统中开启CGroup v2并安装containerd容器系统和nerdctl容器控制工具的过程。<!-- more -->
## 启动CGroup v2功能
在启动系统的CGroup v2功能之前首先需要确认系统是否提供了CGroup v2的支持并且系统是否已经启动了CGroup v2功能。
在命令行中执行以下命令可以查看系统是否提供了CGroup v2的支持。
```bash
grep cgroup /proc/filesystems
```
如果输出的结果中包含以下内容那就说明系统已经提供了CGroup v2的支持。
```bash
nodev cgroup2
```
接下来是检查系统中是否已经激活了CGroup v2。同样在命令行中执行以下命令
```bash
ls /sys/fs/cgroup/cgroup.controllers
```
如果系统提示找不到指定文件那么就说明系统目前没有激活CGroup v2。
此时就可以激活系统中的CGroup v2了需要注意的是激活系统中的CGroup v2功能会要求系统重新启动如果正在操作生产系统要保证当前系统管理操作不会对系统中所承载的服务产生影响。
打开系统中的`/etc/default/grub/`文件,在其中的`GRUB_CMDLINE_LINUX`参数的尾部增加以下内容。
```text
systemd.unified_cgroup_hierarchy=1
```
添加完以后的`GRUB_CMDLINE_LINUX`参数可能是这样的:
```text
GRUB_CMDLINE_LINUX=" vga=792 console=tty0 console=ttyS0,115200n8 net.ifnames=0 noibrs systemd.unified_cgroup_hierarchy=1"
```
完成添加以后执行以下两条命令,更新系统引导并重新启动系统。
```bash
sudo update-grub
sudo shutdown -r now
```
!!! note ""
如果是使用root用户进行的操作则不必使用`sudo`。
完成系统重启以后可以再次执行检查CGroup v2是否已经激活的命令此时应该会列出`cgroup.controllers`文件。
!!! note ""
执行命令`cat /sys/fs/cgroup/cgroup.controllers`可以检查目前有哪些设备已经托管给了CGroup。
## 安装containerd和nerdctl
containerd是一个OCI标准的容器化支持环境但是并不需要我们单独的去完成containerd的安装。nerdctl的完整安装包内已经集成了containerd、runC和CNI所以直接在Ubuntu中安装nerdctl的完整版即可。
顺序执行以下命令可以下载nerdctl 0.22.2版并将nerdctl和containerd等都安装到`/usr/local`中。
```bash
wget https://ghproxy.com/https://github.com/containerd/nerdctl/releases/download/v0.22.2/nerdctl-full-0.22.2-linux-amd64.tar.gz
tar Cxzvf /usr/local nerdctl-full-0.19.0-linux-amd64.tar.gz
cp /usr/local/lib/systemd/system/*.service /etc/systemd/system/
systemctl enable buildkit containerd
systemctl start buildkit containerd
```
以上命令的最后两行是启动containerd和镜像打包支持。安装包解压完毕以后不必重启系统应该就已经可以执行`nerdctl`命令了。
如果当前不能使用root用户来完成containerd和nerdctl的安装那么就需要使用Rootless方式安装nerdctl了。这种情况下可以执行完上面第二条解压命令以后执行以下命令完成安装。
```bash
containerd-rootless-setuptool.sh install
```

View File

@ -0,0 +1,81 @@
---
title: 自有类型与借用类型
tags:
- Rust
- 类型系统
- 所有权
- 借用
- 引用
categories:
- - Rust
- 语言基础
keywords: 'rust,类型系统,自有类型,借用类型'
date: 2022-07-04 11:03:34
---
在根据Rust的所有权系统使用变量的时候值通常会发生移动来改变其拥有者这通常总是适用于Rust自有类型但是Rust中的借用类型的表现就不一样了因为在这些类型中存放的实际上是另一个内存区域的地址而借用类型的变量一般并不拥有它所指向的那一片内存区域。这种行为上的区别就构成了Rust中两种不同的类型自有类型和借用类型。<!--more-->
## 自有类型
自有类型其实比较好理解这种类型是完全遵守Rust中的所有权机制的。自有类型变量所拥有的内存区域中保存的就是实实在在的值。如果发生转移那么这一块内存区域的所有权就将被直接转移到新的变量名下。
```rust
fn main() {
let person1: String = String::from("John");
// 使用赋值语句将会使person1所拥有的内存区域转移给person_alias。
let person_alias = person1;
// 发生转移以后再使用person1就会失败。
println!("Person name: {}", person1);
}
```
在程序中使用自有类型是不会有任何歧义的因为任何操作都必须遵循Rust的所有权机制。但是使用自有类型会对编程过程中的自由性产生一定的影响。
## 借用类型
Rust中的借用类型就不是那么遵守所有权机制了在代码中借用类型一般都非常好辨认在借用类型的前面通常都会带着一个`&`符号。当然这种类型在其他语言中通常被称作引用类型。
同样是上面的示例,采用借用类型以后,运行效果就会变得不一样。
```rust
fn main() {
let person1: &String = &String::from("John");
// 这里同样使用一个赋值语句但是需要注意的是person_alias现在的类型也是&Stirng
let person_alias = person1;
println!("Person alias: {}", person_alias);
// 这会儿再使用person1的时候并不会出现任何错误。
println!("Person name: {}", person1);
}
```
就像是之前提到过的,借用类型变量所直接拥有的内存区域中保存的实际上是另一块内存区域的地址,程序中所需要使用的值实际上是被放置在这一块内存区域中的,借用类型变量是通过指针指向来访问所需要使用的值的。
在上面的这个示例中,赋值语句的是使用并没有发生任何的所有权转移。这也就是借用类型并不是那么遵守所有权机制的原因。
## 如何选择使用
在了解自有类型和借用类型的区别以后,就能理解为什么从函数中不能返回借用类型的原因了,因为从函数中返回值通常是所有权的转移,但是借用类型对于其所指向的目标内存区域是没有所有权的。所以即便是在函数中使用了借用类型,在返回其指向的值的时候,也应该借助于`.to_owned()`方法将其转换为自有类型,但是要谨记在调用函数的地方还是要处理所有权的。
不管在任何时候,使用自有类型作为函数的参数类型总不是一个好的选择。函数实参的所有权会被转移到函数中,如果这一段内训区域在使用完以后没有把所有权转移回来,那么在调用完函数以后,用作函数实参的变量就不能再用了。所以在选择函数参数类型的时候,应该首选借用类型。
另外,选择可切片类型和胖指针类型作为函数参数类型,还可以避免类型带有强制隐式类型转换带来的代码复杂度。例如传递字符串的时候使用`&str`而不是`&String`,传递数组使用`&[T]`而不是`&Vec<T>`,选择`&T`代替`&Box<T>`。例如有函数`fn str_length(word: &String): i32`,在传入一个引用的时候,是可以正常运行的,例如`str_length(&person_name)`,但是直接传入一个字符串字面量就不行了,例如`str_length("John")`。这是因为在调用函数的时候,表示字符串字面量的`&str`类型不能被强制转换成函数参数所要求的`&String`类型。但是如果将函数定义为`fn str_length(word: &str): i32`,那么就可以避免这个强制类型转换,而解决这个问题。
### 隐式类型转换规则
在Rust中发生这种强制隐式类型转换是有一定规则可循的一般情况下强制隐式类型转换的目的都是弱化指针或者解引用例如常见的有以下形式。
1. 弱化指针:
- `&mut T`转换为`&T`。
- `*mut T`转换为`*const T`。
- `&T`转换为`*const T`。
- `&mut T`转换为`*mut T`。
1. 解引用:
- 如果`T: Deref<U>`,那么可以将`&T`通过表达式`&*x`转换为`&U`。
这种隐式类型转换通常会发生在`let`、`const`、`static`、函数调用传参、从函数返回值等位置。

View File

@ -19,12 +19,20 @@ date: 2021-07-12 14:13:26
| 首次发布 | 最近更新 | 修订版本 | 适用 React 版本 |
| :-----------: | :-----------: | :------: | :-------------: |
| 2019 年 09 月 | 2022 年 05 月 | 47 | 18.1.0 |
| 2019 年 09 月 | 2022 年 06 月 | 49 | 18.1.0 |
点此下载:{% oss_link react-books/React.pdf React技术栈速查手册 %}
点此下载:{% oss_link react-books/React.pdf "《Live with React》" %}
## 更新记录
修订版本 49:
- 增加Zustand状态管理库的使用说明。
修订版本 48:
- 补充使用Redux Toolkit时在一个State片段中响应其他State片段定义的Action的说明。
修订版本 47:
本次手册内容的修订包含一次React大版本的更新本次更新引入了突破性变更的内容。