Rclone 是一款支持在不同对象存储、网盘间同步、上传、下载数据的命令行工具。
我有一个在欧洲的存储型 VPS,硬盘空间很大,但是网络传输速度不足,想要用日本的一台 VPS 加速一下在 Plex 中播放的速度,就想在日本的 VPS 上挂载这一台存储型 VPS,然后在日本的 VPS 上开启 Plex,加速一下网络使用效率,毕竟服务器和服务器之间的网络要更稳定一些。
支持如下主流的对象存储:
官方提供了一键安装脚本。
Linux/macOS
curl https://rclone.org/install.sh | sudo bash
Beta 版本:
curl https://rclone.org/install.sh | sudo bash -s beta
如果在使用的过程中遇到如下的错误,可以尝试安装 fuse
Fatal error: failed to mount FUSE fs: fusermount: exec: “fusermount”: executable file not found in $PATH
在 Debian/Ubuntu 下安装:
sudo apt install fuse
安装完成之后可以通过 rclone 提供的交互式配置选项添加配置,直接运行 rclone config
,根据提示添加远程访问的配置,比如通过 SFTP 添加远程大存储 VPS,或者添加 OneDrive 或 Google Drive 这样的云端存储。
交互式的配置添加方法非常直观,这里就略过。
当完成远程配置的添加之后就可以使用 mount
命令来在本地挂载远程主机的内容。比如在 rclone 的配置中已经添加了一个 remote_name
的配置,如果要挂载到本地 local_path
,就可以通过如下的命令。
rclone mount remote_name:/path/to/remote ~/local_path --read-only --transfers 4 --buffer-size 1024M --low-level-retries 200 --dir-cache-time 12h --vfs-read-chunk-size 128M --vfs-read-chunk-size-limit 1G
在最初挂载的时候可能会遇到这种问题,这个时候可以在命令行中加入 -vv
来输出 DEBUG 日志。
执行 mount
命令之后终端会处于等待中,这是正常的。如果在执行中使用了 Ctrl+C 中断了命令,那么本地不再能访问挂载的内容,但是挂载状态并没有结束,需要执行:
sudo umount ~/local_path
# 或者
fusermount -qzu ~/local_path
rclone 命令有非常多的参数可以调整,更多的使用细节需要插件其官方文档
在 /etc/init.d/rcloned
创建如下文件,记住修改其中的 NAME
, REMOTE
, LOCAL
这三个内容。
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
NAME_BIN="rclone"
### BEGIN INIT INFO
# Provides: rclone
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start rclone at boot time
# Description: Enable rclone by daemon.
### END INIT INFO
NAME="remote_name" #Rclone配置时填写的name
REMOTE='/path/to/remote' #远程文件夹,网盘里的挂载的一个文件夹,留空为整个网盘
LOCAL='/local_path' #挂载地址,VPS本地挂载目录
LOG="/$HOME/.rclone/rcloned.log"
Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m"
Info="${Green_font_prefix}[信息]${Font_color_suffix}"
Error="${Red_font_prefix}[错误]${Font_color_suffix}"
RETVAL=0
check_running(){
PID="$(ps -C $NAME_BIN -o pid= |head -n1 |grep -o '[0-9]\{1,\}')"
if [[ ! -z ${PID} ]]; then
return 0
else
return 1
fi
}
do_start(){
check_running
if [[ $? -eq 0 ]]; then
echo -e "${Info} $NAME_BIN (PID ${PID}) 正在运行..." && exit 0
else
fusermount -zuq $LOCAL >/dev/null 2>&1
mkdir -p $LOCAL
mkdir -p ${LOG%/*}
sudo /usr/bin/rclone mount -vv $NAME:$REMOTE $LOCAL --copy-links --allow-other --allow-non-empty --umask 000 > "${LOG}" 2>&1 &
sleep 2s
check_running
if [[ $? -eq 0 ]]; then
echo -e "${Info} $NAME_BIN 启动成功 !"
else
echo -e "${Error} $NAME_BIN 启动失败 !"
fi
fi
}
do_stop(){
check_running
if [[ $? -eq 0 ]]; then
kill -9 ${PID}
RETVAL=$?
if [[ $RETVAL -eq 0 ]]; then
echo -e "${Info} $NAME_BIN 停止成功 !"
else
echo -e "${Error} $NAME_BIN 停止失败 !"
fi
else
echo -e "${Info} $NAME_BIN 未运行"
RETVAL=1
fi
fusermount -zuq $LOCAL >/dev/null 2>&1
}
do_status(){
check_running
if [[ $? -eq 0 ]]; then
echo -e "${Info} $NAME_BIN (PID $(echo ${PID})) 正在运行..."
else
echo -e "${Info} $NAME_BIN 未运行 !"
RETVAL=1
fi
}
do_restart(){
do_stop
sleep 2s
do_start
}
case "$1" in
start|stop|restart|status)
do_$1
;;
*)
echo "使用方法: $0 { start | stop | restart | status }"
RETVAL=1
;;
esac
exit $RETVAL
授予执行权限,并添加启动:
chmod +x /etc/init.d/rcloned
update-rc.d -f rcloned defaults
开始挂载
/etc/init.d/rcloned start
停止挂载
/etc/init.d/rcloned stop
重新挂载
/etc/init.d/rcloned restart
查看日志
tail -f /$HOME/.rclone/rcloned.log
卸载服务:
/etc/init.d/rcloned stop
update-rc.d -f rcloned remove
PocketBase 是一个 Go 编写的开源后端 [[BaaS]] Backend-as-a-Service,只用了一个二进制文件就可以实现:
所以基本上用户可以通过 PocketBase 来作为应用的后台,比如说要用[[Nuxt.js]] 写一个网站,可以不用写后端服务器代码,而直接使用 PocketBase。
PocketBase 的 SQLite 可以搭配 [[Litestream]] 一起使用。
Litestream 是一个使用 Go 编写的,用于 SQLite 数据库流式复制的工具。它作为一个单独的后台进程运行,并不断地从磁盘上复制写前日志页到一个或多个副本。 这种异步复制提供了类似于 Postgres 或 MySQL 等数据库服务器的灾难恢复。 SQLite 有一个名为”WAL”(预写日志)的日志模式。
PocketBase 和 Litestream 都只需要非常少的资源,完全可以在 512 MB 内存的 VPS 上运行。
zsh 的环境变量配置文件有:
.zprofile
.zlogin
.zshrc
.zshenv
.zlogout
对我而言最熟悉的就是 .zshrc
,大部分的命令行或者折腾 zsh 的时候总是要很多配置需要放在 .zshrc
。所以因此也可以看到 .zshrc
就是用来对 Shell 整体做个性化配置的。
.zprofile
和 .zlogin
差不多是一样的,他们都会被 login shells 设置环境变量,只是加载时间可能有一些差别。.zprofile
是基于 Bash 的 .bash_profile
,而 .zlogin
则是仿照 CSH 的 .login
遗留下来的名字.zshrc
会设置 interactive shells 的环境变量。它会在 .zprofile
之后加载。通常可以设置 $PATH
, $PROMPT
, aliases
, functions
等等。.zshenv
总是会被读取,所以也可以在这里设置环境变量,$PATH
或 $EDITOR
等,但一般不怎么使用zlogout
是在一个会话登出的时候被加载,非常适合用来清理临时的配置,比如重置终端窗口的标题zsh 会在用户登录时(login shell)加载 ~/.zprofile
zsh 会在开启新的终端会话时加载 ~/.zshrc
需要注意的是首先会加载 /etc/zshenv
下的内容, 然后再加载 HOME 目录下的配置文件:
.zshenv → [.zprofile if login] → [.zshrc if interactive] → [.zlogin if login] → [.zlogout].
之前的一篇文章介绍过 HestiaCP 的简单使用,在 HestiaCP 中是通过模板配置文件来配置网站。修改网站的模板可能会造成服务器错误,修改之前请小心。
HestiaCP 的模板文件存放在 /data/templates/
目录中,对于 Web 服务器,包括了一个初始化脚本 .sh
文件,一个默认的模板 .tpl
和一个 ssl 模板 .stpl
。
模板的位置:
Service | Location |
---|---|
Nginx(Proxy) | /usr/local/hestia/data/templates/web/nginx/ |
Nginx - PHP FPM | /usr/local/hestia/data/templates/web/nginx/php-fpm/ |
Apache2 (Legacy / mod-php ) | /usr/local/hestia/data/templates/web/apache2/ |
Apache2 - PHP FPM | /usr/local/hestia/data/templates/web/apache2/php-fpm/ |
PHP-FPM | /usr/local/hestia/data/templates/web/php-fpm/ |
创建新模板的方法最好是从原来的模板中复制。
cp original.tpl new.tpl
cp original.stpl new.stpl
cp original.sh new.sh
当完成模板编辑之后,需要在界面中启用。
在修改现成的模板之后,需要重新构建用户配置,可以通过 v-rebuild-user
命令或者在网页管理端操作。
Name | Example | Description |
---|---|---|
%ip% | 123.123.123.123 | IP Address of Server |
%proxy_port% | 80 | Port of Proxy |
%proxy_port_ssl% | 443 | Port of Proxy (SSL) |
%web_port% | 80 or 8080 | Port of Webserver |
%web_ssl_port% | 443 or 8443 | Port of Webserver (SSL) |
%domain% | domain.tld | Domain |
%domain_idn% | domain.tld | Domain (Internationalised) |
%alias_idn% | alias.domain.tld | Alias Domain (Internationalised) |
%docroot% | /home/username/web/public_html/ | Document root of domain |
%sdocroot% | /home/username/web/public_shtml/ | Private root of domain |
%ssl_pem% | /usr/local/hestia/data/user/username/ssl | Location of SSL Certificate |
%ssl_key% | /usr/local/hestia/data/user/username/ssl | Location of SSL Key |
%web_system% | Nginx / Apache | Software used as Webserver |
%home% | /home | Default home directory |
%user% | username | Username of user |
%backend_lsnr% | proxy:fcgi://127.0.0.1:9000 | Your default FPM Server |
%proxy_extentions% | List of extensions | Extensions that should be handled by the proxy server |
虽然很早就已经知道阿加莎·克里斯蒂,也曾经看过一些她的作品,比如《无人生还》、《尼罗河上的惨案》这类非常脍炙人口的作品,但是对其人一直不是非常了解,直到去年偶然间在路上听了一期关于阿加莎·克里斯蒂的播客,直到讲到她的生平,经历两次世界大战,有传奇的婚姻,才逐渐对她产生了兴趣。她是有怎么样的人生经历才能够塑造出如此精彩的虚构人物?她又是有怎么样的新奇的遭遇才能构造出如此出人意料的作案手法?
阿加莎出生于 1890 年的伦敦德文郡托基,是英国著名的侦探小说家,剧作家。她在第一次世界大战期间志愿成为了一名护工,战争结束之后创作了第一步侦探小说《斯泰尔斯庄园奇案》,几经周折之后在 1920 年出版,从此开启了克里斯蒂传奇而辉煌的创作生涯。阿加莎克里斯蒂创作生涯持续五十余年,一共创作了八十部小说,作品畅销全世界,被称为继柯南·道尔之后最伟大的侦探小说家。
全书一共分成了十一个章节,涵盖了阿加莎从小成长,到青年,成熟直至垂暮的所有人生故事。阿加莎在写自传时已经有 60 岁的高龄,写了 15 年才最终定稿。这和她自己在写作侦探小说时文思泉涌,连续写作几天成一本书的写作方式完全不同。但也正是因为如此耗时的写作才使得这部自传内容翔实。
关于第一次世界大战、第二次世界大战,我更多的是在影视作品中通过视觉化的方式看到,很少有机会通过一手的文字信息去了解那些年真正在发生的事情。就像大部分人看到的战争一样,突然之间就爆发了,而这也影响到了青年时期的阿加莎克里斯蒂。
阿加莎的一生中经历了两次婚姻,在 1926 年母亲去世的那一年,第一段婚姻因为丈夫的婚外情而结束,这也使得阿加莎曾经一度离家出走失踪。但也正是因为命运的多舛,才让阿加莎独自一人向东旅行,在途中遇到了第二任丈夫。
过去很长一段时间我都不喜欢读名人的自传,有意地避开了很多,但是最近几年却越来越喜欢读一些自传,读过富兰克林的自传,读过微软 CEO 萨提亚 纳德拉,读过 Linus Torvalds 的自传《Just for Fun》,也读了巴菲特的自传,过去我常常想去读自传,不如去读这些人物的其他专题性作品,但读过之后才渐渐地意识到这些名人的成就也好,思想也好,都脱离不开那个时代,那个环境,他们在生活中的遭遇,以及他们人生的转折都只能在自传中窥见。而这些名人的形象,也只有我读完全书之后才能在我的脑海中变得立体,而平时他们只能是维基百科上的一副二维照片,而通常也只是某个年龄拍下的,而我读完这些自传记住的是十几岁离家出走到处漂泊的富兰克林,记住的是因为自己的兴趣而发布在 FTP 上 Linux 内核的青年时期的 Linux,记住的是那个从印度移民美国拥抱文化开放、照顾患病孩子父亲形象的纳德拉。而在这一部阿加莎的自传中,我能看到那个幽默、命运坎坷的阿加莎,她人生的每一次转折都在塑造她对世界的认识,也正是她见到的每个人,遭遇的每一个时代变化,才让她能在战争期间学到药剂知识,才能让她在离婚之后去周游世界,才能让她为了生计几十年写作。
对阿加莎·克里斯蒂的作品感兴趣的人
DevToysMac 是一款 macOS 上的开发者常用工具集合,在 Windows 上有一款使用 C# 实现的开发者工具合集工具叫做 DevToys,但是在 macOS 上使用不了,于是 ObuchiYuki 就使用 Swift 编写了一个 macOS 上原生的应用。
使用 Homebrew :
brew install --cask devtoys
DevToysMac 提供的一些功能:
编解码:
格式化:
生成器:
文本相关:
图像相关:
媒体相关:
REST-assured 是 Java 实现的一套 REST API 测试框架。在 Java 中测试和验证 REST 接口的难度要大于动态语言比如 Ruby 或 Groovy,而 REST Assured 将测试接口的能力大大简化了。
Maven:
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
导入静态类:
import static io.restassured.RestAssured.*;
使用:
given().
XXXX
when().
XXXX
then().
XXXX
行为驱动开发中定义的结构,Given-When-Then。
测试 GET 请求:
given().
queryParam("mobilephone","13323234545").
queryParam("password","123456").
when().
get("http://httpbin.org/get").
then().
log().body();
测试 POST 请求:
表单:
given().
formParam("mobilephone","13323234545").
formParam("password","123456").
when().
post("http://httpbin.org/post").
then().
log().body();
JSON 参数:
String jsonData = "{\"mobilephone\":\"18023234545\",\"password\":\"23456456\"}";
given().
body(jsonData).contentType(ContentType.JSON).
when().
post("http://httpbin.org/post").
then().
log().body();
上传文件:
given().
multiPart(new File("D:\\file.png")).
when().
post("http://httpbin.org/post").
then().
log().body();
本文总结一下注册 ChatGPT 的方法。
打开虚拟号码接收验证码平台 sms-activate.org (带邀请 AFF),注册一个账号
注册完成之后,需要充值使用,接码平台使用的货币是卢布。
接收一次 OpenAI 的电话验证大约需要 11 卢布,换算成人民币大概是 1 块钱,平台充值的时候接收美元,可以先充值 1 美元。
打开浏览器的隐身模式,然后访问 ChatGPT(OpenAI) 的账户注册页面 。直接使用谷歌邮箱登录注册的成功率比较高,推荐直接通过 Google 登录注册。如果不想关联 Google,也可以直接使用邮箱注册。
使用邮箱注册后会收到一个验证邮件,再接受的邮件中点击验证链接,正式进入注册。如果遇到提示说不能在当前国家服务,那么就需要切换代理了。
另外需要注意的是,如果出现了当前国家不提供服务的错误,最好是清空 Cookie 之后再试。如果是在隐身模式下,那就关闭隐身模式,重新登录。
通过了地区校验之后可以填写手机号,这里需要回到 sms-activate 接码平台上,在左侧边栏搜索 OpenAI,然后选择一个国家,可以选择一个手机号接码最便宜的国家,比如印度尼西亚,肯尼亚等
然后点击购物车,复制这个号码到 ChatGPT(OpenAI) 的注册页面,然后点击发送验证码,在接码网站会收到验证码。
最后就是完成 OpenAI 的注册。
然后就能访问 ChatGPT 了。新注册的 OpenAI 账号官方会赠送 5 美元的 API 调用额度。可以利用这个 API Key 做一些想做的事情。
如果不想自己注册,也可以到小店 里面购买共享的账号。
把自己之前用 J3455-itx 主板组的 NAS 搬回了,但突然无法启动,这里就记录一下排错的过程。
最早启动的时候,无法进入系统,启动日志里面报错:
ata 7: COMRESET failed (errno=16)
开始怀疑是搬家的时候硬盘坏了。所以拆开主机,把其中的第四块硬盘 SATA 线拔掉了。重新启动主机,发现竟然能进入系统了。并且用 fdisk 查看,所有的其他硬盘都没有问题。
这个时候我仔细的检查了一下 SATA 的连线,J3455-itx 这块主板只有 4 个 SATA 口,但是我使用 PCIe 扩展了 2 个 SATA 口,一共接了 5 块硬盘,1 块 SSD 安装了系统,4 块 HDD 机械硬盘。
为了腾位置给 SSD,所以我将一块 HDD 的 SATA 线连接到了扩展卡的 SATA 接口,就是将这个接口拔掉,才能够进入系统。这个时候我开始怀疑是不是扩展卡在搬运的过程中损坏了。于是加紧在京东又下单了一个全新的 PCIe 转 SATA 扩展卡。
今天终于把全新的扩展卡安装上来,但是发现这一块机械硬盘还是无法读取。一度又让我怀疑真的是磁盘坏了,为了排除这个嫌疑,我拿出了之前买过的 SATA 转 USB 的设备,拿了 Linux Mint 发现能正常读取这一块硬盘,因为四块机械硬盘是通过 [[MergerFS]] 合并成一块逻辑硬盘使用的,所以这一块硬盘上也能读取到部分的数据,证明机械硬盘是没有问题的。
这个时候我已经排除了机械硬盘的问题,扩展卡的问题,我又在怀疑难道是 PCIe 接口坏了。这个时候我就把 SSD 拆了下来,然后把四块机械硬盘连接到了主板上的四个 SATA 接口,通过 USB 来启动 SSD,过程中我发现系统完全启动正常,并且能够在 [[Proxmox VE]] 下安装的 [[OpenMediaVault]] 下正常挂载 4 块硬盘,读写也完全没有问题。
启动系统的过程中还遇到了 soft lockup 问题,这个时候还以为是磁盘的 IO 造成的。但后来仔细想想应该是通过 USB 启动的系统在读写上存在瓶颈导致的。
那剩下的问题就肯定出在 PCIe 这个接口上。我又换回了之前的扩展卡,然后重新在 BIOS 中查看,调整配置。当我将 SSD 连接到扩展卡,并启动的时候 J3455-itx 主板无法找到可启动的设备,直接进入了 BIOS。
这个时候我突然想起来用 J3455 和扩展卡在 Google 搜索了一下。于是就看到了 这个帖子 其中的一句话惊醒了我。
主板 BOIS 里打开 CSM 试试
我在 BIOS 里面找到 CSM 设置,启用,然后重启系统,竟然能够从 SSD 启动了,扩展卡没有坏,硬盘没有坏,只是 BIOS 里面的一行配置变了!
CSM 全称是 Compatibility Support Module,是 BIOS 用来启动旧版操作系统和其他旧软件的一种特性。可以让 UEFI BIOS 兼容 Legacy+MBR 启动模式。
我已经忘记了之前安装 Proxmox VE 的时候用的什么引导了,但启用了 CSM 的时候就能够找到磁盘上的引导程序,并成功启动系统了。
至此整个 Debug 的过程才算结束。没想到的是新年假期竟然花了半天时间 Debug 硬件,o<(=╯□╰=)>o
前两年对哲学,期权,投资等等分类下的书籍比较多,但是 2022 年看得书就比较杂,有一些是在书单中放了很久的书,正好有契机拿出来看看。
之前历年的记录: