去(lang)与nginx – 服务静态文件

目前我有以下用Go编写的HTTP服务器:

func main() { http.HandleFunc("/", func(response http.ResponseWriter, request *http.Request) { http.ServeFile(response, request, "/var/www/default/htdocs/index.html") }) http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("/var/www/default/htdocs/public")))) http.HandleFunc("/json", func(response http.ResponseWriter, request *http.Request) { // serves a JSON response }) http.HandleFunc("/socket", func(w http.ResponseWriter, r *http.Request) { // replies to the WebSocket }) http.ListenAndServe(":3000", nil) } 

我已经看到了一些基准,表明nginx在静态文件方面每秒可以提供更多的请求。 nginx的另一个有用的function是它可以透明地gzip响应,甚至可以使用gzip_static模块提供预压缩的文件。

理想情况下,我希望nginx提供所有现有的(静态)文件,并将所有不存在的东西代理到Go:

 location / { try_files $uri $uri/ @go; } location @go { proxy_pass http://127.0.0.1:3000/; proxy_set_header Host $host; } 

不幸的是,nginx不喜欢上面的configuration:

nginx:[emerg]“proxy_pass”在正则expression式给定的位置,或者在命名的位置,或者if语句中,或者在/ etc / nginx / sites-enabled / default中的“limit_except”

在这一点上,我知道我有几个select:

1)把proxy_pass放在location / block中

但是,这将代理一切,即使是现有的(静态)文件。

2)在nginx中写个人/json/socket位置块

但是如果我想在Go中添加更多的处理程序,我也必须相应地更新nginx虚拟主机。

3)重写Go代码并在nginx中使用fastcgi_pass而不是proxy_pass

 location @go { fastcgi_pass 127.0.0.1:9000; } 

我也必须更改Go代码来使用net/http/fcgi而不是net/http ,问题在于我不知道如何使用fcgi.Serve()指定path( /json/socketfcgi.Serve()

另外,FastCGI似乎比HTTP的速度慢4倍: https : //gist.github.com/hgfischer/7965620 。

4)完全丢弃nginx

Make Go提供一切服务(包括静态文件),并在每个请求上处理gzip压缩。


我怎样才能让nginx和Go的行为像我想(最好与HTTP接口)?

道歉,如果这个问题太基本,这是我第一次写一个Go的Web应用程序的经验。

附加问题

在PHP中,我将fastcgi_pass指向了php-fpm Unix套接字。 如果有任何请求遇到PHP致命错误 ,即将发出的请求仍将被提供。 但是,如果我的Go代码调用panic()程序将被终止,服务将停止响应。 在Go中处理这个问题的最好方法是什么?

“proxy_pass”的问题似乎是因为拖拽/试图删除它,因为它没有任何方法。 如果您需要在将URI传递给代理之前更改URI,请尝试使用重写,即删除URI的某个部分,请尝试如下所示:

 location @go { rewrite ^/part_to_remove(/.*)$ $1; proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; } 

我使用了下面的nginxconfiguration – 资源

 server { server_name _; root /home/vagrant/htdocs/sinatra-test; location / { try_files $uri $uri/ @backend; } location @backend { proxy_pass http://localhost:4567; } } 

以下是我的目录结构:

 /home/vagrant/htdocs/sinatra-test |-- Gemfile |-- Gemfile.lock |-- app.rb `-- assets `-- css `-- screen.css 

根据这个网站我运行一个简单的sinatra应用程序:

 require 'sinatra' get '/hi' do "Hello World!" end 

这就是答案

 # logged in the sinatra log $ curl localhost/hi Hello World! # not logged in the sinatra log - comes directly from nginx $ curl localhost/assets/css/screen.css body { background: red; } # logged in the sinatra log $ curl localhost/test <!DOCTYPE html> <html> <head> <style type="text/css"> body { text-align:center;font-family:helvetica,arial;font-size:22px; color:#888;margin:20px} #c {margin:0 auto;width:500px;text-align:left} </style> </head> <body> <h2>Sinatra doesn&rsquo;t know this ditty.</h2> <img src='http://localhost:4567/__sinatra__/404.png'> <div id="c"> Try this: <pre>get '/test' do "Hello World" end </pre> </div> </body> </html> 

正如你可以看到,如果该文件不存在的请求去sinatra应用程序。

 $ nginx -V nginx version: nginx/1.2.1