为什么不使用Go语言实现WSGI?

huangapple go评论82阅读模式
英文:

why not a golang WSGI implementation

问题

我们在Python中遇到了并发问题。这些WSGI服务器并不像预期的那样工作得很好。我四处寻找,找不到像Golang编写的带有goroutines的WSGI服务器。

有什么原因吗?

英文:

We have concurrent issues in Python. These WSGI Servers just do not work that wonderful. I have a look around, get nothing like a Golang written WSGI Server with its goroutines.

Any reasons?

答案1

得分: 37

WSGI协议是特定于Python的。对于Go语言,你有三个选项(实际上是四个选项,但是纯粹的CGI在中高负载环境下不应该考虑):

  • Go标准库中的内置HTTP服务设施。

    在这种情况下,你的应用程序是一个独立的服务器。这可能是最简单的设置,但可能会遇到以下问题:

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

    大多数情况下消除了独立变体的问题,但仍然需要传递完整的HTTP流量的开销。

  • 通过适当的Web服务器使用FastCGINginxApache(以及其他许多服务器)都可以使用FastCGIGo标准库中提供了FCGI客户端实现

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

所以,如果你的设置目前使用WSGI,我建议使用FCGI

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


2020-11-19更新

正如Andrea Citrolo在他们的评论中正确指出的那样,随着当前普遍存在的容器化,当你部署多个相同服务的副本并需要对它们进行负载均衡时,使用纯HTTP通常是唯一的选择。

我还要补充的是,如果你打算将用Go编写的程序暴露在互联网上(这是可以的),你应该阅读这篇文章

英文:

WSGI protocol is specific to Python¹. With Go you have three options (actually, four, but plain CGI should supposedly be not considered for moderate to high load setups):

  • Built-in HTTP serving facilities of Go's standard library.

    In this case your app is a standalone server. This might be the simplest setup but it might have the following problems:

    • To run your app with downgraded privileges (you have to do this) on a privileged port number (below 1024, and 80 is in this range) you'll need to use a specialized wrapper or POSIX capabilities.
    • To provide for graceful redeployments without losing connections, you'll need another wrapper (like goagain).
  • Same as above, but behind a reverse HTTP proxy in the form of a web server.

    Mostly removes the problems of the standalone variant but still have the overhead of passing full HTTP traffic back and forth.

  • FastCGI via a suitable webserver. Nginx and Apache (and numerous others) are okay with this. FCGI client implementation is available in the Go standard library.

    In addition to not having the problems of the standalone setup, implements a more efficient data exchange protocol. Another bonus is that your Go server might communicate with the front-end web server using Unix pipes which have less transmission cost than TCP sockets involved in the reverse HTTP proxy variant.

So, if your setup currently uses WSGI, I'd say go with FCGI.

¹ As several commenters pointed out, strictly speaking, this is not quite correct: WSGI allows decoupling a web-serving application written in any language from a web server or an application server (connected, in turn, to a web server).
In order for this to happen, both parties must speak the same protocol, WSGI, which is language-agnostic.
Still, it appears that most software not written in Python would either use HTTP or FastCGI to communicate with the front-end server.


Updated in 2020-11-19

As Andrea Citrolo correctly points out in their comment, with presently-ubiquitous containerization, when you have multple replicas of the same service deployed, and need to have load balancing over them, using plain HTTP is usually the only way to go.

I would also add that should you intend to expose your program written in Go to the internet (which is fine), you should read this.

答案2

得分: 3

虽然Go语言本身可能不支持WSGI协议,但是相当流行的WSGI服务器uWSGI却支持Go语言。目前看来,对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()
}
英文:

While Go may not support the WSGI protocol per se, uWSGI, which is a pretty popular WSGI server has support for Go. Currently it looks like support is limited and not updated often, but it may be something to look into.

> By default the uWSGI Go plugin supports the http.DefaultServeMux handler, so if your app is already based on it, running it in uWSGI should be extremely simple.

The following example is adapted from the uWSGI docs:

package main

import (
    &quot;uwsgi&quot;
    &quot;net/http&quot;
    &quot;fmt&quot;
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, &quot;&lt;h1&gt;Hello, World!&lt;/h1&gt;&quot;)
}

func main() {
    http.HandleFunc(&quot;/hello/&quot;, helloHandler)
    uwsgi.Run()
}

答案3

得分: 3

这里有一个 Go WSGI 服务器:

http://bitbucket.org/classroomsystems/wsgi

然而,它的目的并不是为了更快地运行 Python 服务器 - 它运行一个带有 GIL 的单个 CPython 解释器。我编写它是为了在我们的产品从 Python 迁移到 Go 的过程中为我的客户提供平稳的过渡。

英文:

There is a Go WSGI server here:

http://bitbucket.org/classroomsystems/wsgi

However, its intention is not to run Python servers faster – it runs a single CPython interpreter with a GIL. I wrote it to facilitate a smooth transition for my customers while our product is being moved from Python to Go.

huangapple
  • 本文由 发表于 2013年12月25日 18:44:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/20771890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定