使用Nginx服务器的Go Web服务器在Web应用程序中。

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

Go web server with nginx server in web application

问题

抱歉,我无法从谷歌搜索中找到这个答案,也没有人清楚地解释纯Go Web服务器和nginx反向代理之间的区别。似乎每个人都在使用nginx作为Web应用程序的前端。

我的问题是,虽然Go具有所有的HTTP服务功能,但使用nginx而不是纯Go Web服务器有什么好处?

在大多数情况下,我们在这里设置Go Web服务器的所有路由,并在前面进行nginx配置。

类似于:

limit_req_zone $binary_remote_addr zone=limit:10m rate=2r/s;

server {
    listen 80;

    log_format lf '[$time_local] $remote_addr ;

    access_log /var/log/nginx/access.log lf;
    error_log /var/log/nginx/error.log;

    set_real_ip_from 0.0.0.0/0;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
    server_name 1.2.3.4 mywebsite.com;
}

当我们有这个Go代码时:

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

nginx和Go Web服务器的流量是否不同?如果不是,为什么我们需要两层Web服务器?

请帮助我理解这个问题。

谢谢!

英文:

Sorry, I cannot find this answer from Google search
and nobody seems to explain clearly the difference between pure Go webserver
and nginx reverse proxy. Everybody seems to use nginx in front
for web applications.

My question is, while Go has all http serving functions,
what is the benefit of using nginx over pure Go web servers?

And in most cases, we set up the Go webserver for all routes here
and have the nginx configurations in front.

Something like:

limit_req_zone $binary_remote_addr zone=limit:10m rate=2r/s;

server {
    listen 80;

    log_format lf '[$time_local] $remote_addr ;

    access_log /var/log/nginx/access.log lf;
    error_log /var/log/nginx/error.log;

    set_real_ip_from 0.0.0.0/0;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
    server_name 1.2.3.4 mywebsite.com;
}

When we have this Go:

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

Are the traffic to nginx and Go web server different?
If not, why do we have two layers of web server?

Please help me understand this.

Thanks,

答案1

得分: 6

没有什么阻止你直接使用Go来处理请求。

另一方面,nginx提供了一些开箱即用的功能,可能会很有用,例如:

  • 处理多个虚拟服务器(例如,在app.example.com上响应Go应用程序,在www.example.com上响应不同的应用程序)

  • 在某些路径上进行HTTP基本身份验证,比如www.example.com/secure

  • 访问日志

  • 等等

所有这些都可以在Go中完成,但需要编程,而在nginx中只需要编辑一个.conf文件并重新加载配置即可。甚至不需要重新启动nginx就可以生效这些更改。

(从“进程”角度来看,nginx可以由具有root权限的运维员管理,在一个众所周知的端口上运行,而开发人员则在更高的端口上部署他们的应用程序。)

英文:

There's nothing stopping you from serving requests from Go directly.

On the other hand, there are some features that nginx provides out-of-the box that may be useful, for example:

  • handle many virtual servers (e.g. have go respond on app.example.com and a different app on www.example.com)

  • http basic auth in some paths, say www.example.com/secure

  • access logs

  • etc

All of this can be done in go but would require programming, while in nginx it's just a matter of editing a .conf file and reloading the configuration. Nginx doesn't even need a restart for this changes to take place.

(From a "process" point of view, nginx could be managed by an ops employee, with root permissions, running in a well known port, while developers deploy their apps on higher ones.)

答案2

得分: 1

在这种情况下使用nginx的一般思路是通过nginx提供静态资源,并允许Go处理其他所有内容。

在nginx中搜索"try_files"。它允许检查磁盘上文件的存在并直接提供它,而无需在Go应用程序中处理静态资源。

英文:

The general idea of using nginx in this scenario is to serve up static resources via nginx and allow Go to handle everything else.

Search for "try_files" in nginx. It allows for checking the disk for the existence of a file and serving it directly instead of having to handle static assets in the Go app.

答案3

得分: 1

这个问题之前已经被问过几次[1],但为了记录下来:

> 这要看情况。
>
> 默认情况下,将nginx作为反向代理放在前面会给你带来以下好处:
>
> - 访问日志
> - 错误日志
> - 简单的SSL终止
> - SPDY支持
> - gzip支持
> - 通过几行代码轻松设置特定路由的HTTP头
> - 非常快速的静态资源服务(如果你是从S3等地方提供服务的话,这个可能不太相关)
>
> Go的HTTP服务器非常好,但是你需要自己重新实现一些功能(这没问题:它并不是要面面俱到的)。
>
> 我发现将nginx放在前面更容易一些,因为这正是它擅长的,让它来处理“Web服务器”相关的事情。我的Go应用程序只负责应用程序相关的事情,以及它所需的最基本的头部等。不要认为将nginx放在前面是一件“坏”事情。

此外,为了扩展我在那里的回答,还有一个问题是崩溃恢复能力:你的Go应用程序不受配置语言的限制,可以做很多事情。

其中一些事情可能会导致程序崩溃。使用nginx(或HAProxy、Varnish等)作为反向代理可以提供一些请求缓冲(以允许程序重新启动)和/或从本地缓存中提供陈旧内容(即静态主页),这可能比浏览器超时并显示“无法连接到服务器错误”更好。

另一方面,如果你正在构建小型内部服务,使用自己的日志库的“裸”Go Web服务器可能更容易管理(从运维的角度来看)。

如果你确实想将所有东西都放在Go程序中,请查看gorilla/handlers以获取gzip、日志和代理头中间件,以及lumberjack用于日志轮转(否则你可以使用系统的日志工具)。

英文:

This has been asked a few times before[1] but for posterity:

> It depends.
>
> Out of the box, putting nginx in front as a reverse proxy is going to
> give you:
>
> - Access logs
> - Error logs
> - Easy SSL termination
> - SPDY support
> - gzip support
> - Easy ways to set HTTP headers for certain routes in a couple of lines
> - Very fast static asset serving (if you're serving off S3/etc. though, this isn't that relevant)
>
> The Go HTTP server is very good, but you will need to reinvent the
> wheel to do some of these things (which is fine: it's not meant to be
> everything to everyone).
>
> I've always found it easier to put nginx in front—which is what it is
> good at—and let it do the "web server" stuff. My Go application does
> the application stuff, and only the bare minimum of headers/etc. that
> it needs to. Don't look at putting nginx in front as a "bad" thing.

Further, to extend on my answer there, there's also the question of crash resilience: your Go application isn't restricted by a configuration language and can do a lot of things.

Some of these things may crash your program. Having nginx (or HAProxy, or Varnish, etc.) as a reverse proxy can give you a some request buffering (to allow your program to restart) and/or serve stale content from its local cache (i.e. your static home page), which may be better than having the browser time out and serve a "cannot connect to server error".

On the other hand, if you're building small internal services, 'naked' Go web servers with your own logging library can be easier to manage (in terms of ops).

If you do want to keep everything in your Go program, look at gorilla/handlers for gzip, logging and proxy header middleware, and lumberjack for log rotation (else you can use your system's logging tools).

huangapple
  • 本文由 发表于 2015年9月4日 06:31:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/32386451.html
匿名

发表评论

匿名网友

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

确定