记录一次神奇的 ZEIT Debug 经历

事情是这样的，总所周知，因为我的主要博客每次构建的时候会涉及到一些动态内容以及优化，所以它是被 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 端口的信息，而且还是随机占用？有的时候占用，有的时候不占用？

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