风起 发布的文章

[记录]IDEA或者GoLand调试Go提示Delve is too old的解决方案

完整的报错信息大概是这样WARNING: undefined behavior - version of Delve is too old for Go version 1.21.9 (maximum supported version 1.18)

报错的原因是因为delve版本低,不支持调试高版本的Go,也可以按照下面的方法来解决这个问题。

1. 确定dlv.exe路径

可以使用Everthing类的工具,但通常的路径是这样的,你可以尝试直接定位:

C:\Users\fengqi\AppData\Roaming\JetBrains\IntelliJIdea2021.3\plugins\go\lib\dlv\windows\

如果是MacOS,通常的路径是这样的:

/Users/fengqi/Library/Application Support/JetBrains/IntelliJIdea2021.3/plugins/go/lib/dlv

2. 安装最新版本的dlv.exe

可以参考文档 https://github.com/go-delve/delve/tree/master/Documentation/installation,或者直接下载源码编译,如果你和我一样使用go install安装的,那么路径大概是在 C:\Users\fengqi\go\bin\dlv.exe

3. 备份并替换Jetbrains的dlv.exe

亲测可行。

Linux下开启CPU睿频,降低功耗

Linux下默认CPU会使用高性能模式,AMD不清楚,但是Intel默认会启用固定频率也就是最高频率,对于家用NAS或者ALL-IN-BOOM来说其实有点浪费电,因为大多数情况下CPU并不是满载的,开启睿频可以省电。

1. 验证当前模式

cat /sys/devices/system/cpu/intel_pstate/no_turbo
1
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
performance
performance
performance
performance

这里看到是关闭了睿频,且启用高性能模式。

2. 关闭定频固定频率

grub添加intel_pstate=disable参数

vi /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="splash intel_pstate=disable intel_iommu=on iommu=pt"
update-grub
reboot

- 阅读剩余部分 -

[记录] macOS下 VirtualBox-7.0 无界面模式(Headless)Dock有图标的解决办法

升级了macOS Ventura 13.4以后,VirtuaoBox 6.1就不能使用了,必须升级7.0才可以。

升级后碰到的最大的问题就是无界面模式(Headless)启动后,Dock(程序坞)上会出现一个VirtualBox的图标,然后一直弹跳,各种乱点后来变成普通不弹跳的图标,但是忘记操作过程。

此时关闭VirtualBox界面后,Dock上会残留一个图标,不像之前那样完全后台运行,经过长达几分钟的摸索发现,只要在虚拟机设置-显示-屏幕-扩展特性取消勾选启用3D加速就可以了,具体原因未知,也不打算深究了。

nginx自动屏蔽不友好的ip

查看nginx日志的时候发现大量的404302尝试访问不存在的资源,大概率是使用工具扫描。

{"connection": "2572288","pid": "176228","request_id": "7d5dcaac3e4be47a536a4a0d1b5c7abb","request_length": "157","remote_addr": "52.170.115.255","time_local": "08/Apr/2022:17:44:50 +0800","status":"302","host":"fengqi.me","uri":"/Panels.txt","server":"fengqi.me","port":"443","protocol":"HTTP/1.1","request_uri":"/Panels.txt","args": "","scheme": "https","request_time": "0.000","request_method":"GET","http_referrer":"","body_bytes_sent":"138","http_x_forwarded_for":"","http_user_agent":"python-requests/2.27.1","upstream_response_time":""}
{"connection": "2572337","pid": "176261","request_id": "cf56fa6708c4b68d1b8e3b4d7871103c","request_length": "150","remote_addr": "52.170.115.255","time_local": "08/Apr/2022:17:45:09 +0800","status":"302","host":"fengqi.me","uri":"/Panels.txt","server":"fengqi.me","port":"443","protocol":"HTTP/1.1","request_uri":"/Panels.txt","args": "","scheme": "https","request_time": "0.000","request_method":"GET","http_referrer":"","body_bytes_sent":"146","http_x_forwarded_for":"","http_user_agent":"python-requests/2.27.1","upstream_response_time":""}
{"connection": "2186500","pid": "164519","request_id": "aa21defaa0a590422420732b52c58f83","request_length": "253","remote_addr": "13.93.105.179","time_local": "08/Apr/2022:16:18:21 +0800","status":"302","host":"fengqi.me","uri":"/new-index.php","server":"fengqi.me","port":"443","protocol":"HTTP/1.1","request_uri":"/new-index.php","args": "","scheme": "https","request_time": "0.000","request_method":"GET","http_referrer":"","body_bytes_sent":"138","http_x_forwarded_for":"","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36","upstream_response_time":""}

正常用户不会这么访问,所以基本上一个ip重复来这么几次就是有问题的,写个脚本,定时扫描nginxaccess.log统计出频繁的ip,然后干掉。

- 阅读剩余部分 -

我通过自制的Kodi命令行刮削器申请到了JetBrains的开源许可证

项目地址

Kodi 刮削器命令行版本,使用TMDB数据源

更早的起源

2021年的双十一我在京东购买了索尼的X91J 65英寸版本,同时幸运的使用了那个2000的特殊优惠券,感谢京东没有回收这个羊毛。

电视安装完成后,我开始着手构建自己的影音环境,在此之前,我是通过PT下载到NAS,然后电脑+2.0音箱播放,没有刮削,这之后我会转移到电视上来。

索尼电视使用的是和当贝合作的Android系统国内特供版,不过也允许用户随意的安装第三方应用,我进行了大量的尝试,最后只保留了Bilibili、Kodi、SmartTubeNext、Netflix、Aptoide这几个应用。

其中Kodi用来管理我从网络下载的电影和剧集,提供海报墙,观看进度跟踪,因为Kodi自带的刮削器不能满足我的需求,tinyMediaManager等半自动又太麻烦,所以我决定自制刮削器。

- 阅读剩余部分 -

[记录]关于新增新字段sqlx报错missing destination name

正常情况下,将数据的字段映射到一个struct的时候,需要使用db这个tag指定关系,典型的使用场景如下:

type News struct {
    Id int64 `json:"id" db:"id"`
    GroupId int64 `json:"group_id" db:"group_id"`
}

news := &News{}
err := db.QueryRowx("select...", x).StructScan(news)

部分类库比如xorm会尝试根据驼峰、下划线去对应,sqlx并不会,而是会报panic级别的错误。

查看源码,发现StructScan内部调用了scanAny这个方法,继续往下看,可以发现这样一段代码:

fields := m.TraversalsByName(v.Type(), columns)
// if we are not unsafe and are missing fields, return an error
if f, err := missingFields(fields); err != nil && !r.unsafe {
    return fmt.Errorf("missing destination name %s in %T", columns[f], dest)
}

这里判断是否有字段缺失,同时有个unsafe开关,如果没有打开,就会报错,unsafe是在初始化db链接的时候指定的,可以通过调用db.Unsafe()方法返回一个打开unsafe开关的db实例,至于是全局使用还是每次调用时指定,看你自己了。

PS: 如果愿意动动手,也可以通过db.Mapper = xx覆盖默认的Mapper方法,其中包括字段名映射逻辑,比如把xorm的逻辑移植过来。

Proxmox VE关于Alpine虚机、MAC地址还有Hostname的小坑

Proxmox VE简称PVE,有kvmlxc两种模式,说人话就是虚拟机和容器,比较轻量的应用我会优先使用lxc,磁盘和内存占用都非常低。

如果对glic没有强制要求的,我会优先使用 Alpine Linux 这个发行版,除开应用本身的资源,只有2m左右的系统文件,几乎没有内存和磁盘浪费。

我的PVE和虚机优先跑在SSD上,会比跑在HDD上有更好的io,所有SSD空间需要省着用。

问题1:Alpine DHCP可能不发送主机名

我在使用Alpine的时候发现部分机器启动后,DHCP不会发送Hostname,导致OpenWrt看到的主机名是问号?爬了一下Alpine的文档后找到,可在/etc/network/interfaces 增加hostname参数来自定义发送主机名,问题解决,验证方式是查找系统进程udhcpc 看运行参数是否有 hostname:xxx字样,例如:

> ps|grep dhcp
> /sbin/udhcpc -b -R -p /var/run/udhcpc.eth0.pid -i eth0 -x hostname:ptn

原因未知,使用的镜像都是一致的,部分容器开起来就是会出问题。。。可能隐藏的比较深。

- 阅读剩余部分 -

正则表达式阶段性记录

昨天在写一个diff脚本的时候,需要过滤#开头的注释,以及过滤掉过滤#后出现的空行,Google后我的脚本变成了grep -v '^#' | grep -v '^$' 这样,可用但是并太不明白^$的意思,猜测可能是开始即结束?

因为我尝试加上几个空格匹配会失败,且改成 grep -v '^#'|grep -Ev '^\s+$' 是可以的,今天又搜了下想确认猜测,然而并没有找到相关的说明,但是也有其他收获。

首先是梳理了下正则的各种分支和规范,比如POSIX、Perl、RE2等以及包含的子集。

其次是匹配包括换行的写法,以前在写PHP的时候比较习惯使用flag,比如i、s、U这些,现在又多了几种写法:[\s\S]*[\d\D]*[\w\W]*[\v\V]*[\h\H]*

是不是挺迷惑,我一开始也是,那现在再来回顾下语法:

\d    数字,[0-9]
\D    非数字,[^0-9]
\s    白空格,[\t\n\f\r ]
\S    非白空格,[^\t\n\f\r ]
\w    整个单词,[0-9A-Za-z_]
\W    非整个单词,[^0-9A-Za-z_]
\h    水平空格
\H    非水平空格
\v    垂直空格
\V    非垂直空格

- 阅读剩余部分 -

如何解压 .zst 和 tar.zst 压缩文件

.zsttar.zst 是使用 Facebook 开源的 Zstandard 算法压缩出来的文件。

tar 命令有个参数 -I(--use-compress-program) 可以指定压缩和解压缩使用的子命令,所以解压的完整命令如下:

tar --use-compress-program=unzstd -xvf archive.tar.zst

如果报错:zstd: Cannot exec: No such file or directory,请尝试使用 apt、yum等系统自带的包管理软件安装zstd。

参考:How can I decompress an archive file having .zst or tar.zst?

恢复git push -f丢失的提交

如果有人本地仓库比较新,让他暂时不要更新,并 git push -f,然后你拉取并合并即可,同时吸取教训,将重要分支设置为保护,如果是在线修改或没人拉取最新代码,能否恢复取决于远端仓库是否执行gc,否则神仙也救不回来了。

以没有gc过为例,登录到远程git服务器,并找到仓库所在目录,以我使用的gitea为例,gitlab类似:

git clone /home/git/gitea-repositories/fengqi/exmaple.git rescue
cd rescue

# 查找丢失的提交,如果没有输出commit表示没救了
git fsck --lost-found
Checking object directories: 100% (256/256), done.
Checking objects: 100% (31/31), done.
dangling commit 558aac381bc8acb161447686361928e2e2edc9bf
dangling blob 82f865770e1590763574a60d53286f2102f6b03b
dangling blob d912156bec00a9f00850ab2ec3a3baf1016c2141
dangling blob f02e11383e55a7f7ac33d8dc6554ce4901e55a64

# 查看内容
git show 558aac381bc8acb161447686361928e2e2edc9bf

git checkout branch_xxx
git rebase 558aac381bc8acb161447686361928e2e2edc9bf

# 这里可能提示和远端不一样导致push失败,可以fetch后rebase,也可以pull,看你喜好
git push branch_xxx

因为原始信息只在远端,如果你没有权限登录到git远程仓库,大概率也没救了。