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

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

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

问题

我想使用Golang作为我的服务器端语言,但是我读到的所有内容都指向使用nginx作为Web服务器,而不是依赖于net/http(不是说它不好,只是整体上似乎更可取,不过这不是本文的重点)。

我找到了一些关于在Golang中使用fastcgi的文章,但是在反向代理和HTTP等方面,除了这个基准测试之外,我没有找到任何相关的内容,不幸的是,它没有提供足够详细的信息。

是否有任何关于这个操作方式的教程/指南可用?

例如,有一个Stackoverflow上的大型帖子详细介绍了使用Node的情况,但我找不到类似的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.

答案1

得分: 1

这已经不再需要了,除非你正在使用nginx进行缓存,Golang 1.6+已经足够好,可以直接提供http和https服务。

然而,如果你坚持要这样做,我会暗自评判你并嘲笑你,以下是工作流程:

  1. 你的Go应用程序监听一个本地端口,比如"127.0.0.1:8080"。
  2. nginx监听0.0.0.0:80和0.0.0.0:443,并将所有请求代理到127.0.0.1:8080。
  3. 受到评判。

在https://stackoverflow.com/questions/5009324/node-js-nginx-what-now中的nginx设置与你用于Go或任何其他独立服务器的设置完全相同,而不是cgi/fastcgi。

英文:

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 https://stackoverflow.com/questions/5009324/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.

答案2

得分: 1

我在生产环境中非常有效地使用Nginx,使用Unix套接字而不是TCP进行FastCGI连接。这段代码片段来自于Manners,但你可以很容易地将其适应于普通的Go API。

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

请查看line 252,这是在HTTP通过TCP连接和FastCGI通过Unix域套接字之间切换的位置。

使用Unix套接字,您需要调整启动脚本,以确保套接字以正确的所有权和权限有序地创建。如果做对了,其余的就很容易了。


回答其他关于为什么要使用Nginx的问题,这总是取决于您的用例。我有Nginx托管的静态/PHP网站;在这种情况下,在同一台服务器上使用它作为反向代理是方便的。

英文:

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.

huangapple
  • 本文由 发表于 2016年4月27日 09:23:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/36878684.html
匿名

发表评论

匿名网友

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

确定