分类目录归档:神奇的问题

TypeError: Descriptors cannot not be created directly. Downgrade the protobuf package to 3.20.x or lower

今天启动sd-webui的时候报了这个错误,由于启动之前更新过所有扩展,所以可能是哪个扩展的依赖版本冲突了,这时候按照它的提示将此模块降级即可。

首先进cmd并激活项目的venv,不激活会安装到全局去,然后执行

pip install protobuf==3.20.2

执行完后可能会有提示依然和某个模块不兼容,但是我试了一下可以正常启动webui了

[vue-router]点击链接导航后组件不刷新

这一个奇怪的bug困扰了我2天半,浪费了我很多时间来反复修改调试找问题,最后虽然找到了问题点,但是依然不知道是怎么发生的。

和网上很多其它能找到的页面不刷新的问题不同,他们要么是忘了写`<router-view>`,要么就是靠给`<router-view>`加key来解决缓存问题。而我这里的症状是页面加载后直接显示了最后一个路由的内容,不管点哪个链接都会显示最后添加的路由组件的内容。

最后我在控制台打出了所有组件的渲染函数和data函数才发现,并不是vue在渲染时选错了渲染对象,而是所有组件的渲染函数和data函数都直接指向了最后一个路由的函数,但我并没有代码去动态修改这些组件的函数,于是我在某个组件的data函数里填了一点数据再测试,问题就解决了。

由于是测试组件,原本data返回的对象是空的,像这样:

export default {
	data() {
		return {

		};
	},
}

填完数据之后变成这样:

export default {
	data() {
		return {
			poi:'poipoi',
		};
	},
}

然后这一个组件里面就不会自动变成最后一个路由组件的render函数和data函数了,但如果两个组件里面data返回的对象填写的内容也一样,那么前一个组件里面的这两个函数依然会指向后一个的,这在代码逻辑上怎么都讲不通,只能说应该是在某个优化环节出问题了,把字面一样的函数直接简化成了同一个,然后就产生了这种所有路由组件全部渲染出最后一个组件的内容的情况。

 

程序无法监听端口,但端口未被占用

之前写过一个情况,是由于程序权限不足而导致无法监听小端口号,但是今天我又遇到一个奇怪的情况。

调试node.js后端的时候需要监听3000端口,前几天都是好的,但是刚才启动的时候报了`bind EACCES` 错误,查看端口并没有被使用,程序在别的电脑上就正常。整来整去还是不行,于是开始在网上找有没有类似的情况,竟然让我找到了。

在一个搜索结果里出现列Hyper-V字样立刻吸引了我的注意,因为我昨天由于一些软件无法启动,排查问题的时候打开了Windows Sandbox,这是微软基于Hyper-V做的windows沙盒。

看了看内容应该大差不差找到原因了,启用Hyper-V会导致系统保留一些端口,这些端口不能被别的程序使用,而我用的3000正好在里面,于是就出现了今天这种端口明明没有被别的程序使用,但就是不能监听的情况。

解决方法原文在这里

简单描述一下就是在启用Hyper-V之前要用netsh设置一下你需要的端口列表,确保启用Hyper-V之后这些端口不会被保留。

netsh int ipv4 add excludedportrange protocol=tcp startport=3000 numberofports=1

然后再启用Hyper-V就可以了。

要注意的是在Hyper-V或者Sandbox启用的情况下进行设置不会直接生效,必须先禁用再启用才行。

相关资料:

2022/3/1 更新

今天发现一个更方便的方法,不需要先关闭hyper-v服务再开,方案在这里

首先重新分配一个端口段,只要我们需要监听的端口不在里面即可


netsh int ipv4 set dynamicport tcp start=49152 num=16384

然后编辑注册表禁用端口排除(但是使用`netsh int ipv4 show excludedportrange protocol=tcp` 可以看到还是有排除的端口,只不过变成了前一条命令设置的范围)


reg add HKLM\SYSTEM\CurrentControlSet\Services\hns\State /v EnableExcludedPortRange /d 0 /f

然后重启

重要提示:设置排除端口时你必须设置足够多的端口(几千到几万个)才能保证需要对外发起连接的程序能正常工作,因为发起连接需要占用一个端口,如果你设置的排除端口不够多,那么端口资源很快就会被耗尽,之后发起的连接就会出现addr in use之类的报错。

[Nginx]特殊后缀路径不走反代地址

一个很迷惑的问题整了我一晚上,我在服务器上新加了个网站,用nginx反代到一个后端,但是因为是复制的另一个有静态文件的网站的配置来改的,忘了删nginx的root配置了,于是这个本该是单纯反代的配置就有了一个静态文件输出的功能.

在我发现问题把root选项去掉了之后,它依然保留了静态文件输出的功能,而且文件路径改到默认静态文件目录了,我甚至可以打开nginx的默认index.html,不管我怎么改,一些特定后缀的地址都会被nginx拦截下来当作静态文件去找,然后返回404,根本不pass到后端去。

在我翻了一圈配置文件看到底是哪里出问题的时候,发现了在一个expires.conf里定义了这么两个规则

location ~ .*\.(js|css|html)$ {
	expires 10d;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|mp4|mp3)$ {
	expires 30d;
}

所有出问题的后缀都是这里面定义的后缀,当我把这几行全都注释掉了之后重启了nginx,这个问题竟然就解决了。

但更奇怪的地方是,在这个出问题的站的配置上根本就没有include这个配置文件,我到现在还是没搞清到底是咋回事。

总之 It Works!

[MySQL]This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled

MySQL中创建函数的时候如果出现了这个错误,表示创建语句中缺少错误中所示的3个函数行为声明,只要根据需求加在Begin前面就可以了。

如果你不确定,那就需要加`DETERMINISTIC` ,如果这个函数不会去操作数据库就写`NO SQL` (不是完全不能有SQL语句),如果需要读取数据就加`READS SQL DATA` 。

比如

CREATE DEFINER=`root`@`%` FUNCTION `poi`() RETURNS int
    NO SQL
BEGIN
	SELECT 1+1 into @r;
	return @r;
END

Certify申请Let’s Encrypt 错误 DNS problem: query timed out looking up CAA for

这是一个多月前开始出现的问题,我想着本来一直都好好的,会不会只是let’s encrypt服务器抽了,说不定过段时间就好了,但是一直到现在都没好,于是就来研究一下这个问题。

标题上这个错误是查询域名的CAA记录超时,我查了一圈CAA是个什么东西,大概就是说要有这么条记录,内容是允许哪个机构颁发什么样的证书。

使用Certify测试时发现在Cloudflare里面会自动添加对应的TXT记录,但是从没自动添加过CAA,既然是必须条目为啥它不添加呢。我在寻找相关问题时别人都是DNS解析服务不支持CAA记录,然后换个服务商解决的,cf又不是不支持。

我怀疑是不是软件问题,于是手动去cf添加了一个CAA记录,这下终于不会出现这个错误了。添加方法如下:

点添加记录按钮添加一个CAA记录,要给哪个域名设置就在名称写哪个域名(根域名写@保存会自动变为完整域名,子域名写子域名),TTL随意,CA域名那里写证书机构地址,比如Let’s Encrypt就写letsencrypt.org,前一个“标记”表示这条记录允许的是上面名称里写的那一个域名还是那个域名通配的子域名。

保存了之后再去Certify中申请证书就可以成功了。

 

如果还遇到了cf返回的错误“Cloudflare DNS API :: An error occurred while sending the request.”,可以试试把设置中cf的验证方式从“邮箱+Global API Key”改成“API Token”。

 

 

esp32连接wifi触发wdt

之前碰到一个奇怪的问题,就是一调用`WiFi.begin()` 就会整个板子卡住然后触发task wdt,也没别的报错什么的。

经过反复注释各种代码,最后终于发现是因为这一句`ets_update_cpu_frequency(240000000UL)` ,这句是用来调整cpu频率的,注释掉了之后wifi就正常了。

后来发现是搞错了参数的单位,这里面填240就可以,单位就是Mhz,而不是hz。

大红黑病了

从前天开始大红黑打不开所有的游戏了。

具体症状是

  • 打开游戏全部闪退
  • 打开KMPlayer跳出错误框提示调用远程方法错误
  • windows update报0x80070643错误
  • 事件查看器里可以找到osu的crash日志,报未知错误0x00000005,百度说是访问了无权访问的内存地址
  • 打开网易云音乐连跳3个崩溃提示
  • 打开QQ影像崩溃,错误日志表示访问了不该访问的内存地址
  • QQ影音打开卡死,奇怪的是windows media player一点事也没有
  • windows关机后主板不断电,风扇依然在转,需要手动断电
  • 其它的还有待测试

看样子是涉及到某个图形部件的程序都会爆炸,比如D3D或者OpenGL,或者两个都挂了,显驱完全删干净重装了还是这样。

问题是有很小的几率我能打开osu,这说明这不是硬性问题,应该是被某个程序影响了。

 

我已经试过禁用所有非系统启动项,确定了不是阿里呸保护进程的锅也不是QProtect的锅。

 

我一直怀疑是不是某个windows update包把我系统搞挂了。

 

Error: Cannot find module ‘npmlog’

手动安装node的时候一不注意就会出现这个错误,装好了之后使用命令`npm` 测试一下出来了这个错误:`Error: Cannot find module ‘npmlog’` 。

 

这一般是放在/bin里的链接不对导致的。

可能情况1

链接指向的不是`node_modules/npm/bin/npm-cli.js` ,初次手动安装难免会搞不清要链接哪个文件,把链接指向正确的位置即可。

情况2

使用的不是软链接,由于npm-cli.js中使用的是相对路径,要是你一不小心链了个硬链接,那么npm就会从/bin解析相对路径,所以就找不到npmlog模块了。要使用软链接,在ln命令后加上`-s` 选项:`ln -s node_modules/npm/bin/npm-cli.js /bin/npm`

 

解决node无法调用全局模块的问题

刚刚我把SPDY装到全局,`npm -g install spdy` ,

spdy@2.0.4 /usr/local/lib/node_modules/spdy
├── http-deceiver@1.2.4
├── handle-thing@1.2.4
├── select-hose@2.0.0
├── debug@2.2.0 (ms@0.7.1)
└── spdy-transport@1.1.8 (obuf@1.1.1, wbuf@1.7.0, hpack.js@2.1.4, readable-stream@2.0.2)

可以看到这个模块被装到/usr/local/lib/node_modules里了

 

 

 

然后开个环境测试一下,结果

> require('spdy')
Error: Cannot find module 'spdy'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.Module._load (module.js:286:25)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at repl:1:1
    at REPLServer.defaultEval (repl.js:154:27)
    at bound (domain.js:254:14)
    at REPLServer.runBound [as eval] (domain.js:267:12)
    at REPLServer.<anonymous> (repl.js:308:12)
    at emitOne (events.js:77:13)

吓得我满脑子都是doge!!!这是为什么?

继续阅读解决node无法调用全局模块的问题

[Node.js]isFile

昨天被nodejs的`isfile` 坑了一下午。

本来我是这么用的

var fs=require("fs");
var stat=new fs.Stats();

stat.isFile(文件路径);

结果没有任何返回,也没有报错。于是我就研究了一下午是不是相对路径问题,是不是系统问题什么的。。。

为什么我要这么写呢,因为API文档很简单就带过了这个内容,连个例子也没有:


 

Class: fs.Stats

`fs.stat()` , `fs.lstat()`  和 `fs.fstat()`  以及他们对应的同步版本返回的对象。

stats.isFile()
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isSymbolicLink() (仅在与 fs.lstat()一起使用时合法)
stats.isFIFO()
stats.isSocket()

 


由于看到了`class fs.Stats` ,我第一反应就是先`new` 一个出来,结果就悲剧了。后来经过不断探索,昂头奋进,披荆斩棘,终于从废渣信息爆满的百度里找到了`isFile` 的正确用法,是这样:

var fs=require("fs");
fs.statSync(路径).isFile();//同步版

fs.stat(path,function(s){//异步版
	callback(s.isFile());
});

`isDirectory()` 和`isFile()` 同理