> For the complete documentation index, see [llms.txt](https://walkman42.gitbook.io/best-practice-in-7days/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://walkman42.gitbook.io/best-practice-in-7days/mainbody/day2/2.3-translanguaging-and-multilingual-parallelism.md).

# 2.3 转语言和多语言并行

> 在很多大型项目里，都出现过转语言或多语言的现象。 本质是利用不同语言的特性，解决特定问题。

在我们的项目中，是否有必要用到多语言？ 如果从一开始选定一个最终语言，能节约很多后期转语言的时间，也能减少配置多位不同语言程序员的成本，同时还能在团队规模较小的情况下，降低风险。 那么有哪些转语言或者多语言的成功案例？

* Alibaba：阿里巴巴内部以Java为主，但是到了服务器运维方面，Python能在短时间解决大量问题，包括代码服务调度，在CI/CD方面有很好的表现。而且运维人员就能轻松操作，不需要关注业务的程序员的参与。
* Instagram: 最初，Instagram 的后端是用 Python 的 Django 框架编写的。随着用户量的增长，为了提高性能和效率，Instagram 的团队对其代码进行了大量的优化，并继续使用 Python，但他们也引入了其他技术和语言，如 Golang。
* Twitter: 最初，Twitter 的后端是用 Ruby on Rails 构建的。随着用户数量的增长，为了提高性能和可伸缩性，Twitter 逐渐将其核心组件迁移到了 Scala 和 JVM（Java 虚拟机）上。
* Dropbox: 虽然 Dropbox 的主要代码是用 Python 写的，但为了性能和效率，他们的团队在某些关键部分引入了 Go 和 Rust。
* WhatsApp: 在其早期，WhatsApp 的服务器是用 Erlang 编写的，这有助于其高并发的需求。然而，随着功能和需求的增长，他们也开始使用其他语言，如 C++。
* Slack: Slack 的原始代码是用 PHP 写的，但为了提高性能，他们逐渐将关键部分的代码迁移到了 Java 和 Hack（由 Facebook 开发的 PHP 方言）。
* Shopify: Shopify 的核心代码是用 Ruby on Rails 编写的。但随着其增长和性能需求的变化，他们开始在某些部分使用 Go 语言。

再来看我们的项目，GPT-Onion在后期访问请求增多的情况下，**流式回复**会带来一些问题。

#### 2.3.1 流式回复场景下的考量 <a href="#id-2.3.1-liu-shi-hui-fu-chang-jing-xia-de-kao-liang" id="id-2.3.1-liu-shi-hui-fu-chang-jing-xia-de-kao-liang"></a>

&#x20;流式回复带来的问题包括：

1. 连接持续时间：使用流式回复时，连接会被打开并保持活跃更长的时间，尤其是当数据流动地比较慢或数据量很大时。这意味着在给定的时间内，更多的连接可能会保持打开状态，从而占用服务器的并发连接资源。
2. 并发限制：大多数服务器和操作系统都有并发连接数的上限。超出这个限制可能会导致新的连接请求被拒绝或系统资源被耗尽。
3. 资源使用：除了并发连接本身，持续的连接可能会消耗其他系统资源，如内存、文件描述符或其他关联的网络资源。
4. 其他影响：流式回复可能会影响到其他系统部分，如负载均衡器或反向代理，因为这些设备/软件可能需要跟踪和管理更多的活动连接。当然我们也可以根据URI规则跳过一些。

尽管存在上述的开销和限制，流式回复也有其优势。它可以提供更好的用户体验，尤其是在需要实时更新或大量数据传输的情况下。此外，它可能会减少服务器上的内存使用，因为不需要在内存中缓存整个响应。

抛开Golang不谈，PHP/Python/Java在流式回复的场景下，服务器资源的开销都不小。 如果要展开说的话：

1. **内存回收机制**：
   * **PHP**：PHP 使用引用计数以及周期性垃圾回收机制来管理内存。每个请求结束后，PHP 会尝试释放与该请求相关的所有资源。长时间的流式回复可能会增加内存使用，但这主要取决于处理请求的具体代码。
   * **Python**：Python 使用引用计数和周期性垃圾回收来管理内存。流式回复在 Python 中可能会增加内存使用，但这同样取决于具体的代码实现和数据处理。
   * **Java**：Java 使用基于代的垃圾回收机制。长时间运行的流式回复可能会使老年代堆积更多对象，从而增加垃圾回收的次数和开销。
2. **单个请求占用时间**：
   * **PHP**：传统上，PHP 是用于处理短生命周期的请求的，每个请求启动和终止都有一定的开销。长时间运行的请求可能会更有效地使用资源，因为初始化开销在整个请求生命周期中被摊销。
   * **Python**：Python 通常可以有效地处理长时间运行的请求，尤其是使用像 Tornado 这样的异步框架。
   * **Java**：Java 很适合长时间运行的请求，尤其是在使用了 Servlets、Netty 等技术的情况下。
3. **Lifetime 机制**：
   * **PHP**：PHP 的生命周期通常与请求绑定。这意味着长时间的流式回复可能会受到 PHP 的 `max_execution_time` 配置的限制。
   * **Python**：Python 进程的生命周期通常独立于单个请求，所以它不受到与 PHP 类似的限制。
   * **Java**：Java 应用（例如基于 Tomcat 的应用）的生命周期也独立于单个请求，因此它可以很好地处理长时间的流式回复。

总的来说，这三种语言在处理流式回复时都有其优点和局限性。Java 由于其垃圾回收机制、长时间运行的进程和多线程能力，通常被认为是处理流式和长时间连接的理想选择。Python，尤其是当使用异步框架时，也可以非常有效。而 PHP，虽然不是传统上用于流式回复的选择，但在适当的配置和环境下也能处理得很好。

那么处理流式请求时，Golang跟他们相比，又有哪些明显优势呢？

1. **轻量级并发**：
   * **Goroutines**：Go 使用 goroutines 作为其主要的并发机制。goroutines 是非常轻量级的，这意味着你可以同时启动数十万或数百万个 goroutines 而不会耗尽系统资源。这与 Java 的线程或 Python 的线程/协程相比具有明显的优势。
2. **原生支持并发**：
   * Go 从设计之初就考虑到了并发。这与 Python（后来通过 asyncio 或其他库增加并发支持）和 PHP（通常依赖外部扩展进行并发处理）形成对比。
3. **Channels**：
   * Go 的 channels 提供了一种内置的、类型安全的方式来进行 goroutines 之间的通信，这使得构建复杂的并发模式变得更加简单和直观。
4. **性能和资源使用**：
   * Go 是编译型语言，编译为机器代码，通常比解释型语言（如 Python 和 PHP）更快。同时，Go 的静态类型系统和直接的内存管理通常会导致更有效的资源使用。
5. **标准库**：
   * Go 的标准库为网络编程、HTTP 服务器和客户端以及其他与流式请求相关的任务提供了广泛的支持。这意味着我们可以使用原生工具而不是依赖外部库。
6. **简化的错误处理**：
   * Go 有其特有的错误处理模式，虽然某些开发者可能觉得它有些啰嗦，但它鼓励明确和直接地处理错误，这在流式请求中尤为重要，因为这种请求可能会遇到各种网络或数据中断的问题。
7. **跨平台一致性**：
   * Go 应用可以容易地在多个平台上编译和运行，不需要任何外部依赖。这提供了一种跨平台的一致性，与需要运行时或虚拟机的 Java 或特定解释器的 PHP/Python 形成对比。

显而易见，Golang 由于其并发原语、性能特性和强大的标准库，对于处理流式请求和其他高并发任务非常适合。这并不是说其他语言不能处理这些任务，但 Golang 提供了一种更简洁、高效的方式来实现这些功能。

似乎，Golang是最终解法。 那么，7天的时间，Golang真的能够开发出这样的系统吗？
