


How to use Nginx as a Perl program server and its Perl module under Linux
May 16, 2023 pm 11:25 PMperl + fastcgi + nginx搭建
nginx + fastcgi是php下最流行的一套環(huán)境了,那perl會不會也有fastcgi呢,當(dāng)然有,今天來搭建下nginx下perl的fastcgi.性能方面也不亞于php,但是現(xiàn)在web程序php的流行程度perl無法比擬了,性能再好也枉然,但是部分小功能可以考慮使用perl的fastcgi來搞定.進(jìn)入正題.
1. 準(zhǔn)備軟件環(huán)境:
nginx
perl:系統(tǒng)自帶
fastcgi
1.2 perl安裝
一般linux都有自帶perl,可以不用安裝,如果確實(shí)沒有,請執(zhí)行:
# yum install perl
1.3 perl-fastcgi安裝
# cd /usr/local/src # wget http://www.cpan.org/modules/by-module/fcgi/fcgi-0.74.tar.gz # tar -xzvf fcgi-0.74.tar.gz # cd fcgi-0.74 # perl makefile.pl # make # make install
2. nginx虛擬主機(jī)配置
server { listen 80; server_name test.jb51.net; #access_log /data/logs/nginx/test.jb51.net.access.log main; index index.html index.php index.html; root /data/site/test.jb51.net; location / { } location ~ \.pl$ { include fastcgi_params; fastcgi_pass 127.0.0.1:8999; #fastcgi_pass unix:/var/run/jb51.net.perl.sock; fastcgi_index index.pl; } }
如果想把tcp/ip方式改為socket方式,可以修改fastcgi-wrapper.pl.
$socket = fcgi::opensocket( "127.0.0.1:8999", 10 ); #use ip sockets
改為
$socket = fcgi::opensocket( "/var/run/jb51.net.perl.sock", 10 ); #use ip sockets
3. 配置腳本
3.1 fastcgi監(jiān)聽腳本
文件路徑:/usr/bin/fastcgi-wrapper.pl
#!/usr/bin/perl use fcgi; use socket; use posix qw(setsid); require 'syscall.ph'; &daemonize; #this keeps the program alive or something after exec'ing perl scripts end() { } begin() { } *core::global::exit = sub { die "fakeexit\nrc=".shift()."\n"; }; eval q{exit}; if ($@) { exit unless $@ =~ /^fakeexit/; }; &main; sub daemonize() { chdir '/' or die "can't chdir to /: $!"; defined(my $pid = fork) or die "can't fork: $!"; exit if $pid; setsid or die "can't start a new session: $!"; umask 0; } sub main { $socket = fcgi::opensocket( "127.0.0.1:8999", 10 ); #use ip sockets $request = fcgi::request( \*stdin, \*stdout, \*stderr, \%req_params, $socket ); if ($request) { request_loop()}; fcgi::closesocket( $socket ); } sub request_loop { while( $request->accept() >= 0 ) { #processing any stdin input from webserver (for cgi-post actions) $stdin_passthrough =''; $req_len = 0 + $req_params{'content_length'}; if (($req_params{'request_method'} eq 'post') && ($req_len != 0) ){ my $bytes_read = 0; while ($bytes_read < $req_len) { my $data = ''; my $bytes = read(stdin, $data, ($req_len - $bytes_read)); last if ($bytes == 0 || !defined($bytes)); $stdin_passthrough .= $data; $bytes_read += $bytes; } } #running the cgi app if ( (-x $req_params{script_filename}) && #can i execute this? (-s $req_params{script_filename}) && #is this file empty? (-r $req_params{script_filename}) #can i read this file? ){ pipe(child_rd, parent_wr); my $pid = open(kid_to_read, "-|"); unless(defined($pid)) { print("content-type: text/plain\r\n\r\n"); print "error: cgi app returned no output - "; print "executing $req_params{script_filename} failed !\n"; next; } if ($pid > 0) { close(child_rd); print parent_wr $stdin_passthrough; close(parent_wr); while(my $s =) { print $s; } close kid_to_read; waitpid($pid, 0); } else { foreach $key ( keys %req_params){ $env{$key} = $req_params{$key}; } # cd to the script's local directory if ($req_params{script_filename} =~ /^(.*)\/[^\/]+$/) { chdir $1; } close(parent_wr); close(stdin); #fcntl(child_rd, f_dupfd, 0); syscall(&sys_dup2, fileno(child_rd), 0); #open(stdin, "<&child_rd"); exec($req_params{script_filename}); die("exec failed"); } } else { print("content-type: text/plain\r\n\r\n"); print "error: no such cgi app - $req_params{script_filename} may not "; print "exist or is not executable by this process.\n"; } } }
3.2 fastcgi自啟動服務(wù)腳本:
文件路徑:/etc/rc.d/init.d/perl-fastcgi
文件路徑:/etc/rc.d/init.d/perl-fastcgi
#!/bin/sh # # nginx – this script starts and stops the nginx daemon # # chkconfig: - 85 15 # description: nginx is an http(s) server, http(s) reverse \ # proxy and imap/pop3 proxy server # processname: nginx # config: /opt/nginx/conf/nginx.conf # pidfile: /opt/nginx/logs/nginx.pid # source function library. . /etc/rc.d/init.d/functions # source networking configuration. . /etc/sysconfig/network # check that networking is up. [ "$networking" = "no" ] && exit 0 perlfastcgi="/usr/bin/fastcgi-wrapper.pl" prog=$(basename perl) lockfile=/var/lock/subsys/perl-fastcgi start() { [ -x $perlfastcgi ] || exit 5 echo -n $"starting $prog: " daemon $perlfastcgi retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"stopping $prog: " killproc $prog -quit retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { stop start } reload() { echo -n $”reloading $prog: ” killproc $nginx -hup retval=$? echo } force_reload() { restart } rh_status() { status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $"usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" exit 2 esac
3.3 設(shè)置腳本權(quán)限
# chmod a+x /usr/bin/fastcgi-wrapper.pl # chmod a+x /etc/rc.d/init.d/perl-fastcgi
4. fastcgi測試
4.1 啟動nginx與fastcgi
# /usr/local/nginx-1.4.2/sbin/nginx # /etc/init.d/perl-fastcgi start
4.2 perl測試文件:
文件路徑/data/site/test.jb51.net/test.pl
#!/usr/bin/perl print "content-type:text/html\n\n"; print <<endofhtml; <html><head><title>perl environment variables</title></head> <body> <h1>perl environment variables</h1> endofhtml foreach $key (sort(keys %env)) { print "$key = $env{$key}<br>\n"; } print "</body></html>";
5. 訪問測試
5.1 訪問
http://http:test.jb51.net/test.pl,出現(xiàn)內(nèi)容表示ok.
6. 簡單壓力測試:
6.1 使用tcp/ip方式
ab -n 1000 -c 10 http://test.jb51.net/test.pl
他是在是太慢了,只好用10個并發(fā),共計100個請求來測試.
6.2 使用socket方式:
ab -n 100000 -c 500 http://test.jb51.net/test.pl
很奇怪,使用tcp/ip方式,每秒就140多個請求,而使用socket方式卻有5800個請求/秒。差距不是一般的大。順便測試了一下php的fastcgi,大概請求在3000(tcp/ip方式),4800(socket方式)。
perl模塊的使用
如果對于一個絕大部分內(nèi)容是靜態(tài)的網(wǎng)站,只有極少數(shù)的地方需要動態(tài)顯示,碰巧你又了解一點(diǎn)perl知識,那么nginx + perl的結(jié)合就能很好解決問題。要想nginx支持perl腳本,在編譯nginx時候需要如下參數(shù):
./configure --with-http_perl_module
如果make時候出現(xiàn)如下類似錯誤:
can't locate extutils/embed.pm in @inc (@inc contains: /usr/lib/perl5/5.10.0/i386-linux-thread-multi /usr/lib/perl5/5.10.0 /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi /usr/local/lib/perl5/site_perl/5.10.0 /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.10.0 /usr/lib/perl5/vendor_perl /usr/local/lib/perl5/site_perl .)
你的機(jī)器上可能需要安裝perl-devel perl-extutils-embed,對于centos系統(tǒng),直接使用yum搞定,例如:
yum -y install perl-devel perl-extutils-embed
nginx中使用perl有兩種方法,一種是直接在配置文件寫,還有一種是把perl腳本寫在外部文件中,下面主要介紹一下第二種用法。
假設(shè)nginx的根目錄為/usr/local/nginx,perl腳本存放的目錄為nginx的根目錄下的perl/lib下,腳本名字為test.pm,nginx配置為:
#位于http配置中 perl_modules perl/lib; perl_require test.pm; #位于server配置中 location /user/ { perl pkg_name::process; }
上述配置是把所有來自http://servername/user/下的請求交由test.pm腳本中定義的process方法來處理。
test.pm腳本的內(nèi)容如下:
package pkg_name; use time::local; use nginx; sub process { my $r = shift; $r->send_http_header('text/html; charset=utf-8'); my @arr = split('/', $r->uri); my $username = @arr[2]; if (!$username || ($username eq "")) { $username = "anonymous"; } $r->print('hello, you name is : <strong>' . $username . '</strong>'); $r->rflush(); return; } 1; __end__
當(dāng)你訪問http://servername/user/netingcn,你應(yīng)該可以在網(wǎng)頁上看到:
hello, you name is : netingcn
另外:當(dāng)使用 use nginx 時,會有如下的對象可以調(diào)用,可以看到上面 shift 一個對象到 $r 上,然后就可以用 $r 調(diào)用那些對象了:
$r->args – 請求的參數(shù) .
$r->discard_request_body – 這個參數(shù)是讓 nginx 放棄 request 的 body 的內(nèi)容.
$r->filename – 返回合適的請求文件的名字
$r->has_request_body(function) – 如果沒有請求主體,返回0,但是如果請求主體存在,那么建立傳遞的函數(shù)并返回1,在程序的最后,nginx將調(diào)用指定的處理器.
$r->header_in(header) – 查找請求頭的信息
$r->header_only – 如果我們只要返回一個響應(yīng)的頭
$r->header_out(header, value) – 設(shè)置響應(yīng)的頭
$r->internal_redirect(uri) – 使內(nèi)部重定向到指定的uri,重定向僅在完成perl腳本后發(fā)生.可以使用 header_out(location….的方法來讓瀏覽器自己重定向
$r->print(args, …) – 發(fā)送數(shù)據(jù)給客戶端
$r->request_body – 得到客戶端提交過來的內(nèi)容 (body 的參數(shù),可能需要修改 nginx 的 client_body_buffer_size. )
$r->request_body_file —給客戶的 body 存成文件,并返回文件名
$r->request_method — 得到請求 http method.
$r->remote_addr – 得到客戶端的 ip 地址.
$r->rflush – Immediately transmit data to the client
$r->sendfile(file [, displacement [, length ] ) – Transmit the content of the specified file to the client. The optional parameters indicate that only the offset and length of the data are transmitted. The precise transmission only takes effect after the perl script is executed. This is the so-called advanced function
$r->send_http_header(type) – Add a response http header information
- ##$r->sleep(milliseconds, handler) – Set to The request uses the specified processing method and stops processing at the specified time. During this period, nginx will continue to process other requests. After the specified time, nginx will run the installed processing method. Note that you need to pass a reference for the processing method. To forward data between processors, you can use $r->variable().
- $r->status(code) – Set the http response code
- $r->unescape(text) – Use the http method to encrypt content such as %xx
- $r->uri – Get the requested url.
- $r->variable(name[, value]) – Set the value of a variable
The above is the detailed content of How to use Nginx as a Perl program server and its Perl module under Linux. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

PHP code can be executed in many ways: 1. Use the command line to directly enter the "php file name" to execute the script; 2. Put the file into the document root directory and access it through the browser through the web server; 3. Run it in the IDE and use the built-in debugging tool; 4. Use the online PHP sandbox or code execution platform for testing.

[Common Directory Description] Directory/bin stores binary executable files (ls, cat, mkdir, etc.), and common commands are generally here. /etc stores system management and configuration files/home stores all user files. The root directory of the user's home directory is the basis of the user's home directory. For example, the home directory of the user user is /home/user. You can use ~user to represent /usr to store system applications. The more important directory /usr/local Local system administrator software installation directory (install system-level applications). This is the largest directory, and almost all the applications and files to be used are in this directory. /usr/x11r6?Directory for storing x?window/usr/bin?Many

Setting the location of the interpreter in PyCharm can be achieved through the following steps: 1. Open PyCharm, click the "File" menu, and select "Settings" or "Preferences". 2. Find and click "Project:[Your Project Name]" and select "PythonInterpreter". 3. Click "AddInterpreter", select "SystemInterpreter", browse to the Python installation directory, select the Python executable file, and click "OK". When setting up the interpreter, you need to pay attention to path correctness, version compatibility and the use of the virtual environment to ensure the smooth operation of the project.

The main difference between Java and other programming languages ??is its cross-platform feature of "writing at once, running everywhere". 1. The syntax of Java is close to C, but it removes pointer operations that are prone to errors, making it suitable for large enterprise applications. 2. Compared with Python, Java has more advantages in performance and large-scale data processing. The cross-platform advantage of Java stems from the Java virtual machine (JVM), which can run the same bytecode on different platforms, simplifying development and deployment, but be careful to avoid using platform-specific APIs to maintain cross-platformity.

The installation and configuration of MySQL can be completed through the following steps: 1. Download the installation package suitable for the operating system from the official website. 2. Run the installer, select the "Developer Default" option and set the root user password. 3. After installation, configure environment variables to ensure that the bin directory of MySQL is in PATH. 4. When creating a user, follow the principle of minimum permissions and set a strong password. 5. Adjust the innodb_buffer_pool_size and max_connections parameters when optimizing performance. 6. Back up the database regularly and optimize query statements to improve performance.

Informix and MySQL are both popular relational database management systems. They perform well in Linux environments and are widely used. The following is a comparison and analysis of the two on the Linux platform: Installing and configuring Informix: Deploying Informix on Linux requires downloading the corresponding installation files, and then completing the installation and configuration process according to the official documentation. MySQL: The installation process of MySQL is relatively simple, and can be easily installed through system package management tools (such as apt or yum), and there are a large number of tutorials and community support on the network for reference. Performance Informix: Informix has excellent performance and

I have a lot of experience in participating in VSCode offline technology exchange activities, and my main gains include sharing of plug-in development, practical demonstrations and communication with other developers. 1. Sharing of plug-in development: I learned how to use VSCode's plug-in API to improve development efficiency, such as automatic formatting and static analysis plug-ins. 2. Practical demonstration: I learned how to use VSCode for remote development and realized its flexibility and scalability. 3. Communicate with developers: I have obtained skills to optimize VSCode startup speed, such as reducing the number of plug-ins loaded at startup and managing the plug-in loading order. In short, this event has benefited me a lot and I highly recommend those who are interested in VSCode to participate.

When configuring Nginx on Debian system, the following are some practical tips: The basic structure of the configuration file global settings: Define behavioral parameters that affect the entire Nginx service, such as the number of worker threads and the permissions of running users. Event handling part: Deciding how Nginx deals with network connections is a key configuration for improving performance. HTTP service part: contains a large number of settings related to HTTP service, and can embed multiple servers and location blocks. Core configuration options worker_connections: Define the maximum number of connections that each worker thread can handle, usually set to 1024. multi_accept: Activate the multi-connection reception mode and enhance the ability of concurrent processing. s
