【问题标题】:An explanation of the nginx/starman/dancer web stacknginx/starman/dancer web 栈的解释
【发布时间】:2012-08-21 02:09:54
【问题描述】:

我从事网络编程已经有一段时间了,对 LAMP 堆栈非常熟悉。我决定尝试使用 nginx/starman/dancer 堆栈,但我对如何从高层次理解所有部分如何相互关联感到有些困惑。设置堆栈似乎不像设置 LAMP 堆栈那么简单,但这可能是因为我不太了解这些部分之间的关​​系。

我了解 nginx 所扮演的角色 - 一个轻量级网络服务器/代理 - 但我对 starman 与 pgsi、plack 和 dancer 之间的关系感到困惑。

我希望能对这些部分如何相互关联以及为什么每个部分都是必要(或不必要)进行堆栈设置的原因进行高级分解。谢谢!

【问题讨论】:

    标签: nginx dancer plack starman


    【解决方案1】:

    我花了最后一天阅读各种组件,我认为我有足够的理解来回答我自己的问题。我的大部分答案都可以在网络上的各个地方找到,但希望将所有部分放在一个地方会有一些价值:

    • Nginx:首先要了解的堆栈中最明显的部分是 nginx。 Nginx 是一个轻量级的网络服务器,可以替代无处不在的 Apache 网络服务器。 Nginx 也可以充当代理服务器。它的使用一直在迅速增长,目前服务于所有网络域中的 10%。 nginx 的一个关键优势是它是异步的和事件驱动的,而不是创建一个进程线程来处理每个连接。从理论上讲,这意味着 nginx 能够处理大量连接而无需使用大量系统资源。
    • PSGI:PSGI 是一种协议(以将其与协议的特定实现区分开来,例如 Plack)。据我所知,创建 PSGI 的主要动机是,当首次创建 Apache 时,没有原生支持使用用例如 Perl 编写的脚本来处理请求。使用 mod_cgi 为 Apache 添加了执行此操作的能力。要测试您的 Perl 应用程序,您必须运行整个网络服务器,因为应用程序在网络服务器中运行。相比之下,PSGI 提供了一种协议,网络服务器可以通过该协议与用例如 .珀尔。这样做的好处之一是独立于 Web 服务器测试 Perl 服务器要容易得多。另一个好处是,一旦构建了应用服务器,就可以很容易地切换到不同的 PSGI 兼容网络服务器来测试哪个提供了最佳性能。
    • Plack:这是 PSGI 协议的一种特殊实现,它提供了 PSGI 兼容的网络服务器和 perl 应用程序服务器之间的粘合剂。 Plack 相当于 Perl 的 Ruby 的 Rack。
    • Starman:基于 perl 的 Web 服务器,与 PSGI 协议兼容。我有一个困惑是为什么我想同时使用 Starman 和 Nginx,但幸运的是这个问题是 Stackoverflow 上的answered quite well。本质是让 nginx 提供静态文件而不需要 perl 进程来做这件事可能会更好,同时还允许 perl 应用程序服务器在更高的端口上运行。
    • Dancer:Perl 的 Web 应用程序框架。相当于 Ruby on Rails。或者更准确地说,相当于 Sinatra for Ruby(不同之处在于 Sinatra 是一个极简框架,而 Ruby on Rails 是一个更全面的 Web 框架)。作为一个处理 PHP 并且之前没有真正使用过 Web 框架的人,我对这与服务堆栈的关系感到有些困惑。 Web 框架的重点是它们抽象出 Web 应用程序中非常频繁执行的常见任务,例如将数据库查询转换为 Web 应用程序中的对象/数据结构。

    • 安装(在 ubuntu 上):

    sudo apt-get 安装 nginx sudo apt-get install build-essential curl sudo cpan App::cpanminus sudo cpanm Starman sudo cpanm 任务::Plack sudo apt-get install libdancer-perl
    • 让它运行:
    光盘 舞者 -a mywebapp sudo plackup -s Starman -p 5001 -E 部署 --workers=10 -a mywebapp/bin/app.pl

    现在您将拥有一个 Starman 服务器,在端口 5001 上运行您的 Dancer 应用程序。要使 nginx 向服务器发送流量,您必须进行修改

    /etc/nginx/nginx.conf
    并将类似这样的规则添加到 http 部分: 服务器 { server_name Permanentinvesting.com 听 80; 位置 /css/ { 别名/home/ubuntu/mywebapp/public/css/; 30天到期; access_log 关闭; } 地点 / { proxy_pass http://localhost:5001; proxy_set_header X-Real-IP $remote_addr; } }

    第一个位置规则指定 nginx 应该处理 /css 目录中的静态内容,方法是从

    /home/ubuntu/mywebapp/public/css/
    。第二个位置规则说,在端口 80 上的网络服务器的流量应该被发送到 Starman 服务器来处理。现在我们只需要启动 nginx: sudo 服务 nginx 启动

    【讨论】:

    • 我最近在配置 nginx 时遇到了问题,它没有代理给 starman。我只需要修改配置文件中的一行(通过在它前面放一个 # 来注释它):include /etc/nginx/sites-enabled/*;
    • 很好的解释!帮了我很多!
    • 几年过去了,但这对我来说仍然是一个有用的起点。
    【解决方案2】:

    到目前为止,您的答案是正确的,但最好通过以下方式设置 nginx:

    server {
        listen 80;
        server_name foo.example.com;
    
        location / {
            # Serve static files directly:
            if (-f $request_filename) {
                expires 30d;
                break;
            }
    
            # Pass on other requests to Dancer app
            proxy_pass_header Server;
            proxy_pass http://localhost:5001/;
        }
    }
    

    这使得 nginx 服务于所有静态文件(JavaScript 和图像),而不仅仅是 css。

    这个例子取自 2011 Perl Dancer Advent :)

    【讨论】:

    • 想知道这个统计信息 (-f) 是否发生在每个请求中,或者 nginx 是否缓存了它?
    • 我也对stat调用很好奇,但更困惑的是:
    • 在我的模板资产 (js,..) 中尝试使用 request.base_uri 在应用程序中进行绝对设置。模板工具包示例:<link rel="stylesheet" href="[% request.uri_base %]/css/style.css" />。除了相对 url 还有哪些其他方法?
    • 这是否意味着他们可以访问您的代码?
    • 根据 nginx 文档,使用if 不是一个好习惯。见nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls
    【解决方案3】:

    来自 nginx 维基:
    “IfIsEvil ...指令如果在位置上下文中使用时出现问题,在某些情况下,它并没有达到您的预期,而是完全不同。在某些情况下,它甚至会出现段错误。如果可能的话,避免它通常是个好主意。 ……”

    更好的设置是:

    server {
        listen 80;
        server_name foo.example.com;
    
        location / {  
        # Checks the existence of files and uses the first match
                    try_files $uri $uri/ @dancer;
              } 
    
        location @dancer {
        # Pass on other requests to Dancer app
                proxy_pass_header Server;
                proxy_pass http://localhost:5001/;
            }
    }
    

    【讨论】:

      【解决方案4】:

      更正s.magri的回答:

      location @dancer {
        # Pass on other requests to Dancer app
        proxy_pass_header Server;
        proxy_pass http://localhost:5001;
      }
      

      我必须删除最后一个 proxy_pass 指令中的斜杠。我的 nginx (1.10.3) 版本不会以斜杠开头。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-07
        • 1970-01-01
        相关资源
        最近更新 更多