在生产环境中提供Go Web应用程序服务

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

Serving Go Webapps In production

问题

在生产环境中处理Go Web应用程序的静态内容、灵活性和安全性的最佳方法是什么?

我应该将Go应用程序放在一个完全缓冲的反向代理(如nginx)后面进行服务吗?如果是这样,我应该让nginx处理静态内容吗?

我应该使用ServeMuxFileServer来从Go应用程序中提供静态内容,就像这里建议的那样:https://stackoverflow.com/questions/14086063/serve-homepage-and-static-content-from-root?

在生产环境中,我需要使用像NaCL或AppArmor这样的沙箱技术来保护我的应用程序吗?

英文:

What's the best way to handle serving a Go web app in production in regards to static content, flexibility, and security?

Should I serve Go from behind a fully buffered reverse proxy like nginx? If so, should I let nginx handle static content?

Should I serve static content from the Go app using a ServeMux and FileServer like what is suggested here https://stackoverflow.com/questions/14086063/serve-homepage-and-static-content-from-root?

Do I need to using sandboxing like NaCL or AppArmor with my app in production?

答案1

得分: 6

你的问题很好地概述了你的权衡。我不能确定你应该选择哪个,因为这将根据你的应用程序而有很大的差异,但是以下是每个选项的一些要点。

安全性

你提到了安全性的两个问题:

  1. 在nginx后面进行反向代理
  2. 沙箱化

如果你运行的是敏感应用程序(金融数据等),使用nginx(或apache)终止SSL连接对你来说将是一件大事,因为它们将使用经过多位安全专家验证和审查的OpenSSL。Go加密库非常好,并且由该领域中备受尊敬的人撰写,但它尚未经过同样的审查。

我不能告诉你对你的应用程序来说什么是最好的选择,但我还没有看到在使用自己编写的Go应用程序进行生产服务时有太多关于沙箱化的讨论。一个与此相关的令人兴奋的新项目是docker.io,它可以在多个层面上为你提供沙箱化,甚至超出你的Go应用程序范围之外。在我看来,只要你跟踪Go的最新版本,并避免做不安全的事情(比如导入"unsafe"和使用cgo),使用NaCl或AppArmor可能会带来更多麻烦。尽管如此,如果你正在做类似于Go Playground的事情,几乎肯定需要对不受信任的Go程序进行沙箱化。

静态内容

你可以按照自己的意愿进行处理。我会选择最简单的方式。Go应用程序可以很容易地同时提供静态内容和动态内容,所以我认为在你的基准测试和监控告诉你它无法处理负载之前,将其分离出来往往是一种过早的优化。

灵活性

我认为很难反驳将所有内容都放在一个二进制文件中的灵活性。这使得部署变得非常容易,减少了需要进行的配置和监控的数量等等。现在是静态文件,以后可以是动态文件;如果事实证明你需要内存缓存或共享内存缓存,你可以在那里添加它。往往很难准确知道未来会需要什么,所以在原型设计和初始部署阶段尽可能保持灵活性可能会带来巨大的好处。

作为一个额外的奖励,这也回到了前面两个问题,如果你的应用程序/网站变得非常成功,你可能会在CDN(如CloudFlare)后面提供服务,他们恰好在其基础设施的一些关键部分使用Go),这将处理你的静态内容的缓存和SSL连接的终止。这可以成为保持事情简单并最小化前期工程成本的理由,因为如果需要,你可以在以后使用现有的解决方案。

英文:

Your question outlines your tradeoffs pretty well. I can't tell you for certain which you should pick, though, as that's going to vary widely depending on your application, but here are some points on each.

Security

You bring up two points about security:

  1. Reverse proxying behind nginx
  2. Sandboxing

If you're running a sensitive application (financial data, etc), terminating SSL connections with nginx (or apache) is going to be a big deal for you because they will be using OpenSSL, which has been vetted and reviewed by numerous security experts. The Go crypto library is very good and is authored by someone who's well-respected in the field, but it has not yet been subject to the same scrutiny.

I can't tell you what's best for your application, but I haven't seen a lot of talk about sandboxing home-grown Go apps when using them to serve in production. One exciting new project that is relevant to this is docker.io, which can give you sandboxing at a number of levels even outside of your Go application. In my opinion, as long as you track the latest releases of Go and you avoid doing unsafe things (like importing "unsafe" and using cgo), using NaCl or AppArmor is probably going to be more trouble than it's worth. That said, sandboxing untrusted Go programs is almost certainly required, if you're doing something like the Go Playground.

Static Content

You can really do this however you want. I'd go with whichever is easiest for you. Go applications can easily serve both their own static content alongside their dynamic content, so I would say that it's often a premature optimization to separate it out until your benchmarks and monitoring tell you it can't handle the load.

Flexibility

I think it's hard to argue with the flexibility of keeping everything in a single binary. That makes it incredibly easy to deploy, it reduces the amount of configuration and monitoring you need to do, etc. What is a static file now can be dynamic later; if it turns out you need in-memory caching or shared memcache, you can add it there. It's often hard to know exactly what you're going to need down the road, so maintaining as much flexibility as possible while you're prototyping and in the initial stages of deployment can be a huge benefit.

As a bonus here that also goes back to both of the earlier questions, if your application/website becomes highly successful you might wind up serving behind a CDN (like CloudFlare, which happens to use Go for some key pieces of their infrastructure) that will both handle caching of your static content and termination of SSL connections. This can be an argument for keeping things simple and minimizing the upfront engineering cost because you can use existing solutions later if required.

huangapple
  • 本文由 发表于 2014年1月27日 07:40:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/21370779.html
匿名

发表评论

匿名网友

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

确定