事情是这样的,总所周知因为我的博客每次构建的时候会涉及到一些动态内容以及优化,所以它是被 host 在 ZEIT 的服务器上。具体的来说,在构建的时候我会通过脚本启动一个本地 NodeJS 服务器,然后 Jekyll 通过 RPC 来调用指令或的结果。我随机给 NodeJS 服务器设置了一个 5001 端口,然后这样的配置也一直稳定运行了一年多。

然后,从大概一年前开始,ZEIT 会随机对博客的构建过程报错,内容是 HTTP 请求不能发往 HTTPS 服务器。我傻了,一是我的 NodeJS 服务器就是 HTTP 服务器,二是本来这就是构建过程中的本地临时服务器,上线后这个服务器就被关闭了,好像并没有用 HTTP 的必要?但这些都不是重点,重点是博客没有通过通过构建正确上线了,于是我开始排查原因。我首先想的是是不是 Express 因为某种原因强行默认 HTTPS 设置,虽然这从道理上讲不太可能,但是现在软件为了安全性其实什么都可能做得出来。但我调研后发现并没有这样的事情。然后我就在想是不是 ZEIT 为了安全默认把所有 HTTP 连接都代理成 HTTPS,包括内部连接。

于是在我准备给 ZEIT 工程师发邮件之前,我准备做一个最小可复现项目来为我的邮件提供论点支撑。OK,最诡异的事情发生了,我做不出这样的一个稳定复现的最小项目。同样的配置,同样的版本,在我的博客构建过程中就会报错,但我新开一个项目就没有任何问题。再加上我博客构建的报错也不是稳定触发的,一开始只有 10% 的几率触发,到后来慢慢变大到 90% 的几率触发,但都不是 100%。到这个时候我已经有点崩溃了。

于是我还是给 ZEIT 工程师发了一个邮件,他告诉我应该不是 ZEIT 的问题,是我自己的问题。我觉得也是可信的,要不然同时以 ZEIT 为提供商的众多开源项目主页以及甚至许多商业项目早就给 ZEIT 发律师函了。所以我开始对我的代码做详细的审计。其实在开启 NodeJS 服务部分代码不多,只有不到 50 行,但我翻来覆去看了好久,始终没有发现任何问题。况且根据报错服务器应该是被成功启动了的,只是不知道为什么只接受 HTTPS 请求。但我在服务器端明明白白是启动了一个 HTTP 服务器,到底为什么他会最后变成一个 HTTPS 服务器?再加上开启服务器的过程是在我博客构建的最后阶段,之前会有大概10分钟的依赖安装,前戏等等。也就是说我每一次 Debug,就算我就改了一个字符,也要等至少 10 分钟才能看到结果。我真的要被搞崩溃了。

再无数次试错后(因为我根本不知道错在哪),我脑筋突然不知道怎么了,把端口号从 5001 改成 4001。然后,构建成功了。。。

也就是说,其实我的服务器一直都没有启动成功,而是 ZEIT 有一个 5001 的服务一直在运行。。。而不知为什么,我的服务器启动脚本也没有报启动失败端口占用的错误。

但问题是,为什么 5001 端口被占用没有写在文档里呢?我保证我全网都没有搜到 ZEIT 会占用 5001 端口的信息,而且还是随机占用?有的时候占用,有的时候不占用?

于是,这个困扰了我快一年的问题,就换了一个端口后,解决了。。。



发现存在错别字或者事实错误?请麻烦您点击 这里 汇报。谢谢您!