35

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

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

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

4

4 回答 4

50

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

  • Nginx:要了解的第一个也是最明显的堆栈部分是 nginx。Nginx 是一个轻量级的网络服务器,可以替代无处不在的 Apache 网络服务器。Nginx 也可以充当代理服务器。它的使用量一直在迅速增长,目前服务于所有网络域的约10%。nginx 的一个关键优势是它是异步的和事件驱动的,而不是创建一个进程线程来处理每个连接。从理论上讲,这意味着 nginx 能够处理大量连接而无需使用大量系统资源。
  • PSGI:PSGI是一种协议(将其与特定实现区分开来协议,例如 Plack)。据我所知,创建 PSGI 的主要动机是,当首次创建 Apache 时,没有原生支持使用用 Perl 编写的脚本来处理请求。使用 mod_cgi 为 Apache 添加了执行此操作的能力。要测试您的 Perl 应用程序,您必须运行整个网络服务器,因为应用程序在网络服务器中运行。相比之下,PSGI 提供了一种协议,通过该协议,Web 服务器可以与用 Perl 等编写的服务器进行通信。这样做的好处之一是独立于 Web 服务器测试 Perl 服务器要容易得多。另一个好处是,一旦构建了应用程序服务器,就可以很容易地切换到不同的 PSGI 兼容网络服务器来测试哪个提供了最佳性能。
  • Plack:这是 PSGI 协议的一种特殊实现,它提供了 PSGI 兼容的网络服务器和 perl 应用程序服务器之间的粘合剂。Plack 相当于 Perl 的 Ruby 的 Rack。
  • Starman:基于 perl 的 Web 服务器,与 PSGI 协议兼容。我有一个困惑是为什么我想同时使用 Starman 和 Nginx,但幸运的是,这个问题在 Stackoverflow 上得到了很好的回答。本质是让 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 启动
于 2012-08-26T22:51:10.257 回答
5

到目前为止,您的答案是正确的,但最好通过以下方式设置 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 :)

于 2012-12-29T18:25:21.730 回答
4

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

更好的设置是:

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/;
        }
}
于 2014-06-20T03:12:22.557 回答
1

更正来自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) 版本不会以斜杠开头。

于 2018-04-18T13:22:30.073 回答