【问题标题】:why not a golang WSGI implementation为什么不使用 golang WSGI 实现
【发布时间】:2014-01-13 08:17:27
【问题描述】:

我们在 Python 中存在并发问题。这些 WSGI 服务器并不能很好地工作。我环顾四周,没有得到像 Golang 编写的带有 goroutines 的 WSGI 服务器。

有什么原因吗?

【问题讨论】:

  • WSGI 是 Python Web 服务器的规范。
  • 就是不能用 Golang 写一个 Python Web 服务器?
  • 什么不适合你?你是在问为什么 Go 服务器比 Python 运行得更好?
  • Go 的 goroutine 比 greenlet 快得多,所以想知道为什么不使用 goroutine 实现一个 WSGI 服务器...
  • 为什么要为 Python 应用程序使用 Go 服务器?如果你对 Python 服务器不满意,为什么不把它变成 C 呢?

标签: go wsgi


【解决方案1】:

WSGI 协议特定于 Python¹。使用 Go,您有三个选项(实际上是四个,但应该不考虑普通的 CGI 用于中高负载设置):

  • Built-in HTTP serving facilities 的 Go 标准库。

    在这种情况下,您的应用是独立服务器。这可能是最简单的设置,但可能存在以下问题:

    • 要在特权端口号(低于 1024,80 在此范围内)上以降级权限运行您的应用程序(您必须这样做),您需要使用专门的包装器或POSIX 功能。
    • 要在不丢失连接的情况下提供优雅的重新部署,您需要另一个包装器(如 goagain)。
  • 与上述相同,但在 Web 服务器形式的反向 HTTP 代理之后。

    主要消除了独立变体的问题,但仍然有来回传递完整的HTTP 流量的开销。

  • FastCGI 通过合适的网络服务器。 NginxApache(以及许多其他人)对此表示同意。 FCGI 客户端实现是available in the Go standard library

    除了没有独立设置的问题外,还实现了更高效的数据交换协议。另一个好处是,您的 Go 服务器可能使用 Unix 管道与前端 Web 服务器通信,与反向 HTTP 代理变体中涉及的 TCP 套接字相比,传输成本更低。

所以,如果您的设置当前使用WSGI,我会说使用FCGI

¹ 正如几位评论者指出的那样,严格来说,这并不完全正确:WSGI 允许将使用任何语言编写的 Web 服务应用程序与 Web 服务器或应用程序服务器(依次连接到 Web 服务器)解耦.
为了实现这一点,双方必须使用与语言无关的相同协议 WSGI。 尽管如此,大多数不是用 Python 编写的软件似乎都使用 HTTP 或 FastCGI 与前端服务器进行通信。


于 2020 年 11 月 19 日更新

正如Andrea Citrolo 在他们的评论中正确指出的那样,随着目前无处不在的容器化,当您部署了相同服务的多个副本并且需要对它们进行负载平衡时,使用纯 HTTP 通常是唯一的方法.

我还要补充一点,如果您打算将用 Go 编写的程序公开到互联网上(这很好),您应该阅读this

【讨论】:

  • ++ 以获得超出所提出问题的有用响应。
  • 您的建议是否基于基准测试?我的猜测是,内置方法(通过 goagain)将轻松胜过 FastCGI - 但我更愿意在决定之前查看数字。在一个站点上,Go HTTP 是一项特定基准测试 (techempower.com/benchmarks) 的当前领导者,最近领先于 JVM 产品。
  • @Rick-777,不,不幸的是,我没有确凿的数据来支持我的主张。我对更有效的数据交换协议的评论是关于比较 FastCGIHTTP 反向代理——我同意你的观点,即独立服务器应该是最快的。
  • From : wsgi.tutorial.codepoint.net > WSGI[1] 不是服务器、python 模块、框架、API 或任何类型的软件。它只是服务器和应用程序通信的接口规范。在 PEP 3333 中指定了服务器端和应用程序接口端。如果将应用程序(或框架或工具包)写入 WSGI 规范,那么它将在任何写入该规范的服务器上运行。
  • @kostix 需要指出的是,如果目标是通过容器化运行 go 服务的多个副本(现在几乎任何人都可能这样做),那么选项二是正确的方法.
【解决方案2】:

虽然 Go 本身可能不支持 WSGI 协议,但 uWSGI,这是一个非常流行的 WSGI 服务器 has support for Go。目前看来支持有限且不经常更新,但可能需要研究一下。

默认情况下,uWSGI Go 插件支持http.DefaultServeMux 处理程序,所以如果你的应用程序已经基于它,在uWSGI 中运行它应该非常简单。

以下示例改编自 uWSGI 文档:

package main

import (
    "uwsgi"
    "net/http"
    "fmt"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "<h1>Hello, World!</h1>")
}

func main() {
    http.HandleFunc("/hello/", helloHandler)
    uwsgi.Run()
}

【讨论】:

  • uwsgi 不是你想象的那样。我很惊讶人们对此表示赞同。 uwsgi 是一个多用途工具,可以运行多种脚本语言或编译语言。它与手头的问题几乎没有关系。您发布的示例将使用 uwsgi 运行一个 go 程序。所以你有 uwsgi.Run() 而不是http.ListenAndServe()。 uwsgi 就像一个适配器,可以让你插入不同的语言。 WSGI 是一种协议。 uwsgi 只共享字母“wsgi”。这就像说香蕉和娜娜是一样的,如果你需要一个保姆,你应该买一个香蕉。不混合
  • @dalu 1.5 年后重读这个问题,我确实发现我误解了这个问题。我确实知道 uwsgi 是什么,我现在看到 OP 实际上是在询问是否有一个用 Go 编写的 WSGI 服务器(它将运行 Python WSGI 应用程序。)
【解决方案3】:

这里有一个 Go WSGI 服务器:

http://bitbucket.org/classroomsystems/wsgi

但是,它的目的不是为了更快地运行 Python 服务器 - 它运行带有 GIL 的单个 CPython 解释器。在我们的产品从 Python 迁移到 Go 时,我编写它是为了帮助我的客户顺利过渡。

【讨论】:

    猜你喜欢
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 2011-06-03
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    相关资源
    最近更新 更多