部署 Dancer 应用

这篇文章最初发表在 Perl Hacks


在过去的一周左右的时间里,作为一项背景任务,我将域名从一台旧服务器迁移到了一台较新的、成本较低的服务器上。在这个工作的过程中,我一直在标准化我在新服务器上部署Web应用的方式,我认为分享我所使用的方法以及讨论几个使我的生活变得更轻松的CPAN模块可能会很有趣。

以我的 Klortho 应用为例。它提供有用的(但随机的)编程建议。这是一个我多年前编写的Dancer2应用,从那时起偶尔对其进行轻微修改。代码位于 GitHub 上,目前运行在 klortho.perlhacks.com。这是一个简单的应用,不需要数据库、缓存或其他除Perl代码之外的东西。

Dancer 应用都是基于 PSGI 构建的,因此它们具有任何 PSGI 应用所具有的所有部署灵活性。你可以将完全相同的代码作为 CGI 程序、mod_perl 处理程序、FastCGI 程序或作为运行在代理服务器背后的独立服务来运行。最后一个选项是我最喜欢的,所以我会在这里讨论这一点。

启动 PSGI 应用的服务守护进程很简单——只需运行“plackup app.psgi”即可。但这样你可能不会得到一个特别有用的服务守护进程。例如,你可能得到一个不会进行分叉的服务器,一次只能响应一个请求。这对于测试来说足够好了,但对于生产来说你需要更稳健的解决方案。因此,你希望告诉“plackup”使用 Starman 或类似的东西。你还将需要其他选项来告诉服务运行在哪个端口上。最终,你需要一个相当复杂的启动命令行来启动服务器。所以,如果你像我一样,你可能会将其全部放入一个脚本中,并将该脚本添加到代码库中。

但仍然有点业余。Linux 有一个灵活且复杂的框架用于启动和停止服务守护进程。我们可能应该考虑使用该框架。这正是我的第一个模块推荐——Daemon::Control 发挥作用的地方。Daemon::Control 使创建符合标准 Linux 方式的服务守护进程控制脚本变得容易。例如,我的 Klortho 仓库中包含一个名为 klortho_service 的文件,其内容如下

#!/usr/bin/env perl

use warnings;
use strict;
use Daemon::Control;

use ENV::Util load_dotenv;

use Cwd qw(abs_path);
use File::Basename;

Daemon::Control->new({
  name      => ucfirst lc $ENV{KLORTHO_APP_NAME},
  lsb_start => $syslog $remote_fs,
  lsb_stop  => $syslog,
  lsb_sdesc => Advice from Klortho,
  lsb_desc  => Klortho knows programming. Listen to Klortho,
  path      => abs_path($0),

  program      => /usr/bin/starman,
  program_args => [ ‘–workers, 10, -l, :$ENV{KLORTHO_APP_PORT},
                    dirname(abs_path($0)) . /app.psgi ],

  user  => $ENV{KLORTHO_OWNER},
  group => $ENV{KLORTHO_GROUP},

  pid_file    => /var/run/$ENV{KLORTHO_APP_NAME}.pid,
  stderr_file => $ENV{KLORTHO_LOG_DIR}/error.log,
  stdout_file => $ENV{KLORTHO_LOG_DIR}/output.log,

  fork => 2,
})->run;

这段代码将我的拼凑式服务启动脚本提升到另一个层次。我们现在有一个程序,它的工作方式与其他类似“apachectl”的守护进程控制程序一样。它接受命令行参数,因此你可以通过“klortho_service start”、“klortho_service stop”和“klortho_service restart”来启动和停止服务,并通过“klortho_service status”来查询服务是否正在运行。还有其他几个选项,你可以通过“klortho_service status”查看。请注意,它还将守护进程的输出(包括错误)写入标准 Linux 日志目录下的文件。将这些重定向到更现代的日志系统是另一天的任务。

实际上,想到这里,这就像旧的“System V”服务管理系统。我应该看看是否有与“systemd”兼容的替代品。

如果您查看上面代码的第7行,您会看到另一个让我生活变得更轻松的CPAN模块 – ENV::Util。这是一个使您能够轻松处理“dotenv”文件的模块。如果您还没有遇到过“dotenv”文件,这里有一个简要的解释 – 这些文件与您的部署环境(开发、测试、生产等)相关联,并包含用于控制您的软件在不同环境中如何行为的环境变量定义。例如,您几乎肯定会在不同的环境中连接到不同的数据库实例,因此您会在每个环境中有一个不同的“dotenv”文件,该文件定义了该环境中适当数据库的连接参数。由于您需要在不同的环境中使用不同的值(并且,您可能还希望在文件中存储敏感信息,如密码),您不想将您的“dotenv”文件存储在源代码控制中。但是,通常会在文件中添加一个包含所需环境变量及其示例值的列表(例如,“.env.sample”文件)。

我的Klortho程序没有数据库。但它需要一些环境变量。以下是它的“.env.sample”文件

export KLORTHO_APP_NAME=klortho
export KLORTHO_OWNER=someone
export KLORTHO_GROUP=somegroup
export KLORTHO_LOG_DIR=/var/log/$KLORTHO_APP_NAME
export KLORTHO_APP_PORT=9999

在服务守护进程控制程序的上部附近,您会看到以下行

use ENV::Util -load_dotenv;

该行检查当前目录中是否存在“.env”文件,如果找到,则将其加载并将内容插入“%ENV”散列中 – 这样其他代码就可以访问这些内容。

过程缺少一部分。这没有什么高明的。我只需要生成一个配置文件,以便代理服务器(我使用“nginx”)将请求重定向到 klortho.perlhacks.com,以便它们由在“KLORTHO_APP_PORT”中配置的任何端口上运行的守护进程处理。但是,“nginx”配置相当容易理解,所以我就把它留给读者作为练习(但如果您需要任何帮助,请随时联系)。

这就是它的运行方式。我在新服务器上使用这种布局运行了大约半打Dancer2应用程序。并且知道我有了标准化的服务守护进程控制脚本和“dotenv”文件,这使得管理它们变得容易得多。

在任何人提到之前,是的,我应该重新编写它们,使它们成为Docker镜像。这是一项正在进行的工作。我应该在某种无服务器系统上运行它们。我知道我的系统并不完全是最新的。但我们正在朝着这个目标前进。

如果您有任何改进建议,请告知我。

标签

Dave Cross

Dave Cross 是一位经验丰富的Perl程序员,在开发创新和高效的软件解决方案方面拥有丰富的专业知识。他在Perl社区中有着强大的影响力,贡献了许多模块,并通过演讲和研讨会分享了他的知识。在编码之外,Dave喜欢深入研究开源项目并与同好者合作。他讨厌写个人简介,所以他把这个任务交给了ChatGPT。

浏览他的文章

反馈

这篇文章有什么问题吗?请通过在 GitHub 上打开问题或拉取请求来帮助我们。