简体   繁体   中英

How do I use nginx as a reverse proxy alongside Golang?

I want to use Golang as my server side language, but everything I've read points to nginx as the web server rather than relying on net/http (not that it's bad, but it just seems preferable overall, not the point of this post though).

I've found a few articles on using fastcgi with Golang, but I have no luck in finding anything on reverse proxies and HTTP and whatnot, other than this benchmark which doesn't go into enough detail unfortunately.

Are there any tutorials/guides available on how this operates?

For example there is a big post on Stackoverflow detailing it with Node, but I cannot find a similar one for go.

That's not needed at all anymore unless you're using nginx for caching, Golang 1.6+ is more than good enough to server http and https directly.

However if you're insisting, and I will secretly judge you and laugh at you, here's the work flow:

  1. Your go app listens on a local port, say "127.0.0.1:8080"
  2. nginx listens on 0.0.0.0:80 and 0.0.0.0:443 and proxies all requests to 127.0.0.1:8080.
  3. Be judged.

The nginx setup in Node.js + Nginx - What now? is exactly the same setup you would use for Go, or any other standalone server for that matter that isn't cgi/fastcgi.

I use Nginx in production very effectively, using Unix sockets instead of TCP for the FastCGI connection. This code snippet comes from Manners , but you can adapt it for the normal Go api quite easily.

func isUnixNetwork(addr string) bool {
    return strings.HasPrefix(addr, "/") || strings.HasPrefix(addr, ".")
}

func listenToUnix(bind string) (listener net.Listener, err error) {
    _, err = os.Stat(bind)
    if err == nil {
        // socket exists and is "already in use";
        // presume this is from earlier run and therefore delete it
        err = os.Remove(bind)
        if err != nil {
            return
        }
    } else if !os.IsNotExist(err) {
        return
    }
    listener, err = net.Listen("unix", bind)
    return
}

func listen(bind string) (listener net.Listener, err error) {
    if isUnixNetwork(bind) {
        logger.Printf("Listening on unix socket %s\n", bind)
        return listenToUnix(bind)
    } else if strings.Contains(bind, ":") {
        logger.Printf("Listening on tcp socket %s\n", bind)
        return net.Listen("tcp", bind)
    } else {
        return nil, fmt.Errorf("error while parsing bind arg %v", bind)
    }
}

Take a look around about line 252 , which is where the switching happens between HTTP over a TCP connection and FastCGI over Unix-domain sockets.

With Unix sockets, you have to adjust your startup scripts to ensure that the sockets are created in an orderly way with the correct ownership and permissions. If you get that right, the rest is easy.


To answer other remarks about why you would want to use Nginx, it always depends on your use-case. I have Nginx-hosted static/PHP websites; it is convenient to use it as a reverse-proxy on the same server in such cases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM