This is nifty tool. Out of curiosity, does this work in a similar way to how templates are embedded in the godoc binary?
Another similar tool I have run across before is go-bindata.
Just did a little comparison, and go-bindata is much, much better than statik.
statik naively encodes the data as a Go string, which is a) terrible for binary data and b) gets incredibly slow for anything other than small assets (<100K).
Seems you can only import one static directory in one binary with statik: it’s registering the dir globally. Seems pretty weird that they’d use global variables like that, when the alternative approach (attach the data to an exported variable) is that much more flexible.
Guess go-bindata it is (:
I would love to see benchmarks of serving a web application this way vs. proxying the Go part behind something like nginx and having nginx serve the static files
The only thing by removing nginx (or any other buffering reverse-proxy) from your stack is that you may be opening yourself up to malicious slow clients. Go can handle each request in a goroutine, but that may not save you if you don’t carefully handle larger requests.
You can run a safe, secury Go server directly, but given the amount of time the nginx team has spent making it great for this purpose…
I will say that I have performance tested my Go web applications by themselves and behind nginx. I used the built in benchmark tools that come with Go and the nginx webserver starts erroring and not handling requests during the bench tests and the built in Go http server does just fine and far out performs the nginx proxy. This was done quite some time ago on a windows machine so take that for what it’s worth. I know that the http library in Go has since improved, and that the environment makes quite a difference. With nginx I usually see 20-25k req/sec be handled before it starts having issues, and with go I commonly see 60k without any issue. Go handles static content very well as does nginx, but I think nginx as a proxy is just a bottleneck. I’ve since built a Go proxy for the application instances because of this. Good luck!
There are also other considerations besides performance. Nginx has a lot of features that the Go http server library doesn’t, like rate-limiting, https, load-balancing, etc. If all you want is to serve a web app from a single host, you wouldn’t care about these things, but otherwise Nginx gives you a lot of functionality that would take a while to implement yourself.
The obvious solution to this, of course, would be for someone to implement a web proxy in Go that has all those features. Then you could get the best of both. I’m curious, though, if the performance drop was caused by the overhead of having to pass requests from one process to another, and not so much Nginx itself. Have you benchmarked your Go proxy to see how it compares?
I can’t wait to see someone build a feature compatible with Nginx server in Go. I’m guessing performance wise they’d be darn close, and the code would certainly be much more easily maintained in Go. I’d miss openresty, though, which is extremely useful for providing custom functionality to Nginx, or just straight up raw, dynamic web apps.