AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 584774
Accepted
Alix Axel
Alix Axel
Asked: 2014-03-27 13:23:26 +0800 CST2014-03-27 13:23:26 +0800 CST 2014-03-27 13:23:26 +0800 CST

Go(lang) with nginx - 提供静态文件

  • 772

目前我有以下用 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 每秒可以处理更多的请求。gzip_staticnginx 的另一个有用特性是它可以透明地 gzip 响应,甚至可以使用模块提供预压缩文件。

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

location / {
    try_files               $uri $uri/ @go;
}

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

不幸的是,nginx不喜欢上面的配置:

nginx:[emerg]“proxy_pass”不能在正则表达式给出的位置、命名位置、“if”语句或/etc/nginx/sites-enabled/default:23中的“limit_except”块中包含URI部分

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

1) 放入proxy_pass块location /中

但这将代理所有内容,甚至是现有的(静态)文件。

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

但是如果我想在 Go 中添加更多的处理程序,我还必须相应地更新 nginx vhost。

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

location @go {
    fastcgi_pass            127.0.0.1:9000;
}

我还必须更改 Go 代码以使用,net/http/fcgi而不是net/http,问题是我不知道如何指定路径(/json或/socket)fcgi.Serve()。

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

4)完全丢弃nginx

让 Go 服务所有内容(包括静态文件)并处理每个请求的 gzip 压缩。


我怎样才能让 nginx 和 Go 表现得像我想要的那样(最好使用 HTTP 接口)?

抱歉,如果这个问题太基础,这是我编写 Go 网络应用程序的第一次体验。

附加问题

在 PHP 中,我指向fastcgi_passUnixphp-fpm套接字。如果任何请求遇到PHP 致命错误,仍会处理即将到来的请求。但是,如果我的 Go 代码调用panic()程序将终止并且服务将停止响应。在 Go 中处理这个问题的最佳方法是什么?

nginx
  • 2 2 个回答
  • 6645 Views

2 个回答

  • Voted
  1. Best Answer
    F2nd
    2014-03-27T17:49:38+08:002014-03-27T17:49:38+08:00

    “proxy_pass”的问题似乎是因为尾随/,尝试删除它,因为它没有任何作用。如果您需要在将 URI 传递给代理之前更改它,请尝试使用重写,即删除 URI 的某些部分,请尝试以下操作:

    location @go {
        rewrite           ^/part_to_remove(/.*)$ $1;
        proxy_pass        http://127.0.0.1:3000;
        proxy_set_header  Host $host;
    }
    
    • 4
  2. czerasz
    2014-03-27T15:47:25+08:002014-03-27T15:47:25+08:00

    我使用了以下 nginx 配置 -资源

    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
    
    • 2

相关问题

  • Gzip 与反向代理缓存

  • nginx 作为代理的行为

  • Nginx 学习资源 [关闭]

  • 提供 70,000 个静态文件 (jpg) 的最佳方式?

  • 在 Apache、LightTPD 和 Nginx Web 服务器上提供 PHP 5.x 应用程序的现状?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve