为了Awstats给Nginx添加FastCGI方式的Perl支持
有个应用(awstats)需要Perl脚本支持,但是用的Nginx服务器,对Perl支持不好,于是通过FastCGI方式来使用Perl。
首先安装Perl的FCGI模块
-
wget http://www.cpan.org/modules/by-module/FCGI/FCGI-0.67.tar.gz
-
tar -zxvf FCGI-0.67.tar.gz
-
cd FCGI-0.67
-
perl Makefile.PL
-
make && make install
还可以使用如下方法安装:
perl -MCPAN -e 'install FCGI'
安装FCGI-ProcManager
-
wget http://search.cpan.org/CPAN/authors/id/G/GB/GBJK/FCGI-ProcManager-0.18.tar.gz
-
tar -xzxf FCGI-ProcManager-0.18.tar.gz
-
cd FCGI-ProcManager-0.18
-
perl Makefile.PL
-
make
-
make install
Perl的FastCGI启动脚本
参考这篇文章 http://bbs.chinaunix.net/archiver/?tid-1224968.html
vi fcgi_perl
-
#!/usr/bin/perl -w
-
use FCGI;
-
use Socket;
-
use FCGI::ProcManager;
-
sub shutdown { FCGI::CloseSocket($socket); exit; }
-
sub restart { FCGI::CloseSocket($socket); &main; }
-
use sigtrap 'handler', \&shutdown, 'normal-signals';
-
use sigtrap 'handler', \&restart, 'HUP';
-
require 'syscall.ph';
-
use POSIX qw(setsid);
-
-
#&daemonize; we don't daemonize when running under runsv
-
#this keeps the program alive or something after exec'ing perl scripts
-
END() { }
-
BEGIN() { }
-
{
-
no warnings;
-
*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 {
-
#如果使用 IP sockets
-
#$socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 );
-
#如果使用 UNIX sockets
-
#$socket = FCGI::OpenSocket( "/var/run/perl_cgi-dispatch.sock", 10 );
-
-
#foreach $item (keys %ENV) { delete $ENV{$item}; }
-
#设置fastcgi进程数,默认四个
-
my $n_processes = $ENV{FCGI_NPROCESSES} || 4;
-
$proc_manager = FCGI::ProcManager->new( {n_processes => $n_processes} );
-
#使用unix socket
-
$socket = FCGI::OpenSocket( "$ENV{FCGI_SOCKET_PATH}", 10 );
-
#设置Socket权限
-
chmod 0777, $ENV{FCGI_SOCKET_PATH};
-
-
; #use UNIX sockets - user running this script must have w access to the 'nginx' folder!!
-
$request =
-
FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket,
-
&FCGI::FAIL_ACCEPT_ON_INTR );
-
$proc_manager->pm_manage();
-
if ($request) { request_loop() }
-
FCGI::CloseSocket($socket);
-
}
-
-
sub request_loop {
-
while ( $request->Accept() >= 0 ) {
-
$proc_manager->pm_pre_dispatch();
-
-
#processing any STDIN input from WebServer (for CGI-POST actions)
-
$stdin_passthrough = '';
-
{ no warnings; $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 );
-
pipe( PARENT_ERR, CHILD_ERR );
-
my $pid = open( CHILD_O, "-|" );
-
unless ( defined($pid) ) {
-
print("Content-type: text/plain\r\n\r\n");
-
print
-
"Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !\n";
-
next;
-
}
-
$oldfh = select(PARENT_ERR);
-
$| = 1;
-
select(CHILD_O);
-
$| = 1;
-
select($oldfh);
-
if ( $pid > 0 ) {
-
close(CHILD_RD);
-
close(CHILD_ERR);
-
print PARENT_WR $stdin_passthrough;
-
close(PARENT_WR);
-
$rin = $rout = $ein = $eout = '';
-
vec( $rin, fileno(CHILD_O), 1 ) = 1;
-
vec( $rin, fileno(PARENT_ERR), 1 ) = 1;
-
$ein = $rin;
-
$nfound = 0;
-
-
while ( $nfound =
-
select( $rout = $rin, undef, $ein = $eout, 10 ) )
-
{
-
die "$!" unless $nfound != -1;
-
$r1 = vec( $rout, fileno(PARENT_ERR), 1 ) == 1;
-
$r2 = vec( $rout, fileno(CHILD_O), 1 ) == 1;
-
$e1 = vec( $eout, fileno(PARENT_ERR), 1 ) == 1;
-
$e2 = vec( $eout, fileno(CHILD_O), 1 ) == 1;
-
-
if ($r1) {
-
while ( $bytes = read( PARENT_ERR, $errbytes, 4096 ) ) {
-
print STDERR $errbytes;
-
}
-
-
if ($!) {
-
$err = $!;
-
die $!;
-
vec( $rin, fileno(PARENT_ERR), 1 ) = 0
-
unless ( $err == EINTR or $err == EAGAIN );
-
}
-
}
-
if ($r2) {
-
while ( $bytes = read( CHILD_O, $s, 4096 ) ) {
-
print $s;
-
}
-
if ( !defined($bytes) ) {
-
$err = $!;
-
die $!;
-
vec( $rin, fileno(CHILD_O), 1 ) = 0
-
unless ( $err == EINTR or $err == EAGAIN );
-
}
-
}
-
last if ( $e1 || $e2 );
-
}
-
close CHILD_RD;
-
close PARENT_ERR;
-
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(PARENT_ERR);
-
close(STDIN);
-
close(STDERR);
-
-
#fcntl(CHILD_RD, F_DUPFD, 0);
-
syscall( &SYS_dup2, fileno(CHILD_RD), 0 );
-
syscall( &SYS_dup2, fileno(CHILD_ERR), 2 );
-
-
#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 exist or is not executable by this process.\n";
-
}
-
}
-
}
再设置启动的脚本
vi startfcgiperl
-
export FCGI_SOCKET_PATH="/tmp/perl_fcgi.socket"
-
export FCGI_NPROCESSES=4
-
./fcgi_perl &
为Nginx添加FastCGI的Perl支持
编辑 nginx.conf 脚本,添加如下内容
location ~* .*\.pl$
{
include awstats.conf;
}
location /awstatsicon/
{
alias /var/www/awstats-6.8/wwwroot/icon/;
}
vi awstats.conf
fastcgi_pass unix:/tmp/perl_fcgi.socket; fastcgi_index awstats.pl; #fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #fastcgi_param SCRIPT_FILENAME /var/www/awstats-6.8/wwwroot/cgi-bin$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME /var/www/awstats-6.8/wwwroot/cgi-bin/awstats.pl; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; fastcgi_read_timeout 60;
配置Awstats
运行 /var/www/awstats-6.8/tools/awstats_configure.pl 设置好一些变量
mkdir -p /etc/awstats cp /var/www/awstats-6.8/wwwroot/awstats.model.conf /etc/awstats/awstats.my.site.com.conf
使用 vi /etc/awstats.my.site.com.conf 进行一些参数修改,设置icon目录,DirData数据存放目录,来源log日志文件路径等
使用 /var/www/awstats-6.8/tool/awstats_updateall.pl now -awstatsprog=/var/www/awstats-6.8/wwwroot/cgi-bin/awstats.pl 命令进行初始数据更新
使用 http://my.site.com/awstats.pl 查看数据
后续
将 ./awstats_updateall.pl now -awstatsprog=/var/www/awstats-6.8/wwwroot/cgi-bin/awstats.pl 放到crontab 中做定时更新,可以做一个脚本和日志文件的处理一起做。
碰到问题
在使用unix socket时,碰到两个问题
1.写socket的目录没有写权限,添加上解决
2.nginx连不上socket, 看日志提示没有权限,在创建了socket后添加一句
chmod 0777, $ENV{FCGI_SOCKET_PATH};
问题解决。
遗留对awstats.pl访问密码限制问题尚未解决好。
解决 在 nginx 中按如下配置方式
location /awstats {
root /var/www/awstats-6.8/;
include awstats.conf;
auth_basic "awstats";
auth_basic_user_file /var/www/.passwd;
}
其中 将 awstats-6.8 目录下的 wwwroot 修改为 awstats, /var/www/.passwd 为访问目录要用来验证的账号密码文件,用apache的提供的工具htpasswd制作而成
Popularity: 48% [?]
Related
WinXP系统应用程序中文字乱码乱字符问题解决
今天装了一个英文版的软件试用,试用后将其卸掉后发现电脑上的一些文字输出乱码,甚至一些标准的对话框上也是看不明白的乱字符(也许装了这个软件后就有这个现象,不过在安装后到卸载之间没有使用其他软件,没有注意这个问题)。
为此头痛了好一会,后来经过试验发现在
“控制面板”=>”区域和语言选项”=>”高级” 中先将 “非Unicode程序的语言” 修改”英文(英国)” 或其他语言也可以,应用重启后,再重复上面过程,将”非Unicode程序的语言“修改为”中文(中国)”,再一次应用后重启。再看原先有问题的地方,发现正常。
Popularity: 27% [?]
Random Posts
Nagios的check检查脚本资源
地址在
http://www.nagiosexchange.org/cgi-bin/page.cgi?d=1
这儿有对各种数据库,硬件,软件监控的check脚本等,这些脚本有用Shell 写的,有用 perl 写的,有用 php 写的,也有用其他一些工具写的,可以根据自己的需要下载使用。
同时可以参考这些代码,编写符合自己需要的check脚本。
Popularity: 23% [?]
Related
Delphi2009正式版发布了
Delphi2009发布了,在网上找了一些地址下载不过要么是连接数过多,无法下载,要么是要下载一个特别的下载工具再下载,最后总算找到一个有可以下载地址连接的页面。
http://www.soapui.cn/wordpress/index.php/archives/35
里面有文件下载地址,需要每个文件单独下载,麻烦,不过有FlashGet这样的工具,下载整个页面上连接文件也简单。
同时这个页面上还有特别文件的下载地址,就不要再到别处找了。
刚好周末了,回家慢慢下载,等着做Delphi2009的使用体验。
Popularity: 36% [?]
Related
Nagios安装配置_被监控机器
Nagios 网站 http://www.nagios.org/
首先到 nagios 网站下载 nrpe-2.12.tar.gz
先将压缩包解压
-
tar -xzvf nrpe-2.12.tar.gz
编译安装
-
./configure
服务使用 nagios:nagios 账号组,并使用 5666 端口
首先在iptables中设置端口
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -d 192.168.0.2/24 -p tcp --dport 5666 -j ACCEPT
创建nagios需要使用的账号组
-
groupadd -g 499 nagios
-
useradd -g 499 nagios
-
usermod -c "Nagios Monitor User" -g nagios -G nagios,nagios -u 499 nagios
安装编译好的nagios
-
./make
-
./make install
修改/etc/services文件,在最后添加如下一行端口说明
nrpe 5666/tcp #nrpe
将安装主控机安装的 plugin 拷贝过来
或用源码包编译安装一下
下载源码包 nagios-plugins-1.4.11.tar.gz
-
tar -xzvf nagios-plugins-1.4.11.tar.gz
-
cd nagios-plugins-1.4.11
-
./configure
-
./make
-
./make install
编辑 /etc/xinetd.d/nrpe文件
# description: NRPE
service nrpe
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = nagios
server = /usr/local/nagios/bin/nrpe
server_args = -c /usr/local/nagios/etc/nrpe.cfg -i
log_on_failure += USERID
}
编辑 /usr/local/nagios/etc/nrpe.cfg
cp sample-config/nrpe.cfg /usr/local/nagios/etc/ chown nagios.nagios -R /usr/local/nagios/etc
重新启动xinetd 服务,使nrpe服务器作用
service xinetd restart
检查服务运行状态
netstat -na |grep 5666
最后在主控机器上的配置脚本中添加入对该机器的监控
检查和被控机连接情况
-
/usr/local/nagios301/libexec/check_nrpe -H 192.168.0.11
一些碰到的问题
- 在主控机上执行检查命令是,出现 CHECK_NRPE: Error - Could not complete SSL handshake. 错误
- 在主控端没有能够取得被控端的状态
可能问题:
a. 对 /usr/local/nagios/etc/nrge.cfg 文件,nagios账号没有读取权限
b. 服务设置了allow_from 地址限制,可以在 /etc/xinet.d/nrge 和 /usr/local/nagios/etc/nrge.cfg 中检查
c. 看是否开放了防火墙的 5666 端口访问权限
a. 检查被控端 /usr/local/nagios/etc/nrge.cfg 文件的最后部分,看看有没有对应主控端的查询命令。如果没有,在这儿设置上去。
Popularity: 24% [?]
Related
编译mogileFS的php模块
下载 php 的mofileFS 模块, 下载地址在http://www.sunnyu.com/?p=10有列出
1. 解压
2. 执行 phpize 命令
3. 执行 ./configure –with-php-config=/usr/local/php526/bin/php-config
4. 执行 make
碰到错误,原来是没有安装 neon 开发包,于是在linux安装盘上找到 neon-0.24.7-4.i386.rpm, neon-devel-0.24.7-4.i386.rpm
将其安装上
-
rpm -ivh neon-0.24.7-4.i386.rpm
-
rpm -ivh neon-devel-0.24.7-4.i386.rpm
再使用 make ,一切正常
5. make install
记录下拷贝到的路径
6. 修改php.ini 里面添加上新的模块
再module部分添加上上面记录下的文件路径
7. 编写一个php 页面做测试
Popularity: 52% [?]
Related
RPM包安装碰到 warning: waiting for transaction lock, 不能继续
今天由于安装一个rpm包,不慎按了Ctrl+C中止了安装,结果在继续安装时总是提示 warning: waiting for transaction lock 从而安装不能继续。
google查了一下,发现是由于前次安装没有完毕,安装步骤被锁。没有找到网上所说的 /var/lib/rpm/RPMLOCK 和 rpmdb_deadlock 等文件,
不过在 /var/lock/rpm/目录下找到一个 transaction 文件,将其 rm 掉,rpm包的安装终于可以继续下去了。
Popularity: 24% [?]
Random Posts
为Linux安装NTP时间同步服务
一组Linux服务器常有时间不一致,这就需要安装ntp时间同布服务.
安装NTP服务端
1.安装ntp服务包,这个在安装盘上基本都有的,没有的找一下rpm包,安装一下
2.找到系统可以访问使用的基准时间服务器,一个公共地址 www.ntp.org
3.配置 /etc/ntp.conf,主要设置 server和driftfile两项设置
4.启动 ntp 后台服务
-
service ntpd start
5. 不要忘记打开iptables中的端口限制
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 123 -j ACCEPT
一些免费的 标准时间服务器
cn.asia.pool.ntp.org
0.asia.pool.ntp.org
1.asia.pool.ntp.org
客户端机器配置
1.同样也开一个ntp服务
2.使用一个crontab定时和内部的ntp服务器作时间同步
*/30 * * * * /usr/sbin/ntpdate 192.168.0.11
Popularity: 25% [?]
Related
使用Delphi4Php的模板功能
Delphi4php使用了smarty做为其内部的模板引擎,在实际使用中,我们只要设置 Page 的 TemplateEngine 属性值为 SmartyTemplate,并将 TemplateFileName 属性设置为该页面对应的 模板文件,在实际使用的时候就会使用模板中设置的布局来显示。
模板文件遵循Smarty 的风格,区别就是使用 {% 和 %} 来包含模板脚本内容, 而不是我们习惯的 { 和 }包含。
在模板中可以直接使用在 Page 上定义的属性,比如,在 Page 上放一个 Label 取名称 lbTest, 则在模板文件中可以通过 {% $lbTest %} 来将lbTest的Label显示出来, 被显示的lbTest将按照lbTest所定义的各种属性行为来表现,比如字体的大小颜色等,对 lbTest 定义的事件处理方法也会转化为相关的脚本调用。
默认模板可以使用在Page上放置的组件变量,如果要在模板中使用非Page上放置的组件对象,则需要设置Page 的 OnTemplate 事件, 比如。
-
function IndexTemplate($sender, $params)
-
{
-
// 获取使用的模板引擎对象
-
$smarty = $params['template']->_smarty;
-
// 为模板设置一些非控件的变量值,这儿设置变量名称为 test
-
$smarty->assign('test', "测试额外变量文字");
-
}
然后在模板中使用 {% $test %} 就可以显示在这儿设置的文字内容。
——-
我测试时发现一个问题,如果在设计时指定好 Page 的 TemplateEngine 和 TemplateFileName,则在修改模板内容并做保存时,会将Page的事件处理关联关系去除,而且按F11不能编辑Page的属性了,不知道是Delphi4Php的Bug问题还是我的RP问题。
好在通过在设计时先不设置这两个属性的值,然后在Page的OnCreate中动态的设置这两个属性的值可以解决这个问题。
-
function IndexCreate($sender, $params)
-
{
-
$this->TemplateEngine = "SmartyTemplate";
-
$this->TemplateFilename = "index.tpl";
-
}
Popularity: 40% [?]
Related
Delphi4Php 2.0 使用浅尝
自前两天知道Delphi4Php推出2.0版后,于是就从网上下载了下来试一下后的感觉如下:
1.IDE的启动运行速度很快,而且占用资源不多,只有十来兆的内存。(和ZendStudio没有办法比,Delphi4PHP就好像轻装上阵的大奔,ZendStudio就好像肥胖的骡子拉车,毕竟还是原生的Win32程序在运行速度和资源占用上比java写的程序强很多)
2. Delphi4Php 2.0 的IDE原生支持简体中文,只要在 options 的Interface language 中选择 simplified chinese重新启动IDE环境就可以看到菜单什么的都变为中文提示了,只可惜帮助还是英文的,要是再有中文帮助就更好了。
3. 使用类似于Delphi VCL的组件,使php的编程方式延续以前delphi的一些风格,这个对以前用习惯了delphi使用的人还是比较方便的。(使用的是开源的 VCL4Php 包)
4. 使用 smarty 做后台模板处理引擎,但是使用 {% 和 %} 做 smarty 模板代码的识别标志,这样以前对php 的smarty 使用经验可以继续。
5. 有完好的代码完成功能,这个比直接用 EditPlus 编写php代码要方便很多,可以在很大程度上降低代码拼写错的几率
6. 其他一些作为一个ide所应该具有的特性,而且延续了delphi ide的一些功能
7. …
不过有缺憾,没有zend所支持的集成的版本控制库功能。
总的感觉作为一个php的IDE环境在运行速度,资源消耗和功能上还是可以的,但是通过使用VCL4PHP所写出来的代码执行效率就不知道会怎么样了,下次在做测试。
使用中发现一点小问题,当使用一个模板页面做测试时,运行后提示
Fatal error: Smarty error: the $compile_dir ‘/tmp’ does not exist, or is not a directory.
查看了一下SmartyTemplate.inc.php 文件代码,发现在WIN系统下要使用 $_ENV['TMP'] 值的,在我的环境中不知怎么这个为空,于是添加了几行小代码。
global $_ENV; $_ENV['TMP'] =’d:\www\delphi4phptest\tmp’;
在运行,问题解决。
还有就是js脚本对 firefox 的支持不是太好。
使用了一个简单的 button.click 事件的处理,用来设置一个标签上的文字,在IE下运行完好,但是在 firefox 下脚本却不起作用,后来google查找,发现这个地址有说明: FireFox对脚本的执行有限制,引用的js必须要和文件在同一个驱动器下才行(右键查看页面代码可以看到测试运行时,页面有对安装目录下的js引用,使用的是绝对路径),我的测试工程目录和delphi4php的安装目录不在同一个驱动器下,于是将测试工程挪到安装驱动器下继续测试,这时在firefox下打开正常。
Popularity: 41% [?]
