英文:
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服务器使用
FastCGI
。Nginx
和Apache
(以及其他许多服务器)都可以使用FastCGI
。Go
标准库中提供了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
andApache
(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 (
"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()
}
答案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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论