为什么不使用golang 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?

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.

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()
}

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.