部署 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 上打开问题或拉取请求来帮助我们。