PHP 和 Go 作为技术栈。

首先,让我先说一下为什么我更喜欢这个而不是其他著名的 JAVASCRIPT 技术栈。

  • 我讨厌“Javascript 适用于一切”的趋势。是的。Javascript 现在几乎可以做任何事情。但是,它这样做有效吗?
  • 让我们举一个非常耗 CPU 的任务的例子。这是一个模拟 CPU 密集型任务的代码示例。让我们看看 Javascript 的表现如何。
  • 原因 1:Javascript 不擅长处理 CPU 密集型任务!

    setTimeout(function() {
        console.log("Hello world")
    }, 1000)
    
    const startTime = Date.now();
    while (Date.now() - startTime < 3000) {} //Simulating a long CPU intensive main thread task..
    
    console.log("End")
  • 那么,我们这里有什么?作为 JAVASCRIPT 的用户,我期望在 1 秒后看到打印出“hello world”。但你猜怎么着。它没有。它在 3 秒后输出“hello world”。
  • 为什么会发生这种情况?要理解这一点,我们需要了解浏览器和 Node.js 中的事件循环是如何工作的。简单来说,事件循环同时检查调用堆栈和回调队列。一旦计时器完成 1000 毫秒,我们在 setTimeout() 中传递的回调函数就会进入回调队列。
  • 但是猜怎么着...当计时器完成工作时,调用堆栈不是空的...它仍然忙于执行我们编写的 3 秒 CPU 密集型任务(是的...它是一个模拟...而不是一个现实世界中的愚蠢程序,它需要 3 秒钟来完成它打算做的任何事情)。
  • 因此,回调队列和微任务队列中的回调函数将处于饥饿状态。可怜的回调函数。它们只有在 3 秒后才有机会进入调用堆栈。这就是为什么我们看到“hello world”在 3 秒后才打印出来,尽管我指定了 1000 毫秒。
  • Image description

    是的。这是我从网上下载的事件循环的随机图像。很酷的图像。

    让我们来看看执行相同操作的 Go 代码。

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        time.AfterFunc(1*time.Second, func() {
            fmt.Println("Hello world")
        })
    
        // Simulating a long CPU-intensive main thread task
        startTime := time.Now()
        for time.Since(startTime) < 3*time.Second {
        }
    
        print("End")
    }

    这里,“hello world”在 1 秒后被打印出来。为什么?因为“AfterFunc()”在其自己的 GoRoutine 上运行,它与主 GoRoutine 没有任何关系。

    原因 2:我个人讨厌客户端渲染。

  • 让我们来谈谈 reactJS。它将 javascript 组件推送到客户端,并用太多东西塞住客户端,以至于客户端开始节流。
  • 想象一下,一台低端 PC 请求某个静态 HTML 文件,然后你得到了一堆 React 组件垃圾。客户端会有什么感觉?它变慢了。浏览器必须解析 javascript,执行虚拟 DOM,从中生成 HTML。还有其他什么。
  • 浏览器正在完成服务器必须做的所有工作。
  • 还记得网络的自然流动吗?
  • 首先加载 HTML,然后才加载 javascript?为什么?为了让初始绘制尽可能快。还记得我们在 HTML 文档页脚中加载 javascript 的日子吗?
  • React 只是把整个流程颠倒了。
  • 结果是,客户必须长时间盯着空白的屏幕。
  • 理由如上所述......

  • 我选择了两种在其各自世界中闪耀的语言。
  • 让我印象深刻的是,Go 是一种编译语言,并且是静态类型的。你可以盲目地说,Go 速度超级快,比 javascript 快很多。
  • 它具有内置的轻量级线程“GoRoutines”,由于 Go 线程是轻量级的,因此它比实际的 OS 线程快得多。
  • Go 可用于构建 RESTful 端点或用于任何后端服务。
  • 但是,我不能将 Go 用于 SSR。PHP 在这方面表现出色。在我的堆栈中,Go 将被大量用于 CPU 密集型 API 或任何后端服务。
  • PHP

  • PHP 是我在 SSR 中使用过的最好的东西。简单直接。为每个客户端创建一个进程。速度有点慢。但这些进程仍然彼此独立,不像线程会共享相同的进程内存空间,这对竞争条件和许多其他线程相关问题不利。
  • 在我看来,PHP 也与 Web 紧密结合。开箱即用的超级全局变量,如 $_GET、$_SERVER 等,使其更容易与 Web 协同工作。
  • PHP 中的会话管理太好了.. 与语言本身一起提供.. 并且管理会话太容易了..
  • 结论:

  • PHP 可以纯粹用于 SSR。和会话管理。我不能相信 PHP 可以执行 CPU 密集型任务,因为它在这方面很糟糕。为什么?它是一种解释型语言,而且它也不是多线程的。
  • 因此,我将所有 CPU 密集型调用转移到 Go 上。
  • 两全其美.. PHP 用于 SSR,这样客户端就不会受到影响,而 Go 用于 CPU 密集型任务,因为它可以很好地进行并发处理......