为什么带有uwsgi_psgi的Perlbrew PSGI应用程序会导致“错误的”Perl包含路径?

时间:2018-02-09 09:52:00

标签: perl uwsgi dancer perlbrew psgi

我想使用uWSGI网关接口部署基于PSGI的Web应用程序。

为了实现这一点,我在我的Debian服务器上本地安装了Perlbrew,没有root访问权限。

perlbrew init
# close shell and reopen new shell
perlbrew self-install
# close shell and reopen new shell
perlbrew self-upgrade
# close shell and reopen new shell
perlbrew install-patchperl
perlbrew install-cpanm
# close shell and reopen new shell
perlbrew install -j 10 perl-5.26.1
perlbrew lib create perl-5.26.1@main
perlbrew switch perl-5.26.1@main
# close shell and reopen new shell

然后我使用cpanm -V Perl环境检查:

cpanm (App::cpanminus) version 1.7043 (/home/soeren/perl5/perlbrew/bin/cpanm)
perl version 5.026001 (/home/soeren/perl5/perlbrew/perls/perl-5.26.1/bin/perl)

  %Config:
    archname=x86_64-linux
    installsitelib=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/site_perl/5.26.1
    installsitebin=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/bin
    installman1dir=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/man/man1
    installman3dir=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/man/man3
    sitearchexp=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/site_perl/5.26.1/x86_64-linux
    sitelibexp=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/site_perl/5.26.1
    archlibexp=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/5.26.1/x86_64-linux
    privlibexp=/home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/5.26.1
  %ENV:
    PERL5LIB=/home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5
    PERLBREW_HOME=/home/soeren/.perlbrew
    PERLBREW_LIB=main
    PERLBREW_MANPATH=/home/soeren/.perlbrew/libs/perl-5.26.1@main/man:/home/soeren/perl5/perlbrew/perls/perl-5.26.1/man
    PERLBREW_PATH=/home/soeren/.perlbrew/libs/perl-5.26.1@main/bin:/home/soeren/perl5/perlbrew/bin:/home/soeren/perl5/perlbrew/perls/perl-5.26.1/bin
    PERLBREW_PERL=perl-5.26.1
    PERLBREW_ROOT=/home/soeren/perl5/perlbrew
    PERLBREW_SHELLRC_VERSION=0.82
    PERLBREW_VERSION=0.82
    PERL_LOCAL_LIB_ROOT=/home/soeren/.perlbrew/libs/perl-5.26.1@main
    PERL_MB_OPT=--install_base /home/soeren/.perlbrew/libs/perl-5.26.1@main
    PERL_MM_OPT=INSTALL_BASE=/home/soeren/.perlbrew/libs/perl-5.26.1@main
  @INC:
    FatPacked::93953009226544=HASH(0x557323bd9330)
    /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/x86_64-linux
    /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5
    /home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/site_perl/5.26.1/x86_64-linux
    /home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/site_perl/5.26.1
    /home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/5.26.1/x86_64-linux
    /home/soeren/perl5/perlbrew/perls/perl-5.26.1/lib/5.26.1

一切看起来都不错,所以我安装了Dancer2作为首选的Web框架,并成功启动了骨架测试应用程序:

dancer2 gen --application DemoApp
cd ./DemoApp
plackup ./bin/app.psgi

Plack内部HTTP Web服务器已启动并准备好为该应用程序提供服务。

再次,到目前为止一切顺利。但我想与uWSGI合作,而不是在服务链中拥有另一个完全成熟的Web服务器。

所以我安装了uwsgi-plugin-psgi自动附带uwsgi-core

apt install uwsgi-plugin-psgi

现在我想启动uWSGI网关接口......:

uwsgi_psgi --uwsgi-socket 127.0.0.1:5999 --psgi /home/soeren/DemoApp/bin/app.psgi

......应用程序崩溃了:

[uwsgi] implicit plugin requested psgi
*** Starting uWSGI 2.0.14-debian (64bit) on [Fri Feb  9 10:41:20 2018] ***
compiled with version: 6.2.1 20161124 on 07 December 2016 16:14:59
os: Linux-4.9.0-5-amd64 #1 SMP Debian 4.9.65-3+deb9u2 (2018-01-04)
nodename: skde-deu-02.sklink.de
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 8
current working directory: /home/soeren/DemoApp
detected binary path: /usr/bin/uwsgi-core
*** WARNING: you are running uWSGI without its master process manager ***
your processes number limit is 256817
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address 127.0.0.1:5999 fd 3
initialized Perl 5.24.1 main interpreter at 0x557337c6fd40
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 72768 bytes (71 KB) for 1 cores
*** Operational MODE: single process ***
Error while loading /home/soeren/DemoApp/bin/app.psgi: Can't locate WWW/Form/UrlEncoded.pm in @INC (you may need to install the WWW::Form::UrlEncoded module) (@INC contains: /home/soeren/DemoApp/bin/../lib /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/5.24.1/x86_64-linux-gnu-thread-multi /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/5.24.1 /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/x86_64-linux-gnu-thread-multi /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5 /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.24.1 /usr/local/share/perl/5.24.1 /usr/lib/x86_64-linux-gnu/perl5/5.24 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.24 /usr/share/perl/5.24 /usr/local/lib/site_perl) at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/HTTP/Entity/Parser/UrlEncoded.pm line 5.
BEGIN failed--compilation aborted at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/HTTP/Entity/Parser/UrlEncoded.pm line 5.
Compilation failed in require at /usr/share/perl/5.24/Module/Load.pm line 77.
Can't locate HTTP/Entity/Parser/UrlEncoded in @INC (@INC contains: /home/soeren/DemoApp/bin/../lib /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/5.24.1/x86_64-linux-gnu-thread-multi /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/5.24.1 /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/x86_64-linux-gnu-thread-multi /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5 /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.24.1 /usr/local/share/perl/5.24.1 /usr/lib/x86_64-linux-gnu/perl5/5.24 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.24 /usr/share/perl/5.24 /usr/local/lib/site_perl) at /usr/share/perl/5.24/Module/Load.pm line 77.
Compilation failed in require at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Plack/Request.pm line 17.
BEGIN failed--compilation aborted at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Plack/Request.pm line 17.
Compilation failed in require at /usr/share/perl/5.24/parent.pm line 16.
BEGIN failed--compilation aborted at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Dancer2/Core/Request.pm line 6.
Compilation failed in require at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Dancer2/Core/App.pm line 29.
BEGIN failed--compilation aborted at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Dancer2/Core/App.pm line 29.
Compilation failed in require at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Dancer2.pm line 11.
BEGIN failed--compilation aborted at /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/Dancer2.pm line 11.
Compilation failed in require at /home/soeren/DemoApp/bin/../lib/DemoApp.pm line 2.
BEGIN failed--compilation aborted at /home/soeren/DemoApp/bin/../lib/DemoApp.pm line 2.
Compilation failed in require at /home/soeren/DemoApp/bin/app.psgi line 10.
BEGIN failed--compilation aborted at /home/soeren/DemoApp/bin/app.psgi line 10.
unable to find PSGI function entry point.
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI worker 1 (and the only) (pid: 9769, cores: 1)

我看到的第一件事就是建筑。使用“x86_64-linux”架构的其他(cpnamplackup)程序,只有uWSGI使用“x86_64-linux-gnu-thread-multi”。

Perl的“x86_64-linux-gnu-thread-multi”架构文件夹可用,但不包含任何模块。大多数模块都安装在“根库路径”和“x86_64-linux”架构文件夹中。

/home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5
/home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/x86_64-linux

我尝试使用uwsgi_psgi命令行开关--perl-local-lib解决此问题,但没有运气:

uwsgi_psgi --uwsgi-socket 127.0.0.1:5999 --psgi /home/soeren/DemoApp/bin/app.psgi --perl-local-lib /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5
uwsgi_psgi --uwsgi-socket 127.0.0.1:5999 --psgi /home/soeren/DemoApp/bin/app.psgi --perl-local-lib /home/soeren/.perlbrew/libs/perl-5.26.1@main/lib/perl5/x86_64-linux

我也讨论过不同的uWSGI操作模式(单进程,prefork,线程),但也没有运气。

为什么uWSGI会修改包含路径?如何启动uWSGI以使其与其他程序一样工作或者另外安装该架构的模块?

1 个答案:

答案 0 :(得分:3)

我找到了一个解决方案,感谢@simbabque。

我的问题是我使用的是系统本地uwsgi_psgi,它是使用系统Perl安装编译的,并且与我本地的Perlbrew安装不兼容。

这个mailing list thread建议在Perlbrew范围内重新编译uwsgi,以便能够(仅)使用本地Perlbrew安装。

因此,通过执行以下编译,我可以设法启动Perl应用程序:

curl http://uwsgi.it/install | bash -s psgi /home/soeren/perl5/perlbrew/bin/uwsgi

但是上面显示的命令不是最好的方法,因为它缺少所有进一步重要的编译开关(例如pcre,jit)。

随着时间的推移,我将使用更多的编译开关改进这个答案。