事情是这样的,总所周知,因为我的主要博客每次构建的时候会涉及到一些动态内容以及优化,所以它是被 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
端口的信息,而且还是随机占用?有的时候占用,有的时候不占用?
于是,这个困扰了我快一年的问题,就换了一个端口后,解决了。。。