普通视图

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

Mac新版微信4.0版本以上如何备份聊天记录到移动硬盘

2025年5月7日 11:14
这篇文章介绍了微信备份迁移的相关知识,重点针对mac用户在微信备份文件不兼容问题的解决方法。用户因微信版本更新引发的整个备份布局变化感到困惑,文章详细指导了如何迁移旧版备份文件、创建新备份文件、完成备份操作,并解决了备份文件丢失及无法截图等问题。文章还提供了具体的操作步骤:复制备份文件至移动硬盘、创建软链接、使用codesign命令重新签名微信应用、授予系统访问权限等。同时,文章提醒用户注意备份前的检查,确保硬盘连接正常,以避免操作失误。整体内容结构清晰,语言简洁明了,非常适合mac用户快速掌握微信备份迁移的技巧。

在银河麒麟桌面操作系统 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;

# 其他配置...
}

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

PS邀请函多名字怎么处理?批量制作证书、邀请函、奖状图片

2025年4月15日 15:27
这篇文章介绍了如何利用Photoshop的变量功能高效制作个性化邀请函。第一步是设计邀请函模板,并将替换的文本分别放置在独立的文本图层中。接着,创建一个包含名单的CSV文件,随后在Photoshop中为文本图层定义变量并导入CSV文件作为数据组。通过文件>导出>数据组作为文件功能,可以进行批量生成。最后,使用快速操作或图像处理器将PSD文件转换为图片格式。这种方法不仅节省了大量时间,还特别适合需要批量制作个性化邀请函的情况。

宝塔面板与Bitwarden插件不兼容,登录提示:验证码长度错误 解决方法

2025年4月15日 14:55
这篇文章介绍了宝塔面板与Bitwarden在开启2FA后存在不兼容问题,登录时提示“验证码长度错误”且验证码无法加载,作者经过测试发现是宝塔将2FA验证码误识为登录验证码,建议关闭宝塔的动态验证码并在Bitwarden中删除验证器密钥以解决问题,目前已向社区反馈但是否官方修复仍未知。

Photoshop换电脑如何迁移工作区,将习惯的布局拷贝到其他电脑上

2025年4月15日 11:03
这篇文章介绍了在Adobe Photoshop中导出和导入工作区设置的方法帮助用户在不同电脑之间轻松切换工作环境首先需确保已有自定义工作区接着通过保存工作区设置文件存储于用户特定路径下的WorkSpaces文件夹可将设置备份至U盘或云端在新电脑上通过复制备份文件至相应路径并重启Photoshop即可导入原先的工作区设置实现无缝切换。

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。如果一切顺利,我们应该不再看到错误消息。

OpenWrt如何开启SSH仅密钥登录,取消密码登录增强安全性

2025年3月24日 11:37
这篇文章介绍了如何通过家庭路由器R5S的安全配置来增强网络安全性。首先,移除了默认的密码登录功能,改用更加安全的密钥登录方式。具体来说,可以通过Bitwarden自动生成密钥或在本地计算机上生成密钥后再传输至路由器并设置权限。此外,文章还提供了如何测试SSH登录和禁用密码登录的方法,以进一步提升网络安全性。

iStoreOS统一文件共享无法连接smb怎么办,windows无法挂在smb提示拒绝访问

2025年3月24日 11:04
这篇文章介绍了如何使用SMB(Server Message Block)协议在局域网内实现文件共享,从而替代传统的WebDAV。具体步骤包括:确保Samba服务的正常运行;创建和管理用户账户;并通过SSH远程登录来配置文件共享。此外,文章还总结了成功的解决方案,并特别强调了使用命令行工具的重要性。

米家空调伴侣接入HomeAssistant不显示当前温度的解决方法,解决HomeKit空调始终21度问题

2025年3月21日 10:48
这篇文章介绍了米家空调伴侣在接入HomeAssistant时无法显示当前温度的问题,并提供了解决方法。作者之前通过自定义实体解决了该问题,但由于Xiaomi Miot Auto登录问题转到了Xiaomi Home,导致功能失效。为彻底解决这一问题,作者开发了一个新的Home Assistant自定义集成——洪绘空调,用于创建虚拟空调设备并显示当前温度。文章详细介绍了如何安装和配置该集成,并指导用户将其接入HomeKit以实现正常显示和控制。

加密 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 时也需要注意一些事项。

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

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

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

如何获取视频的LUFS(响度单位)?通过视频文件测量视频音量响度水平

2025年3月3日 17:54
这篇文章介绍了视频音量的重要性及其调整方法。文中提到,视频音量过低会影响观看体验,特别是在信息流中与其他大声视频竞争时。为了解决这一问题,文章引入了LUFS(Loudness Units Full Scale)作为衡量音频响度的标准,并解释了其在广播和流媒体中的应用。作者推荐使用ffmpeg工具来测量视频的LUFS值,并提供了具体的操作命令和参数说明。最后,文章还详细解读了测量结果中各项参数的意义,帮助用户更好地调整视频音量以符合不同平台的要求。

Hexo上传服务器建议使用rsync来替代git上传,repo文件夹越来越大解决方法

2025年2月24日 15:40
这篇文章介绍了如何通过rsync工具解决Hexo部署时服务器文件占用过大问题的方法。文章建议使用hexo-deployer-rsync插件,并通过npm安装该插件。在配置时需修改博客根目录下的_config.yml文件,添加rsync的相关参数,包括远程服务器地址、用户信息、目标目录等设置。此外,还可以选择性删除其他不必要的部署方式,并调整运行目录以适应具体环境需求。

探索 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 命令清理缓存。

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

如何静态化Docker容器的IP地址?构建网络实现容器固定IP

2025年2月21日 17:36
这篇文章介绍了如何在使用 docker-compose 部署的环境中为容器设置固定的 IP 地址,以解决容器在重启后因 IP 自动变化导致无法上网的问题。文章首先创建了一个名为 heo_global_network 的自定义桥接网络,并将其 IP 地址段设置为 172.168.0.0/16。然后修改 docker-compose 文件,将容器连接到该外部网络并指定静态 IPv4 地址。通过这些步骤,用户可以确保容器在网络重启后保持稳定的 IP 地址,并成功实现上网功能。

iStoreOS如何给硬盘分区扩容?Openwrt已经正在使用的分区如何扩容?

2025年2月21日 10:26
这篇文章介绍了在iStoreOS x86根分区中扩容的具体步骤。通过使用parted工具查看硬盘信息,用户可以确认要扩展的分区为4号分区,当前容量为21.5GB。通过执行resizepart命令,用户可以输入新的终止位置30GB,从而实现分区扩大。此外,还需要使用resize2fs -p命令对文件系统进行调整,最终完成扩容操作,无需重启服务器或卸载挂载点。

当了UP主四年多: 油管/Youtube上传了700多期视频, 2000个粉丝

2025年2月14日 03:46

youtube 当了UP主四年多: 油管/Youtube上传了700多期视频, 2000个粉丝 折腾 教娃 教育 育儿 视频

油管/Youtube

我曾经说过不想做UP主。后来觉得孩子大了,可以开始教他们编程,于是尝试了几节课,朋友建议把这些内容上传到油管,既能记录也能分享。我觉得这个主意不错,于是就开始了。前500期视频因为没有时间剪辑和加字幕,所以直接用iPhone拍好后就上传了。

到了500期后,我强迫自己开始剪辑,使用了手机上的“必剪”App和PC上的“剪影”软件,这两款都是字节跳动出品的。现在这两款软件的自动字幕功能已经不再免费了。

最初只上传到油管,后来也同步到了B站,接着又上传到西瓜视频、微信视频号,还尝试了小红书和微博视频。我把视频上传到这么多平台,主要是为了备份,利用这些免费的云存储多做些备份,同时还能赚点小钱。

不过要是真是按付出时间和挣得的钱来算,真是亏麻了。能挣钱的UP主并不是很多,大多数人还是不挣钱的,投入的时间和收入不成正比。我们总是在网上听人说挣了很多钱,这大概率是幸存者偏差,头部效应。UP主一旦停止更新,很有可能就会很快失去流量,失去流量就等于失去收入

到现在为止,油管还没达到YouTube Partner Program的收入门槛,B站的收入大概几千元,应该是前两年有过一些推广活动。西瓜视频提现过一次,应该也是两三千元,微信视频号的收入就几块钱。

目前,B站有四万多粉丝,油管只有2000个。留下来的都是铁杆粉丝。B站上我把所有的视频都放在一个账号里,包括教媳妇编程的内容;而在油管,我把中英文的内容分成了两个频道,也许是因为这个原因,油管/Youtube的公开观看时长不够。

我的频道:油管/Youtube | 中文油管频道/教媳妇 | B站/小破站 | 微博视频 | 西瓜视频 | 微信视频号 | X/推特 | 小红书

youtube-700-days 当了UP主四年多: 油管/Youtube上传了700多期视频, 2000个粉丝 折腾 教娃 教育 育儿 视频

油管上陆陆续续上传了700天,每期视频都几十次浏览,一两个Like/赞。

youtube-2000-subscribers 当了UP主四年多: 油管/Youtube上传了700多期视频, 2000个粉丝 折腾 教娃 教育 育儿 视频

终于在今年初过了2000个粉丝。

youtube-channel-day-1 当了UP主四年多: 油管/Youtube上传了700多期视频, 2000个粉丝 折腾 教娃 教育 育儿 视频

第一天上传视频是2020年11月22日,当时还在亚马逊AWS S3工作。

youtube-earning-public-watch-hours 当了UP主四年多: 油管/Youtube上传了700多期视频, 2000个粉丝 折腾 教娃 教育 育儿 视频

油管得YPP开通挣钱门槛需要3000/4000个小时公开观看时长。

教娃编程

本文一共 816 个汉字, 你数一下对不对.
当了UP主四年多: 油管/Youtube上传了700多期视频, 2000个粉丝. (AMP 移动加速版本)

扫描二维码,分享本文到微信朋友圈
75a5a60b9cac61e5c8c71a96e17f2d9c 当了UP主四年多: 油管/Youtube上传了700多期视频, 2000个粉丝 折腾 教娃 教育 育儿 视频
The post 当了UP主四年多: 油管/Youtube上传了700多期视频, 2000个粉丝 first appeared on 小赖子的英国生活和资讯.

相关文章:

  1. 按揭贷款(房贷,车贷) 每月还贷计算器 去年给银行借了17万英镑 买了20万7500英镑的房子, 25年还清. 前2年是定率 Fix Rate 的合同 (年利率2.49%). 每个月大概是还 700多英镑. 有很多种还贷的计算方式, 定率/每月固定 是比较常用的. 简单来说就是 每个月交的钱是...
  2. 智能手机 HTC One M9 使用测评 虽然我对手机要求不高, 远远没有像追求VPS服务器一样, 但是怎么算来两年内换了四个手机, 先是三星 S4 用了一年多, 然后 Nokia Lumia 635 Windows Phone, 后来又是 BLU, 半年多前换了...
  3. 同一台服务器上多个WORDPRESS站点的一些设置可以移出去 我自从把所有网站都挪到一处VPS服务器上 就发现很多事情省事很多 可以同时管理多个网站 包括 WORDPRESS博客. 比如我有四个WORDPRESS博客 然后我就把通用的一些资料给移出去 移到 HTTP或者HTTPS都不能直接访问的文件夹里这样就更安全许多. 文件 wp-conn.php 存储了 相同的数据库资料. 1 2...
  4. 英国房子的EPC节能报告(Energe/Efficiency Performance Certificate) EPC (Energe/Efficiency Performance Certificate) 是英国房子的节能报告, 法律上规定, 每个房子都必须要有一个EPC报告, 报告的有效期为十年. 房东在把房子出租或者想卖房的时候, 这个EPC就必须有效, 在一些情况下 比如出租房子的时候, 这个EPC报告还必须符合一些最低标准, 比如房子必须满足 F档(类似及格线)...
  5. 公司请的专业摄影师 公司来了新的CEO管理之后,很多事情都不一样了, 特别是一些公司对外形象的事情就特别的在意, 比如公司网站用上SSL.现在公司还有空闲的位置,请速来(钱多人不傻). 一月份出差回LUTON,刚好公司请来摄影师给高层管理照像放网站上的,于是我也凑了凑热闹(但是却还不够资格被放在公司网站上),不过没关系,放这里也差不多. 人到中年, 沧桑感强了些. 更新更新: 同事用他NB的单反给谢菲尔得办公室的人也拍了一组这样的照片.看起来很不错, 很专业,灯光,道具应有尽有.我已经用在了LINKEDIN页面上,立马高大上. 本文一共 230 个汉字, 你数一下对不对. 公司请的专业摄影师. (AMP...
  6. 面向猫猫编程 Cat Oriented Programming (Chessly/Pyro这一生持续更新) 家里有两只猫 Chessly/Pyro,想着找个地方记录它们的生活,最后决定还是写在这里的博客。猫的一生很短,差不多也就二十年。 Chessly(黑白猫)是我加入微软剑桥研究院MSRC第一个月带回家的,过了两三个月,又把Pyro(橘猫)也接回了家。两只猫的名字是孩子们取的:Chessly因为黑白的像棋盘,加上“ly”听起来像个女孩的名字;而Pyro的意思是一团火(烟火),充满活力。 刚开始的时候,Chessly特别喜欢待在我的工作区域。她有时候趴在键盘上或旁边,有时候藏在显示器后面。偶尔还会绕到我身边“咕咕”地撒娇,等着我去摸她。有时更干脆跑到我腿上,舒舒服服地躺着。 不过,现在它们俩的体型都大了很多,躺在桌上就会挡住屏幕,真是“面向猫猫编程”(Cat Oriented Programming)的极致体验。 记录生活的点滴,也是一种珍惜,毕竟这二十年,我们会一起走过。 2024年 2025年 Ring视频:两猫日常就是打闹,Chessly追上Pyro想舔他,在猫的世界里,地位高的才能舔地位低的。 我家猫现在越来越胖,很喜欢在我工作的时候躺在显示器钱,很影响我的工作,不过这时候我就是会休息一下摸摸她,就当放松一下了。 Pyro在窗边喝水,这是个小的煮饭锅,现在不用了,就给猫当喝水的碗。Pyro很胆小,经常看到我就跑。没法跑就咕咕叫。 Chessly很喜欢陪我工作,然后她很好厅的盯着屏幕上的鼠标光标,真怕她把屏幕抓坏了。 哥哥弹琴,弟弟唱歌,Chessly午睡,真是幸福啊,下辈子做只猫吧。...
  7. 在英国给孩子换学校的经历: 孩子离开了村里的小学 由于搬了家, 孩子上学得提前半小时出门了, 因为早上堵, 也得开车半小时才能到. 之前在 Fen Drayton 村庄上小学, 早上8:45学校门开, 9点敲钟孩子排队依次进入教室, 我们由于在村里, 只需要提前5分钟出门和孩子一起走路就可以了. 现在一下子早上变得很匆忙, 得叫孩子起床, 做早饭,...
  8. 公司给配了台高配DELL笔记本 早上例会结束的时候我顺便说了一句 我的笔记本有点慢, 当时我并不知道我的经理远程用电话也参加会议了(他全程在听), senior staff SE 对着电话说, “peter, you hear that? btw, my disks are...

麒麟服务器操作系统 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

HomeAssistant如何设置自动备份,定期自动备份并自动删除旧备份

2025年2月8日 14:18
这篇文章介绍了HomeAssistant的新自动备份功能。用户可以通过进入系统设置并选择备份选项来启用该功能。下载紧急套件后,可以设置每日或每周一次的备份周期,例如每周一进行备份。此外,为了节省存储空间,可以选择关闭历史数据的备份功能,仅保留必要的信息。完成这些设置后,备份文件体积将大幅减少,存储在backups目录中。

如何在mac上隐藏应用程序在dock栏中的图标

2025年2月6日 13:59
这篇文章介绍了如何在macOS上隐藏应用程序图标,不再显示在Dock栏中。方法是通过修改应用的Info.plist文件,将LSUIElement值设置为1,这样图标就不会出现在Dock里,但应用仍然可以在后台运行。如果想恢复,只需将值改回0或删除该行代码。这是一个适合不经常更新的后台菜单栏应用的解决方案。

如何自定义ollama模型存储位置?Mac、Windows修改模型存储位置教程

2025年2月6日 12:31
这篇文章介绍了如何自定义Ollama模型的存储位置,适用于Mac和Windows系统。文章详细说明了在两种操作系统下修改模型存储路径的方法,并强调了设置稳定存储路径的重要性。对于Windows用户,可以通过环境变量OLLAMA_MODELS指定新路径或使用软链接迁移模型;而Mac用户则需要编辑shell配置文件并设置环境变量。文章还提醒读者,在进行任何更改前应退出Ollama服务以避免意外错误,并建议选择可靠的存储设备以确保模型顺利运行。

Certimate接入宝塔更新宝塔网站证书教程,自动更新证书到所有网站

2025年2月5日 11:07
这篇文章介绍了如何利用宝塔面板的计划任务实现自动化的 SSL 证书更新,从而减少手动操作的工作量。文章详细说明了通过 Python 脚本来批量更新网站证书的方法,并结合 Certimate 的证书部署功能,展示了如何设置每天定时任务来完成这一过程。这种方式既安全又高效,避免了频繁的手动干预。

在Mac上部署DeepSeek R1模型,设置知识库对话、Prompt等

2025年2月2日 22:21
这篇文章介绍了在Mac上本地部署DeepSeek R1大模型的方法,并展示了如何通过Ollama进行模型运行和管理。作者详细讲解了从下载Ollama应用、安装命令行工具,到在终端中运行不同内存分配下的模型版本的过程。此外,还介绍了使用Page Assist插件设置对话界面,并通过Prompt引导AI行为。最后,文章还提到了如何通过文本嵌入模型自定义知识库,满足特定需求的对话场景。

教娃编程有趣的瞬间 vlog视频集合

2025年1月22日 04:59

教娃700天:写在教娃编程700天, what’s next?。有很多有意思的瞬间记录一下,持续更新。

和孩子一起打闹,学习,成长。

教娃编程孩子有趣的瞬间 vlog(Day 641)





娃说我不够 Senior(Day 701)

Bro.. I thought you’re like senior…
Yes, I am senior!
You should know how to do it then..
I’ll ask ChatGPT..
Bro, you don’t need ChatGPT..
OK, we can talk about it next lesson.

油管 | 微博 | 小红书 | 微信视频 | B站

娃嫌弃我的中式英文

油管 | 微博 | 微信视频 | B站 | 西瓜视频 | 小红书

儿子说在谷歌工作要比在微软挣得多

儿子说在谷歌工作要比在微软挣得多

教娃好玩的视频 vlog 片段

本文一共 252 个汉字, 你数一下对不对.
教娃编程有趣的瞬间 vlog视频集合. (AMP 移动加速版本)

扫描二维码,分享本文到微信朋友圈
75a5a60b9cac61e5c8c71a96e17f2d9c 教娃编程有趣的瞬间 vlog视频集合 VLog 学校 教娃 教程 教育 生活 视频
The post 教娃编程有趣的瞬间 vlog视频集合 first appeared on 小赖子的英国生活和资讯.

相关文章:

  1. 个人网站Adsense广告申请通过: 需要最少15篇文章 我的个人网站 zhihua-lai.com 本月通过了 Adsense 审核,终于可以再次放置广告,赚些零花钱了。 其实,最初 Adsense 账户通过审核后就能直接放广告,但后来规则变得严格了。如果一个网站长时间没有放置任何 Adsense 广告代码,账户资格会被撤销。重新启用时,需要进行单独审核。如今,在 Google Adsense 中新增一个域名,也必须通过审核后才能投放广告。 为了让我的网站通过审核,我尝试了几次,但总是被拒,原因之一是必须要有足够的内容支持。例如,以前我做的工具网站 SlowAPI.com...
  2. 新的旅途 – 离别总是伤感的, 离开了一起创业的公司 2周前, 正式离开了一起创业的公司, 这公司是我博士毕业后的第一份正式工作, 待了8年多了, 离别总是伤感的. 我是9月初提的离职, 三个月 Notice Period, 最后的几周交接完工作确实没有什么压力了. 11月30号, 在公司最后一天, 公司有个习惯, 对于 Good...
  3. Minuet in C – 小步舞曲C Posted Youtube – 油管地址 孩子弹琴的时候最帅了. 我现在成了我儿子的粉丝了. Eric (Aged 6) is playing “Minuet in C” when...
  4. 上了年纪痛风脚崴了的惨痛经历(尿酸过高) 痛风是一种疼痛性关节炎, 当血液中的尿酸水平高, 导致晶体形成并积聚在关节内或关节周围, 就会发生痛风. 当人体分解一种叫做嘌呤的化学物质时, 就会产生尿酸. 嘌呤自然存在于您的身体中, 也存在于某些食物中. 尿酸通过尿液从体内排出. 上两周, 和媳妇吵架, 然后就自己一人睡, 有一天起床后脚踝就开始疼了, 然后明显比左脚肿了. 我刚开始就以为是睡觉的时候不小心姿势不对,...
  5. 今晚可能是英国倒数第三次冬令时时间调整 来英国生活过的人都知道 英国有一个很有意思的夏令时和冬令时时间调整. 夏令时是每年3月份的最后一个星期天凌晨会暴力的把时间往后调整1个小时, 也就是1点的时候很神奇的时间会自动变成2点. 冬令时是相反, 在每年的十月份最后一个周日凌晨暴力的把时间往前调整一个小时, 也就是2点神奇的变成1点. 现在大多数电子设备都能自动调整时间了, 比如你的智能手机和电脑. 但是传统的一些钟表, 还需要人为的调整时间. 夏令时 (Daylight Saving Time)调整的那一天,...
  6. 优衣库 感觉像炒作 这几天 这个在北京三里屯 ‘优衣库’ 试衣间自拍的视频真的很火, 男女主角均被人肉. 不可否认 这个效果还真的不错 因为我之前根本不知道 “优衣库” 是干嘛的 很刺激 在试衣间XXOO是多么爽的事情 女主角 95后妹子 长相甜美....
  7. 因为一个 try catch 好几天优秀点赞程序挂掉了我却以为是节点的问题 YY银行有四个点赞程序, 分别跑于四台服务器上, 它们是: 股东点赞(代理给 @justyy ) 自己的号 足球队 优秀作者(排名前30, 还有跟随点赞) 这几天我就发现, 有些赞没有给出, 我还以为是节点的原因, 因为查看记录, 发现是...
  8. 怎么样查看 STEEMSQL 是否数据同步完全? 尽管它已经转换为按月订阅模式, SteemSQL是由@arcange开发和维护的一个很好的服务(MSSQL). 其实对于这些中心化的数据库来说, 最重要的就是它要能够及时的从区块链上同步数据. 如果数据不全, 那么其实是没有多大用处的. STEEMSQL每隔8分钟就会从区块链上同步数据. 之前有过几回, STEEMSQL数据并不及时的同步, 如果你的程序很需要很及时的数据, 则STEEMSQL并不是很好的选择. 相反, 如果你只是想运行几个语句去查询以往的数据, 则STEEMSQL是个很好的方案, 毕竟从中心化关系型数据库取数据要比去区块链上取数据快得多....

如何在不同操作系统上安装和使用 FFmpeg?macOS、Windows、Ubuntu、CentOS安装ffmpeg教程

2025年1月16日 16:14
这篇文章介绍了如何在不同操作系统上安装和使用 FFmpeg。文章详细说明了在 macOS、Windows、Ubuntu 和 CentOS 上安装 FFmpeg 的步骤,包括使用 Homebrew、APT、YUM 或手动下载的方式。每个操作系统的安装过程都配有具体命令,并提供了验证安装是否成功的方法。此外,文章还介绍了 FFmpeg 的基本使用方法,如转换视频格式和提取音频,为用户提供了简单易懂的指南,帮助读者顺利安装并使用 FFmpeg。

如何提取英雄联盟资源文件:获取lol客户端图片、技能图标、皮肤原画

2025年1月13日 16:03
这篇文章介绍了如何提取《英雄联盟》客户端中的资源文件,包括技能图标、皮肤原画及英雄模型等内容。首先安装Obsidian并关联游戏文件夹,然后通过搜索关键词查找所需图标或音频资源。文章还分享了提取皮肤和导出模型的方法,包括选择目标皮肤数据、使用Lol2dae工具转换文件格式、加载纹理等详细步骤,帮助用户将游戏模型导入3D软件进行进一步处理。

使用 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

Calibre 推荐配置与插件

2025年1月12日 13:40

在我的2024年阅读记录中,电子书的阅读量已经占整年阅读量的70%以上,家里的纸质书也逐步二手转让,电子书和阅读笔记就不可避免遇到整理的问题。

阅读笔记我主要是通过阅读器或阅读软件导出并整理到 Obsidian 中,我在 Obsidian 中设计了固定且简洁的阅读笔记模板,保证统一的格式和可检索性,但不会过度保存书籍的原始信息(书籍封面、页数等等感觉没必要)。

对于电子书的整理,这类软件没太多选择,灵活度且支持多平台的也只有 Calibre 能胜任。此外 Calibre-Web 更能通过 Docker 部署到 NAS 或者云主机中,折腾首选。因为我只考虑本地电子书的整理,平时阅读主要依赖墨水屏和微信读书,所以 Calibre-Web 就不折腾了。

Calibre 完全免费,支持中文,可以在 Windows、Mac 和 Linux 系统上运行,支持 TXT、PDF、EPUB、MOBI、DOCX、HTML、Markdown 等等众多格式,支持复杂的条件搜索语法和书籍全文搜索,支持本机建立内容服务器,局域网内使用浏览器访问书库及阅读。

下面介绍一下我使用 Calibre 的一些配置经验和推荐的插件(本文以 MacOS 15.2,Calibre v7.24.0 版本,本地管理方式为例)。

 

配置建议

1. 自定义栏目管理增加状态、阅读进度标记

通过“首选项”》“管理栏目”创建自定义栏目,增加“状态”栏目,用于标识电子书的阅读状态,比如我会使用”在读,已读,搁置,已读2遍,已读3遍“来记录阅读状态。同样的方法,你可以更加精细的记录阅读进度、读后短评等等。

Calibre 推荐配置与插件-雅余

 

2. 优化日期的显示方式

通过“首选项”》“优化调整”对日期的显示方式进行自定义。默认设置“MMM yyyy”实在看着别扭,建议把出版日期修改为 “yyyy-MM”,加入日期和修改日期修改为 “yyyy-MM-dd”。

Calibre 推荐配置与插件-雅余

 

3. 调整界面外观图标主题

默认图标风格太丑,可通过“首选项”》“界面外观”调整图标主题,推荐 Setenove 系列,图标大小设置为中小

Calibre 推荐配置与插件-雅余

 

4. 以中文名称保存书籍至硬盘

Calibre 默认提取书籍保存到硬盘是使用“作者简称/标题/标题 - 作者”作为路径和名称,实在啰嗦。建议按截图勾选,禁止转换为字符和封面单独保存等,保存模板直接设置以标题保存即可。更多的时候提取只是为了分享或者发送到硬件设备中。

Calibre 推荐配置与插件-雅余

 

5. 使用中文路径(禁止 Calibre 翻译文件路径)

多年以前我不愿使用 Calibre 是因为它会自动把中文名称和路径翻译转换为拼音,可读性太差,强迫症受不了。感谢 Cirn09 的 “Calibre-do-not-translate-my-path”(将我的书库从拼音目录切换至非纯英文(中文)命名)这个插件拯救了不少患者。

Calibre 推荐配置与插件-雅余

patch 方案:
通过 Github 下载 Calibre-do-not-translate-my-path

解压下载的包,得到 python-lib.bypy.frozen 文件。

打开 Finder,进入“应用程序” (/Applications),右键点击“Calibre——显示包内容”,进入 Contents/Frameworks/plugins (对应的完整路径是 /Applications/calibre.app/Contents/Frameworks/plugins )。将第 1 步下载包里的 python-lib.bypy.frozen,拷贝覆盖原文件,重新打开 Calibre 即可。

Git 上有其他系统的使用方法,作者也提供了对已建书库的批量处理方法。

 

6. 精选元数据来源

在“首选项”》“插件”中展开“元数据来源”,禁用不需要的元数据来源,减少插件的加载。

Calibre 推荐配置与插件-雅余

在“首选项”》“下载元数据”中勾选不需要的数据源,减少查询元数据时对速度的影响。我仅保留3项,基本能满足中英文书籍查询,通过豆瓣获取封面优先级为最高。

Calibre 推荐配置与插件-雅余

 

7. 禁用在线书店

在“首选项”》“插件”中展开“在线书店”,禁用不需要插件。我还把菜单栏上的快捷入口删除了。基本用不着这个功能。

Calibre 推荐配置与插件-雅余

 

8. 精选设备接口

在“首选项”》“插件”中展开“设备接口”,禁用不需要插件。我仅保留了安卓和 Kindle,其他全部禁用。

Calibre 推荐配置与插件-雅余

 

9. 备份 Calibre 设置项

在“首选项”》“杂项”中,点击“打开 'calibre 配置'文件夹“,可以跳转到 calibre 的配置文件夹,对整个文件夹进行打包备份,以便重装软件等等不时之需。

Calibre 推荐配置与插件-雅余

 

10. 生成书库书目及制作成电子书

Calibre 支持为书库所有书籍制作电子书目,可自定义书目包含的元数据字段信息,支持生成 CSV、EPUB、XML 等多种格式,生成后在书库内直接浏览。建议导出 CSV 格式,方便处理导入其他软件中使用。

Calibre 推荐配置与插件-雅余

 

11. 书库备份

硬盘富余的话,可以考虑定期对整个书库进行备份。我暂时仍保留着原始文件夹整理和 Calibre 整理两种方式。

Calibre 推荐配置与插件-雅余

 

推荐插件

1. Highlights to Obsidian

实现一键同步 Calibre 的批注内容到 Obsidian 中,同步内容包括高亮位置的链接、高亮内容、自己对高亮内容的批注等。通过插件可以自定义同步到 Obsidian 中的模板格式,灵活度很高。该插件可以通过 Calibre 进行搜索安装,也可以通过 Github 下载安装包。

2. Ebook Translator

Ebook Translator 是书伴开发的一款 Calibre 插件,可以将不同格式不同语言的电子书翻译成指定语言(原文译文对照)指定格式的电子书,支持 Google、ChatGPT 和 DeepL 翻译引擎。该插件可以通过 Calibre 进行搜索安装。

3. New Douban Books

实现通过豆瓣获取书籍元数据和封面图片。建议通过 Github 中获取一个较新的安装包,并通过“从文件加载插件”的方式进行安装。

安装插件还是坚持一个原则,能免则免,能精则精,不要贪多。

-

参考资料:
- 阅读批注样样通,我的 Calibre 书籍库管理方法论
- Ebook Translator:用 Calibre 翻译多格式双语对照电子书
- 用Calibre管理图书,还能一键同步批注到Obsidian
- Calibre 不要翻译我的文件路径

给博客增加 文章归档 和 年度统计 功能

2024年12月30日 17:30

终于在建站11年的当下终于给博客增加了文章归档页。
是基于 Rank Math SEO 插件的 Sitemap Settings 功能实现了一个简单的文章归档页。
顺带在文章归档页内塞了一个额外的网站数据年度统计功能。
大概长这样:文章归档


起因 为什么想要加文章归档页了

起因是在《WindowTabs: 让几乎一切 Windows 窗口支持多标签功能》一文下,博友 ddw2019 在评论中提到我的站点“没有找到 Archive 页面,一个个翻页起来,感觉还是有点点费劲的呀。”

之前我一直感觉文章归档页的感知不强,我认为它的主要意义和好处是:系统化整理文章、提高可发现性、增强用户体验、SEO优化、展示创作历程这 5 个方面。

毕竟现在右侧有文章分类、随机文章、热门文章三个模块。系统化整理文章提高可发现性性上已经足够了。
SEO 优化上文章归档页固然归可以帮助搜索引擎更好地抓取和索引博客内容,不过在已经有 xml 站点地图的时候,文章归档页对于提供博客的 SEO 优化上作用不大,相较这种 html 格式站点地图,xml 格式的站点地图对搜索引擎会更加友好一些。

不过嘛,确实考虑到博客里确实是缺少一个展示创作历程和增强用户体验的东西。于是在2024年的年底,终于在建站 11 年后决定加上这个东西。

思考 实现文章归档页的方案

那么现在问题来了,如何多快好省的实现文章归档页 Archive 呢?
从这个博客的可以称之为极简的风格上估计大家都能看出,我并不太喜欢在美化折腾博客页面上消耗过多精力。

  • 方案一 网友 ddw2019 的博客中写到的方案 年度归档插件
    好处是省事的多,装个插件的事情。缺点是又双叒叕需要多装一个插件了,博客速度又要被拖累。
  • 方案二 利用现有插件 Rank Math SEO 的站点地图功能实现。
    好处是利用了现有插件,少装了一个插件,缺点是样式就简陋的多了,样式的自定义空间也小的多。

  • 方案三 自己实现一个页面
    优点是更加轻量,样式完全可以自定义。缺点是自己写东西需要费更多的时间。

权衡利弊后,我决定先用方案二顶上,先解决有无问题再说。

开干 实现文章归档

以下的必要前提是:你要有装 Rank Math SEO 这个插件,并且开启了他的 Sitemap 组件。
这里我只介绍必要的操作,如果想了解更多一点,这里有篇不错的文章 《家庭数据中心系列Rank Math SEO设置与优化-无敌的个人博客》

  1. 新建一个页面,起名叫文章归档并把固定链接设置为ex.your.domain/archives并发布。
    (是的,内容为空就行)
  2. 进入博客后台,左侧找到 Rank Math SEO 的 Sitemap Settings 部分,切换到 HTML Sitemap 标签,并开启开关。

  3. 将 Display Format (显示模式)设置为 Page 也就是页面模式。如果你想在文章归档页放入额外的东西,也可以设置为 Shortcode 模式,这样上一步时,需要在你想要插入文章归档页的地方写短代码[rank_math_html_sitemap] 即可。

  4. Sort by (排序方式),既然是文章归档页,那自然是选 Published Date (基于发表日期)啦。并且开启下边的 Show Dates (显示日期),这样文章后面就会显示发布日期了。

  5. Item Titles (项目标题),作为文章归档页,建议选 Item Titles (文章标题)而不是 SEO Titles (SEO用标题)这两者的区别是:SEO用标题是给搜索引擎和搜索结果用户看的,可能会比实际的文章标题会有些奇妙的拉长和缩短。比如文章实际标题很长,但是 SEO 标题可能会为了能保证在搜索结果页把关键词凸显出来会相对减少次要描述。也就是说 Item Titles (文章标题)更能反映文章内容。

  6. 最后保存即可,现在前边设定的固定链接看到一个比较简陋的,文章归档页了。
    类似本站这样:文章归档 (https://www.tjsky.net/archives)

增强 增加博客年度数据统计功能

本来事情就该结束了,结果中午的时候,我又在博友圈里看到了 ts小陈 的文章:《为WordPress网站添加年度数据汇总
我发现,“诶,这个东西不错嘛,可以很直观的展现每年博客的发展数据。”
随后尝试直接套用代码,然后果不其然的发现:事情并没有那么简单。
毕竟我现在用的主题上次更新已经是2022年了,主题并没有完美支持页面模板php文件。
并不能像他原文介绍的那样:

  • 将php文件上传到你主题的页面模板文件夹(pages文件夹)
  • 创建新页面选择该模板-年度数据
  • 发布页面,搞定。

于是我又研究了一下WordPress这个页面模板php文件应该怎么写,以及他代码具体是做了什么。
重新写了适配自己主题的页面模板文件。主要修改点是三个

  • 修改一下样式适配博客主题
    主要是套用原有page页的代码,改一个新的模板文件。还有些小修改,比如表格做成圆角啊,表格改个主题色啊,属于毫无技术含量的修改。
  • 修改其中统计字数的函数str_word_count()mb_strlen()
    中文不用空格来分隔单词,对于中文字符串,str_word_count()会将两个标点之间的整个字符串都视为一个单词,mb_strlen()则会根据当前PHP设定的编码自适应用基于UTF8或gbk等编码正确统计字数。所以改一下得到准确的字数统计。

//修改前的代码,在原文文件的第79行
word_count = str_word_count(strip_tags(content)); // 去除HTML标签后计算字数

//修改后的代码
word_count = mb_strlen(strip_tags(content)); // 去除HTML标签后计算中文字数

大部分面板和一键脚本部署的 PHP 应该默认就开了 mb_strlen 这个函数,不过对于用虚拟主机的可能需要注意下,这个 PHP 函数不一定被启用了。

  • 把缓存改成1天,30天有些长了。

原文写的是”数据使用 Memcached 缓存”,让人以为只能用于 Memcached。不过实际上,如果你用 Redis 或者其他什么缓存,只要你装了对应的缓存插件,比如用 Redis 并且装了 Redis Object Cache。可以保证wp_cache_get()wp_cache_set() 函数能正常工作就不需要注释掉缓存代码,不然每次都现场计算一次,这性能浪费不小。

最终效果如下图

很直观的数据
2017年上一个博客被我rm -rf */干没了之后,在 17 年 12月 底重建,18 年还在保持正常的更新,可惜博客没啥人看(看评论数量),外在驱动力不足 导致 19 ~ 21 年我基本上没更新过博客,21 年底,因为一些机缘巧合博客收获了一波较大流量,加之因为这个机缘巧合重新拾起写代码的乐趣,重新开始恢复正常的更新频率。

The post 给博客增加 文章归档 和 年度统计 功能 appeared first on 秋风于渭水.

写在教娃编程700天, what’s next?

2024年12月28日 06:19

今年明显减少了教孩子编程的频率。从年初的一周两节课,逐渐减少到一节课,最终在今年8月26日迎来了第700天的里程碑。在此期间,还新增了一个系列——教孩子学习理财和赚钱的知识。

随着事情越来越多,孩子逐渐长大,学校的作业负担加重,再加上练琴等其他活动,时间变得格外紧张。经过反复考虑,决定不再设定硬性指标,改为随缘而教,有时间就继续。

从第1天到达成第700天,这段旅程已经非常不容易。第1天始于2020年11月22日,第700天是2024年8月26日,间隔1374天,平均每1.96天上一次编程课。我在第200天时曾立下计划,要坚持到1000天,但现在看来这个目标无法实现。到了500天后,开始剪辑教学视频,进度逐渐放缓。正所谓“行百里者半九十”,许多事情越接近目标,越难坚持。

回想起第一天教编程时,我还在亚马逊工作。3.76年后,我在微软剑桥研究院,而孩子在这4年中也发生了很大的变化。翻看早期的视频,可以清晰感受到孩子的成长,尤其是声音的变化,让人感慨万分。

教孩子编程不仅是开发智力的一种好方法,也让我更深入地了解了他们的兴趣与未来的方向。大儿子表示他未来想从事金融相关的工作,小儿子则对计算机领域充满热情,计划成为一名工程师,目前他对硬件相关方向更感兴趣。两娃的数学都很不错。

这700天的编程教学,不仅是孩子们的成长,也是我自身的提升。我通过费曼学习法,提高了自己的表达能力和英语口语水平。这段旅程,无疑是一段珍贵的记忆,也是一笔丰厚的收获。

完整700天的视频只上传到了B站和油管。西瓜视频从300天到697天(后面上传不了了:西瓜视频再也上传不了视频了(字节头条: 抖西合并)),微博视频从680天到700天,还有就是后面百来天上传到了微信视频号。

youtube-channel-doctorlai-700-days-teaching-kids 写在教娃编程700天, what's next? 教娃 教程 教育 生活 编程 育儿

油管频道doctorlai教娃视频700天

bilibili-700-days-teaching-kids-scaled 写在教娃编程700天, what's next? 教娃 教程 教育 生活 编程 育儿

B站教娃视频700天

教娃编程

对了:教娃编程有趣的瞬间 vlog视频集合

本文一共 765 个汉字, 你数一下对不对.
写在教娃编程700天, what’s next?. (AMP 移动加速版本)

扫描二维码,分享本文到微信朋友圈
75a5a60b9cac61e5c8c71a96e17f2d9c 写在教娃编程700天, what's next? 教娃 教程 教育 生活 编程 育儿
The post 写在教娃编程700天, what’s next? first appeared on 小赖子的英国生活和资讯.

相关文章:

  1. 按揭贷款(房贷,车贷) 每月还贷计算器 去年给银行借了17万英镑 买了20万7500英镑的房子, 25年还清. 前2年是定率 Fix Rate 的合同 (年利率2.49%). 每个月大概是还 700多英镑. 有很多种还贷的计算方式, 定率/每月固定 是比较常用的. 简单来说就是 每个月交的钱是...
  2. 智能手机 HTC One M9 使用测评 虽然我对手机要求不高, 远远没有像追求VPS服务器一样, 但是怎么算来两年内换了四个手机, 先是三星 S4 用了一年多, 然后 Nokia Lumia 635 Windows Phone, 后来又是 BLU, 半年多前换了...
  3. 在英国给孩子换学校的经历: 孩子离开了村里的小学 由于搬了家, 孩子上学得提前半小时出门了, 因为早上堵, 也得开车半小时才能到. 之前在 Fen Drayton 村庄上小学, 早上8:45学校门开, 9点敲钟孩子排队依次进入教室, 我们由于在村里, 只需要提前5分钟出门和孩子一起走路就可以了. 现在一下子早上变得很匆忙, 得叫孩子起床, 做早饭,...
  4. 同一台服务器上多个WORDPRESS站点的一些设置可以移出去 我自从把所有网站都挪到一处VPS服务器上 就发现很多事情省事很多 可以同时管理多个网站 包括 WORDPRESS博客. 比如我有四个WORDPRESS博客 然后我就把通用的一些资料给移出去 移到 HTTP或者HTTPS都不能直接访问的文件夹里这样就更安全许多. 文件 wp-conn.php 存储了 相同的数据库资料. 1 2...
  5. 英国房子的EPC节能报告(Energe/Efficiency Performance Certificate) EPC (Energe/Efficiency Performance Certificate) 是英国房子的节能报告, 法律上规定, 每个房子都必须要有一个EPC报告, 报告的有效期为十年. 房东在把房子出租或者想卖房的时候, 这个EPC就必须有效, 在一些情况下 比如出租房子的时候, 这个EPC报告还必须符合一些最低标准, 比如房子必须满足 F档(类似及格线)...
  6. 公司请的专业摄影师 公司来了新的CEO管理之后,很多事情都不一样了, 特别是一些公司对外形象的事情就特别的在意, 比如公司网站用上SSL.现在公司还有空闲的位置,请速来(钱多人不傻). 一月份出差回LUTON,刚好公司请来摄影师给高层管理照像放网站上的,于是我也凑了凑热闹(但是却还不够资格被放在公司网站上),不过没关系,放这里也差不多. 人到中年, 沧桑感强了些. 更新更新: 同事用他NB的单反给谢菲尔得办公室的人也拍了一组这样的照片.看起来很不错, 很专业,灯光,道具应有尽有.我已经用在了LINKEDIN页面上,立马高大上. 本文一共 230 个汉字, 你数一下对不对. 公司请的专业摄影师. (AMP...
  7. 面向猫猫编程 Cat Oriented Programming (Chessly/Pyro这一生持续更新) 家里有两只猫 Chessly/Pyro,想着找个地方记录它们的生活,最后决定还是写在这里的博客。猫的一生很短,差不多也就二十年。 Chessly(黑白猫)是我加入微软剑桥研究院MSRC第一个月带回家的,过了两三个月,又把Pyro(橘猫)也接回了家。两只猫的名字是孩子们取的:Chessly因为黑白的像棋盘,加上“ly”听起来像个女孩的名字;而Pyro的意思是一团火(烟火),充满活力。 刚开始的时候,Chessly特别喜欢待在我的工作区域。她有时候趴在键盘上或旁边,有时候藏在显示器后面。偶尔还会绕到我身边“咕咕”地撒娇,等着我去摸她。有时更干脆跑到我腿上,舒舒服服地躺着。 不过,现在它们俩的体型都大了很多,躺在桌上就会挡住屏幕,真是“面向猫猫编程”(Cat Oriented Programming)的极致体验。 记录生活的点滴,也是一种珍惜,毕竟这二十年,我们会一起走过。 2024年 2025年 Ring视频:两猫日常就是打闹,Chessly追上Pyro想舔他,在猫的世界里,地位高的才能舔地位低的。 本文一共 357 个汉字, 你数一下对不对....
  8. 力扣 Leetcode 的刷题利器: 在线调试器和自动代码提示完成 力扣代码调试器 Debugger 最近 leetcode 刷题网站出了一个在线调试器. 个人感觉非常好用. 因为我平时是用 IPAD+蓝牙键盘来刷题, 而在 ipad 上是没有集成的IDE的, 对于调试来说, 只能很原始的让函数退出一个值, 然后尝试不同的输入来发现问题. leetcode在线调试器的好处...

Karabiner脚本:Mac实现大小写切换键(中英切换键)移动窗口

2024年12月24日 18:38
这篇文章介绍了如何使用 Karabiner 修改 Mac 键盘键位,将大小写切换键优化为短按切换中英文输入,长按实现窗口拖动操作。通过安装软件、配置权限,应用自定义脚本实现功能,短按模拟左 Shift,用于中英文切换,长按触发 cmd+ctrl 组合键移动窗口,提升使用效率。

Python 中寻找数据的众数: mode vs multimode

2024年12月23日 19:30

在 Python 中寻找数据的众数

statistics.mode() 函数是 Python 中 statistics 模块的一部分,它返回数据集中出现次数最多的单个值(众数)。与 multimode() 不同,mode() 如果数据集包含多个众数(即多模态数据)或数据为空,则会引发错误。

以下是一些示例来说明 mode() 的行为:

mode() 的语法

statistics.mode(data)

data: 一个序列(例如 list、tuple),其中的元素是可散列的,用于确定众数。

示例

单一众数(单模态数据)
from statistics import mode
data = [1, 2, 2, 3, 4]
result = mode(data)
print(result)  # 输出: 2
字符串作为数据
from statistics import mode
data = ["apple", "banana", "apple", "cherry"]
result = mode(data)
print(result)  # 输出: "apple"
多模态数据(引发错误)

如果有多个众数,mode() 会引发 StatisticsError。

from statistics import mode
data = [1, 1, 2, 2, 3]
try:
    result = mode(data)
except StatisticsError as e:
    print(e)  # 输出: "no unique mode; found 2 equally common values"
无重复值(引发错误)

如果数据集中没有值重复,mode() 会引发 StatisticsError。

from statistics import mode
data = [1, 2, 3, 4, 5]
try:
    result = mode(data)
except StatisticsError as e:
    print(e)  # 输出: "no unique mode; found 5 equally common values"
空数据集(引发错误)

如果数据集为空,mode() 会引发 StatisticsError。

from statistics import mode
data = []
try:
    result = mode(data)
except StatisticsError as e:
    print(e)  # 输出: "no mode for empty data"

在 Python 中寻找多众数

在 Python 中,术语 multimode 通常指 statistics.multimode() 函数,这是 Python 3.8 中 statistics 模块的一部分。此函数用于找到数据集中出现次数最多的值(众数)。与 statistics.mode() 不同,后者仅返回单个众数(如果数据集是多模态的会引发错误),而 multimode() 可以处理包含多个众数的多模态数据集。

语法

statistics.multimode(data)

data: 一个序列(例如 list、tuple),其中的元素是可散列的,用于查找众数。

行为

返回输入数据中所有众数的列表。如果没有元素重复,则返回所有唯一值的列表,因为在这种情况下每个值都是众数。

示例

单一众数
from statistics import multimode
data = [1, 2, 2, 3, 4]
result = multimode(data)
print(result)  # 输出: [2]
多个众数
from statistics import multimode
data = [1, 1, 2, 2, 3]
result = multimode(data)
print(result)  # 输出: [1, 2]
无重复值
from statistics import multimode
data = [1, 2, 3, 4, 5]
result = multimode(data)
print(result)  # 输出: [1, 2, 3, 4, 5]

主要特性

多模态支持:可以处理包含多个同频值的数据集。
优雅地处理唯一数据:如果没有重复值,则返回所有唯一值。
灵活的输入类型:适用于任何可散列对象的序列,包括字符串和元组。

字符串示例

data = ["apple", "banana", "apple", "cherry", "banana", "banana"]
result = multimode(data)
print(result)  # 输出: ['banana']

使用场景

  • 分析调查结果或投票中具有多个最受欢迎选项的情况。
  • 识别数据集中可能共享最高频率的频繁模式。

局限性

如果数据集很大,计算众数可能会消耗大量计算资源,因为它需要统计所有元素的出现次数。

mode 与 multimode 的比较

特性 mode() multimode()
返回值 单个最频繁的值 所有最频繁值的列表
多模态数据行为 引发 StatisticsError 返回所有众数
空数据集行为 引发 StatisticsError 返回空列表
最佳用途 适用于期望唯一众数的单模态数据 适用于包含多个众数的多模态数据或任意数据

如果不确定数据是否包含多个众数或无重复值,multimode() 是更安全的选择。

英文:The mode vs multimode in Python

本文一共 702 个汉字, 你数一下对不对.
Python 中寻找数据的众数: mode vs multimode. (AMP 移动加速版本)

扫描二维码,分享本文到微信朋友圈
75a5a60b9cac61e5c8c71a96e17f2d9c Python 中寻找数据的众数: mode vs multimode Python Python 学习笔记 数学 程序设计 计算机
The post Python 中寻找数据的众数: mode vs multimode first appeared on 小赖子的英国生活和资讯.

相关文章:

  1. 按揭贷款(房贷,车贷) 每月还贷计算器 去年给银行借了17万英镑 买了20万7500英镑的房子, 25年还清. 前2年是定率 Fix Rate 的合同 (年利率2.49%). 每个月大概是还 700多英镑. 有很多种还贷的计算方式, 定率/每月固定 是比较常用的. 简单来说就是 每个月交的钱是...
  2. 智能手机 HTC One M9 使用测评 虽然我对手机要求不高, 远远没有像追求VPS服务器一样, 但是怎么算来两年内换了四个手机, 先是三星 S4 用了一年多, 然后 Nokia Lumia 635 Windows Phone, 后来又是 BLU, 半年多前换了...
  3. 西瓜视频再也上传不了视频了(字节头条: 抖西合并) 上两个月,我再也没法在西瓜视频上上传我的视频了,也从此少了一个同步视频备份的地方了。现在登陆西瓜平台,要发视频的话会立马转到抖音创作者中心,然后我尝试通过手机号+SMS验证码的方式登录,提示我“请使用抖音手机APP登录” 原来西瓜视频国外的用户,可以通过手机号SMS+验证码的方式登陆网站,上传视频的。由于我人在英国,装的是英国的App Store,无法安装国内的西瓜视频APP,使用上有点不方便的。后来为了同步到国内的抖音平台,让我姐帮我绑定了她的抖音账号,可能就是因为这样,现在强制我得通过抖音平台来发视频了。等哪天有空我让我姐试试是否可以解绑。 西瓜视频已经合并到抖音平台上了,字节头条也不再单独运营西瓜视频了。 我发了邮件问西瓜视频,得到的回复:“您好,若您可以登录账号,请前往抖音,在设置内选择【我的客服】在线咨询,详细描述您的问题并提供问题界面截屏。若您无法登录账号,您可以拨打 95152 热线咨询,热线接听时间为8:30-22:00” 再问:您好,我们国外的用户没法装抖音啊。。。之前西瓜视频一直是 国外手机号登录的。 答:您好,您可以通过以下几种方法找到西瓜客服帮你解决问题:1.手机端入口:【西瓜视频App】更新至最新版本 【我的】-【创作中心】-【问题反馈】2.手机端入口:【西瓜视频App】-【我的】-【反馈与帮助】【意见反馈】3.电脑端入口:登陆【西瓜创作平台西瓜创作平台】点击右下角【问题咨询】。 西瓜视频是由字节跳动公司推出的一款视频分享平台,旨在提供用户一个便捷的观看和创作短视频的空间。西瓜视频自推出以来,凭借其丰富的内容、强大的推荐算法以及用户互动功能,逐渐成为中国大陆地区受欢迎的视频平台之一。 主要特点: 内容丰富:西瓜视频涵盖了多种类型的视频内容,包括娱乐、搞笑、影视、音乐、游戏、教育、科技等,满足不同用户的兴趣需求。 个性化推荐:依托字节跳动强大的机器学习和人工智能技术,西瓜视频通过分析用户的观看历史和行为习惯,提供精准的个性化推荐,提升用户的观看体验。...
  4. MySQL参数一键配置脚本: 有效提升数据库性能 我一直是自己租用VPS服务器,然后搭建各种服务,比如博客就是Apache2+MySQL数据库。一般来说就是默认参数,没有去管,不过最近发现MySQL的性能参数都很保守,不能发挥整个服务器的性能。 然后我就网上搜索了一下,根据参数配置建议,用ChatGPT写了以下Python和BASH脚本。只需要在需要优化的服务器上,跑一下该脚本,然后就会显示参数配置,然后直接把参数添加到MySQL数据库配置参数文件上: /etc/mysql/mysql.conf.d/mysqld.cnf 然后运行: service mysql restart 重启MySQL服务器。 运行了几周,发现效果很好,博客反应速度也快了很多,这很大原因是根据了内存增加了MySQL缓存大小。 Python脚本优化MySQL数据库参数 把下面的Python脚本存成 mysql_config.py 然后运行 python3 mysql_config.py...
  5. 世界再无OneKey币圈美元虚拟卡了 我前两年就了解到OneKey这个币圈虚拟货币出金卡,不过去年年底才注册使用的。当时还花了99美元一步升级到顶级黑卡。然后这一年陆陆续续用了这卡,但用得不多,主要就用于支持一些VPS主机费还有CloudFlare,ChatGPT Pro等。 这个卡是美国地址,卡号有两个段,Visa 和 Mastercard,不过由于地址是美国的,刷卡可能会有问题。比如我ChatGPT Pro注册帐号是英国的,然后用这卡支付了几个月,突然有一天帐号就被封,被告知:您的付款记录很可疑。 印象中,用这虚拟货币Crypto Card美元出金卡有手续费,但是并没有啥Cash Back返现卡,如果是非美元购物则会有另一笔手续费,所以我很少用这卡出金变现。 前两个月,OneKey宣布关闭: 关于 OneKey Card 服务停用通知 尊敬的用户,为提高服务质量和优化产品供应,我们将按照以下时间表停用...
  6. 负电价活久见: 安装Octopus智能电表省电费甚至赚钱 前几周我的电气公司 Octopus 终于来装智能电表了(Smart Meter),虽然是免费安装的,但是排队排了有两三年了吧。因为之前一直写邮件催的时候就老是说 Not Ready。 收到邮件说可以安装智能电表我还是相当开心和期待的,因为已经听说这玩意好,但是还是得亲身体验一下。工程师来安装大概不到2小时,其中需要停电闸一会儿,重新接下线。装好后,给了个小册子,自动切换到了 Agile 的电价,也就是每半小时的电价都不一样,提前一天可以在手机App和网站上查得。 正好在原来的电价计费合同快要结束前2天换到了智能电表计价 Octopus Agile方式,但是系统还是扣了我75英镑 Exit Fee (提前合同结束得交违约费),不过我一个电话打过去,公司很爽快就给我退了。...
  7. 步步高多媒体学生电脑 汇编程序设计 – 1 英文同步 90年代后期步步高生产的软驱一号(又称步步高多媒体学生电脑)和98型学生电脑都带了软驱,一按电源件, 都从软盘启动(98型可以从内置的电子盘启动) 步步高提供了直接在学习机上写汇编开发的工具 BASM. BASM 可以用来写 6502 汇编,并可以编译成 CMD 小型可执行程序 不支持 EXC 程序. CMD...
  8. 力扣刷题获得一件衣服奖励(Leetcode DCC Winner) 我每天都在力扣上刷题。力扣有国服和美服,我两边都会打卡。每天打卡可以获得积分,而积分可以兑换各种礼物,比如T恤、卫衣、水壶,甚至可以用来抵扣一个月的会员费用。 我从2018年8月开始刷题找工作(当时去伦敦面试亚马逊),从那时起每年都会续费会员,费用是159美元,相当于每月13.25美元。我觉得这是对自己最值得的投资。买了力扣会员,就会有动力刷题、思考,通过不断练习让自己熟能生巧,保持一定的竞争力。 到目前为止,我已经用积分兑换了7-8件力扣的衣服,其中有2-3件是卫衣。国内的礼物我都寄到姐姐家。 前不久,我收到了力扣的邮件,说我获得了DCC奖励。我也不知道为什么会获得这个奖,随手回了邮件。没多久,就收到了一件新版的力扣衬衫。 英文:Leetcode DCC Winner T-shirt 本文一共 291 个汉字, 你数一下对不对. 力扣刷题获得一件衣服奖励(Leetcode DCC Winner)....

AE如何制作滚动数字,滚动文字风格动画教程

2024年12月18日 10:17
这篇文章介绍了如何在After Effects中制作滚动数字动画。首先,创建一个文字图层,并确保数字排列为垂直方向。如果遇到对齐问题,可以调整文字的对齐方式。接着,使用矩形工具绘制蒙版,并通过调整羽化效果让蒙版过渡更加柔和。最后,添加位置移动动画,通过调整动画范围实现数字的滚动效果。整个过程结合了文字设置、蒙版和动画,使滚动数字的制作变得简单且高效。

给Unity3D WebGL添加下载与上传

2024年12月17日 18:41

最近基于unity webgl 制作了一个绘图板,其中涉及到读写本地资源,并且处理完成数据后要完成下载操作。

其中既包含了上传,也包含下载。即使都是本地的文件操作,但由于浏览器的沙盒设计,我们并不能直接通过IO类进行文件操作,必须通过与js的通信,进行数据交换。

本篇将说明如何将两者数据进行交换,并提供相应的验证过的代码,你可以直接修改并使用下面代码。
理论上来说,这个代码是可以修改为下载其他任意文件的,比如下载贴图这里传的是内存指针,所以不限于下载图片。上传的代码也类似,给unity发送的是一个url,也是替换为任意类型都可以的。

有一点比较值得注意,在WebGL的开发过程中,每次重新部署后进入浏览器页面测试,都需要手动请清理缓存。
否则会出现部分文件被缓存,测试不正确情况。

文件下载

下面是个js封装库,并且实现了对图片文件的下载与上传。

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
mergeInto(LibraryManager.library, {
DownloadTexture: function (dataPtr, dataLength, fileName) {
var data = HEAPU8.subarray(dataPtr, dataPtr + dataLength);
var fileName = UTF8ToString(fileName);
var blob = new Blob([data], { type: 'image/png' });
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
},

LoadImageFile: function () {
var fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = ".jpg,.png,.tga"; // 限定文件类型
fileInput.style.position = 'fixed'; // 固定定位
fileInput.style.left = '-100vw'; // 定位到屏幕外
fileInput.onchange = function (e) {
var url = URL.createObjectURL(fileInput.files[0]);
window.unityInstance.Module.SendMessage('ImageLoader', 'OnImageLoaded', url);
};
document.body.appendChild(fileInput); // 添加到body,使其可以被点击
fileInput.click(); // 模拟点击
setTimeout(function() {
document.body.removeChild(fileInput); // 移除元素
}, 100); // 稍后移除,确保文件输入有足够的时间打开对话框
}
});

文件上传

当然这里也有一些值得注意的东西:

传入的参数有类型限制

string, a number 就这俩,之前我一度尝试使用byte[],或者从js发送内存指针都提示参数类型不正确。
下面是文档摘录。
Where objectName is the name of an object in your scene; methodName is the name of a method in the script, currently attached to that object; value can be a string, a number, or can be empty. For example:

在input很容易获取浏览器的缓存文件,通过URL.createObjectURL() 方法,创建一个表示参数中给定文件对象或 Blob 对象的 URL。这个方法返回的是一个 DOMString,它包含了一个唯一的 URL,这个 URL 指向由参数指定的文件对象或 Blob 对象,最后通过WebRequest加载这个URL就可以达到我们的目的。

这里使用了async语法,注意如果你改动这部分报错了,大概不会提示出来,会很难查bug哦。哈哈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public async void OnImageLoadedAsync(string url)
{
// 使用 UnityWebRequest 来下载图片数据
UnityWebRequest request = UnityWebRequest.Get(url);
DownloadHandlerTexture texDl = new DownloadHandlerTexture(true);
request.downloadHandler = texDl;

// 发送请求
await request.SendWebRequest();

if (request.result == UnityWebRequest.Result.Success)
{
var imageObject = GameObject.Find("ImageObject");
var sprite = Sprite.Create(texDl.texture, new Rect(0, 0, texDl.texture.width, texDl.texture.height), new Vector2(0.5f, 0.5f));
imageObject.GetComponent<UnityEngine.UI.Image>().sprite = sprite;
}
else
{
Debug.LogError("Error downloading image: " + request.error);
}

request.Dispose();
}

需要获取运行实例

下面摘录自官方文档,大致意思是js要调用unity的逻辑需要找到对应已创建的实例。

1
2
3
4
However, if you are planning to call the internal JavaScript functions from the global scope of the embedding page, you should always assume that there are multiple builds embedded on the page, so you should explicitly specify which build you are referencing to. For example, if your game has been instantiated as:
var gameInstance = UnityLoader.instantiate("gameContainer", "Build/build.json", {onProgress: UnityProgress});
Then you can send a message to the build using gameInstance.SendMessage(), or access the build Module object like this gameInstance.Module.

下面代码是生成后的index.html,我们直接将unity的实例保存到当前window中 window.unityInstance = unityInstance; 方便全局调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    var script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {
document.querySelector("#unity-progress-bar-full").style.width = 100 * progress + "%";
}).then((unityInstance) => {
window.unityInstance = unityInstance;
document.querySelector("#unity-loading-bar").style.display = "none";
document.querySelector("#unity-fullscreen-button").onclick = () => {
unityInstance.SetFullscreen(1);
};

}).catch((message) => {
alert(message);
});
};

document.body.appendChild(script);

参考官方文档 https://docs.unity3d.com/2017.3/Documentation/Manual/webgl-interactingwithbrowserscripting.html

Mac实现快捷键拖动窗口,cmd+ctrl可以让鼠标任意位置拖动窗口

2024年12月17日 18:02
这篇文章介绍了Mac上实现窗口任意位置拖动的教程。这一功能并非系统自带,可通过终端命令开启,开启后能摆脱局限于标题栏拖动的限制。输入命令后需重启电脑,然后利用“cmd+ctrl”组合键在窗口空白处拖动来确认功能生效,若不喜欢此功能,也可通过相应命令取消,恢复至默认状态。此外还介绍了该设置会全局生效及操作终端命令的注意事项,旨在帮助提升Mac使用体验。

如何几乎不损失视频画质而大幅度压缩视频?来试试VBR可变比特率吧!

2024年12月10日 17:09
这篇文章介绍了如何通过可变比特率(VBR)技术实现高效视频压缩,同时保持画质优良。VBR根据内容复杂度动态调整比特率,复杂场景用更多比特率,简单场景用更少,既提升质量又节省空间。文章推荐使用FFmpeg,详细说明了关键参数如恒定质量因子(CRF)和最大比特率的设置,并介绍两遍编码技术以精确控制文件大小。此外,还提到格式工厂作为无需代码操作的替代工具。总结来看,VBR结合FFmpeg既满足高画质需求,又兼顾存储效率,是处理视频的理想选择。

Mac上使用Drawthings的Flux模型进行扩图、补图

2024年12月4日 17:21
这篇文章介绍了在Mac上使用Drawthings应用和Flux模型进行AI扩图与补图的完整步骤。作者从下载应用和模型入手,推荐使用Flux Fill模型,并分享了内外补图的详细参数设置。通过拖入图片、调整大小、擦除不必要部分,并输入补充内容描述来生成修改后的图像,最后提供保存与分享的方法。文中还附有操作截图辅助说明。

Mac使用rsync实现本地文件夹同步到服务器,提交编译好的静态站点,增量提交网站

2024年12月4日 10:48
这篇文章介绍了如何在Mac上使用rsync工具将本地文件夹同步到服务器,实现网站项目的增量部署。作者详细讲解了安装rsync的方法、使用SSH密钥连接服务器以简化操作,以及通过命令完成单向同步的过程。该方法能避免重复文件上传,显著优化上传流程,提高效率,并支持其他备份场景。

Alist如何添加Ubuntu服务器的文件夹,给服务器添加上传SFTP的账号并授予访问权限

2024年12月3日 14:22
这篇文章介绍了如何在Ubuntu服务器上添加文件夹并为其创建专用的SFTP上传账户。首先,使用宝塔面板创建一个新账户,设置用户名和密码。然后,通过SSH为该账户生成密钥对,并保存私钥。接着,使用setfacl命令为指定文件夹(如/www/backup)授予该账户读取权限。最后,将服务器文件夹通过Alist接入,选择SFTP协议,填写服务器信息(IP地址、SSH端口、用户名、私钥等)。完成后,即可通过Alist方便地管理并备份服务器文件夹内容。

教娃编程之: ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型

2024年12月2日 04:20

视频:油管/Youtube | B站/小破站 | 微博视频 | 西瓜视频 | 微信视频号 | X/推特 | 小红书

马斯克的x.ai到年底有免费的25美元的credit可以使用Grok大语言模型

前不久(今年初),伊隆·马斯克/Elon Musk的X公司开源了Grok大语言模型,并且给免费提供了25美元的credit可以调用。可以在其官网x.ai注册一个帐号,申请API KEY即可,官网还贴心的的给出了调用的例子。

curl https://api.x.ai/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer xai-......" -d '{
  "messages": [
    {
      "role": "system",
      "content": "You are a test assistant."
    },
    {
      "role": "user",
      "content": "Testing. Just say hi and hello world and nothing else."
    }
  ],
  "model": "grok-beta",
  "stream": false,
  "temperature": 0
}'

孩子们由于未成年,所以无法申请ChatGPT、X AI等大语言模式的帐号,平时他们只能在免费的微软冰/BING搜索引擎上使用集成的免费Copilot。不过今天听弟弟说,ChatGPT现在已经不需要登陆就可以使用,不过他说这个版本有点受限制。

平均长度来算的话,一句话的Prompt大概是0.0012美元。当然越长的句子花费越贵,毕竟价格是按Token来算的。可以粗略的估计一个单词是一个Token。

x.ai-usage 教娃编程之: ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型 ChatGPT (OpenAI) Grok (X.AI) Python 人工智能 (AI) 折腾 教娃 教程 教育 程序员 程序设计

目测每条Prompt的费用是0.0012美元,25美元可以使用大概2万次

x.ai-free-25-credit 教娃编程之: ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型 ChatGPT (OpenAI) Grok (X.AI) Python 人工智能 (AI) 折腾 教娃 教程 教育 程序员 程序设计

每个帐号有免费的25美元API费用

x.ai-dashboard 教娃编程之: ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型 ChatGPT (OpenAI) Grok (X.AI) Python 人工智能 (AI) 折腾 教娃 教程 教育 程序员 程序设计

X.AI 的API网站界面

x.ai-api-models 教娃编程之: ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型 ChatGPT (OpenAI) Grok (X.AI) Python 人工智能 (AI) 折腾 教娃 教程 教育 程序员 程序设计

API 的 X AI 模型:grok-beta 和 grok-vision-beta

grok-x-ai-api-keys 教娃编程之: ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型 ChatGPT (OpenAI) Grok (X.AI) Python 人工智能 (AI) 折腾 教娃 教程 教育 程序员 程序设计

由 X AI 为 Grok LLM 创建 API 密钥。 Create API Keys for Grok LLM by X AI.

ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型

反正是免费的25美元,于是想着给娃做一个简单的PYTHON程序,然后人机交互,每次调用x.ai的Grok大语言模式,也正好让娃学一学实际的编程应用。于是让ChatGPT写了个程序,这种简单的程序ChatGPT基本上是Bug Free,生成的代码拿来就能用。

import requests
import json

api_key = "x_ai ..."

# Define the API endpoint and headers
url = "https://api.x.ai/v1/chat/completions"
headers = {
    "Content-Type": "application/json",
    f"Authorization": "Bearer {api_key}",
}

# Define a system message for context
system_message = {"role": "system", "content": "You are a test assistant."}

print("Welcome to the Grok, an AI chatbot. Type 'bye' to exit.\n")

while True:
    # Prompt the user for input
    user_input = input("You: ").strip()

    # Check if the user wants to exit
    if user_input.lower() == "bye":
        print("Goodbye!")
        break

    if user_input == "":
        continue

    # Define the payload
    payload = {
        "messages": [
            system_message,
            {"role": "user", "content": user_input}
        ],
        "model": "grok-beta",
        "stream": False,
        "temperature": 0
    }

    try:
        # Make the request
        response = requests.post(url, headers=headers, json=payload)

        # Check the response status
        if response.status_code == 200:
            data = response.json()
            assistant_response = data["choices"][0]["message"]["content"]
            print(f"Grok: {assistant_response}\n")
        else:
            print(f"Error: {response.status_code} - {response.text}")
    except Exception as e:
        print(f"An error occurred: {e}")

之后 简单做了些修改,比如避免空的Prompt,并且用strip函数去除句首和句尾的空格。娃使用的是Mac苹果电脑,还得在Terminal装个Homebrew,然后安装Python,并且用 pip3 install requests 安装上请求包,就可以使用了。

x-ai-prompt-python-2024-12-01-12.53.31-scaled 教娃编程之: ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型 ChatGPT (OpenAI) Grok (X.AI) Python 人工智能 (AI) 折腾 教娃 教程 教育 程序员 程序设计

虽然界面有点素,也就是个简单的终端,但是对于孩子来说已经是个很强大的软件了。

kid-plays-x-ai-grok-llm-2024-12-01-12.53.26-scaled 教娃编程之: ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型 ChatGPT (OpenAI) Grok (X.AI) Python 人工智能 (AI) 折腾 教娃 教程 教育 程序员 程序设计

弟弟在苹果电脑上成功跑起了x.ai的大语言模式 Grok

ChatGPT 可以拿来做什么?

ChatGPT 通用人工智能

英文:ChatGPT writes a Python Script to Interact with Grok LLM from x.ai (Free $25 Credit)

本文一共 743 个汉字, 你数一下对不对.
教娃编程之: ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型. (AMP 移动加速版本)

扫描二维码,分享本文到微信朋友圈
75a5a60b9cac61e5c8c71a96e17f2d9c 教娃编程之: ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型 ChatGPT (OpenAI) Grok (X.AI) Python 人工智能 (AI) 折腾 教娃 教程 教育 程序员 程序设计
The post 教娃编程之: ChatGPT写了一个Python交互程序调用x.ai的Grok大语言模型 first appeared on 小赖子的英国生活和资讯.

相关文章:

  1. HPZ800服务器主板太老不支持超过2TB的大硬盘 我家里一直用的是HPZ800服务器, 很吵, 很老, 虽然这台服务器已经有十年之久(我在EBAY上买来用了五年多了), 但是即使放到今天, 这服务器速度依旧很快, 很稳定. 由于服务器用的是ECC较验内存, 所以基本上不重启关机. HPZ800主机有两个硬核CPU – 因特志强 X5650 – 每个CPU是12核....
  2. 给孩子零花钱培养孩子正确的金钱观价值观 两个娃已经不知不觉7岁8岁了. 媳妇和我商量一下决定给孩子每人每周5英镑的零花钱(Pocket Money). 这样他们慢慢的就有自己的小积蓄备将来不时之需: 比如朋友聚会生日啥的需要准备礼物. 同时, 我们决定不再给孩子买零食(薯片啥的). 孩子一天好几餐, 晚上睡觉前还得吃零食, 我们就多买了很多水果面包, 健康的食物多吃一些总不是啥坏事. 孩子可以用这些零钱买自己想要的东西, 我们也不再过问. 孩子有自己的决定权. 第一周的时候,...
  3. 测测你的幸运 – Linux Fortune-Teller LINUX 下有很好很好玩的命令,之前已经介绍过: figlet, rig, curl. 现在推荐另一个 命令 fortune 是用来随机显示一段(句)话的.fortune 在英文里就是幸运的意思. 这个命令可以不需要 参数 如果没有 可以通过 apt-get...
  4. 负电价活久见: 安装Octopus智能电表省电费甚至赚钱 前几周我的电气公司 Octopus 终于来装智能电表了(Smart Meter),虽然是免费安装的,但是排队排了有两三年了吧。因为之前一直写邮件催的时候就老是说 Not Ready。 收到邮件说可以安装智能电表我还是相当开心和期待的,因为已经听说这玩意好,但是还是得亲身体验一下。工程师来安装大概不到2小时,其中需要停电闸一会儿,重新接下线。装好后,给了个小册子,自动切换到了 Agile 的电价,也就是每半小时的电价都不一样,提前一天可以在手机App和网站上查得。 正好在原来的电价计费合同快要结束前2天换到了智能电表计价 Octopus Agile方式,但是系统还是扣了我75英镑 Exit Fee (提前合同结束得交违约费),不过我一个电话打过去,公司很爽快就给我退了。...
  5. 按揭贷款(房贷,车贷) 每月还贷计算器 去年给银行借了17万英镑 买了20万7500英镑的房子, 25年还清. 前2年是定率 Fix Rate 的合同 (年利率2.49%). 每个月大概是还 700多英镑. 有很多种还贷的计算方式, 定率/每月固定 是比较常用的. 简单来说就是 每个月交的钱是...
  6. 你要找什么样的老婆? 找媳妇的标准 昨天和网友在剑桥面基, 网友奔现, 他从爱尔兰过来, 小我12岁, 就聊到了找对象的标准. TLDR; 找老婆不要(只)看颜值, 而要注重性格, 为人处事和顾家等更重要的品质, 当然性和谐也很重要. 在当今社会, 人们对于找伴侣的标准有所不同. 有些人认为颜值是最重要的, 因为外貌吸引力可以让人在日常生活中感到愉悦, 这是人的本性,...
  7. 智能手机 HTC One M9 使用测评 虽然我对手机要求不高, 远远没有像追求VPS服务器一样, 但是怎么算来两年内换了四个手机, 先是三星 S4 用了一年多, 然后 Nokia Lumia 635 Windows Phone, 后来又是 BLU, 半年多前换了...
  8. 给STEEM中文微信群加了个机器人 之前说到我的公众号 justyyuk 可以查询几种虚拟货币的实时价钱, 但是有点不方便, 因为很多朋友在群里聊天得切换到公众号, 这下好了, 今天往STEEM中文微信群(还有编程群)加了个机器人, 在聊天的时候想了解价钱就直接输入货币代号即可, 如: 既方便自己, 又能方便别人(省事, 价格信息会同时显示给其它成员). 注: 这机器人不是我做的, 只是我拉进来的,...

网站速度很慢?使用 WordPress 短时缓存(Transients)来优化数据库查询和 HTTP 响应!

2024年11月18日 22:40

每个人都想要一个速度很快的网站,网站速度越快,用户停留和点击页面或购买产品的时间就越长,加快网站速度的方法之一是开启缓存,而缓存背后的逻辑就是存储信息,更具体一点说,就是找到一个比连接数据库更快的存储信息的地方。

在 WordPress 中,如果一些复杂的 SQL 查询或者耗时的 HTTP 请求,其实它们的结果在一定时间内是不变的,那么为了网站速度,如果把这些操作的结果缓存起来,这样下次进行同样的 SQL 查询和 HTTP 请求的时候,就可以直接从缓存中获取数据,从而可以显著加快网站的速度,当然一些复杂计算的结果也可以通过该方法进行缓存。

 WordPress Transients

那么在 WordPress 中如何快速缓存 SQL 查询和 HTTP 响应呢?这个时候就要用到 WordPress 的短时缓存(Transients)功能。

什么是短时缓存(Transients)

我们知道 WordPress 缓存有多种类型,比如对象缓存、浏览器缓存、页面缓存甚至数据库缓存,每种类型都有其用途和设置步骤,比如需要安装插件和更改服务器配置以启用对象缓存等。

那么今天介绍的 Transients API,是 WordPress 用于在页面加载期间临时存储 WordPress 中的信息,Transients 本身是“短暂的”或“临时的”意思,那么 Transients API 可以理解为临时缓存或者短暂缓存的意思,我这里将它翻译成短时缓存,它是 WordPress 用来缓存一些复杂的 SQL 查询和运算结果的最简单的方法。

它给这些需要缓存的数据一个过期时间,并且时间一到就会自动删除,所以在制作 WordPress 插件的时候,需要存储一些有一定生命周期的数据的时候,Transients API 就是最好的选择。

简单说,Transients 是一种非常强大的工具,它不仅可以用来避免对页面内容进行不必要的数据库请求,还可以加快生成复杂标记的速度并加快耗时的第三方 API 请求。 

Transients 相关函数

首先说下,Transients 的存储,如果服务器开启了 #Memcached#,那么缓存的数据就会存在 Memcached 的内存中,如果没有开启的话,则存储到 WordPress 数据库的 Options 表中

所以它接口函数和 WordPress 的 Option API get_option, add_option, update_option, delete_option))基本一样,唯一区别就是 Transients API 有一个过期时间,并且它没有 add 方法,统一合并成 set 了,所以 WordPress Transients API 有以下三个函数:

// 保存一个数据到短时缓存中
set_transient( string $transient, mixed $value, int $expiration )

// 从短时缓存中获取一个数据
get_transient( string $transient )

// 从短时缓存中删除一个数据
delete_transient( string $transient )

函数的使用过非常简单,这里不做详细解释,简单注意下两点:

  1. 如果使用获取短时缓存函数 get_transient 去获取数据,已经过期或者不存在的情况下是返回 false 的。
  2. 完全不用担心 Transients API 会将数据库的 Options 表塞满数据,因为临时变量一旦过期,下次获取的时候就会自动被删除,并且上面也说了如果服务器开启了 #Memcached#,那么缓存的数据就会存在 Memcached 的内存中。

一个应用 Transients 的例子

🙋‍♀️🌰 假设你要获取博客的浏览最高的 10 篇文章,文章的浏览数据一般是存在 PostMeta 表中,所以这样的数据库查询会用到 Posts 表和 PostMeta 表进行联表查询,如果文章数量比较多的情况下,这样的查询一般是比较慢的。

而事情的另一面,博客浏览最高的 10 篇文章一般来说在一段时间(比如:12小时)之内很可能是不变的,所以这个功能最适合使用 Transients API 进行缓存了:

$top_10_posts = get_transient('top_10_posts');

if(false === $top_10_posts){ // 临时变量过期了或者根本就没有创建

	// 通过 SQL 查询获取流量最高的 10 篇文章,
	$top_10_posts = wpjam_get_top_viewd_posts(10);

	// 把临时变量存到数据库中,时间为 12 个小时
	set_transient('top_10_posts', $top_10_posts, HOUR_IN_SECONDS*12);
}

我们首先使用 get_transient('top_10_posts') 函数从缓存中看看有没有缓存,如果没有,该函数是返回 false 的。

程序获取缓存结果为 false 的时候,就通过 wpjam_get_top_viewd_posts 这个带有复杂 SQL 的函数获取文章,然后通过函数 set_transient('top_10_posts', $top_10_posts, HOUR_IN_SECONDS*12) 存到缓存中,并且过期时间设置为 12 小时。

这样下次再去获取浏览最高的文章,直接从缓存中返回了,就不用担心不用担心数据库查询过慢的问题了。

使用 Hook 删除短时缓存

如果由于某种原因某篇流行文章删除,这个时候可能流量最高的文章都可能发生变化,我们就可以使用 delete_transient 函数把这个临时变量删除了,这样我们可以使用 WordPress 的删除文章的 Hook delete_post 进行操作:

add_action('delete_post', fn() => delete_transient('top_10_posts'));

如果你想有新文章发布了,虽然这时候一般不会影响浏览最高的文章列表,但是如果想,也可以把缓存清理了,这时候用到是 publish_post Hook:

add_action('publish_post', fn() => delete_transient('top_10_posts'));

WPJAM 终极方法

虽然 Transients API 的使用非常简单,它主要逻辑就是首先使用 get_transient() 函数获取缓存,=如果没有,再通过函数 set_transient() 将数据存到缓存中。

但是这里都有要写个判断,并且缓存的名称也要重复写两次,对于我这么懒的程序是不可能接受的,另外它的逻辑感觉上在破坏了程序的主逻辑,所以我在 #WPJAM Basic# 中集成了 wpjam_transient 函数,它通过回调的方式,让只需一步就实现 WordPress 短时缓存:

首先我们实现看看我的 wpjam_transient 函数的实现:

function wpjam_transient($name, $callback, $expire=86400){
	$data	= get_transient($name);

	if($data === false){
		$data	= $callback();

		if(!is_wp_error($data)){
			set_transient($name, $data, $expire);
		} 
	}

	return $data;
}

可以看到 wpjam_transient 函数把获取和设置短时缓存的函数都内置到了函数中,你只需要关注你程序的主逻辑,所以上面的缓存的浏览最高的 10 篇文章的代码可以简化为 1 行代码:

wpjam_transient('top_10_posts', fn()=> wpjam_get_top_viewd_posts(10), HOUR_IN_SECONDS*12);

是不是非常简洁。🤭

总结

WordPress 短时缓存(Transients API)是 WordPress 用于在页面加载期间临时存储 WordPress 中的信息,该功能用的好,特别是用于缓存复杂的 SQL 查询,耗时 HTTP 请求,以及复杂计算的结果等,对于站点有明显的提高,#WPJAM Basic# 集成的 wpjam_transient 函数进一步提高使用效率,只需一步就实现 WordPress 短时缓存。

WordPress 中如何设置全局选项?一文详解 WordPress 的 Option 功能!

2024年10月24日 22:36

对于进行 WordPress 开发来说,肯定会了解到的一个开发功能就是 WordPress 设置选项的创建,访问,修改和删除,比如主题和插件的设置选项处理,那么 WordPress 具体是怎么管理全局选项的呢?

WordPress 全局选项管理的接口叫做 Option API,它是一种简单且标准化的在数据库中存储数据的方法,它使用给定的自定义名称将数据存储到 wp_options 表中。

WordPress 提供了 Option 的增删查改四个操作的函数,如果你安装的 WordPress 是多站点版本,那么还有对应的 _site_ 函数应用全网选项的函数,同样使用给定的自定义名称将数据存储到 wp_sitemeta 表中。

但是多站点的选项设置用到场景比较少,所以今天我们还是详细介绍一下 Option 的增删查改四个操作的函数:

增加选项|add_option

add_option( string $option, mixed $value = '', string $deprecated = '', string|bool $autoload = null ): bool

add_option 函数实现给 WordPress 增加一个选项,选项的名称通过参数 $option 指定,选项的值 $value 支持标量和非标量,如果非标量的话,则该值可以被序列化,但是无需手动对值进行序列化,该函数会在将值插入数据库之前会进行序列化操作,所以简单说,就是把各种类型值 $value 无需做任何处理,以 $option 作为名称添加到选项中。

另外第三个参数是被放弃的,不用管,如果要用到第四个参数 $autoload 的时候,三个参数的位置直接输入空字符串即可,这里简单说下一下第四个参数 $autoload,用于定义在 WordPress 启动的时候是否自动加载该选项到内存中,该参数默认值为 null,意思是它会自动根据 $value 大小来决定是否自动加载,小于 150000 字节则会自动加载,如果不管大小都要求自动加载,则可以将其设置 'on',无需自动加载,则需要将其设置为 'off'

最后如果该选项如果被成功添加,则返回 true,否则 false,额外说一下如果该选项数据库已有,则无法添加成功,如果你是想如已存在则修改,则建议用到后面介绍 update_option 函数。

add_option( 'my_option', 'my_value' );

比如上面代码就添加一个名称为 'my_option' 选项,它的值为:'my_value'

删除选项|delete_option

delete_option( string $option ): bool

delete_option 函数删除名称为 $option 的选项,删除选项函数比较简单,比如下面的代码就是删除名称为 'my_option' 选项。

delete_option( 'my_option' );

查询选项|get_option

get_option( string $option, mixed $default_value = false ): mixed

get_option 函数用于获取名称为 $option 的选项的值,除该参数之外,它还有第二个参数 $default_value,该参数默认值为 false,如果选项不存在,则返回该值。

get_option 函数返回值的类型可能会因与保存或更新选项时传递的类型不同而不同,如果选项值被序列化了,那么在返回时它将被反序列化,在这种情况下,返回的类型将会相同,比如存储一个如数组这样的非标量值,将返回相同的数组。

在大多数情况下,非字符串的标量和 null 值存储被转换并返回为字符串等效值。比如通过 add_option( 'my_option', $value ) 添加选项,然后通过 get_option( 'my_option' ) 获取选项值将会:

  • false 返回 string(0) ""
  • true 返回 string(1) "1"
  • 0 返回 string(1) "0"
  • 1 返回 string(1) "1"
  • '0' 返回 string(1) "0"
  • '1' 返回 string(1) "1"
  • null 返回 string(0) ""

如果添加是非标量的值,比如 add_option( 'my_array', array( false, 'str', null ) ), 返回的值将与原始值完全相同,因为它在保存到数据库之前已经被序列化了:

array(3) {
    [0] => bool(false)
    [1] => string(3) "str"
    [2] => NULL
}

更新选项|update_option

update_option( string $option, mixed $value, string|bool $autoload = null ): bool

update_option 函数的参数和 add_option 函数参数除了没有放弃的参数,基本都是一致的,用法也是一样的,这里就不重复了。

那么 update_option 函数和 add_option 函数的区别主要是:add_option 函数只会添加,如果已经存在,则不会覆盖,而 update_option 函数则会修改现有的选项,如果不存在,它则会调用 add_option 函数增加。

update_option( 'my_option', 'my_value' );

比如上面代码就修改名称为 'my_option' 选项的值为 'my_value',如果不存在则增加该选项,值也是为 'my_value'。

总结

关于 WordPress 全局选项,或者说站点选项的开发接口介绍,最核心的部分就是这四个函数,只要认真阅读这篇文章,那么进行开发的时候基本不会有太大的问题。

零基础 WordPress 网站建设全攻略:域名注册、环境搭建及内容创作(2024.11)

2024年11月19日 19:55

本零基础 WordPress 网站建设教程涉及内容非常广泛,将从一个小白的视角(老鸟&大神请点右上角)浅显地介绍有关建设网站的方方面面,包括但不限于:域名注册、服务器搭建、WP 建站、内容创作、网络营销等,总归一句话:WordPress 网站建设看完这篇就够了。

就像你一样,博主曾经也是一个对网站建设一无所知的小白,也是经过了无数的挫折和错误才积累了一些经验和见解。这篇文章的目的就是为了帮助你少走弯路,相对简单、直接而全面地学习如何建设一个 WordPress 网站。考虑到你可能是从零开始,文章里所使用的技术和语言尽可能地通俗易懂,倘若你对以下内容有任何疑问也欢迎在评论区留言,Kevin 将会第一时间为你解答。那么,让我们开始吧!

0. 为什么要建设网站?该如何开始

你为什么要建设一个网站呢?请认真思考这个问题,是为了向大家推广你的产品?是对外发布和展示信息?是想建设一个漂亮的页面展示作品?还是说见了别人有属于自己的网站,觉得很酷,想自己也想搞一个…这个问题你必须要明确。

笔者第一次做网站是在十一年前,那会儿我临近大学毕业,可能是看了某个帖子突然就发现做网站似乎也不那么难,于是对此一窍不通的我开始从零开始学习做网站了。得亏我那会儿年轻学习能力强,能熬夜,所以即便走了不少弯路,最终也还是能把小站做得像模像样,当时好像有人愿意出一点钱买那个小破站…???

..... [ 阅读全文 ]

原文链接: https://www.shephe.com/tutorial/wordpress-website-building/
版权声明: Kevin's Space 版权所有,转载请用明链标明本文地址
本站相关: 随机文章 | 站长微博 | 关于本站 | 联系站长 | 捐助作者

宝塔如何开启HTTP3,启用HTTP3使用QUIC进行高性能传输

2024年11月28日 15:29
这篇文章介绍了HTTP/3的优势和通过宝塔面板启用HTTP/3的具体方法。HTTP/3基于QUIC协议,具备连接更快、延迟低、不怕掉包、更安全等优点,适用于移动网络且能降低服务器压力。文章详细阐述了HTTP/3的技术背景,并提供了在宝塔面板中配置Nginx启用HTTP/3的步骤,包括升级Nginx版本、修改配置文件、设置SSL、开放443端口及云服务商的端口配置,最后通过检测工具确认配置结果。

Windows10出现大容量存储设备禁用情况

2024年11月28日 18:29

如果你的电脑出现类似情况,可以参考本篇解决,注意是 “你的电脑” 。

Win + R 在运行中输入 regedit.exe 打开注册表编辑界面。

计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR

可能出现如下权限不足

在编辑,权限一栏中,给User用户组赋予 “完全控制” 权限即可。

给主页添加一个轮播memos动态

2024年11月25日 19:12

常来我博客逛的朋友们应该都注意过,我的右上角有个寄语。如下图:

我在想有没有一种可能直接拉取Memos的数据,从而动态去取呢。
反正是用js的写起来,测起来都很方便。
随后花了半小时,写了个脚本,看起来它运作的不错。
顺便让豆包给了段样式,做了淡入淡出。
有需要的朋友可以自取,注意下版本号,由于是js拉取的,所以你在本地建一个html也可以进行测试。

以下Memos的API版本为:Version: v0.22.4

网页部分

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<script src="./a.js"></script>

<body>
<div id="description">
<a>最近在搜寻有趣博客中...</a>
</div>
</body>

</html>

js脚本

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
String.format = function () {
if (arguments.length == 0)
return null;
var str = arguments[0];
for (var i = 1; i < arguments.length; i++) {
var re = new RegExp('\\{' + (i - 1) + '\\}', 'gm');
str = str.replace(re, arguments[i]);
}
return str;
}


let data = {}
let index = 0

function refreshContentInterval() {
if (index >= 4) index = 0;
index++;
var firstData = data[index]
var result = firstData.snippet;
if (result.length > 30) {
result = result.slice(0, 30) + "...";
}
let post_index = "改成转跳的页面";
const descriptionDiv = document.getElementById('description');
descriptionDiv.innerHTML = '';
const aTag = document.createElement('a');

aTag.textContent = result;
aTag.href = post_index;
aTag.id = "fading-a"
descriptionDiv.appendChild(aTag);
}

function showFirstContent() {
var bbUrl = "https://你的memos域名/api/v1/memos?filter=creator=='users/1'&&visibilities=='PUBLIC'&&pageSize=5";
fetch(bbUrl).then(res => res.json()).then(resdata => {
data = resdata.memos;

refreshContentInterval();
setInterval(refreshContentInterval, 3000);
});
}


// 当页面加载完成后执行的函数
window.onload = function () {
showFirstContent();
}

css样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* 定义要添加淡入淡出效果的a标签样式 */
a#fading-a {
opacity: 0; /* 初始设置为完全透明 */
animation: fadeInOut 3s ease-in-out infinite; /* 应用淡入淡出动画,持续时间3s,缓动效果为ease-in-out,无限循环 */
}

/* 定义淡入淡出动画关键帧 */
@keyframes fadeInOut {
0% {
opacity: 0; /* 开始时完全透明 */
}

30% {
opacity: 1; /* 中间达到完全不透明 */
}

80% {
opacity: 1; /* 中间达到完全不透明 */
}

100% {
opacity: 0; /* 结束时又回到完全透明 */
}
}

以上,晚饭后半小时的摸鱼杰作。

开启 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 命令:

Mac中磁盘没有被推出,因为一个或多个程序可能正在使用它解决方法

2024年11月25日 10:54
这篇文章介绍了在Mac中遇到磁盘无法弹出的情况,通过终端查看和结束占用磁盘的程序以解决问题。具体步骤包括使用lsof | grep /Volumes/磁盘名称命令查看占用磁盘的进程,找到进程PID后使用kill -9 PID命令关闭占用程序,最后再尝试弹出磁盘。

背包大乱斗与俄罗斯方块(代码篇)

2024年11月21日 16:31

前一段时间写了一篇 背包大乱斗与俄罗斯方块(设计篇) ,具体的实现思路在这一文中已经讲清楚了,后来我抽空去实现了一版。目前看效果还不错。

已经实现,形状的变换,定位,移动,消除,障碍判定等。
本篇稍微讲一下具体的实现过程,以及如何去优化这个算法。

基于池去实现节点的创建与回收

一开始就基于这个池模板去管理所有数量上较多的对象,后期优化的压力会小一些。

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
public interface IReset
{
void Reset();
}

public interface IPool<T> where T : IReset
{
Stack<T> nodesPool { get; }

T CreateOne<W>() where W : T, new();
void ReturnOne(T item);
}


public class BasePool<T> : IPool<T> where T : IReset
{
Stack<T> _nodesPool = new Stack<T>();
public Stack<T> nodesPool { get { return _nodesPool; } }

public virtual T CreateOne<W>() where W : T, new()
{
if (nodesPool.Count > 0)
{
return nodesPool.Pop();
}
return new W();
}

public virtual void ReturnOne(T node)
{
node.Reset();
nodesPool.Push(node);
}
}

分离算法与表现

我们的算法是需要适应不同的场景的,如果基于一套UI或者3D/2D渲染,混写代码,就会导致这个代码复用性低,迁移起来费时费力。

TileInfo.cs 作为管理单个形状( 物品) 渲染信息的最小单位。我们并不需要在这里书写任何如何去渲染的逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class TileInfo :  IReset
{
public List<GameObject> Cubes = new List<GameObject>();
public GameObject Tile;
public Color BaseColor;

public void Reset()
{
BaseColor = Color.white;

if (Cubes.Count > 0)
{
for (int i = 0; i < Cubes.Count; i++)
PrefabPoolManager.GetInstance().PushGameObjectByType(PrefabPoolManager.PrefabType.Cube, Cubes[i]);
Cubes.Clear();
}
PrefabPoolManager.GetInstance().PushGameObjectByType(PrefabPoolManager.PrefabType.Tile, Tile);
Tile = null;
}
}

将这个逻辑放到一个单独的Render脚本中,这样处理现在我们已经将渲染画面的功能完全隔离到了 BlockRender。
如果我们有3D的画面,就可以写一个3DBlockRender 或者是 UIBlockRender ,只需要抽象出接口做新的实现即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class BlockRender 
{
public TileInfo UpdatePreSelectNode(PreSelect node, LogicMap map)
{
return UpdateTile(node, node.Shape, node.x, node.y, map);
}

public TileInfo UpdatePreSelectNode(PreSelect node, IShape shap, LogicMap map)
{
return UpdateTile(node, shap, node.x,node.y,map);
}

...

至此我们已经完成了基础逻辑,他包含一个通用的池实现,与一个通用的渲染层。

核心算法

一般来说游戏的业务逻辑复杂度都不高,真要说复杂的,那肯定是渲染逻辑。
这段放置图形的代码,就是背包大乱斗最复杂的业务逻辑了。

通过当前节点的相对点加图形的数据结构中存储的x与y值,就可以推算出逻辑节点的坐标。
注意这边的逻辑节点,需要配置map的信息,比如map的位置信息与缩放进行一个定位,才能换算出真实坐标。

当然下面的代码并没有添加,是否这个位置有阻挡或者已经被占用的判定,由于我们的玩法尚未定型,则将这个判定放到了渲染层,在最后的演示中,你可以看到如果两个图形有重叠部分,重叠部分的区域会变成红色。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public INode PlaceShape(INode node,IShape shape) 
{
node.Shape = shape;

//解析data
var data = shape.Data;
var rows = data.GetLength(1);
var columns = data.GetLength(0);

for (int y = 0; y < rows; y++)
{
for (int x = 0; x < columns; x++)
{
if (data[x, y] == 0)
continue;

INode usedNode = GetNodeWithXY(node.x + x, node.y + y);
usedNode.State = NodeState.CUBE;
}
}

return node;
}

演示

通过空格键可以在左下角创建出方块,wasd去移动,qe可以转换方向,再次空格键可以放下方块。

页面有9M大小,加载较慢。演示地址 : 点我转跳

我尝试在下方加载了一个 iframe ,如果能正常显示的话就不用再转跳到上面的链接了。-

现在上面的演示地址失效,我用来放置游戏demo,当然这个demo也是用如上算法,欢迎参考,关注。

背包大乱斗与俄罗斯方块(设计篇)

2024年11月19日 13:53

前段时间背包大乱斗身边的同事玩的还挺多的,刚好这几天有空去研究研究,我还专门去看了背包大乱斗的攻略。发现,“啊,这不是俄罗斯方块吗 ?” 又一番研究之后确实,背包大乱斗和俄罗斯方块有诸多相似之处。

玩法分析

在空间规划与摆放方式上,俄罗斯方块是要将各种形状方块合理放置在游戏区域,通过移动和旋转来填满行以得分,背包大乱斗则要在有限背包格子内合理放置装备等物品,考虑其形状、属性和搭配来最大化利用空间;

在决策过程中,俄罗斯方块玩家要在方块下落时快速决策其旋转、移动和放置时机,考虑方块间关系和后续空间预留,背包大乱斗玩家要依据职业、已有物品和游戏局势做出购买、合成等决策,两者都要综合考虑多种因素;

从形状与组合多样性来看,俄罗斯方块有七种四格方块,通过旋转和移动创造多样组合,背包大乱斗有多种装备等,通过合成、镶嵌等形成不同搭配;

游戏的动态变化性上,俄罗斯方块随着方块下落和消除游戏区域不断变化,玩家要随之调整策略,背包大乱斗在游戏中因新物品获取、对手情况变化而使局势改变,玩家也需要及时调整背包布局和策略。

游戏是继承与发展的。背包大乱斗本质上是俄罗斯方块机制的延展,从后者的空间利用、策略决策、形状组合和动态变化中获取灵感,深化空间放置与规划理念,发展出更复杂多样的内容,如物品属性和合成搭配,其动态变化也更具挑战性,给玩家全新体验。

背包大乱斗

代码设计

透过现象看本质,背包大乱斗的核心玩法,其实与俄罗斯方块是一致的,在这个基础之上包装了一个RPG。
当然你要说这个游戏,有着更加丰富的玩法,固然如此。但这些玩法最终都要依赖这个核心的玩法。

说了那么多,想必大家心里都有了不同的实现方案。那么现在我们动手去实现一下这个玩法的核心算法。

从一个二维数组开始

在所有的一切开始之前,要定义一个基础 Map ,我们所有的坐标定位都要基于这个二维网格。
顺便,我们将基础坐标系定在第一象限,方便我们定位与计算。

对应的数据可以表示成这样 (10X10) 空白格用0来表示:

1
2
3
4
5
6
7
8
9
10
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000

创建基础单位

一个基础单位,有上下左右,共四种朝向,当然这个基础单位可以任意的长短,这是灵活的,可配置的。

我们用虚线格填充这个基础单位,则有了下图,这样的好处是方便通过数据去描述这个单位长什么样子。

虚线格子用0表示,实线格子用1表示, 结合前面我们提到的,将这个坐标系放在第一象限,并且从下往上,从左至右自增。对于单个方块,我们可以用如下的数据结构去描述,它的不同形态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

010
111


01
11
01


111
010


10
11
10

设计一个运行框架

根据上面的思路我们可以这样去设计程序:

  • 我们的主体就是一张图,其中有N个节点。这个节点有个状态字段,如果不能放置或者被占用则标注之。
  • xy就是节点的坐标,因为我们的节点最终是要存储到一个list内的。
  • ShapeTemplate就是设计的重点,一个图形模板,通常一个图形模板对应多个分形(可以变换的状态)。

实际一个图形,在图中所占用的确切坐标,仅是一个node,根据这个节点定位结合图形的形状,可以轻松的定位到其他几个被影响到的点位。

以上背包大乱斗与俄罗斯方块的玩法分析与代码设计。

开机黑屏时间长,进系统显示器才亮?DP线开机黑屏进不去bios解决方法

2024年11月18日 11:20
这篇文章介绍了由于使用DP线导致开机黑屏和无法进入BIOS的原因及解决方法。作者分享了DP线在10XX及更早显卡上可能需要固件补丁的问题,提供了NVIDIA的固件更新工具下载链接,并列举了可能的解决方案,如使用HDMI启动、切换引导模式等。还提到支持更新的显卡型号包括TITAN、GeForce 10/900/700系列以及部分Quadro产品。

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:

Amazon CloudFront 免费 CDN 配置教程

2024年11月10日 19:40

三十海河 留言文能不能出个教程,下午看了下正好之前给宝子做的博客挂掉了。正好迁移过来,不过不得不说,这个体验的确比较奇怪,cname解析,有的域名能加,有的不能加,这就很离谱。

视频分两段录的,主要是第一段失败了,但是实在不想重新录了。直接看这两段吧。第一段有些问题,第二段也提到了。

整体用起来的感觉就是,很多翻译有些奇怪,包括文档看的也莫名其妙,这个就很蛋疼。

不过好在最后还是成功了,折腾半天,哼唧唧

通过智能插座在HomeAssistant中实现电脑开关机控制,无需米家开机卡

2024年11月11日 14:59
这篇文章介绍了通过智能插座结合HomeAssistant实现电脑远程开关机的方法,无需使用米家开机卡,从而避免持续耗电的问题。作者首先启用主板来电自动开机功能,然后通过安装和配置Airytec Switch Off软件实现远程关机,设置语言、启动项及固定IP地址。同时,通过局域网端口设置和防火墙配置确保远程访问的稳定性。最后,通过HomeAssistant创建模板开关,用HTTP请求实现远程关机,达成电脑远程电源控制的目标。

在中国大陆如何使用 AirPods Pro 2 检测听力,使用听力检测教程

2024年11月6日 16:10
这篇文章介绍了如何在中国大陆使用AirPods Pro 2进行听力检测。用户需要通过Safari打开特定链接进入听力检测,确保在安静环境下佩戴耳机并调整贴合度,以获取准确结果。在测试期间,耳机会播放不同频率和音量的声音,用户需在听到声音时轻点屏幕以完成检测。文章还分享了作者的测试结果,显示左耳和右耳均为10 dBHL或更低的细微损伤或无损伤状态。

Word如何手动制作目录,手动生成自定义目录

2024年11月2日 17:02
这篇文章介绍了如何在Word中手动制作自定义目录的方法,适用于未使用层级样式的拼接文档。步骤包括:先手动编写“标题+页码”目录,接着选中目录段落并右键选择“段落”设置制表位,根据标尺设置位置,确保目录布局整齐。在标题和页码间按下Tab键,以生成指定样式的分隔符,完成目录的排版。

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

截图

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

iStoreOS 路由系统介绍与安装

2024年5月24日 00:00

最近托管在群晖的 GitLab 非常不稳定,想必是群晖的性能不够用了。想着软路由的性能有很多的冗余,就想移植到软路由。结果运行的爱快怎么都不成,看到前段时间宋童靴的推荐,决定更换到 iStoreOS!

系统介绍

iStoreOS 源于 OpenWRT,重点是做了很多很多的交互简化。iStoreOS 入门极客版本 UI 是默认 UI,目标是提供给懂点技术的入门极客爱好者,或者偷懒极客老手,核心特性:

  1. 首页提供网络向导、磁盘向导、Docker 向导等众多向导,不管新手还是老手,都能快速配置自己想要东西;
  2. 修复众多 OpenWRT 不人性的小问题,如 Samba 设置独立用户名密码很麻烦、磁盘挂载;
  3. 更多首页工具帮手,比如在线升级、各种错误检测、网口图形化配置等;
  4. 其它很多常用功能,如 DDNS 配置、Docker 配置等。

iStoreOS 还提供软件中心,尽可能解决插件之间的依赖关系,可让大家自由自在安装插件。手动安装离线包也是支持的。除此之外,为了方便大家折腾不出问题,避免掉坑,还做了很多防坑操作如:

  1. 救援模式,即是固件完全刷坏,也可以进入救援模式救回来;
  2. 沙箱模式,通过 U 盘进入沙箱模式,后续软件安装更新都在沙箱进行。不管如何安装插件搞坏系统,拔掉 U 盘就会回到上个状态。沙箱模式本身也是系统扩容最简单的方法。

系统截图

iStoreOS 的首页截图:

iStoreOS 的软件中心截图:

准备安装

  1. 一个 U 盘;

  2. 一个可连接软路由的显示器;

  3. 一个键盘;

  4. 一台 Windows 系统的电脑。

系统安装

从官网中下载对应版本固件。请注意看中间日期,如 xxx20221123xx-xxx.img.gz,建议下载最新版本。下载完成之后不要解压。电脑上用 Rufus 做 USB 启动盘。电脑插入 U 盘,选择下载好的固件,把固件写入到 U 盘:

选从 U 盘启动,一般按 F11,选择接入 U 盘,就可以启动了。如找不到 U 盘,那么可能是 U 盘不兼容,需换一个 U 盘。登录 U 盘系统,登录成功之后,输入:

1
quickstart

选择 Install X86 一直按确定:

用 Show Interfaces 查看网线插入到了哪个网口,以及查看当前 LAN 口的 IP。系统写入完成,拔掉外接设备,通电启动。使用如下信息进入后台管理:

1
2
3
4
5
6
# 默认地址
http://192.168.100.1
# 默认用户
root
# 默认密码
password

基于 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 压缩模块。

VoceChat 的简介

2023年3月18日 00:00

杜老师又来水文了。使用群晖的小伙伴都因为大陆无法使用 Chat 套件而掉头发,杜老师也一直在寻找解决的办法,机缘巧合遇到了 Vocechat,希望能帮到需要的小伙伴们!

简介

Vocechat 是一个在线语音聊天平台,它为用户提供一个轻松、便捷、安全交流环境。

在 Vocechat,用户可以与世界各地的人们进行语音聊天、语音讨论、语音会议,而且不受时空限制。

Vocechat 主要特点是其高质量的语音聊天体验。与其它的聊天应用不同,Vocechat 提供了高品质的语音通话,无论身处何处,都可以享受到清晰、稳定语音通话体验。

此外,Vocechat 还支持多人语音聊天,这意味着可以与多个人同时进行语音交流。

Vocechat 还具有很高的安全性。用户可创建私人聊天室,只有邀请的人才能加入。

此外,Vocechat 还提供了端到端加密功能,确保用户通话内容不会被第三方窃取。

最后,Vocechat 还提供了一些有趣的功能,如语音的翻译和识别等。这些功能使得用户可以更方便与世界各地的人进行交流。

总之,Vocechat 是一个非常实用聊天工具,为用户提供了高品质的语音聊天体验和安全的交流环境。如果正在寻找一个可以随时随地与他人进行语音交流的工具,那么 Vocechat 就是最好的选择。

截图

Web 端截图:

Android 端截图:

使用 Memos 搭建时光机教程

2023年3月3日 00:00

首先感谢下林木木童鞋,参考他的代码才有此篇教程。时光机的效果可以参考本博说说广场,不过时光机只会展示个人的说说,如需 Memos 的搭建教程,或是广场搭建教程,可以静等之后教程!

写在前面

此篇教程兼容各类博客框架,不管用的是 Hexo/Hugo/Typecho/WordPress 都可直接使用。

若无服务器可以不用搭建 Memos,借助现有平台「如杜老师的 https://s.dusays.com」注册账户即可。

条数统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="container">
<p>共发表了 <span id="memosCount">0</span> 条 Memos 说说!</p>
</div>
<script>
function getTotal() {
var totalUrl = "https://s.dusays.com/api/v1/memo/stats?creatorId=1";
fetch(totalUrl).then(res => res.json()).then(resdata => {
if (resdata) {
var memosCount = document.getElementById('total');
memosCount.innerHTML = resdata.length;
}
}).catch(err => {
});
};
window.onload = getTotal();
</script>

注意:上面代码的 https://s.dusays.com/api/v1/memo/stats?creatorId=1 一句,s.dusays.com 替换成自己 Memos 的域名,结尾的 1 改为用户的 ID。

前端展示

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="bber"></div>
<script>
var bbMemos = {
memos : 'https://s.dusays.com/',
limit : '10',
creatorId:'1' ,
domId: '#bber',
}
</script>
<script src="https://npm.onmicrosoft.cn/penndu@4.0.9/memos.js"></script>
<script src="https://npm.onmicrosoft.cn/marked/marked.min.js"></script>
<script src="https://jsd.onmicrosoft.cn/gh/Tokinx/ViewImage/view-image.min.js"></script>
<script src="https://jsd.onmicrosoft.cn/gh/Tokinx/Lately/lately.min.js"></script>

注意:上面代码的 bber 可自定义,不要与整站 div 重名;s.dusays.com 替换成自己 Memos 的域名;limit 为展示数量限制,creatorId 对应用户 ID,domId 需与 div id 相同。

补充说明

如果不知道自己的 ID 是多少,可以直接留言问杜老师。或者发表一条说说,然后点击 这里,点击您的用户名称,所进入页面的网址末尾处的数字,就是 ID 了:

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 解析信息,可以提交工单询问客服,然后添加即可:

NAT 的级别是指什么

2022年10月28日 00:00

前段时间写了篇关于内网穿透的文章,突然想到还有个关于 NAT 的知识点,特写此文与大家伙分享。水文一篇,如有错误,欢迎评论!

什么是 NAT

NAT 是英文 Network Address Translation 的简写,中文意为网络地址转换。当在专用网内部的一些主机本来已经分配到了本地 IP 地址即仅在本专用网内使用的专用地址,但又想和因特网上的主机通信并不需要加密时,可使用 NAT 方法。

这种方法需要在专用网私网 IP 连接到因特网公网 IP 的路由器上安装 NAT 软件。装有 NAT 软件的路由叫做 NAT 路由器,它至少有一个有效外部全球 IP 地址公网 IP 地址。这样,所有使用本地地址私网 IP 地址的主机和外界通信时,都要在 NAT 路由器上将其本地地址转换成全球 IP 地址,才能和因特网连接。

另外,这种通过使用少量的全球 IP 地址公网 IP 地址代表较多的私有 IP 地址的方式,将有助于减缓可用的 IP 地址空间枯竭。在 RFC 2663 中有对 NAT 说明。

之前写过一篇《思科网络地址转换》感兴趣的可以看看。

NAT 的级别

A 级:部分宽带服务商会为用户提供公网 IP,将光猫设置为桥接模式,再通过路由器拨号上网,并将指定设备设置为 DMZ 映射。或者使用光猫拨号上网,并将指定设备设置为 DMZ 映射「路由需为桥接模式」此时该设备处于 NAT A 等级;

B 级:部分宽带服务商会为用户提供公网 IP,将光猫设置为拨号上网,并将路由器设置 DMZ 映射,且在路由指定设备为 DMZ 映射,此时该设备处于 NAT B 等级;

C 级:部分宽带服务商为用户提供城域网 IP,将光猫设置为桥接模式,再通过路由器拨号上网,并将指定设备设置为 DMZ 映射。或者使用光猫拨号上网,并将指定设备设置为 DMZ 映射「路由需为桥接模式」此时该设备处于 NAT C 等级;

D 级:部分宽带服务商为用户提供城域网 IP,将光猫设置为拨号上网,并将路由器设置 DMZ 映射,且在路由指定设备为 DMZ 映射,此时该设备处于 NAT D 等级。

补充内容

有小伙伴说看不懂,简单的解释呢,就是数据从公网到设备,经过了几个路由器。

上面的级别说明中,光猫和路由都是路由器,但开启桥接模式后,则相当于变成交换设备,故 A 级为一个路由,B 级两个路由,以此类推。

NAT 有很多转换形式,家用路由常用端口转换,即内网设备 IP 转为外网随机端口,此种转换形式需要内网设备产生数据才可生成转换列表,故效率低且外网不可直接访问到内网。所以有了 DMZ 这类的转换模式。这种模式直接将公网地址转换为内网地址,公网地址所收到的请求,都会转至指定内网设备处理,这样内外网可相互通信。

城域网相当于一个大局域网,城域网与广域网的通信节点,相当于一个路由器,所以城域网的用户默认 NAT 等级比较低。

写在最后

虽然 IPv6 已推出很长时间,但 IPv4 仍是主流。随着 IPv4 的资源耗尽,联网设备越来越多,部分地区的宽带运营商已经不再提供公网地址,改为城域网 IP。

虽说此种变更不会影响我们上网速率,但对于一些较特殊需求场景,例如:网络监控、异地组网、云盘存储,城域网 IP 都会影响使用体验。

好在宽带运营商处都会有 IP 存货,通过客服沟通,可申请到公网地址。部分宽带运营商如移动,也可付费获取公网地址。

再有不懂的可在评论区留言,杜老师磨碎了讲给你听!

杜老师说的内网穿透思路与实践

2022年10月16日 00:00

应 MrZeFr 小朋友的需求,更新一篇关于杜老师如何实现家用服务器实现内网穿透教程,其中包含思路与实践的方法,希望可以对有需求的小伙伴提供借鉴参考。

写在前面

杜老师说之前部署在凉心云 Webify 上,前段时间因为受到攻击,导致账户直接欠费 1200 多「账户余额 0.23 元」

杜老师选择弃号改为本地服务器部署。因本地家用网络限制,不开放 80 端口,所以需要通过内网穿透、端口映射等技术手段实现网站的呈现。

网络拓扑

下面简单看下网络拓扑:

穿透思路

  1. 用户访问杜老师说;

  2. 通过网络将请求转发给前端的 CDN;

  3. CDN 通过 DDNS 指定端口回源;

  4. DDNS 解析的公网地址经由光猫处理转发路由;

  5. 路由器查询端口映射表,将请求数据转发服务器;

  6. 服务器将处理好的数据发给路由;

  7. 路由器将数据交给光猫发出;

  8. CDN 获得回源数据在本地保留缓存;

  9. 并同时将数据经由网络发给用户;

  10. 用户收到数据在本地浏览器呈现网站内容。

穿透实践

首先查询当前宽带所在的服务商,比如杜老师是联通。

然后查询外网 IP 的种类,如果是城域网,则需要致电客服询问如何获取公网 IP「联通、电信一般说明按照监控,或是搭建本地存储即可;移动好像需要付费才行」

接下来是路由,为了有更好的映射效果,墙裂建议将光猫调整为桥接模式,使用路由拨号上网,然后通过路由中 DMZ 映射后端服务设备。

因为每次拨号都会分配不同地址,还需在服务端或路由器上开启 DDNS,这样 IP 发生变动时,可以自动调整域名解析。

知识拓展

上诉方法确切来说属于端口映射,将服务器端口映射到路由器,然后通过公网 IP 来调用;

如果是纯内网穿透「具体概念,可以参考《何为内网穿透》一文」需搭建外网映射服务器。

这里推荐下 NATAPP,使用优惠码 2DE16A7D 可九折购买相关的服务。

另外可以参考教程《natapp 树莓派开机启动脚本》一文,进行本地配置。

写在最后

  1. 因宽带商限制 80 端口的访问,如果搭建网站,还是需要 CDN 回源或内网穿透,不然只能手动指定非 80 端口「好像 443 也不行」

  2. DMZ 的端口映射模式,是将路由所有端口与服务器一一对应,这样会降低安全性,建议只做所需要的端口映射。

去不图床网站架构分享

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 的扩展性和可调配置略差。

❌
❌