普通视图

发现新文章,点击刷新页面。
昨天以前首页

在银河麒麟桌面操作系统 ARM 版上安装 KVM 虚拟化

2025年4月24日 00:00

KVM 是一种开源全虚拟化解决方案,能够在 Linux 系统运行多个操作系统。本文将详细介绍如何在银河麒麟桌面操作系统 ARM 版安装 KVM 虚拟化环境,帮助用户搭建高效的虚拟化平台。

准备工作

  1. 硬件要求

确保 ARM 架构设备支持虚拟化技术。通常,支持虚拟化的 ARM 处理器会支持硬件辅助虚拟化功能。

系统至少需要 4GB 内存和 20GB 的硬盘空间。

  1. 软件要求

银河麒麟桌面操作系统 ARM 版「如 V10」

KVM 虚拟化相关的软件包。

安装 KVM 虚拟化环境

  1. 安装 KVM 和相关工具
1
2
sudo apt update
sudo apt -y install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager

注意:在银河麒麟桌面操作系统 ARM 版上,可以通过上面命令安装 KVM 和相关工具。

  1. 包的作用

上面软件包的作用如下:

包名作用
qemu-kvm提供 KVM 虚拟化核心功能
libvirt-daemon-system用于管理虚拟机的后端服务
libvirt-clients提供客户端工具管理虚拟机
bridge-utils用于配置网络桥接
virt-manager提供图形化界面管理虚拟机
  1. 添加用户到 libvirt 组内
1
sudo usermod -aG libvirt $(whoami)

注意:为方便管理虚拟机,需要将当前用户添加到 libvirt 组,然后注销重新登录,使组成员关系生效。

  1. 验证是否安装成功
1
virsh --version

注意:运行上面命令来检查 KVM 是否正常工作,如果返回版本信息,说明 KVM 安装成功了。

创建 KVM 虚拟机

  1. 下载镜像

可以从银河麒麟官方网站下载适合 ARM 架构的虚拟机镜像文件。

Kylin-Desktop-V10-SP1-2403-Release-20240430-arm64.iso 文件。

  1. 创建虚拟磁盘
1
qemu-img create -f qcow2 /path/to/disk.img 50G

注意:使用上面命令创建虚拟磁盘。其中/path/to/disk.img 是虚拟磁盘路径,50G 表示磁盘的大小。

  1. 启动 KVM 虚拟机安装
1
qemu-system-aarch64 -m 2048 -cpu cortex-a76 -smp 4 -M virt -bios /path/to/QEMU_EFI.fd -device VGA -device nec-usb-xhci -device usb-mouse -device usb-kbd -drive if=none,file=/path/to/disk.img,id=hd0 -device virtio-blk-device,drive=hd0 -drive if=none,file=/path/to/Kylin-Desktop-V10-SP1-2403-Release-20240430-arm64.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom

注意:使用上面命令启动 KVM 虚拟机安装。其中-m 2048 分配 2048MB 内存;-cpu cortex-a76 指定 CPU 类型;-smp 4 是指定虚拟 CPU 核心数。

  1. 完成安装

按照虚拟机安装界面的提示完成安装过程。

安装完成后 KVM 虚拟机将自动重启。

使用 KVM 管理虚拟机

  1. 使用 virsh 命令行工具

列出所有 KVM 虚拟机:

1
virsh list --all

启动 KVM 虚拟机:

1
virsh start <KVM 虚拟机名称>

关闭 KVM 虚拟机:

1
virsh shutdown <KVM 虚拟机名称>

强制停止 KVM 虚拟机:

1
virsh destroy <KVM 虚拟机名称>

挂起 KVM 虚拟机:

1
virsh suspend <KVM 虚拟机名称>

恢复挂起 KVM 虚拟机:

1
virsh resume <KVM 虚拟机名称>
  1. 使用 virt-manager 图形化界面

virt-manager 提供了一个直观的图形化界面,方便用户管理 KVM 虚拟机。

启动 virt-manager 后,可以连接到本地或者远程的 KVM 服务器,创建、启动、停止 KVM 虚拟机。

Linux 系统监控利器 ctop 命令详解

2025年4月6日 00:00

在 Linux 系统,尤其是当我们在管理多个容器时,了解系统和容器的资源使用情况至关重要。今天,就给大家介绍一款强大的监控工具 ctop,本文详细介绍 ctop 的安装、使用、命令选项。

ctop 命令的简介

ctop 是一个类似 top 命令的界面工具,它专注于容器环境,能够实时监控 Docker/Podman 等容器运行时的性能指标,如 CPU、内存、网络、磁盘 I/O 等使用情况。

它以一种直观的方式展示各个容器的详细信息,让管理员可以迅速掌握系统整体健康状况,并且快速定位到可能存在性能瓶颈的容器。

与传统 top 命令相比,ctop 提供更丰富的容器相关数据和更便捷的交互方式。

它不仅能展示容器的基本资源使用率,还能深入到每个容器的进程级别,查看内部运行具体进程,这对于深入分析容器性能表现非常有帮助。

ctop 命令的安装

  1. Linux 系统的安装方法「以 Ubuntu 为例」
1
2
sudo wget https://github.com/bcicen/ctop/releases/download/v0.7.7/ctop-0.7.7-linux-amd64 -O /usr/local/bin/ctop
sudo chmod +x /usr/local/bin/ctop

注意:可以直接从 Github 下载最新版本的二进制文件进行安装,以上是具体的步骤「这里以 v0.7.7 版本为例」最后,用命令 ctop -v 验证是否安装成功,若可以正确显示版本号,说明安装成功。

  1. 通过 Docker 的方法安装
1
docker run --rm -it --name=ctop -v /var/run/docker.sock:/var/run/docker.sock quay.io/vektorlab/ctop:latest

注意:也可以使用 Docker 快速启动 ctop 容器来进行监控。

ctop 命令的使用

  1. 基本使用

在终端中输入 ctop 命令后回车,即可启动 ctop 程序进入主界面。在界面中,会显示出所有正在运行的容器及其资源使用情况的概览,包括容器名称、CPU 使用率、内存使用量及限制、网络收发速率、磁盘读写速率、进程数等信息。

可以通过方向键上下移动光标来选择不同容器,然后按下回车键可以查看到所选容器详细信息,如容器的创建时间、各资源的详细使用数据以及内部运行的进程列表等。

  1. 命令选项

命令选项列表如下:

选项描述
ctop -a只查看正在运行中容器,方便专注那些实际处于活动状态、可能对系统资源产生影响的容器。
ctop -f string查看包含指定字符串的容器,当系统中有大量容器时,利用此选项可快速过滤出我们关心的特定容器进行监控。
ctop -i反转默认颜色,如默认的颜色显示效果不佳,或需要与其它界面风格保持一致,可使用该选项来改变界面的颜色显示。
ctop -r反向容器排列顺序,默认情况下存活的容器在前,使用此选项可将其顺序反转,以便按照不同顺序查看容器。
ctop -s string按照指定字段排序,如执行 ctop -s net 可以按照网络使用率对容器进行排序,从而快速找到网络流量较高容器。

交互操作

交互操作列表如下:

操作描述
h打开帮助,在使用过程中如果忘记了某些快捷键的功能或者想了解更多操作方法,可以随时按下 h 键查看帮助信息。
s打开排序,通过此快捷键可以方便地切换不同的排序字段,无需重新输入命令选项。
q退出打开的对话框,当查看完帮助信息或排序设置后,按下 q 键可以退出相应的对话框,返回到主界面。
a只显示正在运行的容器,与 ctop -a 命令效果一致,但在已经启动了 ctop 程序的情况下,使用快捷键可更快速地切换显示模式。
r反转排序,正在运行容器放在末尾,方便在不同的排序需求之间快速切换。
f输入指定字符串过滤出想要查看容器,与 ctop -f string 命令类似,无需重新输入命令,直接在当前界面中进行过滤操作。
j用于向下移动光标,方便在容器列表中快速定位到不同的容器。
k用于向上移动光标,方便在容器列表中快速定位到不同的容器。
Enter查看指定容器详细指标,当光标定位到某个容器,按下回车键即可进入该容器详细信息界面,查看更全面的资源使用以及进程信息。

Linux 下的高效压缩工具 Zstandard

2025年4月3日 00:00

Zstandard 以其卓越的性能和丰富的功能,成为了 Linux 下一款不可或缺的压缩工具。无论是对单个文件还是整个目录的压缩和解压,它都可以轻松应对,且在处理速度和压缩效果上都有着出色的表现。

Zstandard 的简介

Zstandard 是由 Facebook 开发并开源的一种快速无损压缩算法,2015 年首次发布以来,凭借其高压缩比和快速的解压缩速度,逐渐受到了开发者青睐。

它不仅在压缩效率上超越传统的 gzip 等工具,还能在保持高压缩率的同时,实现极快解压速度,特别适合对数据处理效率要求较高的场景,如大数据处理、日志压缩、网络数据传输等等。

Zstandard 的特点

高压缩比:通常情况下 Zstandard 能够获得比 gzip 更好压缩效果,有效减少数据存储空间。

快速解压:其解压缩速度极快,即使是低压缩等级,解压速度也能远超一些 SSD 的读取速度,大大提高了数据的读取效率。

多线程的支持:Zstandard 自带多线程压缩功能,可以充分利用多核 CPU 的性能,大幅提升压缩速度。例如,在处理大量数据时,多线程压缩能够显著的缩短压缩时间,提高工作效率。

丰富压缩级别选择:提供了从 1 到 22 的压缩级别选择,用户可根据实际需求在压缩速度和压缩率之间进行灵活权衡。压缩级别越高,压缩比率越大,但压缩速度会相应减慢;反之,压缩级别越低,压缩速度越快,但压缩比率会有所降低。

字典压缩模式:Zstandard 为小数据提供一种特殊的字典压缩模式。用户可通过提供一些样本数据来训练生成字典,然后在压缩和解压时加载该字典,从而在小数据上实现更高压缩率,这对于处理大量小文件场景非常有用。

使用模式:Zstandard 提供了多种命令模式,包括压缩、解压、查看压缩信息、测试压缩文件等等。

Zstandard 的安装

Debian/Ubuntu 系统的安装命令如下:

1
sudo apt install zstd

Fedora/Red Hat/CentOS/AlmaLinux 系统的安装命令如下:

1
sudo dnf install zstd

Arch Linux/Manjaro 系统的安装命令如下:

1
sudo pacman -S zstd

也可以从源码编译安装「这里以 1.5.7 版本为例」命令如下:

1
2
3
4
5
wget https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz
tar -zxvf zstd-1.5.7.tar.gz
cd zstd-1.5.7/
make
sudo make install

Zstandard 的使用

  1. 压缩文件

基础压缩:使用命令 zstd file_name 即可对文件进行压缩,压缩后会生成一个扩展名为.zst 的文件,如 zstd doc.txt,会生成 doc.txt.zst 文件。

指定压缩级别:可通过选项来指定压缩级别,例如 zstd -3 file_name 表示使用压缩级别-3 进行压缩。

  1. 解压文件

基础解压:使用 zstd -d archive_name.zst 即可对文件进行解压,解压后的文件会自动去除.zst 后缀。

指定解压后文件名:同样可使用-o 选项来指定解压后的文件名,如 zstd -d archive_name.zst -o new_file_name

  1. 压缩目录

压缩整个目录:可以使用 zstd -rz directory_name 来压缩整个目录,其中-r 表示递归压缩目录中所有文件和子目录,-z 表示压缩的操作。

解压目录:对于压缩后的目录文件,使用 zstd -dr archive_name.zst 进行解压缩,-d 表示解压缩操作,-r 表示递归解压缩。

  1. 查看压缩文件内容

使用 zstd -l archive_name.zst 可以查看压缩文件的相关信息,如压缩比、压缩级别、文件大小等等。

zstd -t archive_name.zst 则可用于测试压缩文件的完整性,确保文件在压缩和传输过程中未损坏。

X Window 与 Wayland 的深度对比

2025年3月28日 00:00

X Window 与 Wayland 不仅代表了图形界面技术不同发展阶段,更体现了设计理念、架构模式及应用场景的显著差异。本文将从历史背景、技术特点、应用场景及未来展望等多个维度,对 X Window 和 Wayland 进行深入剖析。

历史背景演变

X11 诞生于 1984 年,由麻省理工学院 MIT 开发,旨在满足分布式计算环境下图形界面需求。其设计哲学强调网络透明性,允许用户在远程服务器运行应用程序,并在本地终端显示结果,极大地拓展 GUI 的可用性和灵活性。随着时间推移,X11 凭借其广泛的硬件和软件支持,逐渐成为 Linux 桌面环境的标准图形界面后端。

随着计算需求增长,X11 的一些设计局限逐渐显现,例如架构复杂、性能瓶颈和安全性问题。2008 年,Kristian 提出 Wayland 项目,旨在创建一个更加现代、高效窗口系统。Wayland 的设计重点在于简化架构、提高性能和增强安全性,采用客户端 Compositor 通信模型,减少了中间层,提升了效率和响应速度。

技术特点比较

X11 采用 C/S 模型,客户端通过 X 协议与服务器通信,而 X 服务器负责处理所有图形和输入事件。相比之下,Wayland 采用了客户端 Compositor 模型,客户端可直接与 Compositor 通信,Compositor 负责了窗口管理、合成、输出。Wayland 的架构更加贴合现代图形硬件特性,可以更高效地利用 GPU 和现代显示技术。

X11 在安全性方面存在了固有弱点,其复杂协议和广泛权限易被恶意利用。Wayland 通过限制客户端权限以及简化通信模型,显著提高了安全性。例如,Wayland 禁止了应用程序直接访问底层硬件,只允许了它们与 Compositor 通信,从而增强系统的安全性。

Wayland 的协议设计更加高效,减少了延迟和带宽消耗。在移动设备和资源受限的环境中,Wayland 的优势尤为明显。此外,Wayland 避免了不必要的复杂性和额外处理,使得其在性能上优于 X11。尤其是在窗口大小调整以及拖动等操作中,Wayland 显得更加的平滑流畅。

X11 拥有庞大的生态系统,支持大量的应用程序和工具,几乎所有 Linux 发行版默认都使用 X11。然而,Wayland 的生态系统正在快速发展,主要桌面环境如 GNOME 和 KDE 已全面支持 Wayland。尽管如此,一些特定应用程序和工具可能仍需要额外的兼容层或补丁才能在 Wayland 下运行。

应用场景

在桌面环境中,X11 凭借其广泛的兼容性和成熟度,仍然是许多用户的首选。但随着硬件技术的进步和用户对高性能图形渲染的需求增加,Wayland 正在逐渐成为主流的选择。

越来越多的 Linux 发行版开始默认支持 Wayland,例如 Fedora 和 Ubuntu 等。

在移动设备和嵌入式系统中,资源受限是一个普遍的问题。Wayland 的低功耗以及高性能特性使其成为这些场景下的理想选择。

例如,Android 系统中的 SurfaceFlinger 就是基于 Wayland 的原理设计,用于图形显示以及窗口管理。

在虚拟化和云计算的环境中,图形性能以及网络传输效率至关重要。

虽然 X11 的网络透明性在某些场景下仍有些优势,但 Wayland 通过优化的协议和架构,正在成为虚拟桌面基础设施 VDI 和云桌面解决方案的首选,特别在需要高性能图形渲染的场景中。

未来展望

随着 GPU 技术的成熟以及高性能计算需求的增长,图形界面的渲染以及交互将变得更加复杂和多样化。

X11 和 Wayland 都在积极的探索与 Direct Rendering Manager、Mesa 等图形驱动框架的更紧密集成,以实现更高效的图形渲染和硬件加速。

此外,Wayland 还在研究如何更好地支持多显示器配置、高分辨率显示、触控输入,以满足未来计算环境多样化需求。

最后说两句题外话,近一个月杜老师因为工作的原因,拖更了很多篇文章,感谢小伙伴们的关注和催更,近期会大批量发表一些技术文章,欢迎大家关注。

OpenResty 的性能优化配置建议

2025年3月25日 00:00

1Panel 的用户越来越多,内置 Web 服务 OpenResty 使用占比也在增加,但网上对其优化的教程很少。应关关童靴的需求,更新一篇有关 OpenResty 的一些优化建议。可优化设置项较少,需要的小伙伴可以根据实际需求变更配置。

server_names_hash_bucket_size 参数项

含义:该参数用于设置服务器名字 hash 表大小,若名字过长或服务较多,保持默认值可能使 hash 表空间不足,引发错误。

优化建议:一般为 server_names_hash_max_size 的 1/2-1/3 左右,如服务器配置较高,可直接设置 256

gzip 参数项

gzip_min_length 参数项:对小文件压缩可能得不偿失,一般设置为 1k10k 左右,小于该值的文件不压缩。

gzip_comp_level 参数项:压缩级别,1 为最小最快,9 为最大最慢,通常建议设置为 4-6,以平衡压缩效果和 CPU 使用率。

client_header_buffer_size 参数项

含义:用于设置读取客户端请求头的缓冲区大小,若请求头过大,可能超出默认值导致客户端报错。

优化建议:根据实际业务需求调整,如业务请求头通常较大,可设为 32k 左右,确保可以完整读取大部分请求头。

client_max_body_size 参数项

含义:限制客户端请求主体的最大允许大小,超出该值请求将被拒绝。

优化建议:根据业务场景和服务器承受能力设置,如普通表单提交可设置为 10m-20m 左右,对于文件上传等大请求可以适当增大。

keepalive_timeout 参数项

含义:设置长连接的超时时间,即客户端与服务器间连接保持空闲的最大时间。

优化建议:一般设为 60-90 秒左右,时间过短会频繁断开连接且增加开销,过长则可能占用过多的资源。

优化后的配置示例

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
http {
# gzip相关配置
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/json;
gzip_vary on;
gzip_proxied any;
gzip_disable "msie6";

# 服务器名字hash表大小
server_names_hash_bucket_size 128;

# 客户端请求头缓冲区大小
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;

# 客户端请求主体最大允许大小
client_max_body_size 32m;

# 长连接超时时间
keepalive_timeout 60;

# 其他配置...
}

注意:以上配置仅供参考,具体优化需根据实际业务场景和硬件配置进行调优。

Nginx 从配置到缓存的性能优化

2025年3月22日 00:00

Nginx 是一个高性能的 HTTP 服务器和反向代理服务器,广泛应用于处理高并发请求。然而,默认配置并不一定适合所有场景,尤其是在高流量或复杂业务逻辑的情况下。本文将介绍一些 Nginx 的基础配置优化和缓存的使用方法以提升 Nginx 的性能。

基础配置优化

  1. 调整 worker_processes 以及 worker_connections

Nginx 使用多进程模型处理请求。worker_processes 定义 Nginx 使用的工作进程数,而 worker_connections 定义每个工作进程可以处理的最大连接数:

1
2
3
4
worker_processes auto;
events {
worker_connections 1024;
}

参数作用如下:

参数作用
worker_processes设置为 auto 可以让 Nginx 自动根据 CPU 核心数来分配工作进程数。如服务器有 4 个 CPU 核心,Nginx 会启动 4 个工作进程。
worker_connections这个值决定了每个工作进程可以处理的最大连接数。通常,可根据服务器的内存和网络带宽来调整这个值。1024 是一个常见起点,可以调整到 2048。
  1. 启用 keepalive 长连接

HTTP 协议中的 keepalive 机制允许客户端和服务器在同一个连接上发送多个请求,减少了 TCP 连接的建立和关闭开销:

1
2
3
4
http {
keepalive_timeout 65;
keepalive_requests 100;
}

参数作用如下:

参数作用
keepalive_timeout定义客户端与服务器保持连接的时间。设置为 65 秒意味着如果客户端在 65 秒内没有发送新请求,连接将被关闭。
keepalive_requests定义了单个连接上允许的最大请求数。设置为 100 意味着一个连接可以处理 100 个请求后关闭。
  1. 调整 buffer 的大小

Nginx 使用缓冲区来存储请求和响应数据。如缓冲区设置过小,Nginx 可能会频繁地进行磁盘 I/O 操作,影响性能:

1
2
3
4
5
http {
client_body_buffer_size 10K;
client_header_buffer_size 1k;
large_client_header_buffers 48k;
}

参数作用如下:

参数作用
client_body_buffer_size定义用于存储客户端请求体的缓冲区大小。如请求体超过这个大小,会将数据写入磁盘。
client_header_buffer_size定义用于存储客户端请求头的缓冲区大小。
large_client_header_buffers定义用于存储大型请求头的缓冲区数量和大小。

缓存提升性能

  1. 启动静态资源缓存

对于静态资源,启用缓存可以显著减少服务器的负载:

1
2
3
4
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}

参数作用如下:

参数作用
expires定义了资源的缓存时间。30d 表示资源将缓存 30 天。
Cache-Controlpublic 表示资源可以被任何缓存「如浏览器、CDN等」缓存,no-transform 表示不允许代理服务器对资源进行转换「如压缩等」
  1. 使用代理缓存

如使用 Nginx 作为反向代理,可启用代理缓存来缓存后端服务器的响应:

1
2
3
4
5
6
7
8
9
10
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;

server {
location / {
proxy_cache my_cache;
proxy_pass http://backend;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
}
}

参数作用如下:

参数作用
proxy_cache_path定义了缓存存储的路径、缓存键的存储区域、缓存的最大大小及缓存的有效期。
proxy_cache启用缓存并使用指定的缓存区域。
proxy_cache_valid定义不同状态码的缓存时间。
  1. 使用 gzip 压缩减少网络传输量

gzip 压缩可以显著减少传输数据量,从而加快页面加载速度:

1
2
3
4
5
6
7
8
http {
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 6;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
}

参数作用如下:

参数作用
gzip启用压缩。
gzip_types定义了需要压缩的文件类型。通常包括文本文件、CSS/JavaScript/XML 等。
gzip_comp_level定义压缩级别,范围是 1 到 9。1 是最低的压缩率,9 是最高的压缩率。默认值 6
gzip_min_length定义最小压缩文件大小。小于这个大小的文件不会被压缩。
gzip_proxied定义了是否对代理请求启用压缩。any 表示对所有代理请求启用压缩。
gzip_vary添加响应,确保代理服务器能正确处理缓存。

HTTP/2 与速率限制

  1. 使用 HTTP/2 版协议

HTTP/2 提供了多路复用、头部压缩特性,可以显著提升性能:

1
2
3
4
5
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
}

参数作用如下:

参数作用
http2listen 指令中添加 http2 参数即可启用。
  1. 限制请求速率

为了防止恶意请求或突发流量导致服务器过载,可使用 limit_req 模块限制请求速率:

1
2
3
4
5
6
7
8
9
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

server {
location / {
limit_req zone=one burst=5;
}
}
}

参数作用如下:

参数作用
limit_req_zone定义限流区域。$binary_remote_addr 表示根据客户端的 IP 地址进行限流,rate=1r/s 表每秒允许 1 个请求。
limit_req在指定的位置应用限流。burst=5 表允许突发 5 个请求。

LB 和日志优化

  1. 负载均衡
1
2
3
4
5
6
7
8
9
10
upstream backend {
server 192.168.1.1:8080;
server 192.168.1.2:8080;
}

server {
location / {
proxy_pass http://backend;
}
}

注意:通过 upstream 模块可以将请求分发到多个后端服务器,提高并发处理能力。

  1. 日志优化
1
2
access_log /var/log/nginx/access.log main buffer=16k;
error_log /var/log/nginx/error.log warn;

注意:调整日志级别可减少日志输出量,提升性能。这表示将访问日志的缓冲区大小设置为 16KB,并将错误日志级别设置为 warn

解释器权限不够的处理思路

2025年3月16日 00:00

当我们在使用 Linux 系统进行开发或者运维工作时,经常遇到一些错误提示。其中一个常见错误是解释器权限不够。这个错误提示表明在运行 targetcli 命令,系统没有足够权限来执行所需的 Python 解释器。在本文中,我们将探讨这个错误原因和解决方法。

错误原因

为理解这个错误的原因,我们需要先了解下 Linux 系统的权限管理机制。

Linux 系统将用户和组织分为不同的分类,并为每个用户和组织分配不同的权限。这些权限决定用户可以访问和执行哪些文件和目录。

在这个特定错误中,我们看到了一个错误路径/usr/bin/targetcli 和错误消息/usr/bin/python3:解释器错误:权限不够

系统无法在路径/usr/bin/targetcli 下找到所需的 Python 解释器,且没有足够的权限来执行它。

解决方法

  1. 确定缺少的解释器

首先,我们需确定缺少的 Python 解释器。

在错误消息中,我们看到了/usr/bin/targetcli/usr/bin/python3 两个路径。这告诉我们 targetcli 命令需要 python3 来执行。

  1. 确定解释器的位置

接下来我们需要确定 python3 解释器的实际位置。我们可以使用 which 命令来找到解释器的路径。

可在终端中运行命令 which python3。命令的输出将告诉我们 python3 解释器位置。比如,输出可能是/usr/local/bin/python3

  1. 修改 python3 解释器路径

一旦我们找到了 python3 解释器的位置,我们可以通过修改 targetcli 脚本来更新解释器的路径。

打开终端并输入命令 sudo vi /usr/bin/targetcli。这将使用编辑器打开 targetcli 脚本。

在脚本中,我们需要查找#!/usr/bin/python3 这一行,并将其替换为 python3 解释器实际路径。

在这个例子中,我们可以将其替换为#!/usr/bin/python3

  1. 更改脚本权限

最后,我们需要为 targetcli 脚本提供执行权限。

可在终端中运行命令 sudo chmod +x /usr/bin/targetcli。如果一切顺利,我们应该不再看到错误消息。

加密 NFS 搭建保障数据传输与存储安全

2025年3月4日 00:00

在现代企业环境中,数据的安全性至关重要。NFS 作为一种广泛使用的文件共享协议,其数据在传输和存储过程中若是缺乏加密保护,将面临被窃取或篡改的风险。本文将详细介绍加密 NFS 搭建过程。

NFS 的简介

NFS 是允许用户通过网络访问远程文件系统,就像访问本地文件系统一样方便。

它支持跨平台文件共享,广泛应用于 Linux 和 Unix 系统。

然而,传统的 NFS 传输数据时以明文形式在网络中传输,很容易受到中间人攻击和数据泄露的威胁。

在 NFS 的基础上,我们可以使用加密技术来保护数据传输和存储。

加密 NFS 必要性

随着数据安全法规的日益严格和企业对数据保护的重视,对 NFS 进行加密变得必不可少。

在企业中,NFS 的加密功能可以提供数据传输和存储的安全保障。

加密 NFS 可有效防止数据在传输过程中被窃取或篡改,确保数据的完整性和机密性。

同时,它也可以满足企业对数据安全合规的要求,为企业的数据资产提供更可靠的保护。

搭建加密 NFS 的步骤

在 NFS 服务器安装支持加密的 NFS 软件包。例如,在基于 Debian 的系统上,可以使用下面命令进行安装:

1
sudo apt -y install nfs-kernel-server

使用下面的命令编辑 NFS 配置文件,添加加密相关选项。例如,可使用 sec = krb5isec = krb5p 选项来启用 Kerberos 加密。其中,krb5i 提供数据完整性保护,而 krb5p 则同时提供了数据加密和完整性保护:

1
sudo vim /etc/exports

在配置文件中指定要共享的目录及其访问权限。这表示允许客户端 IP 以读写模式访问共享目录,并启用 Kerberos 加密。例如:

1
/path/to/shared/directory client_ip(rw,sync,no_subtree_check,sec=krb5i)

完成配置后重启 NFS 服务。可以使用下面命令重启服务:

1
sudo systemctl restart nfs-kernel-server

使用下面的命令使配置文件生效:

1
exports -rv

在需访问加密 NFS 共享的客户端上安装 NFS 客户端软件。例如,在基于 Debian 的系统上,可以使用下面命令进行安装:

1
sudo apt -y install nfs-common

使用挂载命令将加密的 NFS 共享挂载到本地目录。这将把服务器上的共享目录挂载到客户端本地目录,并启用 Kerberos 加密。例如:

1
sudo mount -t nfs4 -o sec=krb5i server_ip:/path/to/shared/directory /local/mount/point

使用下面命令查看挂载文件系统,确保加密 NFS 共享已成功挂载:

1
df -h 

加密 NFS 优势与注意事项

加密 NFS 有多种优势,例如数据加密传输、身份认证和数据完整性保护等等。

它能够有效防止数据泄露和篡改,提高数据的安全性。

然而,在搭建加密 NFS 时也需要注意一些事项。

首先,加密过程可能会增加系统的性能开销,因此需根据实际需求进行性能评估和优化。

其次,配置过程较为复杂,需仔细检查配置文件和参数设置,确保正确无误。

此外,还需要定期更新加密软件和认证机制,以应对不断变化的安全威胁。

探索 Linux 内存占用找出最吃内存的进程

2025年2月23日 00:00

无论是服务器还是个人电脑,了解哪些进程占用了最多的内存,对于系统管理员和普通用户来说至关重要。不仅可以帮助我们优化系统性能,还能避免因内存不足而导致系统崩溃。本文将介绍如何在 Linux 系统中统计内存占用最多的前 10 个进程。

为什么要统计内存占用

多任务操作系统中,内存是有限的资源。

当多个进程同时运行时,它们会争夺有限的内存空间。

如果某些进程占用内存过多,可能导致系统响应变慢,甚至出现内存不足错误。

因此,定期检查内存占用情况,找出占用最多进程,可以帮助我们更好管理资源,优化系统性能。

使用命令工具统计内存占用

使用 pssort 的命令组合:

1
ps -eo pid,comm,%mem --sort=-%mem | head -n 11

解释:

参数作用
ps -eo pid,comm,%mem列出所有进程的 PID、进程名称和内存占用百分比。
–sort=-%mem按内存占用百分比降序排序。
head -n 11显示前 11 行的内容「第一行是标题,接下来是前 10 个进程的信息」

虽然 top 命令主要用于实时的监控系统资源,但也可通过以下方式快速查看内存占用最多的进程:

1
top -o %MEM -b -n 1 | head -n 18

解释:

参数作用
-o %MEM按照内存占用排序。
-b以批处理模式运行,输出到终端上。
-n 1只需运行一次。
head -n 18过滤出前 18 行「因为 top 输出的前几行是系统信息,实际进程从第 8 行开始」

如果需要更详细的内存占用信息,可结合 pmap 命令:

1
ps -eo pid,%mem,comm --sort=-%mem | head -n 11 | awk '{print $1}' | xargs -I {} pmap {} | grep total

解释:

参数作用
ps -eo pid,%mem,comm –sort=-%mem获取内存占用最高的进程 PID。
awk ‘{print $1}’提取 PID 进程号。
xargs -I {} pmap {}获取每个进程详细内存映射信息。
grep total过滤 total 行,显示每个进程的总内存占用情况。

如果系统安装了 smem 工具,可以更直观地查看内存占用:

1
smem -s rss -c "pid user command rss" --sort=rss | head -n 11

解释:

参数作用
-s rss按 RSS 排序。
-c “pid user command rss”指定显示的列。
–sort=rss按 RSS 排序。
head -n 11显示前 11 行的内容。

如何分析内存占用情况

确认进程是否必要。有些进程可能是系统正常运行所必需,例如 systemd 等。这些进程通常不会占用过多内存。然而,如果某些进程是用户启动的,如某个应用程序或脚本,需确认它们是否在正常运行。

检查进程是否内存泄漏。如某个进程的内存占用持续增加,可能是内存泄漏导致的。内存泄漏是指程序在申请内存后,无法正确释放已分配的内存,导致内存占用不断增加。这种情况下需要检查程序的代码,查找可能导致内存泄漏地方。

限制进程内存使用。如果某个进程占用过多内存,但又不能轻易终止,可以尝试限制它的内存使用。

Linux 提供 ulimit 命令,可设置进程的资源限制。例如,限制某个进程的最大内存使用量为 1GB,可使用命令 ulimit -m 1048576

内存管理其它技巧

除了统计内存占用最多进程,还可通过以下方式优化 Linux 系统的内存管理。

调整交换空间。交换空间是磁盘上的一部分空间,当物理内存不足时,系统会将一些不常用的内存页面移到交换空间。虽然使用交换空间可以避免系统崩溃,但磁盘速度远慢于内存,因此过多地使用交换空间会导致系统性能下降。

可以通过命令 swapon --show 查看交换空间的使用情况。如果交换空间使用过多,可以考虑增加物理内存,或者调整交换空间大小。

使用内存清理工具。Linux 系统会自动管理内存分配、回收,但有时也可以手动清理内存。

例如,可以使用 sync 命令将缓存数据写入磁盘,然后用 echo 3 > /proc/sys/vm/drop_caches 命令清理缓存。

但请注意,这种方法可能会对系统性能产生一定影响,因此需要谨慎使用。

麒麟服务器操作系统 yum 升级报错处理

2025年2月2日 00:00

因为公司要求,杜老师一直使用麒麟服务器操作系统,为了保证系统的新特性,需要经常升级系统。这次在升级过程中遇到错误,本文记录该错误及其解决的方法。如果小伙伴也遇到了类似的问题,可以参考本文或在评论区中留言!

报错信息

1
2
3
4
5
6
The downloaded packages were saved in cache until the next successful transaction.
You can remove cached packages by executing 'yum clean packages'.
Error: Transaction test error:
file /usr/share/doc/ipmitool/ChangeLog from install of ipmitool-1.8.19-1.p01.ky10.x86_64 conflicts with file from package ipmitool-help-1.8.18-19.p02.ky10.noarch
file /usr/share/doc/ipmitool/README from install of ipmitool-1.8.19-1.p01.ky10.x86_64 conflicts with file from package ipmitool-help-1.8.18-19.p02.ky10.noarch
file /usr/share/man/man1/ipmitool.1.gz from install of ipmitool-1.8.19-1.p01.ky10.x86_64 conflicts with file from package ipmitool-help-1.8.18-19.p02.ky10.noarch

注意;杜老师执行命令 yum -y update 用户升级所有软件,在升级过程中提示如上错误信息。

解决思路

根据所提供的错误信息,问题在于 ipmitool-1.8.19-1.p01.ky10.x86_64ipmitool-help-1.8.18-19.p02.ky10.noarch 间存在文件冲突。以下是解决此问题步骤,首先移除冲突的包:

1
yum -y remove ipmitool-help-1.8.18-19.p02.ky10.noarch

清理缓存,确保后续操作不会受到旧缓存的影响:

1
yum clean all

在移除冲突包并清理缓存后,重新安装 ipmitool 软件包:

1
yum -y install ipmitool-1.8.19-1.p01.ky10.x86_64

最后,更新系统中所有包,以确保所有的依赖关系都已解决:

1
yum -y update

使用 GoAccess 分析 Nginx 访问日志

2025年1月10日 00:00

Nginx 的访问日志中蕴含丰富的信息,然而直接阅读对于大多数人来说是一项艰巨的任务。但我们有 GoAccess 这样的强大工具,它能够帮助我们轻松地分析和可视化 Nginx 的访问日志。

工具安装

对于基于 Debian 的系统「如 Ubuntu」,可以使用以下命令安装:

1
2
sudo apt-get update
sudo apt-get install goaccess

对于基于 Red Hat 的系统「如 CentOS」,可以使用以下命令安装:

1
sudo yum -y install goaccess

源码安装

如果想要从源码安装 GoAccess,可以按照以下步骤操作。先下载 GoAccess 的源码包:

1
wget https://tar.goaccess.io/goaccess-1.4.tar.gz

再解压并编译安装:

1
2
3
4
tar -xzvf goaccess-1.4.tar.gz
cd goaccess-1.4/
./configure --enable-geoip --enable-utf8
make && sudo make install

配置工具

我们需要对 GoAccess 进行配置,确保它能够正确地解析 Nginx 的访问日志。GoAccess 配置文件通常位于 /etc/goaccess/goaccess.conf。对于 Nginx 的默认日志格式,可直接使用--log-format=COMBINED 参数。如果 Nginx 配置了自定义的日志格式,需在 GoAccess 的配置文件中指定相应的日志格式。例如:

1
log-format %h %^[%d:%t %^] "%r" %s %b "%R" "%u"

还需指定日期和时间的格式,以确保 GoAccess 能够正确地解析日志文件中的日期和时间信息。例如:

1
2
date-format %d/%b/%Y
time-format %H:%M:%S

分析日志

在终端直接运行 GoAccess,它会进入一个交互式的界面,显示日志分析结果。在交互式界面中可使用键盘方向键和数字键来浏览和查看不同的统计信息。例如:

1
goaccess /var/log/nginx/access.log --log-format=COMBINED

GoAccess 可将分析结果输出为 HTML 格式的报告,方便在 Web 浏览器中查看。下面的命令将生成一个名为 report.html 的文件,包含丰富的统计信息和图表:

1
goaccess /var/log/nginx/access.log -o report.html --log-format=COMBINED

GoAccess 支持实时监控 Nginx 访问日志,可动态地更新统计信息。如要启用实时监控,可以使用以下命令:

1
--real-time-html --daemonize

启动一个后台进程,实时分析日志文件,并将结果输出到指定的 HTML 文件中,完整参考命令如下:

1
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED --real-time-html --daemonize

分析结果解读

GoAccess 提供了丰富的统计信息和图表,帮助我们全面了解网站访问情况,包括访问概览:

维度描述
网站的总访问次数显示网站总访问量。
网站的独立访客数统计访问网站的不同 IP 地址数量。
总数据传输量表示网站传输数据总量,单位通常为 MB 或 GB。

网站的访问者信息:

维度描述
IP 地址的排名列出访问网站的 IP 地址及其访问次数,可以了解访问者的地理位置分布。
访问者的浏览器和操作系统统计访问者使用的浏览器和操作系统类型,有助于优化网站兼容性。

请求信息:

维度描述
请求方法显示不同 HTTP 请求方法的请求次数。
请求的状态码统计不同 HTTP 状态码请求次数,如 200 表示成功,404 表示未找到。
请求 URL 的排名列出被访问最多 URL 地址,可发现网站的热门内容。

性能分析:

维度描述
请求时间分布显示不同时间段请求量,可发现访问高峰期。
最耗时的请求列出响应时间最长请求,有助于发现性能的瓶颈。

高级用法

除了基本分析功能,GoAccess 还支持一些高级用法。例如可使用管道和过滤器来处理日志数据,下面命令将实时地分析 Nginx 的访问日志,并显示最新的统计信息:

1
tail -f /var/log/nginx/access.log | goaccess -p /etc/goaccess/goaccess.conf

GoAccess 可支持同时分析多个日志文件,下面命令将合并多个日志文件的分析结果:

1
goaccess -p /etc/goaccess/goaccess.conf access.log.1 access.log.2

通过 Nginx 的 access_log 分析网站的流量

2025年1月7日 00:00

在当今数字化时代,网站流量分析对于理解用户行为、优化网站性能以及制定营销策略至关重要。本文将探讨如何通过分析 Nginx 的 access_log 获取网站流量的多维度数据,并给出具体操作步骤和分析方法。

日志格式

在开始分析前,我们需要了解 access_log 的默认日志格式。通常情况 access_log 的日志格式如下:

1
2
3
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';

这个格式包含以下字段:

字段说明
$remote_addr客户端 IP 地址
$remote_user客户端用户名
$time_local本地时间
$request请求方法、请求 URI 以及 HTTP 版本
$statusHTTP 状态码
$body_bytes_sent发送给客户端的字节数
$http_referer请求来源的 URL
$http_user_agent客户端浏览器的用户代理字符串

Nginx 访问量分析

要统计网站的总访问量,可通过计算 access_log 文件的行数来实现。在 Linux 系统中可以使用 wc -l 命令,该命令会输出 access.log 文件的行数,即为网站总访问量:

1
wc -l access.log

了解访问量在不同时间段的分布情况,有助于我们发现网站访问高峰和低谷。可以使用 awk 命令按小时或分钟统计请求数,下面的命令会输出按小时或分钟统计的请求数,并且显示请求数最多的前 100 个时间点:

1
2
3
4
# 每小时统计请求数
awk '{print $4}' access.log | cut -c 14-15 | sort | uniq -c | sort -nr | head -n 100
# 每分钟统计请求数
awk '{print $4}' access.log | cut -c 14-18 | sort | uniq -c | sort -nr | head -n 100

访问来源分析

分析访问来源 IP 可以了解用户主要来自哪些地区或网络环境。使用 awksort 命令可以统计访问量最多的 IP 地址,该命令会输出访问量最多的前 10 个 IP 地址及其访问次数:

1
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -n 10

查看访问来源 URL 有助于我们了解用户是如何找到我们网站的。可以使用以下命令统计访问来源最多的 URL,该命令会输出访问来源最多的前 10 个 URL 及访问次数:

1
awk '{print $11}' access.log | sort | uniq -c | sort -nr | head -n 10

页面访问分析

了解哪些页面访问量最高可帮助我们优化这些页面的性能和内容。使用 awk 命令可统计访问最频繁的页面,下面命令会输出访问最频繁的前 100 个页面及其访问次数:

1
awk '{print $7}' access.log | sort | uniq -c | sort -rn | head -n 100

分析页面的访问时间可以发现哪些页面的加载时间较长,需要优化。在 Nginx 的 log_format 中加入 $request_time 字段,然后使用以下命令列出传输时间超过 3 秒页面,该命令会输出传输时间超过 3 秒的页面及其出现的次数,仅显示前 20 条记录:

1
cat access.log | awk '($NF > 3){print $7}' | sort -n | uniq -c | sort -nr | head -20

用户行为分析

分析用户代理字符串可以了解用户使用的浏览器类型和版本。使用 awk 命令可统计不同浏览器的访问次数,该命令会输出不同浏览器访问次数及其用户代理字符串:

1
awk -F '"' '{print $6}' access.log | sort | uniq -c | sort -nr | head -n 10

通过分析用户的访问路径可以了解用户在网站中的导航行为。可以使用以下命令统计访问路径的长度和频率,该命令会输出访问路径的长度及其出现的次数,仅显示前 10 条记录:

1
awk '{print $7}' access.log | awk -F '/' '{print NF-1}' | sort | uniq -c | sort -nr | head -n 10

性能分析

响应时间是衡量网站性能的重要指标之一。可使用以下命令统计响应时间的分布情况,该命令会输出响应时间及其出现次数,仅显示前 10 条记录:

1
awk '{print $NF}' access.log | sort -n | uniq -c | sort -nr | head -n 10

HTTP 状态码反映了请求的成功与否以及错误类型。可以使用以下命令统计不同状态码的出现次数,该命令会输出不同状态码及其出现的次数,仅显示前 10 条记录:

1
awk '{print $9}' access.log | sort | uniq -c | sort -nr | head -n 10

开启 OpenResty 的 QUIC 支持

2024年11月20日 00:00

QUIC 是种基于 UDP 实现的传输层协议,由 Google 提出,旨在减少握手延迟,实现快速连接建立、多路复用、连接迁移功能。本教程分享如何在 OpenResty 开启 QUIC 支持。

准备工作

确保已经成功安装了 OpenResty。如果看到 OpenResty 的欢迎页面,说明安装成功。

OpenResty 通过集成 Nginx 并利用其模块化特性支持 QUIC。需要在 Nginx 配置文件中启用 QUIC 支持。通常涉及到配置监听 UDP 端口,因为 QUIC 运行在 UDP 上。

OpenResty 从 1.25 版本开始支持 QUIC,如果是之前的版本,需要自行编译安装模块以支持 QUIC。

使用支持 QUIC 的客户端工具测试 QUIC 连接是否成功建立。

监听端口

对于每个站点,需在 Nginx 配置文件中为 QUIC 配置监听端口。由于 QUIC 运行在 UDP 上,需为每个站点配置一个监听 UDP 端口的指令。例如,如果有两个站点 site1site2,可以这样配置:

1
2
3
4
5
server {
listen 443 quic reuseport;
server_name site1.dusays.com;
# site1 的其它配置...
}

这里的 443444 是用于 QUIC 的 UDP 端口,quic 指定 QUIC 协议,reuseport 是为了提高性能:

1
2
3
4
5
server {
listen 444 quic reuseport;
server_name site2.dusays.com;
# site2 的其它配置...
}

端口复用

如果在一台服务器包含多个网站,其中一个网站添加 reuseport 参数后,则其它网站无法再次添加 reuseport 参数:

1
2
3
4
5
server {
listen 443 quic reuseport;
server_name site1.dusays.com;
# site1 的 QUIC 加密和伪装配置...
}

多次添加 reuseport 参数会提示端口冲突,这时可以删除其中的 reuseport 参数,或者使用不同的 UDP 端口。例如:

1
2
3
4
5
server {
listen 443 quic;
server_name site2.dusays.com;
# site2 的 QUIC 加密和伪装配置...
}

测试连接

使用支持 QUIC 客户端工具测试每个站点的 QUIC 连接是否成功建立,这可以帮助验证服务器端的配置是否正确:

终端美化工具 X-CMD 安装与使用

2024年11月14日 00:00

X-CMD 是一款强大的终端美化和功能增强工具,它通过模块化设计和集成的包管理器,为用户提供丰富的功能和便捷的使用体验。无论是日常的命令行操作还是开发环境的搭建,X-CMD 都能提供有效的支持。

概述

X-CMD 是一款开源轻量级 POSIX 脚本工具,集成了 500+语言、工具,不需要 root 权限即可使用,提供了原生命令的增强以及现代化的命令行界面 TUI。

本文将详细介绍 X-CMD 安装、基本使用及一些专业术语和功能特性。

安装

X-CMD 支持在主流 POSIX shell 系统环境下运行,包括 bash/zsh 等。以下是在 Linux 系统的安装步骤,打开终端,输入以下命令之一来安装 X-CMD:

1
eval "$(curl https://get.x-cmd.com)"

或使用 wget,这将下载并执行 X-CMD 安装脚本,自动配置环境变量,使得 X-CMD 命令在任何新终端会话中可用:

1
eval "$(wget -O- https://get.x-cmd.com)"

使用

X-CMD 自带的包管理器 x pkg 可以快速安装并管理脚本引擎,例如 Node.js/Python 等。例如,安装并切换 Node.js 版本,使用下面命令安装并切换到指定版本的 Node.js:

1
2
x env use node=v20.11.1
node -v

支持快速执行代码,如 Python 和 Node.js,下面命令允许用户在不安装语言环境的情况下直接运行脚本:

1
2
x python -c 'print("hello x-cmd")'
x node -e 'console.log("hello x-cmd")'

示例

执行 x theme 后,可以预览每个主题在当前终端的显示情况:

增强版 ls 命令,可更方便地查看文件信息和系统信息:

查看进程,交互式查看 ps 数据:

该模块是使用 POSIX shell、awkfind 实现的增强版 cd 命令:

增强版 stat 命令,以 TUI 方式查看当前路径下所有文件的详细信息:

X-CMD 处理 PATH 变量,交互展示当前环境中 PATH 内二进制搜索目录:

增强型 docker 命令:

X-CMD 增强 git 命令:

PM2 安装与使用

2024年11月11日 00:00

在现代的软件开发和系统管理中,进程管理是一个不可或缺的部分。PM2 作为一个强大的进程管理工具,它可以帮助我们管理和保持应用在线状态,自动重启崩溃应用,并提供负载均衡等高级功能。

主要特点

  • 自动重启:应用崩溃时会自动重启。

  • 负载均衡:在多个实例间分配负载。

  • 集群模式:在所有的 CPU 核心上运行应用。

  • 日志管理:实时日志查看和日志持久化。

  • 监控:实时监控应用资源使用情况。

  • 远程管理:通过 API 或者仪表板远程管理应用。

PM2 的安装

PM2 可以通过 npm 命令轻松安装。如果系统暂未安装相关命令,则执行下面的命令「这里以 Ubuntu 系统为例」

1
sudo apt -y install npm

然后在命令行中运行以下命令即可安装 PM2:

1
npm install pm2 -g

PM2 的使用

要使用 PM2 启动一个应用,可使用 start 命令。例如,如果有一个名为 app.js 的 Node.js 应用,可以这样启动。PM2 会启动应用,并在后台运行:

1
pm2 start api.js

重新启动应用程序:

1
pm2 restart api

重新启动所有应用程序:

1
pm2 restart all

重新启动多个应用程序:

1
pm2 restart app1 app2 app3

停止指定应用程序:

1
pm2 stop api

停止所有:

1
pm2 stop all

删除应用程序:

1
pm2 delete api

删除全部:

1
pm2 delete all

使用 list 命令可以查看所有由 PM2 管理应用的状态,这将显示所有应用的 ID、名称、模式、内存使用情况信息:

1
pm2 list

PM2 提供了实时日志查看功能,使用 logs 命令将显示所有应用的实时日志流:

1
pm2 logs

使用下面命令可重启所有由 PM2 管理的进程,可实现零停机重启:

1
pm2 reload all

输入下面命令来保存当前的进程列表,确保在重启后自动加载这些进程:

1
pm2 save

使用下面命令设置开机自启:

1
pm2 startup

使用下面命令取消开机自启:

1
pm2 unstartup

PM2 的命令

PM2 提供了丰富的命令行工具,用于管理应用程序。以下是一些常用的命令:

命令描述
start启动一个应用程序
stop停止一个应用程序
restart重启一个应用程序
delete删除一个应用程序
list列出所有应用程序
monit监控应用程序
dump导出应用程序的配置
reload重新加载应用程序
sendSignal发送信号给应用程序
update更新应用程序

PM2 提供了一种监听应用程序资源使用情况简单方法。可以使用命令 pm2 monit 从终端轻松监听内存和 CPU:

FAST OS DOCKER 容器管理器的安装与使用

2024年6月20日 00:00

今天给小伙伴们分享一款来自于国人大佬开发的一款 Docker 的图形化管理工具,原生中文支持,拥有 Portainer 的大多功能,且界面更简洁好看,适合国人审美。

工具简介

FAST OS DOCKER 和 Portainer 差不多,是一款 Docker 的图形化管理工具。

可为用户提供总览、本地容器管理、远程镜像拉取、主机磁盘映射、服务器网络管理等功能,基本能满足中小型单位对容器管理的全部需求。

工具优点

无需复杂命令,全图形化操作,基本上只需要懂一点点的 Docker 常识就能轻松构建容器。

界面直观简洁,对应功能也是一目了然,那怕新手小白也能快速上手。

FAST OS DOCKER 的后端语言是 Go,前端框架是 Vue,且拥有全面的权限管理机制。

为防止服务器负载过高,进行底层性能优化,较适合 NAS 这种入门级服务器部署安装。且集成 Docker 镜像应用市场,可直接快速安装和部署。

安装步骤

连接服务器后,切换至 root 权限,运行如下命令:

1
2
3
4
docker run --name fastos \
--restart always -p 8081:8081 -p 8082:8082 -e TZ="Asia/Shanghai" -d \
-v /var/run/docker.sock:/var/run/docker.sock -v /etc/docker/:/etc/docker/ \
-v /root/data:/fast/data -e FAST_STORE=http://8.210.124.47:8080 wangbinxingkong/fast:latest

安装完成后在浏览器访问 http://IP:8081。首次登录需要注册,注册成功即可正常使用:

简易教程

主机 Docker 情况总览页,查看硬件配置,Docker 文件安装根目录,主机系统,容器数量,镜像数量,数据卷以及网络环境等配置:

可在镜像菜单处理镜像相关操作:

选择默认简单模式,输入镜像名可拉取镜像:

也可选择高级模式,输入 fromImage=php:7.3.5-fpm&fromSrc=daocloud.io/library/nginx:1.17.8 类似格式字符可拉取镜像:

或者选择搜索模式,搜索后再拉取:

进入数据卷菜单页,删除或添加数据卷:

进入网络菜单,设置网络,添加网络:

进入容器菜单,可实现对容器的增删查改等操作,还可查看日志,监控容器,控制台连接容器等:

进入登记菜单,可以登记第三方私人镜像库,登记后可拉取私人仓库镜像:

进入集群菜单,可连接其它服务器,操作其它服务器的容器,镜像:

DockerUI 容器管理器的安装与使用

2024年6月11日 00:00

本教程给大家带来 DockerUI 的部署方法,通过 DockerUI 我们可以很方便的创建高权限的 Docker 应用,或者随时将配置文件目录挂载到我们的容器中,再通过容器终端去修改配置文件,只要一直保留 DockerUI 不删除,则完全没有后顾之忧了。

介绍

DockerUI 是一个易于使用且轻量级的 docker 管理工具。通过 Web 界面的操作,它方便不熟悉 Docker 指令的用户更快地进入 Docker 世界。

DockerUI 具有易于使用的界面。它不需记住 Docker 指令。只需下载镜像即可完成部署。根据 Docker 的功能,镜像的版本可以直接在 DockerUI 中更新。使用相同设置,可通过重新部署和替换容器,且可以使用最新版本的功能。

DockerUI 覆盖了绝大多数命令功能。通过可视化操作功能在 DockerUI 接口中提供 Docker 环境和 Swarm 管理和维护功能,可以很容易地执行集群环境。

DockerUI 是用于 Docker 容器映像可视化图形管理工具。Dockerui 可用于轻松构建、管理并维护 Docker 环境。它是完全开源和免费的。基于容器安装方法,可实现方便高效的部署。

安装

启动容器「如本地无镜像,则会自动拉取」并映射 8999 端口:

1
docker container run --rm --name docker.ui -v /var/run/docker.sock:/var/run/docker.sock -p 8999:8999 joinsunsoft/docker.ui

容器启动后访问 http://localhost:8999 即可,默认用户名和密码为 dockerui

截图

主页:

镜像列表:

搜索存储库及拉取镜像:

构建镜像:

导出/导入镜像:

推送镜像:

启用映像:

容器列表:

Web 控制台:

容器文件系统:

容器统计:

列出容器进程:

从容器中导出文件:

网络管理:

Swarm 集群管理器:

创建服务:

任务管理:

任务列表:

注意

本教程绿联和群晖同样适用,但是 DockerUI 作者已经不再维护了,所以可以选择《Potainer 容器管理器的安装与使用

DockerUI 虽不再维护,但只是作为一个高权限 Docker 部署或者配置文件目录挂载使用的话已经绰绰有余了。

Potainer 容器管理器的安装与使用

2024年6月5日 00:00

Potainer 是一个轻量级容器管理器,它提供了一种简单而高效的方式来管理 Docker 容器。本篇教程简单介绍 Potainer 的特点、安装过程以及使用示例,如有问题欢迎在评论区留言!

工具特点

  1. 简单易用。Potainer 具有直观的用户界面,使得容器管理变得更加容易,即使对于没有 Docker 经验的用户也能快速上手;

  2. 快速部署。通过 Potainer 可快速部署新的容器,节省了时间和精力;

  3. 资源监控。它提供了对容器资源使用情况的监控,有助于更好地管理系统资源;

  4. 可视管理。Potainer 提供了可视化的界面,可以直观地查看容器的状态和日志等信息。

安装过程

首先,需要确保系统已经安装了 Docker。可通过以下命令来检查是否安装了 Docker。若未安装,可以参考《Docker 的安装》一文:

1
docker --version

接下来使用以下命令安装 Potainer:

1
docker pull potainer/potainer

安装完成后可以通过以下命令启动 Potainer:

1
docker run -d -p 9000:9000 --name potainer potainer/potainer

启动后可以在浏览器中访问下面链接来打开 Potainer 界面:

1
http://localhost:9000

使用示例

登录 Potainer 界面后,将看到一个容器的列表,显示了当前运行的容器。

要创建一个新容器,可点击 Create Container 按钮,填写相关信息,例如容器名称、镜像与端口映射等。

还可以查看容器的详细信息,包括日志和资源使用情况等。可点击相应的容器,在右侧面板中可查看其详细信息。

如需要停止或删除容器,只需点击相应操作按钮即可。

效果截图

登录后的效果如下:

强大的自托管 compose.yaml 管理工具 Dockge

2024年6月2日 00:00

Dockge 是 Uptime Kuma 作者新作品,故 UI 风格与 Uptime Kuma 基本一致。Dockge 主打的是简单易上手,与 Potainer 相比界面简洁易用,新手使用不会感到一头雾水。

优点

  1. 通过 Web 页面管理 compose.yaml 文件;

  2. 拉取等响应式操作输出都会实时显示;

  3. 可以将 docker run 命令转换为 compose.yaml 文件;

  4. 可直接存储 compose.yaml 文件,可使用常规 docker compose 命令进行操作。

缺点

  1. 与 Potainer 等相比功能没那么丰富,例如没有单独管理网络、镜像功能;

  2. 无法接管现有正在运行容器。

安装

创建用于存储堆栈与 Dockge 目录,并进入到目录:

1
2
mkdir -p /opt/stacks /opt/dockge
cd /opt/dockge

创建 compose.yaml 文件并填写如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
version: "3.8"
services:
dockge:
image: louislam/dockge:1
restart: unless-stopped
ports:
- 5001:5001
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data
- /opt/stacks:/opt/stacks
environment:
- DOCKGE_STACKS_DIR=/opt/stacks

根据实际需求修改上面内容,保存后执行下面的命令启动服务:

1
docker compose up -d

如果需要停止使用,可使用下面的命令:

1
docker compose down

截图

初次访问时需创建管理用户,登录后的效果如下:

基于 rsync+sersync 实现文件的同步备份

2024年5月21日 00:00

上一篇我们使用了 rsync+inotify 实现文件的实时同步,inotify 常用于监控目标文件变化。本篇教材说明如何通过 sersync 实现文件的同步备份,底层仍使用 rsync+inotify,优点是只对变化的目录数据操作,甚至是一个文件不同的部分进行同步。

工具介绍

rsync 是一个远程数据同步工具,可通过网络在不同的主机之间快速同步文件和目录。

sersync 是基于 rsync 开发的一款高性能的文件同步工具,它提供了更简单的配置和更好的性能。

部署思路

  1. 在需要进行同步的主机上安装 rsync

  2. 配置 rsync 服务器,在源主机配置 rsync 服务器,允许其它主机通过 rsync 连接并获取文件;

  3. 在目标主机安装 sersync

  4. 配置 sersync 指定源主机信息、要同步文件或目录、同步频率;

  5. 启动 sersync 服务使开始执行文件同步备份操作;

  6. 测试并调试相关的服务,具体的配置步骤可能因操作系统和实际需求而有所不同。

配置参考

以下是一个简单的示例,展示了基本的配置思路。源主机上 rsync 服务器配置:

1
2
3
4
5
6
7
8
9
10
11
# 编辑 rsync 主配置文件
vim /etc/rsyncd.conf
# 添加以下内容
[backup]
path = /path/to/backup/directory
read only = yes
list = yes
auth users = backup_user
secrets file = /path/to/rsync/secrets
# 设置密码
chmod 600 /path/to/rsync/secrets

目标主机上 sersync 配置:

1
2
3
4
5
6
7
8
9
10
# 编辑 sersync 主配置文件
vim /etc/sersync.conf
# 添加以下内容
[source]
rsync_server = server_ip:873
username = backup_user
password = password
remote_src = backup
[destination]
local_dir = /path/to/backup/destination

注意事项

请将上述示例中的路径和用户名、密码等根据实际的情况进行修改。然后启动 sersync 服务并确保其在后台运行。

这只是一个基本的示例,实际配置可能更加复杂,如设置过滤器、排除某些文件或着目录、处理冲突。此外还可使用定时任务或监控工具来自动执行同步操作,并根据需要进行错误处理和日志记录。

在配置和使用 rsync+sersync 进行文件同步备份时,务必仔细阅读相关文档、教程,并根据具体需求进行适当调整和优化。

同时确保网络连接稳定,合理安排同步时间,以避免对业务系统造成影响。如果可能,还可以进行测试和备份恢复演练,以确保备份可靠性和有效性。

基于 rsync+inotifywait 实现文件的实时同步

2024年5月18日 00:00

之前有透露过,杜老师的去不图床使用三点备份,除本地备份外,还有内网存储备份,以及云上备份。而内网存储备份是通过 rsync 实现的,同步周期为每半个小时。近期打算配合 inotifywait 实现文件的实时同步!

工具介绍

rsync 是一个用于文件同步和备份的工具,inotifywait 是一种文件系统事件通知机制。

通过结合用 rsyncinotifywait,可实现文件的实时同步。

工具安装

安装 rsync 软件包:

1
sudo apt -y install rsync

安装 inotify-tools 软件包:

1
sudo apt -y install inotify-tools

服务配置

在源服务器上,创建一个 rsync 的配置文件,如/etc/rsyncd.conf,指定要同步的文件或目录及其它相关设置。

安装并配置 inotifywait,确保 inotifywait 模块已加载。使用 inotifywait 命令监视源目录事件。

编写同步脚本,使用 inotifywait 输出触发 rsync 命令,将更改的文件同步到目标服务器。

设置定时任务或者守护进程,使用 cron 或其它合适的工具定期执行同步脚本以实现实时同步。

示例脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
# 定义源目录和目标目录
SRC_DIR=/path/to/source
DEST_DIR=/path/to/destination
# rsync 的命令
RSYNC_CMD="rsync -avz --delete $SRC_DIR $DEST_DIR"
# inotifywait 的命令
INotify_CMD="inotifywait -mre modify,create,delete,move $SRC_DIR"
# 主题循环
while true; do
# 执行 inotifywait 并捕获输出
output="$(eval $INotify_CMD)"
# 如有事件发生
if [ -n "$output" ]; then
# 则执行 rsync 进行同步
echo "Syncing files..."
eval $RSYNC_CMD
fi
# 等待一段时间(例如 1 秒)
sleep 1
done

注意:这只是一个简要的概述,实际实现可能会因具体需求和环境而有所不同。在这个示例中,inotifywait 命令监视源目录修改、创建、删除、移动事件。当事件发生时,rsync 命令会执行,将源目录中的更改同步到目标目录中。

Windows 更新时出现的错误代码 0x80070643 解决方案

2024年5月3日 00:00

本文介绍如何解决 Windows 更新时出现的错误代码 0x80070643,原因是 WinRE 恢复环境空间不足。先通过进入命令提示符,禁用掉 WinRE,调整磁盘管理工具,扩展 C 盘空间并创建新的 WinRE 分区,最终重启 WinRE 并完成系统更新。

问题截图

如果最近更新 Windows 时,在安装的状态卡了一会,随后报错,并显示错误代码 0x80070643:

首先明确故障来源,错误代码 0x80070643 对应的是系统的 WinRE 恢复盘分区容量不足。这个 RE 盘在资源管理器中是看不到的,可通过磁盘管理器查看它的分区容量。我们可以通过右键点击开始——磁盘管理看到如下界面。可以看到恢复分区不足 750 兆,需要对其扩容:

压缩分区

通过上面截图可以看出,恢复分区的临近分区是 C 盘,我们接下来要从 C 盘中,获取一定的空间给恢复分区。首先要进入命令提示符界面,在搜索框中输入 cmd,右键点击命令提示符并在弹出菜单中选择以管理员身份运行:

打开命令提示符界面后,我们将 WinRE 恢复功能临时禁用,便于后续分区修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
C:\Users\Administrator>reagentc /info
Windows 恢复环境(Windows RE)和系统初始化配置
信息:

Windows RE 状态: Enabled
Windows RE 位置: \\?\GLOBALROOT\device\harddisk0\partition4\Recovery\WindowsRE
引导配置数据(BCD)标识符: c9a5b046-496f-11ec-b9e7-ed5c24c96968
恢复映像位置:
恢复映像索引: 0
自定义映像位置:
自定义映像索引: 0

REAGENTC.EXE: 操作成功。


C:\Users\Administrator>reagentc /disable
REAGENTC.EXE: 操作成功。

开启磁盘管理工具,进入目标磁盘 C 盘。接下来输入 list disk,先检查下磁盘列表,确定我们要进入的是磁盘 0,则输入 sel disk 0。接下来检查磁盘 0 的分区列表输入 list partition。找到 C 盘对应分区号 3 后输入 sel part 3。使用 shrink desired=200 minimum=200 命令从目标分区切出 200 兆容量备用:

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
C:\Users\Administrator>diskpart

Microsoft DiskPart 版本 10.0.20348.1

Copyright (C) Microsoft Corporation.
在计算机上: WIN-B1NQBKNC2UU

DISKPART> list disk

磁盘 ### 状态 大小 可用 Dyn Gpt
-------- ------------- ------- ------- --- ---
磁盘 0 联机 60 GB 1024 KB *

DISKPART> sel disk 0

磁盘 0 现在是所选磁盘。

DISKPART> list partition

分区 ### 类型 大小 偏移量
------------- ---------------- ------- -------
分区 1 系统 100 MB 1024 KB
分区 2 已保留 16 MB 101 MB
分区 3 主要 59 GB 117 MB
分区 4 恢复 616 MB 59 GB

DISKPART> sel part 3

分区 3 现在是所选分区。

DISKPART> shrink desired=200 minimum=200

DiskPart 成功收缩卷: 200 MB

可再次进入到磁盘管理器中查看是否分离成功:

扩容分区

删除原有恢复分区。通过上面操作,我们可以确定恢复分区编号为 4,输入 sel part 4 选择并输入 delete partition override 删除该分区:

1
2
3
4
5
6
7
DISKPART> sel part 4

分区 4 现在是所选分区。

DISKPART> delete partition override

DiskPart 成功地删除了所选分区。

回到磁盘管理页面核对是否删除成功:

右键未分配的分区,选择新建分区,在创建过程中选择不分配分区号:

并指定分区名为 Windows RE Tools

完成更新

回到命令提示符中输入 reagentc /enable 重启 WinRE,输入 reagentc /info 确认 WinRE 启用成功:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
C:\Users\Administrator>reagentc /enable
REAGENTC.EXE: 操作成功。


C:\Users\Administrator>reagentc /info
Windows 恢复环境(Windows RE)和系统初始化配置
信息:

Windows RE 状态: Enabled
Windows RE 位置: \\?\GLOBALROOT\device\harddisk0\partition3\Recovery\WindowsRE
引导配置数据(BCD)标识符: c9a5b048-496f-11ec-b9e7-ed5c24c96968
恢复映像位置:
恢复映像索引: 0
自定义映像位置:
自定义映像索引: 0

REAGENTC.EXE: 操作成功。

接下来回到 Windows 更新界面,重新安装补丁,这次没有报错,很快就完成了升级:

Linux 中挂载 WebDAV 的详细教程

2024年4月30日 00:00

应 Python_Ryan 小伙伴的需求,更新一篇 Linux 中挂载 WebDAV 的详细教程。另外杜老师目前在延吉旅游,行程较满,近期更新暂缓,且评论也是抽空回复的。如有任何问题可以留言,杜老师看到后会尽快回复处理的!

操作步骤

确保已经安装必要的软件包。这里以 Ubuntu 系统为例,可以使用以下命令安装 davfs2 软件包,该软件包用于挂载 WebDAV 的资源:

1
sudo apt install davfs2

创建 WebDAV 挂载点。选择一个目录作为 WebDAV 资源挂载点。例如,如果要将 WebDAV 挂载到/mnt/webdav 目录中,可使用以下命令创建该目录:

1
sudo mkdir /mnt/webdav

挂载资源。使用以下的命令挂载 WebDAV 资源。将 URL 替换为 WebDAV 服务器 URL:

1
sudo mount -t davfs https://URL /mnt/webdav

验证挂载。完成挂载,可以使用以下命令检查挂载是否成功:

1
df -h | grep webdav

挂载选项

设置挂载选项。可以根据需要设置一些挂载选项,如果 WebDAV 服务器需要身份验证,可以使用-o user=username-o pass=password 选项来提供用户名和密码。例如:

1
sudo mount -t davfs https://URL /mnt/webdav -o user=yourusername -o pass=yourpassword

默认情况下挂载 WebDAV 资源可能只有读取权限。如果需要写入权限,可使用-o rw 选项。例如:

1
sudo mount -t davfs https://URL /mnt/webdav -o rw

自动挂载

如希望在系统启动时自动挂载 WebDAV 资源,可以将挂载命令添加到/etc/fstab 文件中。使用下面的命令编辑/etc/fstab 文件:

1
sudo vim /etc/fstab

在文件的末尾添加以下行的内容。注意将 URL/mnt/webdav 等替换为实际值:

1
https://URL /mnt/webdav davfs rw,noauto,user=yourusername,pass=yourpassword 0 0

注意事项

本教材中使用 HTTPS 协议挂载 WebDAV 资源,但 WebDAV 服务器可能并不支持 HTTPS。可以通过 Nginx 或其它代理服务器将 WebDAV 服务器转换为 HTTPS 协议。反代服务配置参考:

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
location ^~ /
{
proxy_pass http://URL;
proxy_set_header Host DOMAIN;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_ssl_server_name on;
proxy_http_version 1.1;
# proxy_hide_header Upgrade;

add_header X-Cache $upstream_cache_status;
#Set Nginx Cache



if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
{
expires 1m;
}
proxy_ignore_headers Set-Cookie Cache-Control expires;
proxy_cache cache_one;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 304 301 302 60m;
}

在测试时遇到上传大文件失败的问题,可以调整 Nginx 主配置文件中的 client_max_body_sizekeepalive_timeout 值:

1
2
client_max_body_size 50m;
keepalive_timeout 60;

一台服务器最大能支持多少条 TCP 连接

2024年2月15日 00:00

这段时间频繁出现图床无法访问,之前为了防护攻击,杜老师选购了高防的服务器,奈何除流量攻击外,还有连接数的攻击形式。而杜老师为了保障服务稳定,将连接数设置较低。本篇文章就简单说明下一台服务器最大能支持多少条 TCP 连接。

一台服务器最大能打开的文件数

我们知道在 Linux 中一切皆文件,那么一台服务器最大能打开多少个文件呢?Linux 上能打开最大文件数量受三个参数影响,分别是 fs.file-max/soft nofile/fs.nr_open。

fs.file-max 参数描述了整个系统可以打开最大文件数量。但是 root 用户不会受该参数的限制。

soft nofile 限制单个进程上可以打开的最大文件数。不能针对不同用户配置不同的值。

fs.nr_open 限制单个进程上可以打开的最大文件数。可以针对不同用户配置不同的值。

如果想加大 soft nofile,那么 hard nofile 参数值也需一起调整。如果因为 hard nofile 参数值设置的低,那么 soft nofile 参数的值设置的再高也没有用,实际生效的值会按照二者最低来。

如果增大了 hard nofile,那么 fs.nr_open 也需要跟着一起调整。如果不小心把 hard nofile 的值设置的比 fs.nr_open 还大,那么后果比较严重。会导致该用户无法登录。

一台服务器最大能支持多少连接

我们知道 TCP 连接从根本上看其实就是客户端和服务端在内存中维护的一组内核对象,它们只要能够找到对方,那就算是一条连接。那么一台服务器最大能建立多少条连接呢?

从理论上应该是约等于两百多万亿条连接。

但是实际上由于受其它软硬件的影响,我们一台服务器不可能能建立这么多连接。

如果只以已连接状态的连接来算,那么一台服务器最大可以建立多少连接呢?以一台 4G 内存的服务器为例!

我们知道一条已连接状态的连接大约消耗 3.3K 的内存,那么通过计算可得知一台 4G 内存的服务器,可以建立百万个 TCP 连接。

上面讨论的都是建立连接的理想情况,在现实中如果有频繁的数据收发,那么一台服务器能支撑 1000 连接都算好的了,所以一台服务器能支撑多少连接还要结合具体的场景去分析。抛开业务逻辑单纯的谈并发没有太大实际意义。

一台客户端机器最多能发起多少连接

我们知道客户端每和服务端建立一个连接便会消耗掉客户端一个端口。一台机器端口数量是 65535,那么是不是说一台客户机最多和一台服务端机器建立 65535 个连接呢?

由 TCP 连接的四元组特性可知,只要四元组里某个元素不同,那就认为这是不同的 TCP 连接。

如果一台客户端仅有一个 IP,服务端也仅有一个 IP 并且仅启动一个程序,监听一个端口的情况下,客户端和这台服务端最大可建立连接条数就是 65535 个。

如一台客户端有多个 IP,服务端仅有一个 IP 并仅启动一个程序,监听一个端口的情况下,一台客户端机器最大能建立的连接条数是 n*65535 个。

如果一台客户端仅有一个 IP,服务端也仅有一个 IP 但是服务端启动多个程序,每个程序监听一个端口的情况下,一台客户端机器最大能建立的连接数量为 65535*m 个

所以,不光是一台服务端可以接收百万个 TCP 连接,一台客户端照样能发出百万个 TCP 连接。

优化 TCP 连接数策略

在网络开发中,很多人对一个基础的问题始终没有彻底搞明白,那就是一台机器最多能支撑多少条 TCP 连接。不过由于客户端和服务端对端口使用方式不同,这个问题拆开来理解要容易一些。

注意,这里说的客户端和服务端都只是角色,并不是指某一台具体的机器。如对于我们自己开发的应用程序来说,当它响应客户端请求的时候,它就是服务端。当向 MySQL 请求数据的时候,它又变成了客户端。

增加服务器的内存可以支持更多的 TCP 连接。

优化 CPU 调度可以提高服务器性能,从而支持更多的 TCP 连接。

通过修改系统的文件描述符限制,可以提高服务器支持的 TCP 连接数。

优化网络配置可以提高服务器网络带宽,从而支持更多的 TCP 连接。

云主机的控制面板选择推荐

2024年1月19日 00:00

多年运营网站,接触了很多的控制面板,有国内有国外、有免费有收费。上篇文中有小伙伴留言询问,推荐用宝塔还是 1Panel,今天简单推荐一下。非专业性测评,仅供参考~

写在前面

杜老师从 03 年开始接触网站搭建,最开始的站点运营在 SaaS 上面「类似于 QQ 空间」

随着对网站了解的深入,再加上 SaaS 平台限制,开始通过虚拟主机等网络资源搭建各类的站点。

直到 09 年杜老师迈入了大学生活,充足的零花钱能够支援起 VPS,于是开始接触各类控制面板。

因为之前适用虚拟主机关系,最开始接触的面板是 cPanel,这是一款国外收费面板,杜老师用的是破解版本,其功能还是非常强大的,可惜占用资源过高「买不起高配 VPS」加上破解版担心数据安全性,于是在网络中寻找各类控制面板。

恰好在大学时有 Linux 相关课程,很长一段时间都是自行部署环境「类似于 LNMP」

那会正好创办了一个工作室,负责学校周边企业网站搭建项目,纯命令的操作界面增加了运维的成本「客户和部分工作室组员不会操作」于是决定通过安装控制面板解决操作问题。

先后接触面板有 wdCP/Easypanel/VestaCP/AMH/AppNode/宝塔/1Panel「还有一些面板记不清了」

到目前为止杜老师所有服务器上,仅在使用宝塔、1Panel 这两款控制面板,恰好有小伙伴问到,在这里就推荐一下,如何选择~

宝塔面板

其实宝塔没什么好说的,几乎新接触面板的小伙伴们,都会第一时间选择宝塔,其在国内主机行业的普及率,几乎宣告了其地位。具备模块化的功能,满足网站搭建所有要求,只是插件收费机制,劝退了一些白嫖客,还好本身免费功能,就足以满足网站的运营需求:

宝塔有 Windows/Linux 双平台的面板,不管什么系统都能运行,且支持 ARM 架构。网站相关服务软件版本齐全,简单配置即可上线站点。该夸的都夸了,下面说说它的缺点,其实也不算是缺点。首先是插件收费的问题,当然有些小伙伴会通过和谐手段跳过收费,但还是不可避免的要求在线验证「使用面板前要登录账号」

1Panel 容器化

1Panel 是去年「2023 年」三月份出现的面板,当时杜老师还是在公众号中看到有关它的介绍,第一时间就被这种清新的界面风格吸引了「主要是被宝塔界面审美疲劳」本着尝鲜精神第一时间购买了服务器,安装了 1Panel。可惜的是刚推出的版本功能不太完善,面板运行不太稳定,所以没用多久,杜老师就放弃了使用 1Panel。后来关于 1Panel 的推荐文越来越多了,杜老师想着更新迭代了如此多的版本,功能和稳定性上应该会比较完善。再次体验之后确实没有让杜老师失望,足以在生产环境中使用:

1Panel 使用 Docker 部署各种服务,并且打包了非常多工具。如 WP、Typecho 等,都可一键部署。这就使得每个服务都是独立运行、互不干扰,且更新迭代非常的方便。相比宝塔需要部署各种运行环境、上传代码、各种调试,1Panel 仅需要选择指定应用进行安装即可。总的来说,Docker 真香客墙裂推荐使用这款面板:

CPU 调频模式和中断设置

2023年11月11日 00:00

随着计算机技术的发展,CPU 性能和功能也在不断提升。为了更好地满足各种应用场景的需求,现代 CPU 提供多种调频模式和中断设置。本文将探讨 CPU 调频模式和中断设置的原理、应用场景及如何合理设置以实现性能和功耗的平衡。

话题背景

本不知道今天写点啥好,在聊天室和小伙伴们交流时,obaby 美女说准备换一个路由器,原因是 CPU 使用率比较高。之前有聊过建立内网服务器事项,obaby 就是通过 CDN 反代家中的服务器,当访问量比较大时,就会出现 CPU 使用率比较高的问题:

相比 obaby 的私人博客,杜老师自信去不图床的访问量更大些,就准备调试下家中核心路由的 CPU 性能,尽可能的提升路由效率。先说下杜老师家中核心路由配置,N6000 处理器 4G 的内存,运行 iKuai 免费版。调试时发现有五种模式,这几个模式有什么区别,又该如何选择,下面详细说明:

调频模式

针对上图中出现的名词解释如下:

名称作用解释
performance性能模式这个模式系统会按设定最大主频率满负荷运转,主频会一直保持在设定范围内最大值。
conservative平滑调整模式在此模式下系统会回设置较低的频率下降响应参数,主频在空闲时下降更快,更加节能,但 CPU 速度调整会相对慢。
powersave省电模式此模式下系统将保持在设定最小的频率低负荷运行。
ondemand快速调整模式这个模式一般是系统的默认模式,根据需要自动调节 CPU 的频率,此模式的特点是频率升高需条件触发,反应迅速,频率下降无需触发,不需要高频率时会自动渐渐下降。
schedutil调度模式更快的响应速度和更精准的调频,更加节能。

中断控制

什么是硬中断:外围硬件发给 CPU 或者内存的异步信号就称为硬中断;

什么是软中断:由软件系统本身发给操作系统内核的中断信号,称之为软中断。通常是由硬中断处理程序或进程调度程序对操作系统内核的中断,也就是我们常说的系统调用。

区别联系

  1. 硬中断是有外设硬件发出的,需要有中断控制器参与。过程是外设侦测到变化,后告知中断控制器,中断控制器通过 CPU 或内存的中断脚通知 CPU,然后硬件进行程序计数器及堆栈寄存器之现场保存工作,并根据中断向量调用硬中断处理程序进行中断处理;

  2. 软中断则通常是由硬中断处理程序或进程调度程序等软件程序发出的中断信号,无需中断控制器之参与,直接以一个 CPU 指令之形式指示 CPU 进行程序计数器及堆栈寄存器之现场保存工作,并调用相应软中断处理程序进行中断处理;

  3. 硬中断直接以硬件方式引发,处理速度较快。软中断以软件指令之方式适合于对响应速度要求不是特别严格的场景;

  4. 硬中断通过设置 CPU 屏蔽位可进行屏蔽,软中断则由于是指令之方式给出,不能屏蔽;

  5. 硬中断发生后,通常会在硬中断处理程序中调用一个软中断来进行后续工作处理;

  6. 硬中断和软中断均会引起上下文切换,进程切换的过程是差不多的。

中断效果

关闭软中断后效果:CPU 不使用系统调用,硬中断处理时,CPU 负载不均衡。

关闭硬中断后效果:关闭硬中断后硬件 CPU 会默认保留一个,关掉硬中断后,软中断全部开启负载让 CPU 起到了一个均衡作用,CPU 使用率比较平均。

注意事项

软中断和硬中断不可以同时关闭。即使界面显示全部关闭,也会保留一个默认的核心作为硬中断。

在某个 CPU 使用率较高的时候,可将这个 CPU 软中断关闭,这样使其 CPU 使用率降低,负荷负载到其它的 CPU 核心上。

自建 CDN 服务器思路

2023年11月5日 00:00

有小伙伴希望杜老师出一篇自建 CDN 的教程,其实网上有那种集成的系统,如 wdCDN。不过这类系统几乎都有节点限制,如果想搭建更多的节点,则需支付相应费用。对此杜老师有一套自用的 CDN 搭建思路,今天同需要的小伙伴分享下!

搭建思路

如图。当用户访问去不图床时,首先通过网络解析域名。杜老师购买了专业版 DNSPod,可以通过地域判断实现智能解析,将请求交给最近一台服务器处理。服务器前置了雷池 Web 应用防火墙,拦截一波攻击流量,正常流量留置反代服务器上。反代节点连接到内穿服务器,从中获得网站数据。而去不图床通过企业路由器内置模块架设内网穿透,以保障连接稳定及高效。因为绘制空间有限,在这里文字说明下,去不图床有 7 个反代服务器,相当于同数量的 CDN 节点。相比常规 CDN 内置 DNS 智能解析,杜老师则借助了 DNSPod「DNSPod 免费版也可实现智能解析,只是地域判断不够精细」

宝塔面板

如您使用宝塔面板,在搭建反代节点时,可先点击网站——添加站点,输入域名后点提交。进入站点设置——反向代理,如下图填写相关的信息即可。这里需要注意的是,为了实现类似 CDN 的加速功能,记得开启缓存,时间根据实际情况填写即可:

1Panel 服务器面板

如您使用 1Panel 服务器面板,在搭建反代节点时,可先点击网站——创建站点——反向代理,输入域名后点提交。进入站点配置页面——反向代理——编辑,如下图填写相关的信息即可。这里需要注意的是,1Panel 服务器面板默认支持 gif|png|jpg|css|js|woff|woff2 格式的缓存,如需缓存其它文件,还需自行修改配置文件:

雷池 Web 应用防火墙

雷池 Web 应用防火墙除可以反代外,还能防御攻击。但本身的特性使得无法缓存数据,即每次访问时都需回源请求数据,故无法实现类似于 CDN 的缓存加速功能。杜老师用其做前置,主要过滤攻击数据,防止无效流量消耗,变相提升了带宽使用率。其防御效果很不错,建议配合其它服务「带有缓存功能」一并使用,如 Nginx Proxy Manager:

南墙 Web 应用防火墙

也是机缘巧合接触到了南墙 Web 应用防火墙,精力有限还未与雷池 Web 应用防火墙做对比,但其内置 CDN 缓存功能很好用,并支持多节点回源、定义回源策略等等。需要注意的是,在添加站点时开启 CDN 后,还需进入 CDN 加速页面中,添加缓存规则,默认支持 jpg|png|bmp|gif|ico|css|js 格式的缓存:

DNSPod 免费智能 DNS 解析

DNSPod 专业版支持 10 个负载均衡节点「免费版仅 2 个」TTL 最小值 60 秒,可在单点故障时迅速切换至其它可用节点。并且可以使用更加精细的地域性智能解析:

frp 关于 HTTP 和 HTTPS 设置

2023年8月15日 00:00

HTTP 和 HTTPS 是 frp 中针对这两种协议额外提供了一些特殊能力。本质上目前这两种应用层协议底层协议都是 TCP。如果不需要用到相关的特殊功能,可以直接使用 TCP 类型的代理,更加简单方便。

修改 HTTP 请求 Header

通常情况下 frp 不会修改转发任何数据。但有一些后端服务会根据 HTTP 请求 Header 中的 Host 字段来展现不同的网站,例如 Nginx 的虚拟主机服务,启用 Host Header 的修改功能可以动态修改 HTTP 请求中的 Host 字段。需要注意的是,该功能仅限于 HTTP 类型的代理。原来 HTTP 请求中的 Host 字段 test.dusays.com 转发到后端服务时被替换为 dev.dusays.com,frpc.ini 的配置如下:

1
2
3
4
5
[web]
type = http
local_port = 80
custom_domains = test.dusays.com
host_header_rewrite = dev.dusays.com

对于参数配置中所有以 header_开头的参数「支持同时配置多个」都会被添加到 HTTP 请求的 Header 中,根据如下配置,会在请求的 Header 中加上 X-From-Where: frp。frpc.ini 的配置如下:

1
2
3
4
5
6
[web]
type = http
local_port = 80
custom_domains = test.dusays.com
host_header_rewrite = dev.dusays.com
header_X-From-Where = frp

通过设置 Basic Auth 来鉴权

1
2
3
4
5
6
[web]
type = http
local_port = 80
custom_domains = test.dusays.com
http_user = abc
http_pwd = abc

注意:由于所有客户端共用一个 frps 的 HTTP 服务端口,任何知道域名和 URL 的人都能访问到内网的服务,但是在某些场景下需要确保只有限定的用户才可以访问。frp 支持通过 Basic Auth 保护 Web 服务,使用户需要通过用户名和密码才能访问到服务。该功能目前仅限于 HTTP 类型的代理,需要在 frpc 的代理配置中添加用户名和密码设置。通过浏览器访问 http://test.dusays.com,需要输入配置的用户名和密码才可以访问。frpc.ini 的配置如上。

自定义二级域名来访问

通过在 frps 配置文件中配置 subdomain_host,就可以启用该特性。之后在 frpc 的 http 类型的代理中可以不配置 custom_domains,仅需要配置一个 subdomain 参数。只需要将*.dusays.com 解析到 frps 所在服务器。之后用户可通过 subdomain 自行指定自己的 web 服务所需要使用的二级域名。frps.ini 的配置如下:

1
2
[common]
subdomain_host = dusays.com

将泛域名*.dusays.com 解析到 frps 所在服务器的 IP 地址。frps 和 frpc 启动成功后,通过 test.dusays.com 就可访问到内网的 Web 服务。frpc.ini 的配置如下:

1
2
3
4
[web]
type = http
local_port = 80
subdomain = test

路由

1
2
3
4
5
6
7
8
9
10
11
[web01]
type = http
local_port = 80
custom_domains = web.dusays.com
locations = /

[web02]
type = http
local_port = 81
custom_domains = web.dusays.com
locations = /news,/about

注意:frp 支持根据请求的 URL 路径路由转发到不同后端服务。通过配置文件中的 locations 字段指定一个或者多个 Proxy 能够匹配的 URL 前缀。如指定 locations = /news,则所有 URL 以/news 开头的请求都会转发到这个服务。按照上述的示例配置后,web.dusays.com 这个域名下所有以/news 以及/about 作为前缀的 URL 请求都会被转发到 web02,其余的请求被转发到 web01。frpc.ini 的配置如上。

frp 多场景使用示例

2023年8月12日 00:00

发现很多小伙伴对 frp 感兴趣,但不知道如何使用,杜老师为小伙伴们分享一些示例。这里包括多个常见的使用场景和配置示例,小伙伴们可用来亲自部署和体验这些示例。

通过 SSH 来访问内网机器

这个示例通过简单配置 TCP 类型的代理让用户访问到内网的服务器。在具有公网 IP 机器上部署 frps,并修改 frps.ini 文件「这里使用了最简化配置」设置 frp 服务器用户接收客户端连接的端口:

1
2
[common]
bind_port = 7000

在需被访问的内网机器上部署 frpc,并修改 frpc.ini 文件,假设 frps 所在服务器的公网 IP 为 x.x.x.xlocal_iplocal_port 配置为本地需暴露到公网的服务地址和端口。remote_port 表示在 frp 服务端监听端口,访问此端口的流量将会被转发到本地服务对应端口:

1
2
3
4
5
6
7
8
9
[common]
server_addr = x.x.x.x
server_port = 7000

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

多个 SSH 服务复用同一个端口

这个示例通过 tcpmux 类型的代理,实现多个 SSH 服务通过同一个端口暴露。与此类似,只要是能够支持 HTTP 代理连接方式的客户端,都可以通过这种方式来实现对端口的复用。在具有公网 IP 机器上部署 frps,并修改 frps.ini 文件「这里使用最简化的配置」

1
2
3
[common]
bind_port = 7000
tcpmux_httpconnect_port = 5002

在内网机器 A 上部署 frpc,配置文件:

1
2
3
4
5
6
7
8
9
10
[common]
server_addr = x.x.x.x
server_port = 7000

[ssh1]
type = tcpmux
multiplexer = httpconnect
custom_domains = machine-a.example.com
local_ip = 127.0.0.1
local_port = 22

在内网机器 B 上部署另外一个 frpc,配置文件:

1
2
3
4
5
6
7
8
9
10
[common]
server_addr = x.x.x.x
server_port = 7000

[ssh2]
type = tcpmux
multiplexer = httpconnect
custom_domains = machine-b.example.com
local_ip = 127.0.0.1
local_port = 22

通过 SSH 访问内网机器 A,假设用户名 test:

1
ssh -o 'proxycommand socat - PROXY:x.x.x.x:machine-a.example.com:22,proxyport=5002' test@machine-a

通过自定义域名访问内网 Web 服务

这个示例通过简单配置 HTTP 类型的代理让用户访问到内网的 Web 服务。HTTP 类型的代理相比于 TCP 类型,不仅在服务端只需要监听一个额外的端口 vhost_http_port 用于接收 HTTP 请求,还额外提供了基于 HTTP 协议的诸多功能。按照下面的代码修改 frps.ini 文件,设置监听 HTTP 请求的端口为 8080

1
2
3
[common]
bind_port = 7000
vhost_http_port = 8080

按照下面的代码修改 frpc.ini 文件,假设 frps 所在服务器的 IP 为 x.x.x.xlocal_port 为本地机器上 Web 服务监听端口,绑定的自定义域名为 custom_domains

1
2
3
4
5
6
7
8
9
10
11
12
13
[common]
server_addr = x.x.x.x
server_port = 7000

[web]
type = http
local_port = 80
custom_domains = www.yourdomain.com

[web2]
type = http
local_port = 8080
custom_domains = www.yourdomain2.com

转发 DNS 的查询请求

这个示例通过简单配置 UDP 类型代理转发 DNS 查询请求。DNS 查询请求通常使用 UDP 协议,frp 支持对内网 UDP 服务的穿透,配置方式和 TCP 基本一致。frps.ini 的内容如下:

1
2
[common]
bind_port = 7000

frpc.ini 的内容如下:

1
2
3
4
5
6
7
8
9
[common]
server_addr = x.x.x.x
server_port = 7000

[dns]
type = udp
local_ip = 8.8.8.8
local_port = 53
remote_port = 6000

转发 Unix 的域套接字

这个示例通过配置 Unix 域套接字客户端插件来通过 TCP 端口访问内网的 Unix 域套接字服务,如 Docker Daemon。frps.ini 的内容如下:

1
2
[common]
bind_port = 7000

frpc.ini 的内容如下:

1
2
3
4
5
6
7
8
9
[common]
server_addr = x.x.x.x
server_port = 7000

[unix_domain_socket]
type = tcp
remote_port = 6000
plugin = unix_domain_socket
plugin_unix_path = /var/run/docker.sock

对外提供简单文件访问服务

这个示例通过配置 static_file 客户端插件来将本地文件暴露在公网上供其他人访问。通过 static_file 插件可以对外提供一个简单的基于 HTTP 的文件访问服务。frps.ini 的内容如下:

1
2
[common]
bind_port = 7000

frpc.ini 的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[common]
server_addr = x.x.x.x
server_port = 7000

[test_static_file]
type = tcp
remote_port = 6000
plugin = static_file
# 要对外暴露的文件目录
plugin_local_path = /tmp/file
# 用户访问 URL 会被去除的前缀,保留内容即为要访问的文件路径
plugin_strip_prefix = static
plugin_http_user = abc
plugin_http_passwd = abc

安全暴露内网服务

这个示例将会创建一个只有自己能访问到的 SSH 服务代理。对于某些服务来说如果直接暴露于公网上将会存在安全隐患。使用 stcp 类型的代理可以避免让任何人都能访问到穿透的服务,但是访问者也需要运行另外一个 frpc 客户端。frps.ini 的内容如下:

1
2
[common]
bind_port = 7000

在需要暴露到外网的机器上部署 frpc 且配置如下:

1
2
3
4
5
6
7
8
9
10
[common]
server_addr = x.x.x.x
server_port = 7000

[secret_ssh]
type = stcp
# 只有 sk 一致的用户才能访问到此服务
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22

在想要访问内网服务的机器上也部署 frpc 且配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[common]
server_addr = x.x.x.x
server_port = 7000

[secret_ssh_visitor]
type = stcp
# stcp 访问者
role = visitor
# 要访问的 stcp 代理的名字
server_name = secret_ssh
sk = abcdefg
# 绑定本地的端口用于访问 SSH 服务
bind_addr = 127.0.0.1
bind_port = 6000

通过 SSH 来访问内网机器,假设用户名 test

1
ssh -oPort=6000 test@127.0.0.1

点对点的内网穿透

这个示例将会演示一种不通过服务器中转流量的方式来访问内网服务。frp 提供了一种新的代理类型 xtcp 用于应对在希望传输大量数据且流量不经过服务器的场景。在需要暴露到外网的机器上部署 frpc 且配置如下:

1
2
3
4
5
6
7
8
9
10
[common]
server_addr = x.x.x.x
server_port = 7000

[p2p_ssh]
type = xtcp
# 只有 sk 一致的用户才能访问到此服务
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22

在想要访问内网服务的机器上也部署 frpc 且配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[common]
server_addr = x.x.x.x
server_port = 7000

[p2p_ssh_visitor]
type = xtcp
# xtcp 访问者
role = visitor
# 要访问的 xtcp 代理的名字
server_name = p2p_ssh
sk = abcdefg
# 绑定本地的端口用于访问 SSH 服务
bind_addr = 127.0.0.1
bind_port = 6000
# 当需要自动保持隧道打开时,设置为 true
# keep_tunnel_open = false

frp 概念及通用功能

2023年8月9日 00:00

很多小伙伴询问 frp 原理,文本简单解释一下。在 frp 中一个代理对应一个需要暴露的内网服务。一个客户端可同时配置多个代理。一些概念,理解它们有助于小伙伴们更好地了解和使用 frp。

原理

frp 是由客户端和服务端组成,服务端通常部署在有公网 IP 的机器上,客户端通常部署在需穿透的内网服务所在的机器上。

内网服务器由于没有公网 IP,不能被非局域网内其他用户访问。

用户通过访问服务端 frps,由 frp 负责根据请求端口或其它信息将请求路由到对应的内网机器,从而实现通信。

通过内网穿透技术,可使内网设备即便没有公网 IP 及端口,也可被公网的用户访问。

类型

frp 支持多种代理类型来适配不同使用场景:

类型描述
tcp单纯的 TCP 端口映射,服务端会根据不同端口路由到不同的内网服务
udp单纯的 UDP 端口映射,服务端会根据不同端口路由到不同的内网服务
http针对 HTTP 应用定制了一些额外功能,如修改 Host Header,增加鉴权
https针对 HTTPS 应用定制了一些额外功能
stcp安全的 TCP 内网代理,需在被访问者和访问者的机器上都部署 frpc,不需在服务端暴露端口
sudp安全的 UDP 内网代理,需在被访问者和访问者的机器上都部署 frpc,不需在服务端暴露端口
xtcp点对点的内网穿透代理,功能同 stcp,但是流量不需要经过服务器中转
tcpmux支持服务端 TCP 端口多路复用,通过同一个端口访问不同的内网服务

TCP

1
2
3
4
5
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

注意:frp 会为本地服务 22 端口,在 frps 所在服务端监听 6000 端口,将 6000 端口接收到的连接和本地服务 22 端口关联,透传流量,从而实现让用户在外部访问内部服务。

UDP

1
2
3
4
5
[dns]
type = udp
local_ip = 127.0.0.1
local_port = 53
remote_port = 6000

注意:frp 会为本地服务 53 端口,在 frps 所在服务端监听 6000 端口,将 6000 端口接收到的连接和本地服务 53 端口关联,透传流量,从而实现让用户在外部访问内部服务。

XTCP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[stcp-visitor]
role = visitor
type = stcp
server_name = stcp-test
sk = abc
bind_port = -1

[xtcp-visitor]
role = visitor
type = xtcp
server_name = xtcp-test
sk = abc
bind_addr = 127.0.0.1
bind_port = 9002
fallback_to = stcp-visitor
fallback_timeout_ms = 200

注意:当连接 127.0.0.1:9002 时超过 200ms 打洞还未成功的话,会回退到用 stcp-visitor 建立连接。fallback 后,之前触发的打洞操作仍然会继续,一般来说打洞完成需要耗时会比较长。

TCPMUX

frp 支持将单个端口收到的连接路由到不同代理。目前支持复用器只有 httpconnect。当 frps.ini 的 common 中设置 tcpmux_httpconnect_port,frps 将会监听在这个端口,接收 HTTP 的请求。frps 会根据 HTTP 请求中的 Host 路由到不同的后端代理。frps.ini 的配置如下:

1
2
3
[common]
bind_port = 7000
tcpmux_httpconnect_port = 1337

frpc.ini 的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[common]
server_addr = x.x.x.x
server_port = 7000

[proxy1]
type = tcpmux
multiplexer = httpconnect
custom_domains = test1
local_port = 80

[proxy2]
type = tcpmux
multiplexer = httpconnect
custom_domains = test2
local_port = 8080

去不图床的故障分析及解决方案

2023年7月7日 00:00

本月月初开始,去不图床一直出现故障,经过长时间的监控分析,最终判断是回源的问题,导致问题的原因是路由器经常性自动重启,每次重启都会导致公网 IP 的重置,进而导致 CDN 无法正常的回源。本文就此问题进行详细说明!

网络架构说明

为了控制图床运营成本,杜老师将程序源码及图片存储都托管在了家中服务器上,然后通过家庭带宽映射给 CDN。架构如图所示:

故障问题描述

为了保障 CDN 可正常回源,首先需要具备公网的 IP 地址,其次要保证 IP 发生变动时会实时反馈给 CDN。

去不图床使用的天御云暂不支持 API 推送更新 IP,所以只能借助网内群晖的 DDNS 实现,而 IP 变动后 DDNS 解析需要一段生效时间,这就是回源失败的原因。

经过一段时间观察发现,导致 IP 经常变动的原因是路由器经常自动重启,重启后拨号就会发生 IP 变动。之前最多每周变动一次「且还是深夜时」现在每天变动多次「且还是用网高峰期」

随着杜老师提供的服务不断增多,且用户量级逐渐的增大,家用机路由器已经无法满足端口映射需求。长时间的高频作业加上夏日高温,会造成路由器自动重启。

预期解决方案

就 IP 变动问题,目前有下面的几种方案。

使用固定 IP 的方案。经查询北京联通支持申请固定 IP,经费每月 100 元。但杜老师使用的是出租房提供的宽带,业务需要房东亲自办理才可,所以该方案暂时不可行。

IP 变动后及时生效方案。天御云在 IP 变动后,会有一段回源失败时间,是因为 DDNS 解析生效还未同步。但使用腾讯云「DDNS 解析托管在 DNSPod 上」CDN 的生效很快,所以采用 CDN 嵌套的方式,缺点是首次回源时时间较长「目前使用该种方式」

更换新路由器方案。通过采购软路由器,在硬件层面直接提升网络端口的映射能力,避免因路由自动重启造成 IP 变动「不变动是不可能的,但可以尽可能减少变动频次」

方案实施进度

目前采用的是 CDN 嵌套的方式,前端是天御云,中端是腾讯云,该种方式尽可能保障出现问题时,十分钟内即可自动恢复「如遇浏览报错,可尝试刷新浏览器」

已采购软路由,并让店家安装好了爱快系统「杜老师偏向 OpenWrt,但考虑需折腾半天才可以用,最终还是选择可尽快上线使用的爱快」

软路由采用 N6000 的处理器,4G 内存 128G 存储,端口是 2.5G,根据官方测试数据,可待机 128 台设备进行端口映射及转发「杜老师家中需映射设备仅有五台」

快递显示 7 月 9 日运到北京,杜老师尽量在下周一前「7 月 10 日」完成路由设备切换,为大家伙带来更稳定的服务!

容器除了 Docker 还有 Podman

2023年6月22日 00:00

了解杜老师的小伙伴都知道,杜老师非常喜欢用 Docker 来部署相关服务。但可能有些小伙伴不太清楚,容器除了 Docker 还有 Podman,今天杜老师为大家简单介绍下 Podman。

什么是 Podman

Podman 是一个开源的容器运行时项目,可在大多数 Linux 平台使用。Podman 提供与 Docker 非常相似的功能。它不需要在系统上运行任何守护进程,并且它也可以在没有 root 权限的情况下运行。

Podman 可管理和运行任何符合 OCI 规范的容器和容器镜像。Podman 提供了一个与 Docker 兼容的命令行前端来管理 Docker 镜像。

主要区别

  1. Docker 在实现 OCI 的时候,需要一个守护进程,其次需要以 root 运行,因此也带来了安全隐患;

  2. Podman 不需要守护程序,不需要 root 用户运行,从逻辑架构上,比 Docker 更加合理;

  3. 在 Docker 的运行体系中,需要多个 daemon 才能调用到 OCI 的实现;

  4. 在容器管理链路中,Docker Engine 实现就是 dockerd;

  5. dockerd 调用 containerd,containerd 调用 containerd-shim。顾名思义 shim 起的作用也就是避免父进程退出影响容器的运行;

  6. Podman 直接调用 OCI,通过 common 作为容器进程的管理工具,但不需要 dockerd 这种以 root 身份运行的守护进程;

  7. Podman 体系中,有个称为 common 的守护进程,运行路径通常是 /usr/libexec/Podman/conmon,它是各个容器进程的父进程,每个容器各有一个,common 的父进程通常是 1 号进程。Podman 中的 common 其实相当于 Docker 体系的 containerd-shim;
    图片

  8. Podman 不需要守护进程,而 Docker 需要守护进程。

使用区别

  1. Podman 的定位也是与 Docker 兼容,因此在使用上面尽量靠近 Docker。使用方面,可以分成两个方面来说,一是系统构建者的角度,二是使用者的角度;

  2. 在系统构建者方面,Podman 的默认软件,与 Docker 区别不大,只在进程模型、进程关系方面有所区别。如果习惯 Docker 几个关联进程的调试方法,在 Podman 中则需要适应。总体来看,Podman 比 Docker 要简单。由于 Podman 比 Docker 少了一层 daemon,因此重启的机制也就不同了;

  3. 在使用者方面,Podman 与 Docker 的命令基本兼容,都包括容器运行时、本地镜像、镜像仓库几个方面。因此 Podman 命令行工具与 Docker 类似,比如构建镜像、启停容器;

  4. Docker/Podman 可进行替换。因此,即便使用了 Podman,仍然可使用 Docker 作为镜像仓库,这也是兼容性最关键的部分。

常用命令

容器相关命令如下:

命令作用
podman run创建启动容器
podman start启动容器
podman ps查看容器
podman stop终止容器
podman restart重启容器
podman exec进入容器
podman export导出容器
podman import导入容器快照
podman rm删除容器
podman logs查看日志

镜像相关命令如下:

命令作用
podman search检索镜像
podman pull获取镜像
podman images列出镜像
podman rmi删除镜像
podman save导出镜像
podman load导入镜像

宝塔 Nginx 安装 Brotli 压缩模块

2023年4月29日 00:00

使用 CDN 的小伙伴都知道,访问优化一块,压缩除了 Gzip 还有 Brotli,而 Brotli 作为新一代的工具,宝塔面板竟然一直没有集成。今天教大家如何手动为 Nginx 安装 Brotli 压缩模块!

安装准备工作

  1. 先卸载您现在使用的 Nginx,避免后面步骤出错;

  2. 下载 Brotli 并修改 Nginx 安装脚本来进行安装。

相关文件下载

连接 SSH 并输入以下命令,首先进入宝塔服务目录:

1
cd /www/server/

其次下载 Brotli 源码包:

1
git clone https://github.com/google/ngx_brotli.git

接着进入 Brotli 源码包目录:

1
cd ngx_brotli/

更新 Brotli 源码子模块:

1
git submodule update --init

修改安装脚本

找到文件 /www/server/panel/install/nginx.sh 并将其中的:

1
./configure --user=www --group=www --prefix=${Setup_Path} ${ENABLE_LUA} --add-module=${Setup_Path}/src/ngx_cache_purge ${ENABLE_STICKY} --with-openssl=${Setup_Path}/src/openssl --with-pcre=pcre-${pcre_version} ${ENABLE_HTTP2} --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt="-Wl,-E" --with-cc-opt="-Wno-error" ${jemallocLD} ${ENABLE_WEBDAV} ${ENABLE_NGX_PAGESPEED} ${ADD_EXTENSION} ${i_make_args}

改为:

1
./configure --user=www --group=www --prefix=${Setup_Path} ${ENABLE_LUA} --add-module=${Setup_Path}/src/ngx_cache_purge ${ENABLE_STICKY} --with-openssl=${Setup_Path}/src/openssl --with-pcre=pcre-${pcre_version} ${ENABLE_HTTP2} --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt="-Wl,-E" --with-cc-opt="-Wno-error" ${jemallocLD} ${ENABLE_WEBDAV} ${ENABLE_NGX_PAGESPEED} ${ADD_EXTENSION} ${i_make_args} --add-module=/www/server/ngx_brotli

重安装 Nginx

1
bash /www/server/panel/install/nginx.sh install 1.23.2

注意:使用上面的命令重新安装 Nginx,其中 1.23.2 为 Nginx 版本号,可以根据实际需求修改!

设置配置文件

1
2
3
4
brotli on;
brotli_comp_level 6;
brotli_static on;
brotli_types application/atom+xml application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;

注意:将上述代码添加到 Nginx 配置文件中即可。

写在文章最后

实测 Brotli 的压缩率为 6 时,与同压缩率的 Gzip 比,体积更小。

部分 CDN 不支持透传 Header 会导致源站不做压缩处理,源站开了压缩 CDN 就不要开了。

什么是 Brotli 压缩

2023年4月26日 00:00

Brotli 压缩是一种由 Google 开发数据压缩算法,最初用于 Web 页面的压缩。它是一种无损压缩算法,可将文本、图片、视频等各种类型的数据压缩到更小的体积,从而提高网站加载速度。

Brotli 的优势

  1. 更高的压缩率:Brotli 压缩算法可以将数据压缩到更小的体积,平均压缩率可以比 Gzip 高出 20%-26%;

  2. 更好的多线程处理:Brotli 压缩算法可以同时使用多个 CPU 核心进行压缩,因此可更快地完成压缩任务。

与 Gzip 对比

  1. 压缩速度:Brotli 需要更多计算来压缩和解压缩文件,因此比 Gzip 更慢。这在一些情况下可能会影响性能,尤其是在较慢的设备上;

  2. 兼容性能:Brotli 是与现代浏览器和服务器兼容的新技术,因此在一些较旧的浏览器和服务器可能不支持。Gzip 则更为广泛支持。

应用场景

  1. Web 服务器:在 Web 服务器上使用 Brotli 压缩可以大大减少网站的带宽使用,加速页面加载速度,减轻服务器的负载压力;

  2. 移动应用程序:移动应用程序的体积往往比较大,使用 Brotli 压缩可以将应用程序的体积压缩到更小,从而降低用户下载应用程序所需的时间和流量。

写在最后

Brotli 压缩算法是一种高效数据压缩算法,它的优势在于更高的压缩率、更好的多线程处理。Brotli 压缩最适合用于 Web 服务器和移动应用程序中,可提高网站的加载速度,并降低用户下载数据时所需的时间和流量。

Gzip 是一种数据压缩格式,它可以将文本、图像、脚本、样式表等各种类型文件压缩成较小的文件大小,从而在网络上传输更快。Gzip 压缩使用一种被称为 Lempel-Ziv 编码的算法。在该算法中重复出现的子字符串被替换为相应指针,从而减少了文件的大小,同时保留了相同内容的副本。在 Web 开发中 Gzip 通常用于压缩网站的 HTML/CSS 和 JavaScript 文件,提高页面加载速度。多数 Web 服务器和现代浏览器都支持 Gzip 压缩。

总的来说,Brotli 比 Gzip 更先进,可以提供更好的压缩率,但需要更高的计算能力。如果您需要快速加载的文件,则 Gzip 可能更为适合。

下一篇教程中,杜老师会分享如何在宝塔的 Nginx 安装 Brotli 压缩模块。

Nextcloud 生产环境部署保姆级教程

2023年2月16日 00:00

Nextcloud 是一个免费专业的私有云存储网盘开源项目,可以简单快速地在电脑、服务器甚至是树莓派等设备上架设一套属于自己或团队专属的云同步网盘,从而实现跨平台跨设备文件同步、共享、版本控制、团队协作功能。

CUE 下前篇

先前发布一篇名为《在 Docker 中部署 Nextcloud》教程,分享如何通过 Docker 快速部署 Nextcloud。

此种部署方式适合个人用户使用,如需部署在生产环境用,建议使用 LAMP 架构加源码部署,详见下文。

环境介绍

杜老师的实验环境为虚拟机加 CentOS7 系统,使用的 LAMP 脚本来自 https://lnmp.org,Nextcloud 为此文撰写时的最新版本。

这里需要注意的是:因 Nextcloud 需要 PHP7.3 以上的版本,所以必须 1G 以上的内存。

服务安装

使用官方命令进行环境部署:

1
wget http://soft.vpser.net/lnmp/lnmp1.9.tar.gz -cO lnmp1.9.tar.gz && tar zxf lnmp1.9.tar.gz && cd lnmp1.9 && ./install.sh lamp

部署时的环境设置如下:

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
+------------------------------------------------------------------------+
| LNMP V1.9 for CentOS Linux Server, Written by Licess |
+------------------------------------------------------------------------+
| A tool to auto-compile & install LNMP/LNMPA/LAMP on Linux |
+------------------------------------------------------------------------+
| For more information please visit https://lnmp.org |
+------------------------------------------------------------------------+
You have 11 options for your DataBase install.
1: Install MySQL 5.1.73
2: Install MySQL 5.5.62 (Default)
3: Install MySQL 5.6.51
4: Install MySQL 5.7.38
5: Install MySQL 8.0.30
6: Install MariaDB 5.5.68
7: Install MariaDB 10.3.35
8: Install MariaDB 10.4.25
9: Install MariaDB 10.5.16
10: Install MariaDB 10.6.8
0: DO NOT Install MySQL/MariaDB
Enter your choice (1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or 0): 4
Using Generic Binaries [y/n]: y
You will install MySQL 5.7.38 Using Generic Binaries.
===========================
Please setup root password of MySQL.
Please enter: Dusays@1234
MySQL root password: Dusays@1234
===========================
Do you want to enable or disable the InnoDB Storage Engine?
Default enable,Enter your choice [Y/n]: Y
You will enable the InnoDB Storage Engine
===========================
You have 9 options for your PHP install.
1: Install PHP 5.2.17
2: Install PHP 5.3.29
3: Install PHP 5.4.45
4: Install PHP 5.5.38
5: Install PHP 5.6.40 (Default)
6: Install PHP 7.0.33
7: Install PHP 7.1.33
8: Install PHP 7.2.34
9: Install PHP 7.3.33
10: Install PHP 7.4.30
11: Install PHP 8.0.20
12: Install PHP 8.1.7
Enter your choice (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12): 11
You will install PHP 8.0.20
===========================
You have 3 options for your Memory Allocator install.
1: Don't install Memory Allocator. (Default)
2: Install Jemalloc
3: Install TCMalloc
Enter your choice (1, 2 or 3): 1
You will install not install Memory Allocator.
===========================
Please enter Administrator Email Address: teacherdu@dusays.com
===========================
Server Administrator Email: teacherdu@dusays.com
===========================
===========================
You have 2 options for your Apache install.
1: Install Apache 2.2.34
2: Install Apache 2.4.53 (Default)
Enter your choice (1 or 2): 2
You will install Apache 2.4.53

Press any key to install...or Press Ctrl+c to cancel

环境部署完成后会出现如下提示:

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
35
36
+------------------------------------------------------------------------+
| LNMP V1.9 for CentOS Linux Server, Written by Licess |
+------------------------------------------------------------------------+
| For more information please visit https://lnmp.org |
+------------------------------------------------------------------------+
| lnmp status manage: lnmp {start|stop|reload|restart|kill|status} |
+------------------------------------------------------------------------+
| phpMyAdmin: http://IP/phpmyadmin/ |
| phpinfo: http://IP/phpinfo.php |
| Prober: http://IP/p.php |
+------------------------------------------------------------------------+
| Add VirtualHost: lnmp vhost add |
+------------------------------------------------------------------------+
| Default directory: /home/wwwroot/default |
+------------------------------------------------------------------------+
| MySQL/MariaDB root password: Dusays@1234 |
+------------------------------------------------------------------------+
+-------------------------------------------+
| Manager for LNMP, Written by Licess |
+-------------------------------------------+
| https://lnmp.org |
+-------------------------------------------+
Apache is running.
SUCCESS! MySQL running (89612)
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:111 *:*
LISTEN 0 5 192.168.122.1:53 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 128 [::]:3306 [::]:*
LISTEN 0 128 [::]:111 [::]:*
LISTEN 0 128 [::]:80 [::]:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 [::1]:631 [::]:*
Install lnmp takes 6 minutes.
Install lnmp V1.9 completed! enjoy it.

使用浏览器访问虚拟机的 IP,即可显示如下页面:

Nextcloud 的部署

直接在默认网站根目录中使用 Nextcloud 官方下载地址进行源码下载,然后对其进行解压操作,并修改对应文件的权限:

1
2
3
4
cd /home/wwwroot/default/
wget https://download.nextcloud.com/server/releases/latest.zip
unzip latest.zip
chown www. /home/wwwroot/default/nextcloud/ -R

在浏览器中使用 IP/nextcloud 打开网站,其中 nextcloud 是刚解压的目录,如有需要可以将其放入根目录中。依次设置管理员账号和密码,生产环境数据量比较大,数据库需要选择 MySQL,并输入数据库连接信息「这里用 root 用户连接,数据库不需要提前创建」

安装后的界面展示:

文件浏览器的界面展示:

媒体界面展示:

动态界面展示:

动态网站备份图解

2023年1月29日 00:00

备份,是数据安全的一种保障方式,今天我们就来说说,如何通过宝塔面板给动态程序网站做备份。应张童鞋需求,此文配合图解说明操作方法。

写在前面

文中提到的动态网站程序指 PHP+MySQL 类程序。

动态程序网站需要备份源码和数据库。

源码备份

手动备份非常简单,找到网站源码所在目录,点击压缩即可完成一次备份:

如需实现自动备份,可通过面板的计划任务实现。点击左侧计划任务,添加网站备份任务,根据需求设置备份周期,以及保留份数即可:

如需异地备份,可以进入软件商店,下载对应服务商等对象存储插件,如套路云 OSS 等:

之前《网站通用备份策略》一文提到,像 WordPress 这类程序,如仅需要备份变动目录,也可使用计划任务备份指定目录:

数据备份

数据库的备份通过面板实现比较简单,仅需要切换到数据库的页面,在需要备份的数据库上点击备份即可:

如果需要实现自动备份,可通过面板的计划任务实现。点击左侧计划任务,添加数据库的备份任务,根据需求设置备份周期,以及保留份数即可「异地备份也可参考源码备份中异地的操作」

写在最后

最近在博客互访时,看到一些小伙伴推荐小厂云平台,价格十分便宜,配置也还不错,因为还未测试所以不知道稳定性如何。

首先杜老师要表示个人或是小作坊运营也可以做大做强,很多大站都是由个人创建的,团队运营,最后注册成企业的。

但有成功做大,就会有失败跑路的。想比经济损失,站长更怕数据丢失,所以建议大家经常备份数据。

有些平台提供主机快照,这种备份方式十分方便,但需注意的是,一旦平台出现无法访问,快照备份也会丢失,所以跨平台的异地备份才是王道!

网站通用备份策略

2023年1月17日 00:00

先向张童靴说一声抱歉,之前答应了发表一篇关于网站数据备份的文章,奈何转身就忘记了。身为老师因疫情耽搁的课程太多,稳定后不是出差就是各种课,虽说最近文章没断,但水份都较大,还要感谢小伙伴们都理解和支持!

注意备份

数据备份是保护数据的重要过程。它可以帮助在硬件故障、人为错误、病毒感染或其它原因导致数据丢失中恢复数据。数据备份对于组织来说是至关重要的,因为数据是组织的核心资产,如果丢失数据可能导致停工、损失信誉甚至财务损失。通过定期备份数据,可以保证在灾难发生时可尽快恢复数据和业务运行。

数据备份通常分为本地备份、异地备份。

本地备份相对简单,在服务器内操作就行了,恢复时也快捷。缺点是服务器一旦出现问题,很有可能导致备份数据丢失。

异地备份相对复杂,有时候需要人为干预才可以。最简单的异地备份,就是服务器备份好数据之后,下载一份到本地上。

本文讨论的是,通过哪些插件可以实现全自动的异地备份。

尽可能保障免代码操作!

静态博客

静态博客是指 Hexo/Hugo 一类的博客框架,根据大家反馈,一般会有两种部署方式:本地部署、异地部署。

本地部署是指在本地上搭建博客环境,再将生成的文件传至网络上进行呈现。

异地部署则是借助如 GitHub Actions 等方式自动生成页面文件并完成部署「杜老师说使用该种方法」

本地部署建议两种备份方案,一种是借助同步盘,如坚果盘,实现数据更新后即备份,出现问题后可随时恢复;或将博客整站源码上传至 GitHub,作为备份使用。

异地部署无需考虑数据备份,因为 GitHub 等平台托管相对更有保障,如想进一步提升数据安全性,可以考虑数据更新时使用新分支,或者同时用多平台备份。

这里需要强调的是,静态博客仅需备份整站源码,无需备份生成页面,这样可以减少备份文件体积,提高备份效率。

推荐本地备份的工具有:百度网盘、坚果盘等,以上客户端都有自动备份的功能。

推荐异地备份工具是 GitHub 官方的 Desktop,虽然是英文版,不过操作比较简单。当然也可使用代码直接同步!

动态网站

动态网站因为页面语言较多,这里仅举例 PHP+MySQL 类型站点。该类型站点需分别备份源码文件和数据库,下面是以去不图床为例,配合宝塔面板,分享备份思路。

去不图床由三部分数据构成:整站源码、图片数据及数据库。

整站源码本地备份可以借助计划任务,如需异地备份,请先在软件商店中,添加宝塔插件,支持阿里云 OSS、谷歌存储、亚马逊 S3、七牛存储、谷歌网盘、腾讯云 COS、百度存储、华为存储、又拍存储、京东存储、微软 OneDrive 等。杜老师策略是每周本地备份,每月异地备份到群晖上。具体备份周期,参考整站代码变动情况,比如去不图床如果没有代码变动,则不需要频繁备份。

图片因数据量较大,且会频繁更新,故杜老师直接用实时异地多节点备份。实施的步骤是:首先将群晖挂载到服务器上,然后使用 rsync 命令将新图片同步至群晖,群晖内使用同步套件上传至阿里云 OSS、腾讯云 COS 及京东云存储。当服务器出现问题,可以通过群晖备份快速恢复。如果内部网络出现问题,也可快速切换至阿里云等节点实现不间断访问,保障图片外链服务稳定!

数据库的变动较大,但是量级较少,所以杜老师的备份周期较短,每小时会本地备份一次,每天异地备份到群晖上,每月被分到阿里云 OSS 及腾讯云 COS。

如果是 WordPress 这种内部文件变动「wp-content 文件夹经常变动」可以使用宝塔计划任务中的目录备份功能,仅备份变动的文件即可。

补充说明

以上强调了备份重要性,及多种数据的备份方法。除此之外,还要考虑到备份文件的空间占用,以及数据恢复策略。

备份文件并未越多越好,虽然更加安全,但也会增加存储空间的占用,所以保留一定数量备份文件即可。杜老师的策略是最大备份周期三份起七份止。比如整站源码本地保留七份,异地保留三份;数据库则本地保留 168 份,群晖保留四份,异地保留三份。

当需要恢复数据时,也需要先做好恢复前数据的备份。毕竟相比备份数据,当前的数据时间点更新,毕竟会产生一定的数据差异,做好恢复前数据的备份可最大限度的防止数据丢失。

最后需要提醒的是,数据断层变动「将数据恢复到上个节点」操作可能导致网站访问出现问题,一般都是出现在缓存上,可通过清理本地或者中间件「如 Redis」缓存数据解决。

SSL 证书申请小窍门

2022年12月27日 00:00

杜老师说站点证书即将到期,为了不影响小伙伴们的访问,应尽快申请新证书替换。然而在申请过程中,出现了一些小插曲,于本片同小伙伴们分享,遇到类似问题可以参考此文解决!

概念普及

SSL 安全套接层是 Netscape 公司先采用的网络安全协议。是在传输通信协议上实现的一种安全协议,采用公开密钥技术。SSL 广泛支持各种类型的网络,同时提供三种基本安全服务,它们都用公开密钥技术。

信息保密,通过使用公开密钥和对称密钥技术以达到信息保密。SSL 客户机和服务器之间所有业务都使用在 SSL 握手过程中建立的密钥和算法进行加密。这样就防止了某些用户通过使用 IP 数据包嗅探工具非法窃听。尽管数据包嗅探仍能捕捉到通信内容,但却无法破译。

信息完整,确保 SSL 业务全部达到目的地。确保服务器和客户机之间的信息内容免受破坏。SSL 利用机密共享和 Hash 函数提供信息完整性服务。

双向认证,客户机和服务器相互识别的过程。它们识别号用公开密钥编码,并在 SSL 握手时交换各自的识别号。为了验证证明持有者是其合法用户而不是冒名用户,SSL 要求证明持有者在握手时对交换数据进行数字式标识。证明持有者对包括证明所有信息数据进行标识,以说明自己是证明的合法拥有者。这样就防止了其他用户冒名使用证明。证明本身并不提供认证,只有证明和密钥一起用才起作用。

SSL 安全性服务对终端用户来讲做到尽可能透明。一般情况,用户只需单击桌面上的一个按钮就可以与 SSL 的主机相连。与标准 HTTP 连接申请不同,一台支持 SSL 的典型网络主机接受 SSL 连接的默认端口是 443,而不是 80。

以上节选自某度百科安全套接层。

免费证书

现在很多平台都在提供免费证书,常见的有 SSL For Free 及一些大厂,两者的区别是:SSL For Free 只能使用三个月,但是支持无限续期;其它大厂每次申请可用一年,不过不能续期,到期后需重新申请,且有申请限制,目前套路云和凉心云每年有 20 个申请名额,其它平台暂未关注,还请小伙伴们补充:

遇到问题

杜老师的主力证书托管平台是凉心云,因为杜老师的所有域名都托管在 DNSPod 上,部分域名例如去不图床需要单独设置解析线路,所以都升级到了专业版。

但是凉心云的 SSL 证书怎么申请都没有通过,始终提醒查询不到验证信息。后来换到了套路云,也是一样情况。总的说 CNAME 和 TXT 的验证形式都无法完成验证。

在 xaoxuu 大佬的提醒下,关闭主域名相关 CNAME 解析,最终实现了 SSL 申请。

表示感谢同时提醒下小伙伴,一般 SSL 的申请及审核速度都很快,可以选择关闭解析一段时间,申请通过后再删除验证解析,重新开启正常解析信息。

特殊情况

有些情况需要添加 CAA 解析值。这个其实不太容易操作,因为如套路云等大厂并未提供 CAA 解析信息,可以提交工单询问客服,然后添加即可:

去不图床网站架构分享

2022年9月5日 00:00

杜老师更新图床架构后,不少小伙伴反馈速度快不少,使用体验较之前提升了很多。也有小伙伴担心图片的稳定性和安全,本篇分享一下去不图床网站架构。

网站架构

其实没有多么复杂,后端并不是多个服务器,而是多个服务组成:

数据走向

  1. 当用户访问图床时,会通过前端的多吉云 CDN 国内节点加速,页面获取极限带宽为 100M;

  2. 当用户上传图片时,数据需先经过自建服务审核,再通过 FTP 协议传至存储模块;

  3. 上传带宽为 500M,理论极限值受审核速度,及 FTP 队列处理速度影响;

  4. 存储模块域名独立,通过多吉云 CDN 国内节点加速,提供高速外链服务。

参与设备

所用到的设备配置为 16H16G。存储为 512NVMe,带宽上行 100M 下行 700M。

图片文件每一小时同步备份至 NAS,保障数据安全。

写在最后

随着图床用户体量增加,原有的服务器已经无法满足运营需求,尽快杜老师做了很多次优化,但因为线路等关系,在大量上传图片时经常出错。

且受节点影响,部分地区的用户出现无法访问等情况。现图床 ICP 备案已下,正式切为国内节点,且服务器配置提升,保障了用户的使用体验。

最后还是要说一下,图床目前使用家用网络,如果出现突发停电、断网等情况则会影响服务稳定性。

杜老师目前住处的电费自动续缴,除线路整修外不会出现突然断电问题「入住一年,就出现了一次,断电了 5 分钟」

目前家中两条带宽,其中一条只跑 NAS 和图床,且 NAS 为双网卡,主要上传下载操作均不会影响到图床带宽。

除图床站点外,杜老师说评论系统、友链的朋友圈、访问统计也运行在该主机上!

Docker 限制 CPU 内存使用

2022年8月24日 00:00

默认情况下容器可以无限制地使用主机的 CPU 和内存资源,可通过设置参数来进行限制。下面说说 Docker 如何限制 CPU 内存使用!

Docker 限制 CPU 使用

  • --cpus=VALUE

限制容器可使用多少 CPU,可设置为小数,如可以设置--cpus=1.5。该选项代表使用 CPU 的百分比,而不是具体的个数。例如主机一共有四个 CPU,设--cpus=2,不代表两个 CPU 被 100%占用,另外两个完全空闲,可能四个 CPU 各被占用 50%。

  • --cpu-period=VALUE

指定 CFS 的周期,通常和--cpu-quota=VALUE 一起使用,单位毫秒。默认是 100 毫秒,但大多用户一般不会改变这个值,使用--cpus=VALUE 更方便。

  • --cpu-quota=VALUE

指定容器在一个 CFS 调度周期中可使用 CPU 的时间,单位毫秒。通常和--cpu-period=VALUE 一起使用,一般使用--cpus=VALUE 更方便。

  • --cpuset-cpus=VALUE

限制容器可以使用指定的 CPU。如果有多个 CPU,可以以逗号分隔或者使用连字符进行指定。

  • --cpu-shares=VALUE

容器使用 CPU 的权重,默认是1024,不设置或者将其设置为 0 都将使用默认值,数值越大权重越大。这是个软限制,只有 CPU 资源不足时才会生效。当 CPU 的资源充足时,各个容器可在不超过资源限制的条件下使用 CPU 资源;当 CPU 资源不足,并有多个容器竞争 CPU 资源时,系统会根据每个容器的权值和所有容器权值的比例来给容器分配 CPU 的使用时间,如果器 A 设置为--cpu-shares=2048,容器 B 设置 --cpu-shares=1024,则容器 A 会被分配约 66%的 CPU 时间,容器 B 被分配约 33%的 CPU 时间。

  • --cap-add=sys_nice

赋予容器 CAP_SYS_NICE 的能力,允许容器增加进程的友好值、设置实时调度策略、设置 CPU 亲和性和其它的操作。

  • --cpu-rt-runtime=VALUE

在 Docker 守护进程的实时调度程序周期内,容器可以实时优先级运行的最长时间,单位毫毛,必须设置了--cap-add=sys_nice 参数才能使用。

  • --ulimit rtprio=VALUE

允许容器设置的最大实时优先级,必须设置了--cap-add=sys_nice 参数才能使用。

限制内存使用

  • --memory=VALUE

内存限制,最小值 6M。

  • --memory-swap=VALUE

内存加交换分区的限制,只有设置了--memory=VALUE 之后,这个参数才有意义。如--memory=300m --memory-swap=1g,那么容器可使用 300M 的内存和 700M 的交换分区;如设置的数值和--memory=VALUE 一样,那么容器无法使用交换分区;如果该值没有设置,容器最多可以使用和--memory=VALUE 一样大的交换分区;如果该值设置为 0,等于没有设置;如果设置为-1,可以使用的交换分区大小无限制。

  • --memory-swappiness=VALUE

默认情况下容器的内核可交换出一定比例的匿名页,此参数用来设置可用的比例。数值在 0-100 之间,0 代表关闭匿名页交换,100 表示所有匿名页都可交换。如果没有设置该值,该值默认从父进程继承而来。

  • --memory-reservation=VALUE

是种软性限制,确保容器不会长时间占用超过--memory-reservation=VALUE 限制内存大小,但不保证时时刻刻都不超过该限制值。该值比--memory=VALUE 小时,在主机内存资源紧张时,会强迫容器内存占用不超过该值;在没有设置时,该值和--memory=VALUE 的值相同;将其设置为 0 或者大于--memory=VALUE 时,等于没有设置。

  • --kernel-memory=VALUE

容器可以使用的最大内核内存值,最小值 4M。

  • --oom-kill-disable

默认情况下 OOM 错误发生时,主机会杀死容器进程来获取更多内存。使用该选项可以避免容器进程被杀死,但是应该在设置了--memory=VALUE 参数之后才能使用该选项,不然不会限制容器内存使用,却禁止主机杀死容器的进程,出现 OOM 错误时,系统会杀死主机进程来获取内存。

Caddy 的简介

2022年7月31日 00:00

Caddy 是一个功能强大、可扩展的平台,用于为网站服务和应用程序提供服务,这些平台是用 Go 编写的。虽然相比 Nginx 等主流 Web 服务效率低,但其关注度非常高!

软件简介

Caddy 是一个支持 HTTP/2 的跨平台 Web 服务,使用和配置都非常简单。Caddy 支持 HTTP/2, IPv6/Markdown/WebSockets/FastCGI 等。

Caddy 常用作 HTTPS 服务器,但它适用于任何长时间运行的 Go 程序。首先,它是一个运行 Go 应用程序的平台。Caddy 只是作为 Caddy 模块实现的 Go 程序。

Caddy 应用程序可立即受益于自动化文档、通过 API 进行的优雅在线配置更改,及与其他 Caddy 应用程序的统一。

虽然 JSON 是 Caddy 的原生配置语言,但 Caddy 可以接受来自配置适配器的输入,这些适配器基本上可以将选择的任何配置格式转换为 Caddyfile/JSON 5/YAML/TOML/Nginx 配置。

配置 Caddy 主要方法是通过其 API,但如果更喜欢配置文件,命令行界面也支持这些文件。

与现有的任何 Web 服务器相比,Caddy 暴露前所未有的控制水平。在 Caddy 中通常在内存中设置初始化类型的实际值,这些值为从 HTTP 处理程序和 TLS 握手到存储介质的所有内容提供支持。Caddy 可扩展性也非常可笑,它具有强大的插件系统,可以比其它 Web 服务器进行巨大的改进。

Caddy 几乎所有配置都包含在单个配置文档中,而不是像其它 Web 服务器那样分散在 CLI 标志和 env 变量及配置文件中。这使得管理服务器配置更加简单,并减少了隐藏的变量和因素。

以上是我从官方机翻过来的,感觉别扭可以找我获取英文原版!

安装方法

Debian/Ubuntu/Raspbian 执行如下指令安装 Caddy:

1
2
3
4
5
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Fedora/RedHat/CentOS 执行如下指令安装 Caddy:

1
2
3
yum install yum-plugin-copr
yum copr enable @caddy/caddy
yum install caddy

配置文件

一个配置示例:

1
2
3
4
5
6
7
https://dusays.com                # Your site's address
ext .html # Clean URLs
errors {
log ../errors.log # Error log
404 error-404.html # Custom error page
}
fastcgi /blog localhost:9000 php # PHP backend

更简单的配置:

1
2
3
4
5
6
7
localhost
gzip
browse
ext .html
websocket /echo cat
log ../access.log
header /api Access-Control-Allow-Origin *

运行服务

1
caddy run

注意:如执行 caddy,该命令仅显示帮助文本。

Argument list too long 原因与解决思路

2022年7月25日 00:00

最近在整理图床文件时,因为文件数量太多,执行 cp 命令提示 Argument list too long。简单说下其原因与解决思路!

问题原因

在 Linux 下使用 cp/mv/rm 等命令时,经常会碰到 Argument list too long 错误。

这个主要是因为要 cp/mv/rm 的文件个数太多而导致的。

解决方法

Argument list too long 这个问题的解决主要会用到两个命令 find 和 xargs。

这里以删除 dusays 目录下以 com 后缀的文件为例:

1
2
find dusays/ -name "*.com" | xargs -i rm -f {}
find dusays/ -name "*.com" -exec rm -f {} \;

复制 dusays 目录下以 com 后缀文件到 7bu 目录:

1
2
find dusays/ -name  "*.com" | xargs -i cp {} 7bu/
find dusays/ -name "*.com" -exec cp {} 7bu/ \;

xargs 用于给其它命令传递参数的一个过滤器,也是组合多命令的一个工具。而-i 参数会将 xargs 的内容赋值给{}。

OpenLiteSpeed 的简介

2022年7月13日 00:00

最近有小伙伴反馈去不图床打开有一些慢,除了网络的问题外,页面处理速度多少也会有些影响,毕竟图床用户越来越多。经朋友的推荐,打算用 OpenLiteSpeed 替代 Nginx 以获取性能提升。

软件简介

OpenLiteSpeed 是 LiteSpeed EnterPrise 的社区版本,OpenLiteSpeed 的组件有官方进行主要维护和更新,提供商用企业级的体验。在性能上,LiteSpeed Tech 提供的 BenchMark 中,在 WordPress/Joomla/OpenCart/ModSecurity和HTTP/2以及小型静态文件的测试上都比 Apache HTTPD 和 Nginx 有这更好的表现:

注意事项

  1. OpenLiteSpeed 兼容 Apache 的伪静态格式,也就是说,可直接读取.htaccess文件;

  2. OpenLiteSpeed 不支持低版本 PHP,如果您需要 PHP5.6以下版本,则不能使用 OpenLiteSpeed;

  3. 请不要为 OpenLiteSpeed 的 PHP 安装 OPcache 扩展,实测证明安装后会降低效率;

  4. OpenLiteSpeed 相较 Nginx,PHP 的扩展性和可调配置略差。

麒麟服务器操作系统安装 Samba 文件共享服务

2022年5月5日 00:00

Samba 是在 Linux 和 Unix 系统上实现 SMB 协议的一个免费软件,由服务器及客户端程序构成。Samba 是能够在任何支持 SMB 协议的主机之间共享文件的一种实现,当然也包括 Windows。该文讲解如何在麒麟服务器操作系统上安装 Samba 文件共享服务。

什么是 SMB

SMB 是一种在局域网上共享文件和打印机的一种通信协议,它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务。

SMB 协议是 C/S 型协议,客户机通过该协议可访问服务器上的共享文件系统、打印机及其它资源。

监听端口

TCP 端口相对应的服务是 smbd 服务,其作用是提供对服务器中文件、打印资源的共享访问;UDP 端口相对应的服务是 nmbd 服务,其作用是提供基于 NetBIOS 主机名称的解析:

TCPUDP
139137
445138

Samba 的安装

1
yum -y install samba

注意:麒麟操作系统官方源中包含 Samba 的安装文件,直接使用上面命令安装即可。

默认配置

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
[global]
workgroup = SAMBA
security = user

passdb backend = tdbsam

printing = cups
printcap name = cups
load printers = yes
cups options = raw

[homes]
comment = Home Directories
valid users = %S, %D%w%S
browseable = No
read only = No
inherit acls = Yes

[printers]
comment = All Printers
path = /var/tmp
printable = Yes
create mask = 0600
browseable = No

[print$]
comment = Printer Drivers
path = /var/lib/samba/drivers
write list = @printadmin root
force group = @printadmin
create mask = 0664
directory mask = 0775

注意:/etc/samba/smb.conf 是服务端的配置文件,刚安装的就自带/etc/samba/smb.conf 文件,直接启动就可使用。

服务启动

1
2
systemctl start smb.services
systemctl enable smb.services

注意:上面的是启动命令,下面的是设置开机自动启动。

创建用户

1
smbpasswd -a USERNAME

注意:用户可以直接用 Linux 用户,但密码也需要设置,使用上面命令可为指定用户设置 Samba 的密码。

Samba 的配置文件

主配置文件/etc/samba/smb.conf

三大组成作用
global全局配置,此处的设置项对整个 Samba 服务器都有效
homes宿主目录共享设置,此处用来设置 Linux 用户的默认共享,对应用户宿主目录。用户访问服务器中与自己用户名同名的共享目录时,通过验证后将会自动映射到该用户的宿主目录
printers打印机的共享设置

常用配置文件参数

主配置文件中常用参数:

参数作用
workgroup表示设置工作组的名称
security表示设置安全级别,其值可设置 user/server/domain
passdb backend表示设置共享帐户文件类型,其值可设置 tdbsam/ldapsam/smbpasswd
comment表示设置对应共享目录注释,说明信息,即文件共享名
browseable表示设置共享是否可见
writable表示设置目录是否可写
path表示共享目录路径
guest ok表示设置是否所有人可访问共享目录
public表示设置是否允许匿名用户访问
write list表示设置允许写的用户和组,组用符号@来表示,如 write list = @root
valid users设置可访问的用户和组,如 valid users = root,@root
hosts deny设置拒绝哪台主机访问,如 hosts deny = 192.168.1.1
hosts allow设置允许哪台主机访问,如 hosts allow = 192.168.1.1
printable表示设置是否为打印机

Samba 的安全级别

Samba 服务器的安全级别有三个,分别是 user/server/domain:

安全级别作用
user基于本地验证
server由另一台指定服务器对用户身份进行认证
domain域控进行身份验证

搭建匿名用户共享

以前的 Samba 版本支持的安全级别有四个,分别是 share/user/server/domain。share 用来设置匿名访问的,但现在的版本已经不支持 share ,但还是可以实现匿名访问的只是配置方式变了。首先我们创建共享目录:

1
2
mkdir /opt/dusays
chmod 777 /opt/dusays/

将上面目录加入到 Samba 配置文件中:

1
2
3
4
5
6
7
[dusays]
comment = dusays
path = /opt/dusays
browseable = yes
guest ok = yes
writable = yes
public = yes

测试配置文件是否有误:

1
testparm

重启服务:

1
systemctl restart smb.services

Windows 下访问共享文件

在 Windows 资源管理器地址上输入\\IP 即可登陆 Samba 服务,如我的 Samba 服务器 IP 地址是 192.168.1.1,则输入\\192.168.1.1

输入的刚才新增的 Samba 用户及密码就行,如果不想每次输入,可以勾选记住密码。

Linux 下共享文件

首先客户端需要安装支持文件共享服务的软件包 cifs-utils

1
yum -y install cifs-utils

然后使用以下命令即可实现挂载:

1
mount -t cifs -o username=USERNAME,password=PASSWORD //192.168.1.1/dusays /mnt/

麒麟高级服务器操作系统安装 Redis

2022年4月8日 00:00

Redis 是一个 Key-Value 的存储系统。和 Memcached 类似,它支持存储 value 类型相对更多,包括链表、集合、有序集合、哈希类型和字符串。这些数据类型都支持 Push/Pull、Add/Remove 及取交集并集和差集及更丰富操作,而且这些操作都是原子性的。在这个基础上,Redis 支持各种不同方式的排序。与 Memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。

搭建说明

如需系统性学习 Redis,点击 这里 即可看到有关 Redis 的系列教程。

本流程演示在麒麟高级服务器操作系统安装 Redis 流程,如有任何问题,欢迎在页面下评论留言!

流程演示

点击播放:

asciicast

RAID10 软阵列搭建流程

2022年4月2日 00:00

RAID 全称 Redundant Array of Inexpensive Disks,廉价冗余磁盘阵列,通过多块磁盘组成一种模式,来提高吞吐量和可靠性。今天杜老师就为大家演示下 RAID10 软阵列搭建流程。

搭建说明

磁盘阵列相关概念参考《磁盘阵列搭建》一文。大家对 RAID10 和 RAID01 理解有些困难,下图是两者的区别。

RAID10 的组建形式:

RAID01 的组建形式:

RAID10 允许在每组中损坏一块盘,不允许坏一组;RAID01 允许坏一组,但不允许跨组坏盘。

流程演示

点击播放:

asciicast

expected shallow list 问题的解决

2022年2月13日 00:00

最近给博客圈小伙伴 Vian 同学架设了在线编辑器,实现了通过 GitLab 管理博客文章,通过 gitlab-runner 激活同步和部署操作。不过在近期升级时遇到一个问题导致部署失败,本文记录解决方法。

问题

1
2
3
4
5
6
7
8
9
10
11
12
Running with gitlab-runner 14.7.0 (98daeee0)
on VM-20-12-centos u6yhrxyg
Preparing the "shell" executor
Using Shell executor...
Preparing environment
Running on VM-20-12-centos...
Getting source from Git repository
Fetching changes with git depth set to 20...
Reinitialized existing Git repository in /root/builds/u6yhrxyg/0/vian/vian/.git/
fatal: git fetch-pack: expected shallow list
fatal: The remote end hung up unexpectedly
ERROR: Job failed: exit status 1

注意:Vian 同学在编辑好文章后,会自动触发 gitlab-runner 激活同步操作,服务器通过 Git 获取 GitLab 上面的文章数据,同步到本地再编译部署。而在同步阶段出现如上错误。

解决

经过筛查,报错主要由 Git 版本较低导致,刚好杜老师前几天分享了如何升级 Git 版本教程,可至《CentOS7 如何升级 Git 版本》查看。

经过升级,最终部署成功。

CentOS7 如何升级 Git 版本

2022年2月10日 00:00

杜老师习惯使用 Git 工具管理代码,最近因为工作所需,要在 CentOS7 服务器上安装 Git 工具,但在使用时出现了一些问题,最终发现因 Git 版本导致,那么就说说如何升级 Git 版本。

版本查询

1
2
[root@localhost ~]# git --version
git version 1.8.3.1

注意:杜老师服务器的 Git 是通过 yum 安装,使用命令查询目前版本。

尝试升级

1
2
3
4
5
6
7
[root@localhost ~]# yum update git
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: mirrors.bfsu.edu.cn
* extras: mirrors.bfsu.edu.cn
* updates: mirrors.bfsu.edu.cn
No packages marked for update

注意:杜老师首先想到的是使用 yum update 更新,结果事与原违,并没有版本的更新。

解决思路

在网上提供的升级方案,其本上都是先删除原来版本,然后在官网上下载最新版本,最后编译安装。编辑安装不仅麻烦,而且容易出错,无意中在网上看到一个 Git 软件源,在此分享一下使用方法:

1
vim /etc/yum.repos.d/wandisco-git.repo

首先输入上门命令新建配置文件,在配置文件中输入下面内容:

1
2
3
4
5
6
[wandisco-git]
name=Wandisco GIT Repository
baseurl=http://opensource.wandisco.com/centos/7/git/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://opensource.wandisco.com/RPM-GPG-KEY-WANdisco

因为开启了 gpgcheck,所以需导入 key 文件:

1
rpm --import http://opensource.wandisco.com/RPM-GPG-KEY-WANdisco

导入成功后即可进行 Git 升级:

1
yum -y udpate git

验证版本

1
2
[root@localhost ~]# git --version
git version 2.31.1

注意:版本升级成功。不过杜老师在升级前查询了官网最新版本是 2.35.1,看来该软件源并非最新版本。

解决 gitlab-runner 部署时 Host key verification failed 的报错问题

2021年12月27日 00:00

服务器例行维护时,升级了所有的软件。当再次使用 gitlab-runner 部署时,出现了 Host key verification failed 问题,本文简单说下解决思路!

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Running with gitlab-runner 14.6.0 (5316d4ac)
on iZ2ze3ifc44ezcec5t2nhrZ mzVoCiZK
Preparing the "shell" executor
00:00
Using Shell executor...
Preparing environment
00:01
Running on iZ2ze3ifc44ezcec5t2nhrZ...
Getting source from Git repository
00:00
Fetching changes with git depth set to 50...
Initialized empty Git repository in /home/gitlab-runner/builds/mzVoCiZK/0/penndu/dusays/.git/
Created fresh repository.
Host key verification failed.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
ERROR: Job failed: exit status 1

注意:上面是部署时报错。

解决

杜老师一开始以为是密钥的问题,曾尝试同步了客户端和服务端的密钥,但还是会报错,且报错的内容不变。

后来直接设置了 SSH 免密登录,问题仍然存在,但报错的内容变了。

提示是权限的问题,于是修改 gitlab-runner 的运行用户,成功搞定。

遇到同样问题的小伙伴,可以参考《修改 gitlab-runner 的执行用户》一文。

对于文本的处理和分析的小练习

2021年12月15日 00:00

在 Linux 中对于文本处理和分析是极为重要的,杜老师找了一道某度的运维工程师面试题,大家不妨试试能否完成要求。

介绍

1
2
cd /root/
wget https://cdn.dusays.com/2021/12/data1

注意:现在有一个文件叫做 data1,可使用上面的命令下载。

目标

data1 文件里记录是一些命令的操作记录,现在需要您从里面找出出现频率次数前 3 的命令并保存在 /root/result。

处理指定的文本文件 /root/data1。

将结果写入 /root/result。

结果包含三行内容,每行内容都是出现的次数和命令名称,如「100 ls」

提示

可能会使用到如下命令:

命令作用
cut截取
uniq去重
sort排序
|管道

答案

请务必自己独立思考解决问题之后再对照参考答案,一开始直接看参考答案收获不大:

cat data1 | cut -c 8- | sort | uniq -dc | sort -rn -k 1 | head -3 > /root/result

sort 的用法

2021年12月12日 00:00

sort 命令在 Linux 里非常有用,它将文本数据进行排序,并将排序结果标准输出。sort 命令既可以从特定的文件,也可以从 stdin 中获取数据。

字典排序

1
$ cat /etc/passwd | sort

反转排序

1
$ cat /etc/passwd | sort -r

特定排序

1
$ cat /etc/passwd | sort -t ':' -k 3

数值排序

1
$ cat /etc/passwd | sort -t ':' -k 3 -n

cut 的用法

2021年12月9日 00:00

cut 是一个选取命令,就是将一段数据经过分析取出我们想要的。一般来说,选取的信息通常是按行来进行分析的。cut 命令从文件的每一行剪切字节、字符和字段将这些字节、字符和字段输送到标准输出。

常用参数

参数作用
-b以字节为单位进行分割
-c以字符为单位进行分割
-d自定义分隔符,默认为制表符
-f与 -d 一起使用,指定显示哪个区域

举个例子

1
2
3
4
penn:~/ $ head -n 3 /etc/passwd | cut -d : -f 1,6 
root:/root
daemon:/usr/sbin
bin:/bin

前五个含

1
$ cut /etc/passwd -c -5

第五个后

1
$ cut /etc/passwd -c 5-

只有第五

1
$ cut /etc/passwd -c 5

二到五间

1
$ cut /etc/passwd -c 2-5

常用的正则表达式

2021年12月6日 00:00

杜老师经常需要使用正则表达式修改大量文件,为了方便大家,也是为了方便自己,杜老师整理了一份常用正则表达式并分享出来,方便大家查阅!

匹配中文字符的正则表达式

1
[\u4e00-\u9fa5]

注意:匹配中文还真是个头疼的事,有这个表达式就好办了。

匹配双字节的字符

1
[^\x00-\xff]

注意:可以用来计算字符串的长度。

匹配空白行正则表达式

1
\n\s*\r

注意:可用来删除空白行。

匹配 HTML 标记正则表达式

1
<(\S*?)[^>]*>.*?</\1>|<.*? />

注意:上面这个仅能匹配部分,对于复杂嵌套标记无能为力。

匹配首尾空白字符的正则表达式

1
^\s*|\s*$

注意:可用来删除行首行尾的空白字符。

匹配 Email 地址正则表达式

1
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

注意:表单验证时很实用。

匹配网址 URL 正则表达式

1
[a-zA-z]+://[^\s]*

注意:上面这个基本可以满足需求。

匹配帐号是否合法

1
^[a-zA-Z][a-zA-Z0-9_]{4,15}$

注意:表单验证时很实用。

匹配国内电话号码

1
\d{3}-\d{8}|\d{4}-\d{7}

注意:匹配形式如 123-45678910 或 1234-5678910。

匹配 QQ 号

1
[1-9][0-9]{4,}

注意:腾讯 QQ 号从 10000 开始。

匹配邮政编码

1
[1-9]\d{5}(?!\d)

注意:邮政编码 6 位数字。

匹配证件

1
[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9xX]

注意:证件为 15 位或 18 位,感谢贝贝提醒,已做更正。

匹配地址

1
\d+\.\d+\.\d+\.\d+

注意:提取 IP 地址时有用。

推荐值得收藏 34 个命令总结

2021年12月3日 00:00

例行维护、问题排查等是运维工程师的日常工作,杜老师收集了 30 个常用命令,推荐给会使用到的小伙伴们,如果您有更多的好用命令欢迎分享给我们!

删除文件

1
find -type f -size 0 -exec rm -rf {} \;

注意:删除 0 字节的文件。

查看进程

按内存使用率从大到小排列:

1
ps -e -o "%C : %p : %z : %a" | sort -k5 -nr

按 CPU 从大到小排列:

1
ps -e -o "%C : %p : %z : %a" | sort -nr

输出信息

1
grep -r -a jpg /data/cache/* | strings | grep "http:" | awk -F 'http:' '{print "http:"$2;}'

注意:打印 cache 里的 URL。

查看连接状态

1
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

注意:查看 http 的并发请求数及其 TCP 连接状态。

替换

1
sed -i '/Root/s/no/yes/' /etc/ssh/sshd_config 

注意:sed 在这个文里 Root 的一行,匹配 Root 行,将 no 替换成 yes。

杀掉进程

1
ps aux | grep mysql | grep -v grep | awk '{print $2}' | xargs kill -9

注意:杀掉 MySQL 的进程。

显示服务

1
ls /etc/rc3.d/S* | cut -c 15-

注意:显示运行 3 级别开启的服务。

显示多个信息

1
2
3
4
5
cat << EOF
+-------------------------------------------+
| === Welcome to dusays.com === |
+-------------------------------------------+
EOF

注意:用 EOF 在编写 Shell 显示多个信息。

for 的巧用

1
2
3
4
5
cd /usr/local/mysql/bin
for i in *
do
ln /usr/local/mysql/bin/$i /usr/bin/$i
done

注意:给 MySQL 建软链接。

取 IP 地址

1
2
ifconfig eth0 | grep "inet addr:" | awk '{print $2}' | cut -c 6-

注意:或 ifconfig | grep 'inet addr:' | grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'

内存大小

1
free -m | grep "Mem" | awk '{print $2}'

注意:截取内存大小数据。

查看端口

1
netstat -ant | grep ":80" | grep ESTABLISHED | awk '{printf "%s %s\n",$5,$6}' | sort

注意:查看 80 端口的连接信息。

统计文件大小

1
find / -name *.jpg -exec wc -c {} \; | awk '{print $1}' | awk '{a+=$1} END {print a}'

注意:统计服务器下面所有 jpg 文件的大小。

CPU 的负载

检查前三个输出值是否超过系统逻辑 CPU 的 4 倍:

1
cat /proc/loadavg

检查 %idle 值是否过低:

1
mpstat 1 1

内存空间

1
free

注意:检查 free 值是否过低,也可用 cat /proc/meminfo

交换空间

1
vmstat 1 5

注意:观察 si 和 so 值是否较大。

磁盘空间

1
df -h

注意:检查是否有分区使用率过高,如发现某分区空间接近用尽,可进入该分区的挂载点,用 du -cks * | sort -rn | head -n 10 命令找出占用空间最多的文件或目录。

磁盘负载

1
iostat -x 1 2

注意:检查 I/O 使用率是否过高。

网络负载

1
sar -n DEV

注意:检查网络流量是否过高。

网络错误

1
netstat -i

注意:检查是否出现网络错误,也可用命令 cat /proc/net/dev

网络连接数目

1
netstat -an | grep -E "^(tcp)" | cut -c 68- | sort | uniq -c | sort -n

注意:查询网络连接数目。

进程总数

1
ps aux | wc -l

注意:检查进程个数是否正常。

可运行的进程数目

1
vmwtat 1 5

注意:列出的是可运行进程的数目,检查是否超过系统逻辑 CPU 的 4 倍。

进程

1
top -id 1

注意:观察是否有异常的进程出现。

用户

1
who | wc -l

注意:检查登录用户是否过多「比如超过 50 个」也可用命令 uptime

系统日志

检查是否有异常的错误记录:

1
cat /var/log/rflogview/*errors

搜寻一些异常的关键字:

1
2
grep -i error /var/log/messages
grep -i fail /var/log/messages

核心日志

1
dmesg

注意:检查是否有异常的错误记录。

系统时间

1
date

注意:检查系统时间是否正确。

打开文件数目

1
lsof | wc -l

注意:检查打开文件总数是否过多。

杀掉进程

1
lsof -i :80 | grep -v ID | awk '{print "kill -9",$2}' | sh

注意:杀掉 80 端口相关的进程。

清除进程

1
ps -eal | awk '{if ($2 == "Z") {print $4}}' | kill -9

注意:清除僵尸进程。

分析数据

1
tcpdump -c 10000 -i eth0 -n dst port 80 > /root/pkts

注意:用 tcpdump 抓包,防止 80 端口被人攻击时可以分析数据。

检查 IP 重复数

1
less pkts | awk {'printf $3"\n"'} | cut -d. -f 1-4 | sort | uniq -c | awk {'printf $1" "$2"\n"'} | sort -n -t\ +0

注意:检查 IP 的重复数并从小到大排序。

查看活动进程

1
netstat -anp | grep php-cgi | grep ^tcp | wc -l

注意:查看有多少个活动的 php-cgi 进程。

使用 Docker 搭建我的世界服务器

2021年11月12日 00:00

这几天一直在研究容器,偶尔抽空玩会我的世界,突发奇想:可否通过 Docker 搭建我的世界服务器?今天就来操作下吧!

设备需求

如果只是自己游戏,那主机的配置没啥要求,能进就行。如果是联网大家玩,建议选择 CPU 主频较高的主机,不要考虑多核多线程的问题,目前不管官方还是其它核心,对多线程优化都不够好。

如果更喜欢高版本的小伙伴「如杜老师」建议使用水桶或纸飞机核心,官方核心实在不推荐的!杜老师强烈推荐纸飞机,相比水桶稳定性差一些「偶尔可能报错,但不影响游戏」纸飞机的性能优化还是很明显的,当然还有其它衍生版本,这里就不再推荐了。

下载镜像

1
2
3
4
5
6
7
8
penn@dusays:~$ sudo docker pull minecraftservers/minecraft-server
Using default tag: latest
latest: Pulling from minecraftservers/minecraft-server
476c1ed2267c: Pull complete
4f4fb700ef54: Pull complete
Digest: sha256:b279da117768925b4a773176dee5c0e8669e3af2abcca58c11b82a05640c6248
Status: Downloaded newer image for minecraftservers/minecraft-server:latest
docker.io/minecraftservers/minecraft-server:latest

注意:在 Docker Hub 上有很多镜像,大多都是玩家自行创建上传分享。杜老师选了一个版本最新且功能最全的为示例。

存档目录

1
2
3
4
penn@dusays:~$ sudo mkdir -v /data
mkdir: 已创建目录 '/data'
penn@dusays:~$ sudo chmod 777 -c /data
'/data' 的权限模式已由 0755 (rwxr-xr-x) 更改为 0777 (rwxrwxrwx)

注意:创建服务器运行容器前,我们需要先创建好游戏存档目录,并赋予 Docker 访问权限。

创建容器

1
2
3
penn@dusays:~$ sudo docker run -itd --name=mc -v /data:/data -p 25565:25565 \
> -e EULA=TRUE -e VERSION=1.17 -e TYPE=PAPER minecraftservers/minecraft-server
0d3f314da12e2e2d9c59ac3a40a2102507c98c54b7601d1332a6f627ed15a4b2

注意:-e EULA=TRUE 为必须参数,如果不设置将无法正常进入游戏;-e VERSION=1.17 用于指定服务端游戏版本,杜老师用的就是 1.17;-e TYPE=PAPER 为指定核心,优势在前文踢到了。

查看存档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
penn@dusays:~$ ls -l /data
总用量 59068
-rw-rw-r-- 1 penn penn 2 11月 16 18:16 banned-ips.json
-rw-rw-r-- 1 penn penn 2 11月 16 18:16 banned-players.json
-rw-rw-r-- 1 penn penn 1136 11月 16 18:16 bukkit.yml
drwxrwxr-x 2 penn penn 4096 11月 16 18:16 cache
-rw-rw-r-- 1 penn penn 598 11月 16 18:16 commands.yml
-rw-rw-r-- 1 penn penn 65 11月 16 18:15 eula.txt
-rw-rw-r-- 1 penn penn 2576 11月 16 18:16 help.yml
drwxrwxr-x 2 penn penn 4096 11月 16 18:16 logs
-rw-rw-r-- 1 penn penn 2 11月 16 18:16 ops.json
-rw-rw-r-- 1 penn penn 60391784 11月 16 18:16 paper-1.17-79.jar
-rw-rw-r-- 1 penn penn 8604 11月 16 18:17 paper.yml
-rw-rw-r-- 1 penn penn 0 11月 16 18:16 permissions.yml
drwxrwxr-x 3 penn penn 4096 11月 16 18:16 plugins
-rwxr-xr-x 1 penn penn 1220 11月 16 18:16 server.properties
-rw-rw-r-- 1 penn penn 4367 11月 16 18:17 spigot.yml
-rw-rw-r-- 1 penn penn 2 11月 16 18:16 usercache.json
-rw-rw-r-- 1 penn penn 44 11月 16 18:16 version_history.json
-rw-rw-r-- 1 penn penn 2 11月 16 18:16 whitelist.json
drwxrwxr-x 8 penn penn 4096 11月 16 18:17 world
drwxrwxr-x 3 penn penn 4096 11月 16 18:17 world_nether
drwxrwxr-x 3 penn penn 4096 11月 16 18:17 world_the_end

注意:启动容器后稍等会,就会在游戏存档目录中,看到新生成的相关文件,具体作用和配置可自行搜索。

进控制台

如果需要进入到游戏控制台,可以参考如下命令,如需退出按CTRL+C即可:

1
2
sudo docker exec -i mc rcon-cli
>

还有一种进入方式,参考如下命令。进入后没有任何提示符,直接输入指令操作即可。只是退出比较麻烦,需先按CTRL+P,后再按CTRL+Q才行:

1
sudo docker attach mc

什么是 Docker in Docker

2021年11月9日 00:00

Docker 技术目前在 DevOps 中被广泛使用,我们需要将测试或者构建的代码和自动化脚本打包成 Docker 镜像,然后部署在各个运行环境中。

需求背景

而在 CI/CD 中,我们常用一些 CI/CD 服务器,比如 Jenkins 和 GoCD 来构建与部署我们的应用,从而实现 CI/CD 自动化。现在一些 CI/CD 服务器也被 Docker 化运行在真实的物理机上。于是我们需在 CI/CD 服务器的 Docker container 里面来 build 与 run 我们的 Docker 镜像,这就涉及到 Docker in Docker 问题。

一个很自然的想法:我们是不是需要在 CI/CD 服务器镜像中安装一个 Docker Daemon 和 Docker 命令?但是 Docker 里面跑 Docker 总感觉有些蹩脚,额外安装与运行 Docker 无疑增加了 CI/CD 服务器镜像的大小,同时还增加了 Docker 的深度。

实现思路

实际上我们并不需要在 CI/CD 服务器上安装 Docker。通过上面的命令在 CI/CD 服务器上运行我们的镜像:

1
docker run -v /var/run/docker.sock:/var/run/docker.sock

Docker 采取的是 C/S 架构,Docker 的成功运行需要 Docker Daemon 和 Docker Client 的支持,当我们运行一些 docker build 等命令时,实际需要 Docker Client 连接 Docker Daemon 发送命令,Docker Daemon 会在宿主机操作系统分配文件、网络资源:

修改 gitlab-runner 的执行用户

2021年10月16日 00:00

安装 gitlab-runner 构建机默认会将用户设置为 gitlab-runner,该设置会导致.gitlab-ci.yml 脚本运行时出现一些权限问题。为了解决这些权限问题,杜老师将 gitlab-runner 构建机上的默认用户设置为 root。

写在最前

这种方式虽然简单粗暴,当然也会带来一些弊端,比如:通过.gitlab-ci.yml 脚本进行文件操作要格外小心。

另外要做好服务端安全设置,确保不要被恶意用户获取到操作权限。

操作步骤

通过下面命令可以查看到 gitlab-runner 的工作目录和默认用户等一系列相关信息:

1
ps aux | grep gitlab-runner

通过下面命令可以卸载掉 gitlab-runner 默认用户:

1
gitlab-runner uninstall

通过下面命令将 gitlab-runner 运行用户设置为 root:

1
gitlab-runner install --user root

最后重启 gitlab-runner 就行了:

1
systemctl restart gitlab-runner

两种通过 Nginx 实现强制 HTTPS 访问方法

2021年10月13日 00:00

现在 HTTPS 已非常普遍,很多网站都加了 SSL 证书,但仍然有许多访客使用 HTTP 的方式访问,今天杜老师分享下两种通过 Nginx 实现强制 HTTPS 访问方法。

强制跳转访问

1
2
3
4
5
#HTTP_TO_HTTPS_START
if ($server_port !~ 443){
rewrite ^(/.*)$ https://$host$1 permanent;
}
#HTTP_TO_HTTPS_END

注意:将上面的代码无需任何编辑,直接复制到 Nginx 的配置文件中即可,当用户通过 HTTP 访问,会强制跳转到 HTTPS 的形式。

强制安全访问

1
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

注意:max-age 为强制最大时间,单位为秒,设置 31536000 则含义为一年内强制使用 HTTPS 的形式访问;includeSubDomains 含义为包含二级域名,如存在该设置,则 dusays.comcdn.dusays.com 都要验证;always 为响应所有的请求头。

Ubuntu 的 DNS 不可用处理办法

2021年10月10日 00:00

受博友圈夏目同学所托,帮其新购置的云服务器搭建网站运行环境。几个 apt 的问题,想都没想就答应了,却未料到一开始就出现问题,Ubuntu 的 DNS 不可用,今天说下如何解决这个问题。

问题

接手新系统后,习惯性第一时间更新软件源,却发现执行失败了。看返回的错误提示,判断应该是域名解析的问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@dusays:~# apt update
Err:1 http://archive.ubuntu.com/ubuntu bionic InRelease
Temporary failure resolving 'archive.ubuntu.com'
Err:2 http://security.ubuntu.com/ubuntu bionic-security InRelease
Temporary failure resolving 'security.ubuntu.com'
Err:3 http://archive.canonical.com/ubuntu bionic InRelease
Temporary failure resolving 'archive.canonical.com'
Err:4 http://archive.ubuntu.com/ubuntu bionic-updates InRelease
Temporary failure resolving 'archive.ubuntu.com'
Reading package lists... Done
Building dependency tree... Done
All packages are up to date.
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/bionic/InRelease Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/bionic-updates/InRelease Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://security.ubuntu.com/ubuntu/dists/bionic-security/InRelease Temporary failure resolving 'security.ubuntu.com'
W: Failed to fetch http://archive.canonical.com/ubuntu/dists/bionic/InRelease Temporary failure resolving 'archive.canonical.com'
W: Some index files failed to download. They have been ignored, or old ones used instead.

测了一下网络的连通性,没有任何问题,可以与 DNS 服务器正常通信:

1
2
3
4
5
6
7
8
9
10
11
root@dusays:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=1.53 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=118 time=1.52 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=118 time=1.56 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=118 time=1.57 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=118 time=1.55 ms
^C
--- 8.8.8.8 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 1.522/1.551/1.575/0.040 ms

又使用杜老师的博客域名做了下测试,果然又报错了,几乎可以确定是 DNS 问题:

1
2
root@dusays:~# ping dusays.com
ping: dusays.com: Temporary failure in name resolution

查看一下通用 DNS 服务器配置文件,发现该文件已被 systemd-resolved 服务替代,看来需要激活 systemd-resolved 才可以:

1
2
3
4
5
root@dusays:~# cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.

解决

添一条设置项到/etc/systemd/resolved.conf「该主机在国外,如果是国内的主机,建议不要用8.8.8.8,以免因为网络不稳导致解析失败」默认该项会被注释,直接执行下面命令即可:

1
root@dusays:~# echo "DNS=8.8.8.8" >> /etc/systemd/resolved.conf

因修改了配置文件,需要重启服务,却发现提示该服务被锁:

1
2
root@dusays:~# systemctl restart systemd-resolved.service
Failed to restart unit: Unit file /etc/systemd/system/systemd-resolved.service is masked.

使用下面命令即可解锁服务:

1
2
root@dusays:~# systemctl unmask systemd-resolved.service
Removed /etc/systemd/system/systemd-resolved.service.

查看一下服务状态,目前该服务已经被解锁,并且服务没在运行,且未设置开机启动:

1
2
3
4
5
6
7
8
root@dusays:~# systemctl status systemd-resolved
● systemd-resolved.service - Network Name Resolution
Loaded: loaded (/lib/systemd/system/systemd-resolved.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:systemd-resolved.service(8)
https://www.freedesktop.org/wiki/Software/systemd/resolved
https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients

使用下面命令启动服务:

1
root@dusays:~# systemctl start systemd-resolved

使用下面命令设置开机启动:

1
2
3
root@dusays:~# systemctl enable systemd-resolved.service
Created symlink /etc/systemd/system/dbus-org.freedesktop.resolve1.service → /lib/systemd/system/systemd-resolved.service.
Created symlink /etc/systemd/system/multi-user.target.wants/systemd-resolved.service → /lib/systemd/system/systemd-resolved.service.

再次通过杜老师说域名测试一下,发现解析没问题了:

1
2
3
4
5
6
7
8
9
root@dusays:~# ping dusays.com
PING dusays.com (76.76.21.21) 56(84) bytes of data.
64 bytes from 76.76.21.21 (76.76.21.21): icmp_seq=1 ttl=120 time=1.91 ms
64 bytes from 76.76.21.21 (76.76.21.21): icmp_seq=2 ttl=120 time=1.91 ms
64 bytes from 76.76.21.21 (76.76.21.21): icmp_seq=3 ttl=120 time=1.89 ms
^C
--- dusays.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 1.896/1.907/1.914/0.007 ms

重新执行下软件源更新命令,执行成功,问题解决:

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
root@dusays:~# apt update
Get:1 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]
Get:2 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
Get:3 http://archive.canonical.com/ubuntu bionic InRelease [10.2 kB]
Get:4 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Get:5 http://archive.ubuntu.com/ubuntu bionic/main amd64 Packages [1019 kB]
Get:6 http://archive.ubuntu.com/ubuntu bionic/main Translation-en [516 kB]
Get:7 http://archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages [9184 B]
Get:8 http://archive.ubuntu.com/ubuntu bionic/restricted Translation-en [3584 B]
Get:9 http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages [8570 kB]
Get:10 http://archive.canonical.com/ubuntu bionic/partner amd64 Packages [1592 B]
Get:11 http://archive.ubuntu.com/ubuntu bionic/universe Translation-en [4941 kB]
Get:12 http://archive.canonical.com/ubuntu bionic/partner Translation-en [1004 B]
Get:13 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [2237 kB]
Get:14 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [1892 kB]
Get:15 http://archive.ubuntu.com/ubuntu bionic-updates/main Translation-en [436 kB]
Get:16 http://archive.ubuntu.com/ubuntu bionic-updates/restricted amd64 Packages [483 kB]
Get:17 http://archive.ubuntu.com/ubuntu bionic-updates/restricted Translation-en [65.6 kB]
Get:18 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [1749 kB]
Get:19 http://archive.ubuntu.com/ubuntu bionic-updates/universe Translation-en [375 kB]
Get:20 http://security.ubuntu.com/ubuntu bionic-security/main Translation-en [344 kB]
Get:21 http://security.ubuntu.com/ubuntu bionic-security/restricted amd64 Packages [459 kB]
Get:22 http://security.ubuntu.com/ubuntu bionic-security/restricted Translation-en [61.7 kB]
Get:23 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [1138 kB]
Get:24 http://security.ubuntu.com/ubuntu bionic-security/universe Translation-en [259 kB]
Get:25 http://security.ubuntu.com/ubuntu bionic-security/multiverse amd64 Packages [20.9 kB]
Get:26 http://security.ubuntu.com/ubuntu bionic-security/multiverse Translation-en [4732 B]
Fetched 25.0 MB in 5s (5376 kB/s)
Reading package lists... Done
Building dependency tree... Done
15 packages can be upgraded. Run 'apt list --upgradable' to see them.
root@dusays:~#

通过 SRV 解析无需端口连接我的世界服务器

2021年9月16日 00:00

SRV 记录是 DNS 服务器的数据库中支持的一种资源记录类型,它记录了哪台计算机提供哪个服务这么一个简单的信息。一般是为 Microsoft 的活动目录设置时的应用。

需求背景

杜老师搭建我的世界服务器已经有一个多月了,有很多小伙伴加入一起游戏,被问到最多的问题就是:游戏的端口是多少?

我们的服务器是同他人合租,所以无法使用默认端口,连接时需输入端口才可进入游戏,无形中增加了记忆成本。

如何免端口进入游戏呢?杜老师之前有写过一篇文章《80 端口重定向三种解决方案》,可以通过反向代理、端口转发等方式解决该问题,但需要在用户和服务器间新增一台中间件,这将会增加游戏的延迟。

最终杜老师了解到,可以通过 DNS 解析中的 SRV 功能,实现不需要端口连接我的世界服务器。

解析设置

这里已 Cloudflare 为例,演示如何添加 SRV 解析项。参考如图,其中类型选 SRV,名称则为二级域名,如需要通过 mc.dusays.com 连接游戏,则名称输入 mc,服务可自定义,因为我们要连接我的世界服务器,所以填写了_minecraft,协议根据实际情况选择 TCP 或者 UDPTTL 可自动,优先级和权重根据需求填写,范围是 0-65535,数字越小优先级和权重越高,端口则写服务器的端口,最后在目标中填写服务器的地址:

设置效果

设置好解析后保存即可,等待解析同步 DNS 缓存服务器,2 小时内即可同步完成「往往等几分钟即可」进入游戏后添加服务器试试,效果如下动画:

解析查询

这里做个技术扩展,我们可以通过 nslookup 命令查看 SRV 解析,完整的命令参考 nslookup -q=srv _minecraft._tcp.mc.dusays.com,执行效果如图:

ip -s link 输出内容的注解

2021年9月10日 00:00

ip 命令用来显示或操纵 Linux 主机的路由、网络设备、策略路由和隧道等,是 Linux 下比较新且功能强大的网络配置工具。下面对 ip -s link 输出的内容进行简单的注解。

命令截图

参数含义

参数含义
lo网卡名称
LOOPBACK环回地址
UP启用状态
LOWER_UP物理网卡处于启动状态
BROADCAST开启广播功能
MULTICAST开启多播功能
mtu 65535MTU 值
qdisc传输队列规则
noqueue没有规则限制
fq_codel流量队列控制延迟
state状态
UNKNOWN未知
mode DEFAULT group default qlen 1000默认模式
link/loopback网卡类型
00:00:00:00:00:00物理地址
brd广播地址
RX: bytes收到的数据量
packets通信的数据包
errors错误的数据包
dropped表示数据包已经进入 Ring Buffer,但由于内存不够等系统原因,导致在拷贝到内存过程中被丢弃。
overrun指被物理网卡丢弃
mcast多播包的数量
TX: bytes发送的数据量
carrier由于 carrier 错误而丢弃的数据包数量
collsns冲突信息包的数目

Ubuntu 设置指定软件不参与升级

2021年9月7日 00:00

与 CentOS 的 yum -y update APPNAME 不同,Ubuntu 在使用 apt -y dist-upgrade 更新时无法指定软件,会更新所有已安装程序,今天杜老师说下如何设置指定软件不参与升级。

查询软件状态

1
2
3
4
5
6
7
8
penn@penn-VMware-Virtual-Platform:~/桌面$ sudo dpkg --get-selections
...
zenity-commoninstall
zhaoxin-linux-graphics-driver-dri:amd64install
zipinstall
zlib1g:amd64install
zlib1g-dev:amd64install
penn@penn-VMware-Virtual-Platform:~/桌面$

注意:使用 sudo dpkg --get-selections 可查询所有软件状态,输出数据会比较多,建议用 more 命令分屏显示。其中左侧为软件名,右侧为软件的状态。install 为升级,hold 为锁定「即不升级」

修改软件状态

如果需要锁定软件,可执行 sudo echo APPNAME hold | sudo dpkg --set-selections,其中 APPNAME 为软件名称,修改后可以通过命令 sudo dpkg --get-selections | grep hold 查询是否生效。下面以 zip 作为演示:

1
2
3
4
5
penn@penn-VMware-Virtual-Platform:~/桌面$ sudo dpkg --get-selections | grep hold
penn@penn-VMware-Virtual-Platform:~/桌面$ sudo echo zip hold | sudo dpkg --set-selections
penn@penn-VMware-Virtual-Platform:~/桌面$ sudo dpkg --get-selections | grep hold
ziphold
penn@penn-VMware-Virtual-Platform:~/桌面$

如需恢复软件状态,可执行 sudo echo APPNAME install | sudo dpkg --set-selections

1
2
3
4
5
penn@penn-VMware-Virtual-Platform:~/桌面$ sudo dpkg --get-selections | grep hold
ziphold
penn@penn-VMware-Virtual-Platform:~/桌面$ sudo echo zip install | sudo dpkg --set-selections
penn@penn-VMware-Virtual-Platform:~/桌面$ sudo dpkg --get-selections | grep hold
penn@penn-VMware-Virtual-Platform:~/桌面$

80 端口重定向三种解决方案

2021年7月27日 00:00

当搭建非 80 端口服务时,是无法直接通过域名访问的。一般我们会通过 Nginx 的反向代理功能实现端口重定向,今天我们聊一下三种重定向解决方案。

通过 Nginx 等反向代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#PROXY-START/
location /
{
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;

add_header X-Cache $upstream_cache_status;

#Set Nginx Cache

add_header Cache-Control no-cache;
expires 12h;
}

#PROXY-END/

注意:其它 Web 引擎的反向代理配置,可以参考《常见 Web 引擎的反向代理配置参考》一文。

通过 CDN 指定源地址

以阿里云 CDN 为例,演示如何配置实现反向代理:

通过 IPTABLES 防火墙

1
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

注意:如果需本机也可以访问,则需配置 OUTPUT 链,可参考命令 iptables -t nat -A OUTPUT -d localhost -p tcp --dport 80 -j REDIRECT --to-ports 8080,外网访问需要经过 PREROUTING 链,但是 localhost 不经过该链,因此需要用 OUTPUT。

通过 firewalld 防火墙

1
firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080

注意:如果需开启 IP 地址伪装,则运行 firewall-cmd --permanent --add-masquerade

Linux 下修改 MTU 值

2021年7月21日 00:00

最大传输单元用来通知对方所能接受数据服务单元最大尺寸,说明发送方能够接受的有效载荷大小。是包或帧最大长度,一般以字节记。如 MTU 过大,碰到路由器时会被拒绝转发,因它不能处理过大的包。如果太小,因为协议一定要在包上加上包头,那实际传送的数据量会过小,这样也划不来。大部分操作系统会提供给用户一个默认值,该值一般对用户比较合适的。

修改 MTU 值

临时修改,重启网络即会失效。NIC 指网卡设备「下同」NUM 为设置 MTU 值:

1
ifconfig NIC mtu NUM up

永久生效,修改配置文件后需重启网络:

1
2
echo 'MTU="NUM"' >> /etc/sysconfig/network-scripts/ifcfg-NIC # for CentOS or Red Hat Enterprise Linux
echo 'mtu NUM' >> /etc/network/interfaces # for Debian or Ubuntu

测试修改

用 Ping 命令,-l 指定包大小,-f 选项为通知操作系统不能私自更改该数据包大小。使用英文操作系统时的提示为 Packet needs to be fragmented but DF set:

mysqldump 实现定时备份远程数据库

2021年6月12日 00:00

mysqldump 可以把整个数据库装载到一个单独的文本文件中。这个文件包含有所有重建您的数据库所需的 SQL 命令。这个命令取得所有的模式并将其转换成 DDL 语法,取得所有数据,并从这些数据中创建 INSERT 语句。这个工具将您的数据库中所有的设计倒转。因为所有的东西都被包含到了一个文本文件中。这个文本文件可用一个简单的批处理和一个合适 SQL 语句导回到 MySQL。

需求背景

杜老师说的评论数据存放于 MySQL 数据库,为保证服务持久性,故需独立部署。单独使用云主机太浪费,云数据库成本又高,所以杜老师选择临时的 MySQL 数据库。

但是无法保障该数据库的安全性,所以需要使用定期备份,以确保评论不丢失。

备份命令

命令格式,其中的大写处为自定义:

1
mysqldump -hHOSTNAME -uUSERNAME -pPASSWORD DATABASE > /PATH/FILENAME.sql

命令解释:

命令解释
mysqldump备份命令
-hHOSTNAME指定数据库的访问地址
-uUSERNAME指定数据库的访问用户
-pPASSWORD数据库用户的密码
DATABASE需备份的数据库名
>将生成的数据写入文件
/PATH/FILENAME.sql备份文件路径

备份脚本

按照日期生成备份文件,脚本内容参考如下:

1
2
#!/bin/bash
mysqldump -hHOSTNAME -uUSERNAME -pPASSWORD DATABASE > /PATH/FILENAME_`date +'%Y%m%d'`.sql

如需定时执行,先执行 crontab -e,然后添加如下内容:

1
0 0 * * * /PATH/mysqldump.sh

写在最后

如提示 mysqldump 命令没有找到,则运行下面的命令安装:

1
2
apt -y install mysql-client # for Debian or Ubuntu
yum -y install mariadb-client # for CentOS or Red Hat Enterprise Linux

如提示文件无权限,则运行下面的命令安装:

1
chmod +x /PATH/mysqldump.sh

如何学习 Linux 呢

2021年5月4日 00:00

近期有一些 Linux 爱好者找到我,问如何学习 Linux。我虽自称为杜老师,不过不做老师也很久了,仅凭记忆总结一些学习路径,希望可以帮到大家!

学习心态

首先明确目的,用 Linux 来干什么,是搭建服务器、程序开发、日常办公,还是娱乐游戏?

其次面对现实,Linux 大都在命令行下操作,能否接受不用或者少用图形界面。

再者是学习 Linux 操作系统本身还是某个 Linux 发行版。

最后注重基础,从头开始。

学习路径

学习路径如下:

Linux 与 Windows 有哪些不同

2021年5月1日 00:00

Linux 的普及程度越来越高,相比大家常用的 Windows 系统,都有哪些不同,今天杜老师通过不同的角度,分享一下两者都有哪些不同!

免费收费

最新正版的 Windows10,需要付费购买。

Linux 免费或少许费用。

软件支持

Windows 的软件支持:

  1. 数量和质量的优势,不过大部分为收费软件;
  2. 由微软官方提供重要支持和服务。

Linux 的软件支持:

  1. 大都属于开源自由软件,用户可以修改定制和再发布,由于基本免费没有资金支持,部分软件的质量和体验欠缺;
  2. 由全球所有的 Linux 开发者们和自由软件社区提供支持。

平台安全

Windows 三天两头打补丁安装系统安全更新,还是会中病毒木马。

如果说 Linux 没有安全问题,那当然是不可能的,这一点仁者见仁智者见智,相对来说肯定比 Windows 平台更加安全,使用 Linux 也不用装某杀毒。

使用习惯

Windows 的普通用户基本都是纯图形界面下操作使用,依靠鼠标、键盘完成一切操作,用户上手容易,入门简单。

Linux 兼具备图形界面操作「需要使用带有桌面环境的发行版」以及完全的命令行操作,可以只用键盘完成一切操作,新手入门比较困难,需一些学习和指导,一旦熟练之后效率极高。

可定制性

Windows 这些年之前算是全封闭的,系统可定制性很差。

Linux 想怎么做都可以,Windows 能做到得它都能,Windows 做不到的它也能。

应用范畴

或许之前不知道 Linux,要知道在访问某度、某宝、杜老师说和去不图床时,支撑这些软件和服务的,是后台成千上万的 Linux 服务器主机,它们时时刻刻都在忙碌地进行数据处理和运算,可以说世界上大部分软件和服务都是运行在 Linux 上的。

如运行 Windows 系统则需要较高的配置,需要更多服务器的运营成本。Linux 则占用资源较少,可以节省运营成本。

Windows 没有的

  1. 较稳定的系统;

  2. 安全和漏洞的快速修补;

  3. 用户和用户组规划;

  4. 相对较少系统资源占用;

  5. 可自定义裁剪,移植到嵌入式平台;

  6. 可选择的多种图形用户界面。

Linux 没有的

  1. 特定支持厂商;

  2. 足够的游戏娱乐支持度;

  3. 足够的专业软件支持度;

  4. 相对绚丽图形界面。

杜老师说网站架构

2021年4月22日 00:00

最近调整了杜老师说的网站架构,保障平稳运行的同时降低运营的成本,此文做记录的同时也向大家分享一下目前架构,如有建议欢迎在评论区留言!

网站架构

杜老师说网站架构:

数据走向

访客通过互联网将请求发送至域名解析服务器,DNS 服务器为 Cloudflare「以下简称为 CF」仅作域名解析,并未开启缓存功能。

CF 将域名指向 CDN 地址,CDN 优先查找对应的缓存数据,如未找到缓存数据,则请求 OSS 中保存的网站数据。

OSS 的网站数据由 ECS 生成,ECS 运行 Hexo,生成的网站源码通过 API 传输至 OSS。

当访客评论时,评论数据发送给 CDN,并经由北京 ECS 存至香港 ECS 数据库。

架构优点

CDN 可以隐藏后端服务器的真实 IP,保护 ECS 不被 DDoS,同时 CDN 的缓存功能可以降低后端负载,且降低 OSS 因流量产生的费用。

ECS 通过内网连接 OSS,提升传输速率同时,降低因流量产生的费用「内网流量免费」

通过 OSS 静态网站功能可以降低 ECS 负载,且外网流量费用低于 ECS「ECS 带宽按流量付费」

多个节点数据互不影响,保障高效运行同时降低因数据丢失产生的影响。

架构缺点

两台 ECS 服务器不在同一地域,跨域访问会影响传输的速率,且会产生额外费用。

CDN 缓存会导致网站内容更新延迟,部分内容更新后需手动刷新缓存数据才可正常访问。

去不图床网站架构

2021年4月19日 00:00

最近调整了去不图床的网站架构,保障平稳运行的同时降低运营的成本,此文做记录的同时也向大家分享一下目前架构,如有建议欢迎在评论区留言!

网站架构

去不图床网站架构:

数据走向

访客通过互联网将请求发送至域名解析服务器,图床的 DNS 为 Cloudflare「以下简称为 CF」CF 已开启缓存功能,会优先查找对应的缓存数据,如未找到缓存数据,则请求 ECS 中运行的网站数据。

当访客上传图片时,通过 ECS 将数据保存至 OSS,并返回图片的访问地址。

当访客通过外链访问图片数据时,CF 优先查找对应的缓存数据,如未找到缓存数据,则请求 CDN 中的缓存数据。

如 CDN 中未找到缓存数据,则从 OSS 中调用图片数据,同时进行图片鉴黄操作,最后将数据传输给访客。

架构优点

CF 可以隐藏后端服务器的真实 IP,保护 ECS 不被 DDoS,同时 CF 的缓存功能可以降低后端负载,且降低 OSS/CDN 因流量产生的费用。

ECS 通过内网连接 OSS,提升传输速率同时,降低因流量产生的费用「内网流量免费」

架构缺点

服务节点较多,获取图片数据需经过三个节点,且三节点不在同一地域,跨域访问会影响传输的速率。

阿里云的 CDN 图片鉴黄功能非实时拦截,需人工做图片拦截操作。

Linux Mint 界面的选择

2021年3月2日 00:00

Cinnamon/Mate 和 Xfce 除了特性和性能之外,还代表了三种不同桌面环境,它们有不同的菜单,不同的面板和配置工具。如果您不确定应该选取哪个桌面,可以看看这篇文章!

风格对比

Linux Mint 有三种不同风格版本,分别提供三种不同桌面环境:

版本特点
Cinnamon最现代最新颖、全功能的桌面
MATE更稳定更快的桌面
Xfce最轻量最稳定

界面效果

Linux Mint 最流行的版本是 Cinnamon 版。Cinnamon 是主要由 Linux Mint 团队开发,专为 Linux Mint 打造的桌面环境,流畅,美观:

Linux Mint 也参与了 MATE 开发。MATE 是一个经典桌面环境。它是 GNOME2 的一个延续,在 2006 到 2011 年间曾作为 Linux Mint 默认桌面环境。虽然它缺少一些新特性,开发也比 Cinnamon 慢,但它运行更加快速,消耗更少资源,比 Cinnamon 更加稳定:

Xfce 是一个轻量级的桌面环境。它支持的特性没有 Cinnamon 和 MATE 那么多,但极其稳定并且消耗极少的资源:

CentOS8 升级 Stream

2021年2月7日 00:00

红帽和 CentOS 最近宣布 CentOS 将以 CentOS Stream 的形式转换为滚动发行版本。本教程中,杜老师将展示如何将 CentOS8 安装更新到 CentOS Stream。

安装新系统源

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
35
[root@localhost ~]# dnf -y install centos-release-stream
CentOS Linux 8 - AppStream 6.4 kB/s | 4.3 kB 00:00
CentOS Linux 8 - BaseOS 7.1 kB/s | 3.9 kB 00:00
CentOS Linux 8 - Extras 2.6 kB/s | 1.5 kB 00:00
依赖关系解决。
================================================================================
软件包 架构 版本 仓库 大小
================================================================================
安装:
centos-release-stream x86_64 8.1-1.1911.0.7.el8 extras 11 k

事务概要
================================================================================
安装 1 软件包

总下载:11 k
安装大小:6.6 k
下载软件包:
centos-release-stream-8.1-1.1911.0.7.el8.x86_64 101 kB/s | 11 kB 00:00
--------------------------------------------------------------------------------
总计 25 kB/s | 11 kB 00:00
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
准备中 : 1/1
安装 : centos-release-stream-8.1-1.1911.0.7.el8.x86_64 1/1
验证 : centos-release-stream-8.1-1.1911.0.7.el8.x86_64 1/1
Installed products updated.

已安装:
centos-release-stream-8.1-1.1911.0.7.el8.x86_64

完毕!

注意:运行命令 dnf -y install centos-release-stream 安装软件包,这包含所有需要的仓库文件。

更新系统文件

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
[root@localhost ~]# dnf -y distro-sync
CentOS-Stream - AppStream 384 kB/s | 6.5 MB 00:17
CentOS-Stream - Base 904 kB/s | 2.3 MB 00:02
CentOS-Stream - Extras 7.4 kB/s | 7.0 kB 00:00
依赖关系解决。
================================================================================
软件包 架构 版本 仓库 大小
================================================================================
安装:
centos-stream-release noarch 8.4-1.el8 Stream-BaseOS 21 k
替换 centos-linux-release.noarch 8.3-1.2011.el8
替换 centos-release-stream.x86_64 8.1-1.1911.0.7.el8
kernel x86_64 4.18.0-269.el8 Stream-BaseOS 5.2 M
kernel-core x86_64 4.18.0-269.el8 Stream-BaseOS 35 M
kernel-modules x86_64 4.18.0-269.el8 Stream-BaseOS 27 M
升级:
NetworkManager x86_64 1:1.30.0-0.5.el8 Stream-BaseOS 2.5 M
NetworkManager-adsl x86_64 1:1.30.0-0.5.el8 Stream-BaseOS 139 k
NetworkManager-bluetooth x86_64 1:1.30.0-0.5.el8 Stream-BaseOS 164 k
NetworkManager-config-server noarch 1:1.30.0-0.5.el8 Stream-BaseOS 126 k
NetworkManager-libnm x86_64 1:1.30.0-0.5.el8 Stream-BaseOS 1.8 M
...
xorg-x11-server-Xorg x86_64 1.20.10-1.el8 Stream-AppStream 1.5 M
xorg-x11-server-Xwayland x86_64 1.20.10-1.el8 Stream-AppStream 978 k
xorg-x11-server-common x86_64 1.20.10-1.el8 Stream-AppStream 42 k
yum noarch 4.4.2-3.el8 Stream-BaseOS 200 k
zlib x86_64 1.2.11-17.el8 Stream-BaseOS 102 k
安装依赖关系:
fuse3 x86_64 3.2.1-12.el8 baseos 50 k
lmdb-libs x86_64 0.9.24-1.el8 appstream 58 k
python3-ptyprocess noarch 0.5.2-4.el8 appstream 31 k
安装弱的依赖:
python3-pexpect noarch 4.3.1-3.el8 appstream 138 k

事务概要
================================================================================
安装 8 软件包
升级 492 软件包

总下载:568 M
下载软件包:
189% [=====================================-] 1.6 kB/s | 1.2 189% [=====================================-] 1.6 kB/s | 1.2 288% [======================================================(1/500): python3-ptyprocess-0.5.2-4.el8.noarch. 214 kB/s | 31 kB 00:00
(2/500): lmdb-libs-0.9.24-1.el8.x86_64.rpm 322 kB/s | 58 kB 00:00
(3/500): python3-pexpect-4.3.1-3.el8.noarch.rpm 635 kB/s | 138 kB 00:00
(4/500): fuse3-3.2.1-12.el8.x86_64.rpm 378 kB/s | 50 kB 00:00
(5/500): centos-stream-release-8.4-1.el8.noarch 134 kB/s | 21 kB 00:00
(6/500): kernel-4.18.0-269.el8.x86_64.rpm 8.4 MB/s | 5.2 MB 00:00
...
(496/500): util-linux-2.32.1-26.el8.x86_64.rpm 9.1 MB/s | 2.5 MB 00:00
(497/500): yum-4.4.2-3.el8.noarch.rpm 2.9 MB/s | 200 kB 00:00
(498/500): wpa_supplicant-2.9-3.el8.x86_64.rpm 9.0 MB/s | 1.9 MB 00:00
(499/500): xfsprogs-5.0.0-8.el8.x86_64.rpm 5.9 MB/s | 1.1 MB 00:00
(500/500): zlib-1.2.11-17.el8.x86_64.rpm 2.3 MB/s | 102 kB 00:00
--------------------------------------------------------------------------------
总计 10 MB/s | 568 MB 00:54
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
运行脚本: filesystem-3.8-4.el8.x86_64 1/1
运行脚本: kmod-kvdo-6.2.4.26-76.el8.x86_64 1/1
准备中 : 1/1
运行脚本: libgcc-8.4.1-1.el8.x86_64 1/1
升级 : libgcc-8.4.1-1.el8.x86_64 1/994
运行脚本: libgcc-8.4.1-1.el8.x86_64 1/994
升级 : filesystem-3.8-4.el8.x86_64 2/994
升级 : libselinux-2.9-5.el8.x86_64 3/994
运行脚本: libselinux-2.9-5.el8.x86_64 3/994
升级 : glibc-langpack-en-2.28-145.el8.x86_64 4/994
升级 : glibc-langpack-zh-2.28-145.el8.x86_64 5/994
升级 : glibc-common-2.28-145.el8.x86_64 6/994
运行脚本: glibc-2.28-145.el8.x86_64 7/994
升级 : glibc-2.28-145.el8.x86_64 7/994
运行脚本: glibc-2.28-145.el8.x86_64 7/994
升级 : bash-4.4.19-14.el8.x86_64 8/994
...
运行脚本: irqbalance-2:1.4.0-5.el8.x86_64 486/994
升级 : rsync-3.1.3-12.el8.x86_64 487/994
升级 : soundtouch-2.0.0-3.el8.x86_64 488/994
运行脚本: soundtouch-2.0.0-3.el8.x86_64 488/994
/sbin/ldconfig: /lib64/libsmbldap.so.2 不是符号链接


升级 : libvncserver-0.9.11-17.el8.x86_64 489/994
运行脚本: libvncserver-0.9.11-17.el8.x86_64 489/994
/sbin/ldconfig: /lib64/libsmbldap.so.2 不是符号链接


升级 : crontabs-1.11-17.20190603git.el8.noarch 490/994
升级 : libgomp-8.4.1-1.el8.x86_64 491/994
运行脚本: libgomp-8.4.1-1.el8.x86_64 491/994
/sbin/ldconfig: /lib64/libsmbldap.so.2 不是符号链接


升级 : unzip-6.0-44.el8.x86_64 492/994
升级 : gpm-libs-1.20.7-17.el8.x86_64 493/994
运行脚本: gpm-libs-1.20.7-17.el8.x86_64 493/994
/sbin/ldconfig: /lib64/libsmbldap.so.2 不是符号链接


升级 : libmpc-1.1.0-9.1.el8.x86_64 494/994
升级 : lsscsi-0.32-2.el8.x86_64 495/994
升级 : net-snmp-libs-1:5.8-19.el8.x86_64 496/994
升级 : libertas-usb8388-firmware-2:20201118-101.git7455a360.el8. 497/994
升级 : NetworkManager-config-server-1:1.30.0-0.5.el8.noarch 498/994
升级 : abattis-cantarell-fonts-0.0.25-6.el8.noarch 499/994
安装 : centos-stream-release-8.4-1.el8.noarch 500/994
运行脚本: tuned-2.14.0-3.el8_3.1.noarch 501/994
清理 : tuned-2.14.0-3.el8_3.1.noarch 501/994
运行脚本: tuned-2.14.0-3.el8_3.1.noarch 501/994
运行脚本: firewalld-0.8.2-2.el8.noarch 502/994
清理 : firewalld-0.8.2-2.el8.noarch 502/994
运行脚本: firewalld-0.8.2-2.el8.noarch 502/994
运行脚本: microcode_ctl-4:20200609-2.20201112.1.el8_3.x86_64 503/994
清理 : microcode_ctl-4:20200609-2.20201112.1.el8_3.x86_64 503/994
运行脚本: microcode_ctl-4:20200609-2.20201112.1.el8_3.x86_64 503/994
清理 : perl-IO-Socket-SSL-2.066-4.module_el8.3.0+410+ff426aa3.no 504/994
清理 : grub2-pc-1:2.02-90.el8.x86_64 505/994
...
运行脚本: libsepol-2.9-1.el8.x86_64 989/994
清理 : bash-4.4.19-12.el8.x86_64 990/994
运行脚本: bash-4.4.19-12.el8.x86_64 990/994
清理 : glibc-langpack-zh-2.28-127.el8.x86_64 991/994
清理 : glibc-2.28-127.el8.x86_64 992/994
清理 : filesystem-3.8-3.el8.x86_64 993/994
清理 : libgcc-8.3.1-5.1.el8.x86_64 994/994
运行脚本: libgcc-8.3.1-5.1.el8.x86_64 994/994
运行脚本: filesystem-3.8-4.el8.x86_64 994/994
运行脚本: container-selinux-2:2.155.0-1.module_el8.4.0+641+6116a774 994/994
运行脚本: nss-3.53.1-17.el8_3.x86_64 994/994
运行脚本: clevis-15-1.el8.x86_64 994/994
运行脚本: sssd-common-2.4.0-5.el8.x86_64 994/994
运行脚本: libvirt-daemon-6.0.0-29.module_el8.4.0+547+a85d02ba.x86_6 994/994
运行脚本: dconf-0.28.0-4.el8.x86_64 994/994
运行脚本: libwbclient-4.13.3-1.el8.x86_64 994/994
运行脚本: kernel-core-4.18.0-269.el8.x86_64 994/994
sort: fflush failed: 'standard output': Broken pipe
sort: write error

gzip: stdout: Broken pipe

gzip: stdout: Broken pipe
sort: write failed: 'standard output': Broken pipe
sort: write error

运行脚本: kmod-kvdo-6.2.4.26-76.el8.x86_64 994/994
sort: fflush failed: 'standard output': Broken pipe
sort: write error

gzip: stdout: Broken pipe

gzip: stdout: Broken pipe
sort: write failed: 'standard output': Broken pipe
sort: write error

运行脚本: libvirt-daemon-config-network-6.0.0-29.module_el8.4.0+547 994/994
运行脚本: authselect-libs-1.2.2-1.el8.x86_64 994/994
运行脚本: authselect-compat-1.2.2-1.el8.x86_64 994/994
运行脚本: evolution-data-server-3.28.5-15.el8.x86_64 994/994
运行脚本: pulseaudio-14.0-1.el8.x86_64 994/994
运行脚本: tuned-2.15.0-1.el8.noarch 994/994
运行脚本: microcode_ctl-4:20201112-1.el8.x86_64 994/994
sort: fflush failed: 'standard output': Broken pipe
sort: write error

gzip: stdout: Broken pipe

gzip: stdout: Broken pipe
sort: write failed: 'standard output': Broken pipe
sort: write error
sort: fflush failed: 'standard output': Broken pipe
sort: write error

gzip: stdout: Broken pipe

gzip: stdout: Broken pipe
sort: write failed: 'standard output': Broken pipe
sort: write error

运行脚本: libgcc-8.3.1-5.1.el8.x86_64 994/994
运行脚本: glibc-common-2.28-145.el8.x86_64 994/994
运行脚本: glib2-2.56.4-9.el8.x86_64 994/994
运行脚本: systemd-239-43.el8.x86_64 994/994
运行脚本: systemd-udev-239-43.el8.x86_64 994/994
运行脚本: gtk2-2.24.32-5.el8.x86_64 994/994
验证 : lmdb-libs-0.9.24-1.el8.x86_64 1/994
验证 : python3-pexpect-4.3.1-3.el8.noarch 2/994
验证 : python3-ptyprocess-0.5.2-4.el8.noarch 3/994
验证 : fuse3-3.2.1-12.el8.x86_64 4/994
验证 : centos-stream-release-8.4-1.el8.noarch 5/994
...
验证 : xfsprogs-5.0.0-4.el8.x86_64 990/994
验证 : yum-4.4.2-3.el8.noarch 991/994
验证 : yum-4.2.23-4.el8.noarch 992/994
验证 : zlib-1.2.11-17.el8.x86_64 993/994
验证 : zlib-1.2.11-16.el8_2.x86_64 994/994
Installed products updated.

已升级:
NetworkManager-1:1.30.0-0.5.el8.x86_64
NetworkManager-adsl-1:1.30.0-0.5.el8.x86_64
NetworkManager-bluetooth-1:1.30.0-0.5.el8.x86_64
NetworkManager-config-server-1:1.30.0-0.5.el8.noarch
NetworkManager-libnm-1:1.30.0-0.5.el8.x86_64
...
xorg-x11-server-Xorg-1.20.10-1.el8.x86_64
xorg-x11-server-Xwayland-1.20.10-1.el8.x86_64
xorg-x11-server-common-1.20.10-1.el8.x86_64
yum-4.4.2-3.el8.noarch
zlib-1.2.11-17.el8.x86_64

已安装:
centos-stream-release-8.4-1.el8.noarch fuse3-3.2.1-12.el8.x86_64
kernel-4.18.0-269.el8.x86_64 kernel-core-4.18.0-269.el8.x86_64
kernel-modules-4.18.0-269.el8.x86_64 lmdb-libs-0.9.24-1.el8.x86_64
python3-pexpect-4.3.1-3.el8.noarch python3-ptyprocess-0.5.2-4.el8.noarch

完毕!

注意:运行 dnf -y distro-sync 命令将系统或软件包更新为特定的,这会将所有本地软件包升级到新版本。

重新启动系统

1
[root@localhost ~]# reboot

注意:使用命令 reboot 重新启动服务器。

检查升级结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost ~]# cat /etc/os-release
NAME="CentOS Stream"
VERSION="8"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Stream 8"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux 8"
REDHAT_SUPPORT_PRODUCT_VERSION="CentOS Stream"

注意:使用命令 cat /etc/os-release 可检查升级结果。

Ubuntu 20.04 LTS 升级 20.10

2021年2月4日 00:00

新的 Ubuntu 20.10 已经于 2020 年 10 月 22 日发布,本篇文章将分享如何将 Ubuntu 20.04 LTS 升级到 20.10 LTS,欢迎在评论区与杜老师交流!

更新当前系统

1
2
3
sudo apt update
sudo apt -y dist-upgrade
sudo apt -y autoremove

注意:上面三个命令的含义依次为检查系统更新、更新软件程序、删除无用软件。

配置升级程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Default behavior for the release upgrader.

[DEFAULT]
# Default prompting and upgrade behavior, valid options:
#
# never - Never check for, or allow upgrading to, a new release.
# normal - Check to see if a new release is available. If more than one new
# release is found, the release upgrader will attempt to upgrade to
# the supported release that immediately succeeds the
# currently-running release.
# lts - Check to see if a new LTS release is available. The upgrader
# will attempt to upgrade to the first LTS release available after
# the currently-running one. Note that if this option is used and
# the currently-running release is not itself an LTS release the
# upgrader will assume prompt was meant to be normal.
Prompt=normal

注意:用命令 vim /etc/update-manager/release-upgrades 编辑文件,将 lts 设置为 normal

执行升级命令

1
$ sudo do-release-upgrade

注意:使用上述命令开始升级系统,升级时需下载大量文件,所以用时较久。

升级注意事项

升级过程会有操作提示,请根据需要输入 y 或 N。如果在生产环境中操作,有可能需对正在运行的服务进行升级,会有配置文件更新提示,根据提示操作即可,如遇问题,欢迎在评论区与杜老师交流。

升级结束后会提示是否重启系统,输入 y 并回车重启即可。Ubuntu 的升级与 Windows 不同,不需要在开机阶段等待很长时间。

在 Windows10 挂载 iSCSI 客户端

2021年2月1日 00:00

上一篇我们讲解了如何在群晖中创建 iSCSI 服务端,今天杜老师将演示,如何在 Windows10 挂载 iSCSI 客户端,感兴趣的小伙伴可以试一下!

操作流程

点击左下角的开始图标,直接输入 iSCSI 使用搜索功能找到 iSCSI 发起程序,点击打开:

首次运行时会提示服务处于关闭状态,需要开启才可以继续使用该服务,点是:

在弹出的 iSCSI 发起程序界面中找到目标,将群晖 NAS 访问地址,填在后面的输入框,然后点击快速连接:

快速连接工具会自动连接到目标 iSCSI 上,并弹出已连接提示,点击完成:

这时我们可以在之前的页面中看到已连接的 iSCSI,点击确认即可:

进入到计算机管理界面,找到左侧存储——磁盘管理:

点击进入后即可对挂载好的 iSCSI 进行初始化设置:

之后可以根据需求,对其进行分区格式化等操作:

注意事项

iSCSI 是通过网络映射存储,所以墙裂建议只做数据存储使用,不要将运行的程序安装在该磁盘,不然会严重影响系统的运行效率!

另外存储分享默认是无需身份验证的,如果您的 iSCSI 服务支持外网访问,强烈建议通过端口转发或者防火墙的形式,限制外网对 iSCSI 服务访问。

在 CentOS8 挂载 iSCSI 客户端

2021年1月26日 00:00

我们在上篇文章中,讲解如何在 CentOS8 系统搭建 iSCSI 服务端。在本篇中,我们讲一下如何进行客户端挂载。如有任何问题,欢迎在评论区与杜老师交流!

工具安装

1
2
3
4
5
6
[root@localhost ~]# dnf -y install iscsi-initiator-utils
上次元数据过期检查:0:32:16 前,执行于 20210124日 星期日 034812秒。
软件包 iscsi-initiator-utils-6.2.0.878-5.gitd791ce0.el8.x86_64 已安装。
依赖关系解决。
无需任何处理。
完毕!

注意:可使用命令 dnf -y install iscsi-initiator-utils 安装,带 GUI 的服务器默认会安装该工具。

编辑文件

1
2
3
[root@localhost ~]# vim /etc/iscsi/initiatorname.iscsi
[root@localhost ~]# cat /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.2021-01.com.dusays:init

注意:使用命令 vim /etc/iscsi/iscsid.conf 修改配置文件的内容。

启动服务

1
2
3
4
5
[root@localhost ~]# systemctl start iscsi
[root@localhost ~]# systemctl enable iscsi
[root@localhost ~]# systemctl start iscsid
[root@localhost ~]# systemctl enable iscsid
Created symlink /etc/systemd/system/multi-user.target.wants/iscsid.service → /usr/lib/systemd/system/iscsid.service.

注意:iscsi 与 iscsid 都需要启动,默认系统会启动 iscsi,要记得手动启用 iscsid。

挂载存储

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost ~]# iscsiadm -m discovery -t sendtargets -p 192.168.1.130
192.168.1.130:3260,1 iqn.2021-01.com.dusays:www
[root@localhost ~]# iscsiadm -m node --login
Logging in to [iface: default, target: iqn.2021-01.com.dusays:www, portal: 192.168.1.130,3260]
Login to [iface: default, target: iqn.2021-01.com.dusays:www, portal: 192.168.1.130,3260] successful.
[root@localhost ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 19G 0 part
├─cl-root 253:0 0 17G 0 lvm /
└─cl-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 1G 0 disk

注意:使用命令 iscsiadm -m discovery -t sendtargets -p 192.168.1.130 显示指定服务器的存储信息,使用命令 iscsiadm -m node --login 实现 iSCSI 映射。可通过命令 lsblk 查看结果。

在 CentOS8 搭建 iSCSI 服务器

2021年1月23日 00:00

在前文中,我们讲解了 iSCSI 相关概念。本文将展示如何在 CentOS8 上配置 iSCSI 存储服务器,如遇任何问题,欢迎在评论区与杜老师交流,让我们开始吧!

服务安装

使用 dnf 命令安装 targetcli:

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
[root@localhost ~]# dnf -y install targetcli
上次元数据过期检查:1:49:08 前,执行于 2021年01月24日 星期日 01时34分43秒。
依赖关系解决。
================================================================================
软件包 架构 版本 仓库 大小
================================================================================
安装:
targetcli noarch 2.1.53-1.el8 appstream 80 k
安装依赖关系:
python3-configshell noarch 1:1.1.28-1.el8 baseos 72 k
python3-kmod x86_64 0.9-20.el8 baseos 90 k
python3-pyparsing noarch 2.1.10-7.el8 baseos 142 k
python3-rtslib noarch 2.1.73-2.el8 baseos 102 k
python3-urwid x86_64 1.3.1-4.el8 baseos 783 k
target-restore noarch 2.1.73-2.el8 baseos 24 k

事务概要
================================================================================
安装 7 软件包

总下载:1.3 M
安装大小:4.7 M
下载软件包:
(1/7): targetcli-2.1.53-1.el8.noarch.rpm 68 kB/s | 80 kB 00:01
(2/7): python3-pyparsing-2.1.10-7.el8.noarch.rp 538 kB/s | 142 kB 00:00
(3/7): python3-configshell-1.1.28-1.el8.noarch. 50 kB/s | 72 kB 00:01
(4/7): python3-kmod-0.9-20.el8.x86_64.rpm 62 kB/s | 90 kB 00:01
(5/7): python3-rtslib-2.1.73-2.el8.noarch.rpm 1.1 MB/s | 102 kB 00:00
(6/7): target-restore-2.1.73-2.el8.noarch.rpm 319 kB/s | 24 kB 00:00
(7/7): python3-urwid-1.3.1-4.el8.x86_64.rpm 3.7 MB/s | 783 kB 00:00
--------------------------------------------------------------------------------
总计 449 kB/s | 1.3 MB 00:02
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
准备中 : 1/1
安装 : python3-urwid-1.3.1-4.el8.x86_64 1/7
安装 : python3-pyparsing-2.1.10-7.el8.noarch 2/7
安装 : python3-configshell-1:1.1.28-1.el8.noarch 3/7
安装 : python3-kmod-0.9-20.el8.x86_64 4/7
安装 : python3-rtslib-2.1.73-2.el8.noarch 5/7
安装 : target-restore-2.1.73-2.el8.noarch 6/7
运行脚本: target-restore-2.1.73-2.el8.noarch 6/7
安装 : targetcli-2.1.53-1.el8.noarch 7/7
运行脚本: targetcli-2.1.53-1.el8.noarch 7/7
验证 : targetcli-2.1.53-1.el8.noarch 1/7
验证 : python3-configshell-1:1.1.28-1.el8.noarch 2/7
验证 : python3-kmod-0.9-20.el8.x86_64 3/7
验证 : python3-pyparsing-2.1.10-7.el8.noarch 4/7
验证 : python3-rtslib-2.1.73-2.el8.noarch 5/7
验证 : python3-urwid-1.3.1-4.el8.x86_64 6/7
验证 : target-restore-2.1.73-2.el8.noarch 7/7
Installed products updated.

已安装:
python3-configshell-1:1.1.28-1.el8.noarch python3-kmod-0.9-20.el8.x86_64
python3-pyparsing-2.1.10-7.el8.noarch python3-rtslib-2.1.73-2.el8.noarch
python3-urwid-1.3.1-4.el8.x86_64 target-restore-2.1.73-2.el8.noarch
targetcli-2.1.53-1.el8.noarch

完毕!

输入 targetcli 命令后会提示配置文件不存在,使用 exit 会自动生成配置文件:

1
2
3
4
5
6
7
8
9
[root@localhost ~]# targetcli
Warning: Could not load preferences file /root/.targetcli/prefs.bin.
targetcli shell version 2.1.53
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.

/> exit
Global pref auto_save_on_exit=true
Configuration saved to /etc/target/saveconfig.json

服务启动

启动服务:

1
[root@localhost ~]# systemctl start target

设置开机启动:

1
2
[root@localhost ~]# systemctl enable target
Created symlink /etc/systemd/system/multi-user.target.wants/target.service → /usr/lib/systemd/system/target.service.

创建存储

这里我们以/dusays/目录为例,使用命令 /backstores/fileio create dusays /dusays/dusays.img 1G 创建名为 dusays 的 1G 大小存储文件,创建后通过 ls 查看执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost ~]# mkdir /dusays
[root@localhost ~]# targetcli
targetcli shell version 2.1.53
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.

/> backstores/fileio/ create www /dusays/www.img 1G
Created fileio www with size 1073741824
/> ls
o- / ..................................................................... [...]
o- backstores .......................................................... [...]
| o- block .............................................. [Storage Objects: 0]
| o- fileio ............................................. [Storage Objects: 1]
| | o- www ................. [/dusays/www.img (1.0GiB) write-back deactivated]
| | o- alua ............................................... [ALUA Groups: 1]
| | o- default_tg_pt_gp ................... [ALUA state: Active/optimized]
| o- pscsi .............................................. [Storage Objects: 0]
| o- ramdisk ............................................ [Storage Objects: 0]
o- iscsi ........................................................ [Targets: 0]
o- loopback ..................................................... [Targets: 0]

接下来我们创建名为 iqn.2021-01.com.dusays:www 的 iSCSI 文件,一般命名规则为 iqn.年份-月份.网址倒叙:存储文件名称,完整命令为 /iscsi create iqn.2021-01.com.dusays:www,创建后通过 ls 查看执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/> iscsi/ create iqn.2021-01.com.dusays:www
Created target iqn.2021-01.com.dusays:www.
Created TPG 1.
Global pref auto_add_default_portal=true
Created default portal listening on all IPs (0.0.0.0), port 3260.
/> ls
o- / ..................................................................... [...]
o- backstores .......................................................... [...]
| o- block .............................................. [Storage Objects: 0]
| o- fileio ............................................. [Storage Objects: 1]
| | o- www ................. [/dusays/www.img (1.0GiB) write-back deactivated]
| | o- alua ............................................... [ALUA Groups: 1]
| | o- default_tg_pt_gp ................... [ALUA state: Active/optimized]
| o- pscsi .............................................. [Storage Objects: 0]
| o- ramdisk ............................................ [Storage Objects: 0]
o- iscsi ........................................................ [Targets: 1]
| o- iqn.2021-01.com.dusays:www .................................... [TPGs: 1]
| o- tpg1 ........................................... [no-gen-acls, no-auth]
| o- acls ...................................................... [ACLs: 0]
| o- luns ...................................................... [LUNs: 0]
| o- portals ................................................ [Portals: 1]
| o- 0.0.0.0:3260 ................................................. [OK]
o- loopback ..................................................... [Targets: 0]

创建 LUN 号

从先前创建的 www 存储中创建 LUN 号,命令为 iscsi/iqn.2021-01.com.dusays:www/tpg1/luns/ create /dusays/www.img,创建后通过 ls 查看执行结果:

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
/> iscsi/iqn.2021-01.com.dusays:www/tpg1/luns/ create /dusays/www.img
Created storage object dusays-www.img.
Created LUN 0.
/> ls
o- / ..................................................................... [...]
o- backstores .......................................................... [...]
| o- block .............................................. [Storage Objects: 0]
| o- fileio ............................................. [Storage Objects: 2]
| | o- dusays-www.img ........ [/dusays/www.img (1.0GiB) write-thru activated]
| | | o- alua ............................................... [ALUA Groups: 1]
| | | o- default_tg_pt_gp ................... [ALUA state: Active/optimized]
| | o- www ................. [/dusays/www.img (1.0GiB) write-back deactivated]
| | o- alua ............................................... [ALUA Groups: 1]
| | o- default_tg_pt_gp ................... [ALUA state: Active/optimized]
| o- pscsi .............................................. [Storage Objects: 0]
| o- ramdisk ............................................ [Storage Objects: 0]
o- iscsi ........................................................ [Targets: 1]
| o- iqn.2021-01.com.dusays:www .................................... [TPGs: 1]
| o- tpg1 ........................................... [no-gen-acls, no-auth]
| o- acls ...................................................... [ACLs: 0]
| o- luns ...................................................... [LUNs: 1]
| | o- lun0 . [fileio/dusays-www.img (/dusays/www.img) (default_tg_pt_gp)]
| o- portals ................................................ [Portals: 1]
| o- 0.0.0.0:3260 ................................................. [OK]
o- loopback ..................................................... [Targets: 0]

为启动器 iqn.2021-01.com.dusays:www 创建 ACL,以便 iSCSI 客户端可以访问此目标中的 LUN,命令为 iscsi/iqn.2021-01.com.dusays:www/tpg1/acls create iqn.2021-01.com.dusays:init 通过 ls 查看执行结果,通过 saveconfig 保存所有的配置,并使用 exit 退出:

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
/> iscsi/iqn.2021-01.com.dusays:www/tpg1/acls create iqn.2021-01.com.dusays:init
Created Node ACL for iqn.2021-01.com.dusays:init
Created mapped LUN 0.
/> ls
o- / ..................................................................... [...]
o- backstores .......................................................... [...]
| o- block .............................................. [Storage Objects: 0]
| o- fileio ............................................. [Storage Objects: 2]
| | o- dusays-www.img ........ [/dusays/www.img (1.0GiB) write-thru activated]
| | | o- alua ............................................... [ALUA Groups: 1]
| | | o- default_tg_pt_gp ................... [ALUA state: Active/optimized]
| | o- www ................. [/dusays/www.img (1.0GiB) write-back deactivated]
| | o- alua ............................................... [ALUA Groups: 1]
| | o- default_tg_pt_gp ................... [ALUA state: Active/optimized]
| o- pscsi .............................................. [Storage Objects: 0]
| o- ramdisk ............................................ [Storage Objects: 0]
o- iscsi ........................................................ [Targets: 1]
| o- iqn.2021-01.com.dusays:www .................................... [TPGs: 1]
| o- tpg1 ........................................... [no-gen-acls, no-auth]
| o- acls ...................................................... [ACLs: 1]
| | o- iqn.2021-01.com.dusays:init ...................... [Mapped LUNs: 1]
| | o- mapped_lun0 ................... [lun0 fileio/dusays-www.img (rw)]
| o- luns ...................................................... [LUNs: 1]
| | o- lun0 . [fileio/dusays-www.img (/dusays/www.img) (default_tg_pt_gp)]
| o- portals ................................................ [Portals: 1]
| o- 0.0.0.0:3260 ................................................. [OK]
o- loopback ..................................................... [Targets: 0]
/> saveconfig
Last 10 configs saved in /etc/target/backup/.
Configuration saved to /etc/target/saveconfig.json
/> exit
Global pref auto_save_on_exit=true
Last 10 configs saved in /etc/target/backup/.
Configuration saved to /etc/target/saveconfig.json

iSCSI 概念及原理

2021年1月20日 00:00

iSCSI 是一种由 IBM 公司研究开发的 IP SAN 技术,该技术是将现有 SCSI 接口与以太网络技术相结合,基于 TCP/IP 的协议连接 iSCSI 服务端和客户端,使得封装后的 SCSI 数据包可以在通用互联网传输,最终实现 iSCSI 服务端映射为一个存储空间提供给已连接认证后的客户端。

什么是 SCSI

SCSI 是种 I/O 技术,规范一种并行的 I/O 总线和相关的协议,SCSI 数据传输是以块的方式进行的。

SCSI 总线通过 SCSI 控制器来和硬盘之类的设备进行通信, SCSI 的控制器称为 Target,访问客户端应用称为 Initiator。

窄 SCSI 总线最多允许 8 个、宽 SCSI 总线最多允许 16 个不同的 SCSI 设备和它进行连接,每个 SCSI 设备都必须有自己唯一的 SCSI ID 设备的地址。

LUN 逻辑单元号,是为使用和描述更多设备及对象而引进的一个方法,每个 SCSI ID 上最多有 32 个 LUN,一个 LUN 对应了一个逻辑设备。

iSCSI 的实现

  1. iSCSI Initiator 客户端。iSCSI 启动器,本质上说,iSCSI 启动器是一个客户端设备,用于将请求连接并启动到服务器。iSCSI 的启动器有三种实现方式,可以完全基于硬件实现,比如 iSCSI HBA 卡,硬件 TOE 卡与软件结合的方式,完全基于软件实现,而且软件 iSCSI 启动器适用于大部分主流操作系统平台;

  2. iSCSI Target 服务端。即 iSCSI 目标,它是 iSCSI 网络服务器组件,用于包含所需要的数据并回应来自 iSCSI 启动器的请求。

工作过程

Initiator 发出请求后,会在本地的操作系统会生成了相应的 SCSI 命令和数据 I/O 的请求,然后这些命令和请求被封装加密成为 IP 信息包,通过以太网 TCP/IP 传输到 Targer。

当 Targer 接收到信息包,将进行解密和解析,将 SCSI 命令和 I/O 请求分开。SCSI 命令被发送到 SCSI 的控制器,再传送到 SCSI 的存储设备。

设备执行 SCSI 命令的响应,经过 Target 封装成 iSCSI 响应 PDU,再通过已连接的 TCP/IP 网络传送给 Initiator。

Initiator 会从 iSCSI 响应 PDU 里解析出 SCSI 响应并传送给操作系统,操作系统再响应给应用程序。

与 NFS 比较

SAN 与 NAS 是完全不相同架构的存储方案,SAN 支持 Block 协议,后者则支持 File 协议;SAN 结构中,文件管理系统还是分别在每一个应用服务器上,会产生 I/O 操作,而 NAS 则是每个应用服务器通过网络共享协议使用同一个文件管理系统,所以 CPU 密集型的应用可以选用 NAS。SAN 是将目光集中在磁盘、磁带以及联接它们的可靠的基础结构,NAS 是将目光集中在应用、用户和文件及它们共享的数据上。

以上区别具体到 iSCSI 和 NFS。iSCSI 可优化空间更大,性能稍好,但是技术难度更高;而 NFS 在系统层面的支持更多,例如一些备份、恢复等操作较简单。

通过 Watchtower 实现 Docker 容器自动更新

2020年12月12日 00:00

杜老师喜欢使用 Docker 部署轻量级的应用,不过后期维护起来还是挺麻烦的,主要是新版本发布后的更新问题,需停止并删除当前容器,更新版本后使用相同参数再运行。今天介绍一款可以自动更新 Docker 容器的工具!

工具介绍

Watchtower 是一个应用程序,它将监视正在运行的 Docker 容器,并监视这些容器最初从其启动镜像的更改。如果 Watchtower 检测到镜像的版本已更改,它将使用新版镜像自动重新启动容器。

只需要将新镜像推送到 Docker Hub 或自己的镜像注册表,即可更新容器化应用的运行版本。Watchtower 将拉下新版镜像,并正常关闭现有的容器,使用与最初部署时相同的选项重新启动它。

工具使用

只需运行下面命令即可:

1
docker run -d -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower

如果正在运行的容器比较多,只想监控其中几个容器,可以按照下面命令执行,如 Nginx/MySQL:

1
docker run -d -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower nginx mysql

如果不需要 Watchtower 一直监控,而是运行一次即可,可运行下面的命令:

1
docker run -d -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --run-once

Watchtower 默认升级新版镜像后,仍保留原版本镜像,如果无需保留,可运行下面的命令:

1
docker run -d -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --cleanup

Watchtower 默认不会监控停止状态的容器,如果需要一并升级,可运行下面的命令:

1
docker run -d -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --include-stopped

Watchtower 默认每 24 小时检查新版本,如果需要修改检查间隔,可运行下面的命令:

1
docker run -d -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --interval 86400

Shell 脚本练习题

2020年11月11日 00:00

作为一枚十分贴心的杜老师,在此给大家准备了六道 Shell 脚本练习题。都是入门级的水准,希望大家踊跃尝试编写。

脚本题目

  1. 编写脚本,计算 1 到 100 的总和;

  2. 编写脚本,输入一个数字 n 并计算 1 到这个数的总和。要求:如果这个数小于等于 1,要求重新输入,直到输入大于 1 的数字为止;

  3. 编写脚本,把/root/目录下的所有目录复制到/tmp/目录;

  4. 编写脚本,批量建立用户,要求用户名的格式为 user_00/user_01,建立 100 个,且用户同属于 users 组;

  5. 编写脚本,在/cjk/目录下的所有文件「不含目录」的文件名后面加.bak;

  6. 编写脚本,给系统中所有已存在的用户打个招呼,格式参考为 hello penndu and your id is 1000。

参考答案

一题:

1
2
3
4
5
6
7
#!/bin/bash
sum=0
for i in `seq 1 100`
do
sum=$[$i+$sum]
done
echo $sum

二题:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
n=0
while [ $n -lt 1 ]
do
read -p "Please input a number, it must greater than 1: " n
done
sum=0
for i in `seq 1 $n`
do
sum=$[$i+$sum]
done
echo $sum

三题:

1
2
3
4
5
6
7
8
#!/bin/bash
cd /root/
for f in `ls`
do
if[ -d $f ] ; then
cd -r $f /tmp/
fi
done

四题:

1
2
3
4
5
6
#!/bin/bash
groupadd users
for i in `seq -w 0 99`
do
useradd -g users user_$i
done

五题:

1
2
3
4
5
6
7
8
#!/bin/bash
cd /cjk/
for f in `ls`
do
if[ -f $f ] ; then
mv $f $f.bak
fi
done

六题:

1
2
3
4
5
6
7
#!/bin/bash
for i in `cat /etc/passwd`
do
username=`echo $i | cut -d : -f 1`
id=`echo $i | cut -d : -f 3`
echo "hello $username and your id is $id"
done

PXE 实战篇

2020年9月9日 00:00

首先完成准备工作,然后开始安装 DHCP/TFTP 服务端,接着提供 BootLoader 及配置文件,挂着光盘把内核文件 cp 到 TFTP 目录,部署 httpd 服务端提供文件服务,设置菜单及提供系统安装软件等。

架构流程

实战案例架构图示如下:

流程图示如下:

流程解读

  1. 客户端向 PXE 服务器上的 DHCP 发送 IP 地址请求消息,DHCP 检测客户端是否合法,同时将 PXE 环境下的 BootLoader 文件 pxelinux.0 的位置信息发给客户端;

  2. 客户端向 PXE 服务器上的 TFTP 请求 pxelinux.0,TFTP 收到消息向客户端发送 pxelinux.0 大小信息,同时等待确认信息,当 TFTP 收到客户端发回的统一大小信息后发送 pxelinux.0;

  3. 客户端执行接收到的 pxelinux.0;

  4. 客户端向 TFTP 请求 pxelinux.cfg 文件「其实它是目录,里面放了启动菜单,即 GRUB 配置文件」TFTP 会将配置文件发回客户端,继而客户端根据配置文件执行后续的操作;

  5. 客户端向 TFTP 发送 Linux 内核请求信息,TFTP 发送 Kernel;

  6. 客户端向 TFTP 发送根文件请求信息,TFTP 接受到消息之后返回 Linux 根文件系统;

  7. 客户端加载 Linux 内核;

  8. 客户端通过 NFS/FTP/HTTP 下载系统安装文件进行安装,如果配置文件指定了 Kickstart 路径,则根据此文件自动应答安装系统。

准备工作

1
2
3
4
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i '/SELINUX/s/enforcing/disabled/g' /etc/selinux/config

注意:以上分别是关闭防火墙和 SELinux。

安装软件

1
yum -y install dhcp httpd syslinux tftp-server xinetd

注意:安装相关工具。

部署 DHCP 服务端

修改 DHCP 配置文件/etc/dhcp/dhcpd.conf:

1
2
3
4
5
6
7
8
9
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.26 192.168.1.30;
option domain-name-servers 119.29.29.29;
option routers 192.168.1.1;
default-lease-time 600;
max-lease-time 7200;
next-server 192.168.1.1;
filename "pxelinux.0";
}

启动服务:

1
2
systemctl start dhcpd
systemctl enable dhcpd

部署 TFTP 服务端

从流程得知 BootLoader 文件 pxelinux.0 以及内核相关的配置文件「目录 pxelinux.cfg 下」主要都是由 TFTP 来提供的:

1
sed -i '/disable/s/no/yes/g' /etc/xinetd.d/tftp

TFTP 是由 xinetd 所管理的,因此设定好 TFTP 之后,要启动的是 xinetd:

1
2
systemctl start tftp xinetd
systemctl enable tftp xinetd

提供 BootLoader 机配置文件

1
cp /usr/share/syslinux/{menu.c32,pxelinux.0} /var/lib/tftpboot

注意:menu.c32 图形化菜单,pxelinux.0 是 BootLoader 机,pxelinux.cfg 是开机菜单设定。

部署 HTTP 服务端

挂载光盘:

1
2
mkdir /var/www/html/centos
mount /dev/cdrom /var/www/html/centos

启动服务:

1
2
systemctl start httpd
systemctl enable httpd

设置菜单

拷贝内核文件:

1
2
3
mkdir /var/lib/tftpboot/pxelinux.cfg
cp /var/www/html/centos/images/pxeboot/{vmlinuz,initrd.img} /var/lib/tftpboot/
cp /var/www/html/centos/isolinux/{vesamenu.c32,boot.msg,splash.png} /var/lib/tftpboot/

通过 vim 新建引导启动菜单/var/lib/tftpboot/pxelinux.cfg/default:

1
2
3
4
5
6
7
8
9
default vesamenu.c32
timeout 60
display boot.msg
menu title ########## PXE Boot Menu ##########
label 1
menu label ^1. Install CentOS 7
menu default
kernel vmlinuz
append initrd=initrd.img inst.repo=http://192.168.1.1/centos ks=http://192.168.1.1/ks.cfg

实现无人值守批量安装

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#platform=x86, AMD64, 或 Intel EM64T
#version=DEVEL
# Install OS instead of upgrade
install
# X Window System configuration information
xconfig --startxonboot
# Keyboard layouts
# old format: keyboard us
# new format:
keyboard --vckeymap=cn --xlayouts='cn'
# Root password
rootpw --iscrypted $1$Y.lO6g1z$S5qz8CU0TSDTocfAVez8h.
# System language
lang zh_CN
# System authorization information
auth --useshadow --passalgo=sha512
# Use graphical install
graphical
# Run the Setup Agent on first boot
firstboot --disabled
# SELinux configuration
selinux --disabled

# System services
services --enabled="chronyd"
ignoredisk --only-use=sda
# Firewall configuration
firewall --disabled
# Reboot after installation
reboot
# System timezone
timezone Asia/Shanghai
# Use network installation
url --url="http://192.168.1.1/centos"
# System bootloader configuration
bootloader --append=" crashkernel=auto" --location=none --boot-drive=sda
autopart --type=lvm
# Partition clearing information
clearpart --none --initlabel

%packages
@^graphical-server-environment
@base
@core
@desktop-debugging
@dial-up
@fonts
@gnome-desktop
@guest-agents
@guest-desktop-agents
@hardware-monitoring
@input-methods
@internet-browser
@multimedia
@print-client
@x11
chrony
kexec-tools

%end

注意:将上述内容写入/var/www/html/ks.cfg。

Kickstart 无人值守原理及简介

2020年9月6日 00:00

机房近期进来大批量的新服务器,装机成了最大烦恼,因为总是遇到一些机械式的重复工作。如何进行一次大批量部署服务器安装成了现在必须要解决的问题。今天杜老师讲解下 Kickstart 无人值守的原理!

简介原理

客户机需通过网卡「即 PXE」启动,发现 DHCP 服务器,从而自动获得 IP 及相关网络配置。

同时也能获取 TFTP 服务器地址,通过 TFTP 提供 BootLoader,从而使客户端可以通过此 BootLoader 指定的 FTP/HTTP/NFS 服务器加载 vmlinuz 和 initrd.img 等安装系统所需包,进而安装系统。

搭建无人值守步骤

  1. 搭建 DHCP 服务器;

  2. 搭建 TFTP 服务器;

  3. 搭建 FTP/HTTP/NFS 服务器。

PXE 的介绍

PXE 预启动执行环境,由 Intel 公司开发,工作于 C/S 网络模式,支持电脑通过网络从远端服务器下载映像,由此支持通过网络启动操作系统,在启动过程中,终端要求服务器分配 IP 地址,再用 TFTP 协议下载一个启动软件包到本机内存中执行,由这个启动软件包完成终端基本软件设置,从而引导预先安装在服务器中的终端操作系统。严格来说,PXE 并不是一种安装方式,而是一种引导方式:

Kickstart 的简介

Kickstart 是种无人值守的安装方式。它的工作原理是在安装过程中记录需要人工干预填写的各种参数,生成一个名为 ks.cfg 的文件。如果在安装过程中出现要填写参数的情况,安装程序首先去查找 ks.cfg 文件,根据此文件的参数自动应答。ks.cfg 文件涵盖安装过程中可能出现的所有需要填写的参数从而实现无人值守自动安装:

Git 与 SVN 的区别

2020年9月3日 00:00

Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大项目。Git 是 Linus Torvalds 为帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Git 与常用的版本控制工具 CVS、Subversion 等不同,它采用分布式版本库的方式,不必服务器端软件支持。

Git 与 SVN 区别点

  1. Git 是分布式的,而 SVN 不是。这是 Git 和其它非分布式版本控制系统,如 SVN、CVS 等,最核心的区别;

  2. Git 把内容按元数据方式存储,而 SVN 是按文件。所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn/.CVS 等的文件夹里;

  3. Git 分支和 SVN 的分支不同。分支在 SVN 中一点不特别,其实它就是版本库中的另外一个目录;

  4. Git 没有一个全局版本号,SVN 有。目前为止这是跟 SVN 相比 Git 缺少最大的一个特征;

  5. Git 内容完整性要优于 SVN。Git 的内容存储用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。

区别图示

Git 与 SVN 区别如下图:

YAML 入门篇教程

2020年8月31日 00:00

YAML 的语法和其它的高级语言类似,并且可以简单表达清单、散列表等数据形态。使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或者编辑数据结构、各种配置文件、倾印调试内容、文件大纲。

基本语法

  1. 大小写较敏感;

  2. 使用缩进表示层级关系;

  3. 缩进不允许使用 tab,仅限空格;

  4. 缩进空格数不重要,只要相同层级的元素左对齐即可;

  5. 井号表示注释。

对象

对象:键值对的集合,又称映射、哈希、字典。

对象键值对使用冒号结构表示 key: value,冒号后面要加一个空格。

也可以使用 key:{key1: value1, key2: value2}。

还可使用缩进表示层级关系;

1
2
3
key:
child-key: value
child-key2: value2

较复杂的对象格式,可使用问号加一个空格代表一个复杂的 key,配合一个冒号加一个空格代表一个 value:

1
2
3
4
5
6
?
- complexkey1
- complexkey2
:
- complexvalue1
- complexvalue2

意思即对象的属性是一个数组[complexkey1,complexkey2],对应值也是一个数组[complexvalue1,complexvalue2]。

数组

数组:一组按照次序排列的值,又称序列、列表。以横杠开头的行表构成一个数组:

1
2
3
- A
- B
- C

支持多维数组,可以使用行内表示:

1
key: [value1, value2]

数据结构子成员是一个数组,则可以在该项下面缩进一个空格:

1
2
3
4
-
- A
- B
- C

一个相对复杂例子:

1
2
3
4
5
6
7
8
9
companies:
-
id: 1
name: company1
price: 200W
-
id: 2
name: company2
price: 500W

意思是 companies 的属性是一个数组,每一个数组元素又是由 id/name/price 三个属性构成的。

数组也可以使用流式的方式表示:

1
companies: [{id: 1,name: company1,price: 200W},{id: 2,name: company2,price: 500W}]

复合结构

数组和对象可构成复合结构,例如:

1
2
3
4
5
6
7
8
9
languages:
- Ruby
- Perl
- Python
websites:
YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org

转换为 JSON:

1
2
3
4
5
6
7
8
9
{ 
languages: [ 'Ruby', 'Perl', 'Python'],
websites: {
YAML: 'yaml.org',
Ruby: 'ruby-lang.org',
Python: 'python.org',
Perl: 'use.perl.org'
}
}

纯量

纯量是最基本,不可再分的值,包括:

  1. 字符;
  2. 布尔;
  3. 整数;
  4. 浮点;
  5. 空值;
  6. 时间;
  7. 日期。

使用一个例子来快速了解纯量的基本使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
boolean: 
- true
- false
float:
- 3.14
- 6.8523015e+5
int:
- 123
- 0b1010_0111_0100_1010_1110
null:
nodeName: 'node'
parent: ~
string:
- 'Hello world'
- newline
newline2
date:
- 2020-03-25
datetime:
- 2020-03-25T00:00:00+08:00

引用

AND 符用来建立锚点,双小于表示合并到当前数据,星号用来引用锚点:

1
2
3
4
5
6
7
8
9
defaults: &defaults
adapter: postgres
host: localhost
development:
database: myapp_development
<<: *defaults
test:
database: myapp_test
<<: *defaults

上面的代码相当于:

1
2
3
4
5
6
7
8
9
10
11
defaults:
adapter: postgres
host: localhost
development:
database: myapp_development
adapter: postgres
host: localhost
test:
database: myapp_test
adapter: postgres
host: localhost

下面是另一个例子:

1
2
3
4
5
- &showell Steve 
- Clark
- Brian
- Oren
- *showell

转换为 JavaScript 代码如下:

1
[ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ]

Ansible Playbook 实战案例篇

2020年8月28日 00:00

Playbook 是一个不同于使用 Ansible 命令行执行方式的模式,其功能更强大灵活。Playbook 可定制配置,可按照指定的操作步骤有序执行,支持同步、异步方式。值得注意的是 Playbook 通过 YAML 格式来进行描述定义的。

案例拓扑

实战案例拓扑如下:

环境规划

网络环境规划如下:

角色NAT 外网 IPNAT 外网 IP部署软件
m01eth0:10.0.0.61eth1:172.16.1.61Ansible
backupeth0:10.0.0.41eth1:172.16.1.41rsync
nfseth0:10.0.0.31eth1:172.16.1.31NFS、sersync
web01eth0:10.0.0.7eth1:172.16.1.7httpd

配置 Ansible 对应的主机

1
2
3
4
5
6
7
[root@m01 ~]# vim /etc/ansible/hosts
[web]
172.16.1.7
[nfs]
172.16.1.31
[backup]
172.16.1.41

注意:上面为 Ansible 主机清单列表。

检查对应主机组和规划的 IP 是否一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@m01 ~]# ansible web --list-host  
hosts (1):
172.16.1.7
[root@m01 ~]# ansible backup --list-host
hosts (1):
172.16.1.41
[root@m01 ~]# ansible nfs --list-host
hosts (1):
172.16.1.31
[root@m01 ~]# ansible all --list-host
hosts (3):
172.16.1.31
172.16.1.41
172.16.1.7

注意:上面命令用于检测主机清单列表是否生效。

建立对应目录站点

1
[root@m01 ~]# mkdir -p /etc/ansible/ansible_playbook/file

注意:上面命令用于建立存放 ansible-playbook 文件的目录。

编写基础模块的 Playbook

实现如下功能:

  1. 基础仓库准备;
  2. 安装 rsync 服务端;
  3. 安装 nfs-utils 服务端;
  4. 创建 www 用户指定 UID/GID;
  5. 准备 rsync 客户端密码文件。

建立基础环境的 YAML:

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
[root@m01 ansible_playbook]# cat base.yml 
- hosts: all
remote_user: root
tasks:
- name: configure yum repos
yum_repository:
name: base
description: base yum repo
baseurl:
- http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
- http://mirrors.aliyuncs.com/centos/$releasever/os/$basearch/
- http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/
gpgcheck: no
- name: configure yum repos
yum_repository:
name: epel
description: epel yum repo
baseurl: http://mirrors.aliyun.com/epel/7/$basearch
gpgcheck: no
- name: Create www Group
group: name=www gid=666
- name: Create www User
user: name=www uid=666 group=666 shell=/sbin/nologin create_home=no
- name: create rsync client pass
copy: content='123456' dest=/etc/rsync.pass mode=0600
- name: Push backup scripts
copy: src=./files/clinet_push_rsync.sh dest=/server/scripts/
when: (ansible_hostname != "backup")
- name: Cron Tasks
cron: name=Rsync_Backup minute=00 hour=01 job='/bin/bash /server/scripts/clinet_push_rsync.sh &>/dev/null'
when: (ansible_hostname != "backup")

使用 ansible-playbook 检测语法并进行模拟执行:

1
2
3
[root@m01 ansible_playbook]# ansible-playbook --syntax-check base.yaml
playbook: base.yaml
[root@m01 ansible_playbook]# ansible-playbook -C base.yaml

编写应用模块 rsync 的剧本:

  1. 安装 rsync 服务端;
  2. 配置 rsync 服务端;
  3. 启动 rsync 服务端;
  4. 准备对应的数据存储仓库/backup、/data 并授权为 www;
  5. 准备虚拟用户和密码文件权限 600;
  6. 变更配置,重载服务。

准备对应配置文件存放至/etc/ansible/ansible_playbook/files/:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@m01 conf]# cat /etc/ansible/ansible_playbook/files/rsyncd.conf 
uid = www
gid = www
port = 873
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false
list = false
auth users = rsync_backup
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log
#####################################
[backup]
path = /backup
[data]
path = /data

编写 rsync 服务端安装的 YAML 语法:

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
[root@m01 ansible_playbook]# cat rsync.yml 
- hosts: backup
remote_user: root
tasks:
- name: Install Rsync Server
yum: name=rsync state=present
- name: Config Rsync Server
copy: src=./files/{{ item.src }} dest=/etc/{{ item.dest }} mode={{ item.mode }}
with_items:
- { src: "rsyncd.conf", dest: "rsyncd.conf", mode: "0644" }
- { src: "rsync.passwd", dest: "rsync.passwd", mode: "0600" }
notify:
- Restart Rsync Server
tags: conf_rsync
- name: Create Directory
file: name={{ item }} state=directory owner=www group=www recurse=yes
with_items:
- /data
- /backup
- name: Server Rsync Server
service: name=rsyncd state=started enabled=yes
- name: Check Rsync Status
shell: netstat -lntp|grep rsync
register: Rsync_Status
- name: Out Rsync Status
debug: msg={{ Rsync_Status.stdout_lines }}
handlers:
- name: Restart Rsync Server
service: name=rsyncd state=restarted

编写应用模块 NFS 的剧本:

  1. 安装 NFS 服务端;
  2. 配置 NFS 服务端;
  3. 启动 NFS 服务端;
  4. 准备对应数据存储仓库/data 并授权为 www;
  5. 变更配置,重载服务。

准备 NFS 配置文件 exports:

1
2
[root@m01 ansible_playbook]# cat /etc/ansible/ansible_playbook/files/exports 
{{ share_dir }} {{ share_ip }}(rw,sync,all_squash,anonuid=666,anongid=666)

编写 NFS 安装与配置的 YAML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@m01 ansible_playbook]# cat /etc/ansible/ansible_playbook/nfs.yml
- hosts: nfs
remote_user: root
vars:
share_dir: /data
share_ip: 172.16.1.0/24
tasks:
- name: Install NFS-Server
yum: name=nfs-utils state=present
- name: Configure NFS-Server
template: src=./files/exports dest=/etc/exports
notify: Restart Nfs Server
- name: Create Directory
file: name={{ share_dir }} state=directory owner=www group=www recurse=yes
- name: Start NFS-Server
service: name=nfs state=started enabled=yes
- name: Check Nfs Server
shell: cat /var/lib/nfs/etab
register: NFS_Status
- name: Out Nfs Server
debug: msg={{ NFS_Status.stdout_lines }}
handlers:
- name: Restart Nfs Server
service: name=nfs state=restarted

编写应用模块 sersync 的剧本:

  1. 安装 sersync 服务端;
  2. 配置 sersync 服务端;
  3. 启动 sersync 服务端。

下载 sersync 软件包:

1
2
[root@m01 ansible_playbook]# ll /etc/ansible/ansible_playbook/file/
-rw-r--r-- 1 root root 727290 Aug 1 12:04 sersync.tar.gz

准备 sersync 实时同步的配置文件:

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
[root@m01 ansible_playbook]# cat /etc/ansible/ansible_playbook/conf/confxml.xml.nfs 
<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
<host hostip="localhost" port="8008"></host>
<debug start="false"/>
<fileSystem xfs="true"/>
<filter start="false">
<exclude expression="(.*)\.svn"></exclude>
<exclude expression="(.*)\.gz"></exclude>
<exclude expression="^info/*"></exclude>
<exclude expression="^static/*"></exclude>
</filter>
<inotify>
<delete start="true"/>
<createFolder start="true"/>
<createFile start="true"/>
<closeWrite start="true"/>
<moveFrom start="true"/>
<moveTo start="true"/>
<attrib start="false"/>
<modify start="false"/>
</inotify>
<sersync>
<localpath watch="/data">
<remote ip="172.16.1.41" name="data"/>
</localpath>
<rsync>
<commonParams params="-az"/>
<auth start="true" users="rsync_backup" passwordfile="/etc/rsync.pass"/>
<userDefinedPort start="false" port="874"/><!-- port=874 -->
<timeout start="true" time="100"/><!-- timeout=100 -->
<ssh start="false"/>
</rsync>
<failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
<crontab start="false" schedule="600"><!--600mins-->
<crontabfilter start="false">
<exclude expression="*.php"></exclude>
<exclude expression="info/*"></exclude>
</crontabfilter>
</crontab>
<plugin start="false" name="command"/>
</sersync>
<plugin name="command">
<param prefix="/bin/sh" suffix="" ignoreError="true"/> <!--prefix /opt/tongbu/mmm.sh suffix-->
<filter start="false">
<include expression="(.*)\.php"/>
<include expression="(.*)\.sh"/>
</filter>
</plugin>
<plugin name="socket">
<localpath watch="/opt/tongbu">
<deshost ip="192.168.138.20" port="8009"/>
</localpath>
</plugin>
<plugin name="refreshCDN">
<localpath watch="/data0/htdocs/cms.xoyo.com/site/">
<cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
<sendurl base="http://pic.xoyo.com/cms"/>
<regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
</localpath>
</plugin>
</head>

编写 sersync 应用 YAML:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@m01 ansible_playbook]# cat sersync.yaml 
- hosts: nfs
tasks:
- name: Installed Sersync
copy: src=./file/sersync.tar.gz dest=/server/tools/
- name: Tar xf Sersync
shell: cd /server/tools/ && tar xf sersync.tar.gz && mv GNU-Linux-x86 /usr/local/sersync
args:
creates: /usr/local/sersync
- name: Config Sersync
copy: src=./conf/confxml.xml.nfs dest=/usr/local/sersync/confxml.xml
- name: Service Start Sersync
shell: /usr/local/sersync/sersync2 -dro /usr/local/sersync/confxml.xml

编写 Web 应用模块的剧本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@m01 ansible_playbook]# cat web.yml 
- hosts: web
remote_user: root
vars:
remote_nfs_ip: 172.16.1.31
local_dir: /var/www/html/
http_port: 80
tasks:
- name: Installed Httpd Server
yum: name=httpd,php state=present
- name: Configure Httpd Server
template: src=./files/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: Restart Httpd Server
- name: Start Httpd Server
service: name=httpd state=started enabled=yes
- name: Mount Nfs Server
mount: src={{remote_nfs_ip}}:/data path={{ local_dir }} fstype=nfs opts=defaults state=mounted
- name: Push kaoshi.zip
unarchive: src=./files/kaoshi.zip dest={{ local_dir }}
handlers:
- name: Restart Httpd Server
service: name=httpd state=restarted

将所有编写好的 YAML 引入至一个文件中, 这样便于一次执行:

1
2
3
4
5
6
[root@m01 ansible_playbook]# cat main.yaml 
- import_playbook: base.yaml
- import_playbook: rsync.yaml
- import_playbook: nfs.yaml
- import_playbook: sersync.yaml
- import_playbook: web.yaml

测试

  1. 测试 Web 是否能同步数据至 NFS 存储;
  2. NFS 是否实时同步至 rsync 的/data;
  3. 使用客户端测试能否推送数据至 rsync 的 backup。

Apache 的三种工作模式介绍「event 篇」

2020年8月25日 00:00

Apache 目前一共有三种稳定的 MPM 模式。它们分别是 prefork/worker 和 event,它们同时也代表 Apache 的演变和发展。今天杜老师就聊下 event 模式!

event 模式的工作原理

event 是 Apache 最新的工作模式,和 worker 模式很像,不同的是在于它解决了 keep-alive 长连接时候占用线程资源被浪费的问题。

event 工作模式中,会有一些专门的线程用来管理这些 keep-alive 类型线程,当真实请求过来的时候,将请求传递给服务器的线程,执行完毕之,又允许它释放。这样,一个线程就可以几个请求了,实现了异步非阻塞。这增强了在高并发场景下的请求处理。

event 工作模式在遇到某些不兼容模块时,如果,将会回退到 worker 模式,一个工作线程处理一个请求。官方自带模块全部支持 event 工作模式的。

event 工作模式需要 Linux 系统对 epoll 支持,才能启用。需要补充的是 HTTPS 的连接,它的运行模式仍然类似 worker 的方式,线程会被一直占用,知道连接关闭。

event 模式的装方法

在编译安装 Apache 的过程中,加入参数–with-mpm=event 即进行编译安装。

也可以使用–enable-mpms-shared=all,这样在编译的时候会在 modules 目录下自动编译出三个 MPM 文件的 so,然后通过修改 httpd.conf 配置文件更改 MPM 即可。

worker 模式的配置参数说明

配置说明
StartServers 3服务启动时初始进程数,默认为 3
MinSpareThreads 75最小空闲子进程数,默认为 75
MaxSpareThreads 250最大空闲子进程数,默认为 250
ThreadsPerChild 25每个子进程产生的线程数量,默认是 25
MaxRequestWorkers 400限定同一时间内客户端最大接入的请求数,默认是 400
MaxConnectionsPerChild 0每个子进程在其生命周期内允许最大请求数量,如果请求总数已经达到这个数值,子进程将结束,如果设置为 0,子进程将永远不会结束。将值设置为非 0 值,可以防止运行 PHP 导致的内存泄露

工作模式与 Web 应用选择

Apache 能更好的为有特殊要求的站点定制。例如,要求更高伸缩性的站点可以选择使用线程的 MPM,即 worker 或 event。

需要可靠性或者与旧软件兼容的站点则可以使用 prefork。就使用 PHP 而言,FastCGI 和 PHP-FPM 是更推荐的使用模式。

Apache 的三种工作模式介绍「worker 篇」

2020年8月22日 00:00

Apache 目前一共有三种稳定的 MPM 模式。它们分别是 prefork/worker 和 event,它们同时也代表 Apache 的演变和发展。今天杜老师就聊下 worker 模式!

worker 模式的工作原理

worker 模式和 prefork 模式相比较,worker 模式使用了多进程和多线程的混合模式,worker 模式也同样会先预派生一些子进程,然后每一个子进程创建一些线程,同时包括一个监听线程,每个请求过来会被分配到一个线程来服务。线程比起进程会更轻量,因为线程是通过共享父进程内存空间,因此,内存的占用会减少一些,在高并发场景下会比 prefork 有更多可用的线程,表现会更优秀一些。另外,如果一个线程出现问题也会导致同一进程下的线程出现问题,如果是多个线程出现了问题,也只是影响 Apache 的一部分,而不是全部的。由于用到多进程多线程,需要考虑到线程的安全,在使用 keep-alive 长连接的时候,某个线程会一直被占用,即使中间没有请求,需要等待到超时才会被释放。

Apache 总是试图维持一个备用或空闲的服务线程池。这样,客户端无须等待新线程或者新进程的建立即可得到处理。在 Unix 中为了能够绑定 80 端口,父进程一般都是以 root 的身份启动,随后,Apache 会以较低权限的用户建立子进程和线程。User 和 Group 指令用于配置 Apache 子进程的权限。虽然子进程必须对其提供内容拥有读权限,但应该尽可能给予它较少的特权。另外,除非使用了 suEXEC ,否则,这些指令配置的权限将被 CGI 脚本继承。

worker 模式的安装方法

在编译安装 Apache 的过程中,加入参数–with-mpm=worker 即进行编译安装。

也可以使用–enable-mpms-shared=all,这样在编译的时候会在 modules 目录下自动编译出三个 MPM 文件的 so,然后通过修改 httpd.conf 配置文件更改 MPM 即可。

worker 模式优缺点

优点:占据更少内存,高并发下表现优秀。

缺点:必须考虑线程安全问题,因为多个子线程是共享父进程内存地址的。如使用 keep-alive 的长连接方式,也许中间几乎没有请求,这时就会发生阻塞,线程会被挂起,需要一直等待到超时才会被释放。如果线程过多,被这样的占据,也会导致高并发场景下的无服务线程可用。

worker 模式配置参数说明

配置说明
StartServers 3服务启动时初始进程数,默认是 3
MinSpareThreads 75最小空闲子进程数,默认是 75
MaxSpareThreads 250最大空闲子进程数,默认是 250
ThreadsPerChild 25每个子进程产生的线程数量,默认是 25
MaxRequestWorkers 400限定同一时间内客户端最大接入请求数量,默认是 400
MaxConnectionsPerChild 0每个子进程在其生命周期内允许最大请求数量,如果请求总数已经达到这个数值,子进程将结束,如果设置为 0,子进程将永远不会结束。如该值设置为非 0 值,可以防止运行 PHP 导致的内存泄露

Apache 的三种工作模式介绍「prefork 篇」

2020年8月16日 00:00

Apache 目前一共有三种稳定的 MPM 模式。它们分别是 prefork/worker 和 event,它们同时也代表 Apache 的演变和发展。今天杜老师就聊下 prefork 模式!

prefork 模式的工作原理

prefork 模式是很古老但是非常稳定的模式。用的是多个子进程,Apache 在启动之初,控制进程会建立若干子进程,然后等待请求进来,并且总是视图保持一些备用的子进程。为不在请求到来时再生成子进程,所以需要根据需求不断的创建新的子进程,最大可以达到每秒 32 个直到满足需求为止。之所以这样做,是为减少频繁创建和销毁进程的开销。每个子进程中只有一个线程,在一个时间点,只能处理一个请求。

在 Unix 系统,父进程通常以 root 身份运行以便绑定 80 端口,而 Apache 产生的子进程通常以一个低特权用户运行。User 和 Group 指令用于配置子进程的低特权用户。运行子进程的用户必须要对它所服务的内容有读取权限,但对服务内容之外的其它资源必须拥有尽可能少的权限。

prefork 模式的安装方法

在编译安装 Apache 的过程中,加参数–with-mpm=prefork 即可,如不加也可以,因为 Apache 默认采用 prefork 模式进行编译安装。

也可以使用–enable-mpms-shared=all,这样在编译的时候会在 modules 目录下自动编译出三个 MPM 文件的 so,然后通过修改 httpd.conf 配置文件更改 MPM 即可。

prefork 模式优缺点

优点:成熟,兼容所有新老模块。进程之间完全独立,使它非常稳定。同时,不需要担心线程安全的问题。

缺点:一个进程相对占用更多系统资源,消耗更多内存。而且,它并不擅长处理高并发请求,在这种场景下,它会将请求放进队列中,一直等有可用进程,请求才被处理。

prefork 模式的配置参数说明

配置参数说明如下:

配置说明
StartServers 5服务启动时初始进程数,默认是 5
MinSpareServers 5最小空闲子进程数,默认是 5
MaxSpareServers 10最大空闲子进程数,默认是 10
MaxRequestWorkers 250限定同一时间内客户端最大接入请求数量,默认是 250
MaxConnectionsPerChild 0每个子进程在其生命周期内允许最大请求数量,如果请求总数已经达到这个数值,子进程将结束,如果设置为 0,子进程将永远不会结束。该值设置为非 0 值,可以防止运行 PHP 导致的内存泄露

MySQL 主键和唯一索引区别

2020年8月13日 00:00

主键的完整称呼是主键约束,是 MySQL 中使用最为频繁的约束。一般情况为了便于 DBMS 更快的查找到表中的记录,都会在表中设一个主键。MYSQL 索引用来快速地寻找那些具有特定值的记录,如果没有索引,执行查询时 MySQL 必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求记录。

两者区别

主键是种约束,唯一索引是种索引,两者在本质上是不同的。

主键创建后一定包含一个唯一性索引,唯一性索引并不一定是主键。

唯一性索引列允许空值,而主键列不允许为空值。

主键列创建时,已经默认为非空值加唯一索引了。

主键可被其他表引用为外键,唯一索引不能。

一个表最多能创建一个主键,但可创建多个唯一索引。

主键和唯一索引都可有多列。

主键适合那些不容易更改的唯一标识,如自动递增列、身份证等。

在 RBO 模式,主键的执行计划优先级高于唯一索引。两者都可以提高查询的速度。

索引是一种特殊的文件,它们包含对数据表里所有记录的引用指针。

总体来说

主键相当于一本书籍的页码,索引相当于书籍的目录。

其实主键和索引都是键,不过主键是逻辑键,索引是物理键,意思是主键不实际存在,而索引实际存在在数据库中,主键一般都要创建,主要用来避免一张表中有相同的记录,索引一般可以不建,但如果需要对该表进行查询操作,则最好建,这样可以加快检索速度。

Win10 的 S 模式是什么

2020年7月8日 00:00

大部分用户可能不知道 Win10 系统下有一个 S 模式,什么是 S 模式?S 模式中的 Win10 是一个受限制的锁定 Windows 操作系统。如果想了解更多 S 模式,不妨看看下面的详细内容吧!

模式介绍

微软在这里投入安全性,速度和稳定性。由于 Win10 只能从商店运行应用程序,因此来自网络的恶意软件将无法运行。您无法从网上安装应用程序,因此它们无法安装启动任务,更不会减慢启动过程或隐藏在后台并侦察您的垃圾文件。

S 模式也推动了 Bing 搜索引擎。在 S 模式下 Edge 网络浏览器使用 Bing 作为默认搜索引擎。您无法将 Edge 的默认搜索引擎更改为 Baidu 或其他任何不首先离开 S 模式的搜索引擎。S 模式下的 Win10 无法通过注册表编辑器直接访问 Windows 注册表。不能使用像 PowerShell 这样的命令行。但其它各种开发工具不会受限制。

如果要运行的所有应用程序在 Microsoft Store 中均可用,那么 S 模式是更安全的体验。这就是为何微软最初为学校推出了 S 模式。可运行 Microsoft Edge、Microsoft Office 和 Store 中其它产品,包括 QQ 以及微信等应用。这有点像 iPad 上的 iPadOS 操作系统,它只允许从 App Store 安装应用程序。而 S 模式是限制在 Microsoft 商店中提供的 Windows 应用程序。

Win10 的 S 模式是可选择的。大多数 Win10 个人电脑都带有标准的 Win10 家庭版或者 Win10 专业版操作系统,可从任何地方运行软件。带有 S 模式的电脑会说它们的产品规格中使用了 S 模式下的 Win10 家庭版或 S 模式下的 Win10 专业版。即使在 S 模式下购买 PC,也可以免费离开 S 模式。它不需要花费任何费用,但这是一次性决定。一旦将 PC 从 S 模式退出,则无法将其重新置于 S 模式。

模式检查

通过前往设置——系统——关于,可以检查是否正使用 S 模式。在关于页面上,向下滚动到 Windows 规格部分。如果在版本条目右侧看到 S 模式字样,则表示正在使用 S 模式。

目前最为常见的 S 模式电脑就是微软的 Surface Go 系列,这个系列对应的则是苹果 iPad 系列。该系列的系统皆运行 S 模式。

模式选择

应该购买带 S 模式的电脑吗?因为离开 S 模式很容易而且自由,所以购买 S 模式附带的电脑没有任何不利之处。即使不需要 S 模式,也可轻松切换。如微软只在 S 模式下销售 Surface Laptop。即使想要一台运行标准版 Windows 操作系统的 Surface Laptop,也可以购买它并免费从 S 模式中退出。

应该在 S 模式下使用吗?S 模式听起来有限,但只需要基本的 Microsoft Edge、Microsoft Office 应用程序以及 Microsoft Store 中提供的任何其它应用程序,则应尝试在 S 模式下使用 PC。S 模式限制提供针对恶意软件的额外保护。

在 S 模式下运行的 PC 也适合年轻学生、仅需少量应用程序的商用 PC 以及经验较少的计算机用户。

当然,如需要商店中不可用的软件,则必须离开 S 模式。但是可以尝试在 S 模式下使用 PC 一段时间,看看它有多好。

模式退出

请先记住:尽管可以随时的离开 S 模式,但选择离开 S 模式是一个永久的决定。一旦离开了 S 模式,则永远不能重新回到 S 模式。它将使用标准的 Win10 家庭版或 Win10 专业版操作系统。但仍可以选择仅允许来自 Win10 上应用商店的应用。

在运行 S 模式的 Wind10 的电脑上,依次打开设置——更新——激活。在切换到 Win10 家庭版或切换到 Win10 专业版部分中选择转到 Microsoft Store。在 Microsoft Store 中显示的退出 S 模式页面上,选择获取按钮。等待页面上显示确认消息后,就可以安装来自 Microsoft Store 之外的应用了。

Linux 服务器大量向外发包问题排查

2020年7月2日 00:00

最近杜老师的一台云服务器,向外大量发送流量,不断的建立 TCP 连接,目标地址是美国一个 IP,估计被当成肉鸡了,比较悲惨,今天杜老师聊一下如何处理这个问题!

问题排查

1
sar -n DEV 2 10

注意:在服务器运行上面命令,确认了出现大量发包的问题。

问题处理

开始之前,先清除 eth0 所有队列规则:

1
tc qdisc del dev eth0 root 2> /dev/null > /dev/null

定义顶层队列规则,指定 default 类别编号:

1
2
tc qdisc add dev eth0 root handle 1: htb default 20
tc class add dev eth0 parent 1: classid 1:20 htb rate 2000kbit

查看状态:

1
2
yum install -y tcpdump
tcpdump -nn

找到大量的 IP 地址,可以将异常 IP 加入到/etc/hosts.deny,或者防火墙设置下。之后安装个 nethogs:

1
2
3
4
5
yum -y install epel-release
yum clean all
yum makecache
yum -y install nethogs
nethogs

处理结果

找到大量发包进程,之后 kill 掉,排查下这个进程是什么程序,文件路径在哪,删除掉异常的文件。

目前的问题解决了,观察一段时间,看看问题是否还会发生,防火墙将公网 IP 进行了访问限制,只允许指定 IP 访问,增加安全。

命令扩展

nethogs 的选项如下:

选项作用
V显示版本信息,注意是大写字母 V
d延迟更新刷新速率,秒为单位。默认为 1
t跟踪模式
p混合模式
设备要监视的设备名称,默认为 eth0

nethogs 运行时,按键效果如下:

按键效果
q退出
m总数、当前使用情况模式之间切换

Ubuntu 如何挂载 OSS

2020年6月29日 00:00

对象存储 OSS 是阿里云提供的海量、安全、可靠的云存储服务。OSS 具有与平台无关的 API 接口,可在任何应用、任何时间、任何地点存储和访问任意类型的数据。

挂载步骤

1
2
3
4
5
6
7
8
wget http://gosspublic.alicdn.com/ossfs/ossfs_1.80.6_ubuntu18.04_amd64.deb
apt update && apt -y install gdebi-core
gdebi ossfs_1.80.6_ubuntu18.04_amd64.deb
echo Bucket:AccessKey ID:AccessKey Secret > /etc/passwd-ossfs
chmod 640 /etc/passwd-ossfs
mkdir /OSSDIR
ossfs Bucket /OSSDIR -ourl=EndPoint
echo 'ossfs Bucket /OSSDIR -ourl=EndPoint' >> /etc/rc.local

注意:第一步的下载地址可以自行搜索,或者在评论去留言找杜老师索取,文中的版本支持 Ubuntu18.04+。

命令注释

  1. 第三步的 Bucket/AccessKey ID/AccessKey Secret 需要根据实际值修改;

  2. 第五步的目录名称可自定义;

  3. 第六步的 EndPoint 需要根据实际值修改;

  4. 使用开机自启脚本实现自动挂载。

Redis 主从复制的配置

2020年6月2日 00:00

Redis 是一个 Key-Value 的存储系统。和 Memcached 类似,它支持存储 value 类型相对更多,包括链表、集合、有序集合、哈希类型和字符串。这些数据类型都支持 Push/Pull、Add/Remove 及取交集并集和差集及更丰富操作,而且这些操作都是原子性的。在这个基础上,Redis 支持各种不同方式的排序。与 Memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。

章节简介

本章节讲解了 Redis 主从复制的配置过程。

内容是大神提供的,考虑到知识版权等问题,本教程以电子书的形式分享。在阅读中遇到问题,可在评论区域留言,杜老师会转述给大神来解答!

在线阅读

在线阅读:

Redis 主从复制的原理

2020年5月30日 00:00

Redis 是一个 Key-Value 的存储系统。和 Memcached 类似,它支持存储 value 类型相对更多,包括链表、集合、有序集合、哈希类型和字符串。这些数据类型都支持 Push/Pull、Add/Remove 及取交集并集和差集及更丰富操作,而且这些操作都是原子性的。在这个基础上,Redis 支持各种不同方式的排序。与 Memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。

章节简介

本章讲解关于主动复制一些概念、原理、Redis 旧版及新版功能实现流程。

内容是大神提供的,考虑到知识版权等问题,本教程以电子书的形式分享。在阅读中遇到问题,可在评论区域留言,杜老师会转述给大神来解答!

在线阅读

在线阅读:

Redis 持久化及主从复制对过期键的处理

2020年5月27日 00:00

Redis 是一个 Key-Value 的存储系统。和 Memcached 类似,它支持存储 value 类型相对更多,包括链表、集合、有序集合、哈希类型和字符串。这些数据类型都支持 Push/Pull、Add/Remove 及取交集并集和差集及更丰富操作,而且这些操作都是原子性的。在这个基础上,Redis 支持各种不同方式的排序。与 Memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。

章节简介

本章节讲解了 RDB 持久化对过期数据的影响,AOF 持久化对过期数据的影响,主从复制模式中对过期键的处理。

内容是大神提供的,考虑到知识版权等问题,本教程以电子书的形式分享。在阅读中遇到问题,可在评论区域留言,杜老师会转述给大神来解答!

在线阅读

在线阅读:

过期键的删除

2020年5月24日 00:00

Redis 是一个 Key-Value 的存储系统。和 Memcached 类似,它支持存储 value 类型相对更多,包括链表、集合、有序集合、哈希类型和字符串。这些数据类型都支持 Push/Pull、Add/Remove 及取交集并集和差集及更丰富操作,而且这些操作都是原子性的。在这个基础上,Redis 支持各种不同方式的排序。与 Memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。

章节简介

键虽然被设置过期时间,但是当过期以后是如何处理的呢?本章讲解三种处理规则。

内容是大神提供的,考虑到知识版权等问题,本教程以电子书的形式分享。在阅读中遇到问题,可在评论区域留言,杜老师会转述给大神来解答!

在线阅读

在线阅读:

过期键的设置、获取、删除过期时间

2020年5月21日 00:00

Redis 是一个 Key-Value 的存储系统。和 Memcached 类似,它支持存储 value 类型相对更多,包括链表、集合、有序集合、哈希类型和字符串。这些数据类型都支持 Push/Pull、Add/Remove 及取交集并集和差集及更丰富操作,而且这些操作都是原子性的。在这个基础上,Redis 支持各种不同方式的排序。与 Memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。

章节简介

本章节讲解了过期键的设置,如何设置过期,如何获取键的过期时间,过期时间返回值的说明。

内容是大神提供的,考虑到知识版权等问题,本教程以电子书的形式分享。在阅读中遇到问题,可在评论区域留言,杜老师会转述给大神来解答!

在线阅读

在线阅读:

AOF 持久化的配置和原理

2020年5月18日 00:00

Redis 是一个 Key-Value 的存储系统。和 Memcached 类似,它支持存储 value 类型相对更多,包括链表、集合、有序集合、哈希类型和字符串。这些数据类型都支持 Push/Pull、Add/Remove 及取交集并集和差集及更丰富操作,而且这些操作都是原子性的。在这个基础上,Redis 支持各种不同方式的排序。与 Memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。

章节简介

本章节讲解了 Redis 的 AOF 持久化相关内容,主要围绕期配置和原理。

内容是大神提供的,考虑到知识版权等问题,本教程以电子书的形式分享。在阅读中遇到问题,可在评论区域留言,杜老师会转述给大神来解答!

在线阅读

在线阅读:

Redis 的配置文件参数说明

2020年5月15日 00:00

Redis 是一个 Key-Value 的存储系统。和 Memcached 类似,它支持存储 value 类型相对更多,包括链表、集合、有序集合、哈希类型和字符串。这些数据类型都支持 Push/Pull、Add/Remove 及取交集并集和差集及更丰富操作,而且这些操作都是原子性的。在这个基础上,Redis 支持各种不同方式的排序。与 Memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。

章节简介

本章节讲解了 Redis 的配置文件参数说明。

内容是大神提供的,考虑到知识版权等问题,本教程以电子书的形式分享。在阅读中遇到问题,可在评论区域留言,杜老师会转述给大神来解答!

在线阅读

在线阅读:

Redis 注册服务与自动启动

2020年5月12日 00:00

Redis 是一个 Key-Value 的存储系统。和 Memcached 类似,它支持存储 value 类型相对更多,包括链表、集合、有序集合、哈希类型和字符串。这些数据类型都支持 Push/Pull、Add/Remove 及取交集并集和差集及更丰富操作,而且这些操作都是原子性的。在这个基础上,Redis 支持各种不同方式的排序。与 Memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。

章节简介

本章讲解了如何为 Redis 注册服务与自动启动。

内容是大神提供的,考虑到知识版权等问题,本教程以电子书的形式分享。在阅读中遇到问题,可在评论区域留言,杜老师会转述给大神来解答!

在线阅读

在线阅读:

Redis 的设置启动信息

2020年5月9日 00:00

Redis 是一个 Key-Value 的存储系统。和 Memcached 类似,它支持存储 value 类型相对更多,包括链表、集合、有序集合、哈希类型和字符串。这些数据类型都支持 Push/Pull、Add/Remove 及取交集并集和差集及更丰富操作,而且这些操作都是原子性的。在这个基础上,Redis 支持各种不同方式的排序。与 Memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。

章节简介

本章讲解 Redis 的设置启动信息。

内容是大神提供的,考虑到知识版权等问题,本教程以电子书的形式分享。在阅读中遇到问题,可在评论区域留言,杜老师会转述给大神来解答!

在线阅读

在线阅读:

❌
❌