OMD系列(二)基础配置和目录介绍

20 Dec 2011 Posted in  monitor

话接上篇,在su和omd start之后,可以看到挂载的一个目录。其/omd是/opt/omd的软连接。目录结构如下: 继续阅读……


OMD系列(一)简介与安装

19 Dec 2011 Posted in  monitor

OMD,全称Open Monitoring Distribution,是一个围绕Nagios core构建的分布式开源监控集。在nagios基础上融合了NRPE、NSCA、check_mk、mod_gearman、pnp4nagios、nagvis、rrdcached等插件,以完成高性能的、可视化的,分权限管理的监控系统。 (我是在看mod_gearman的安装介绍时看到的,感觉这种一体式的安装很爽) 项目主页是http://omdistro.org,提供了rh、debian、suse和src各种安装模式。 比如在centos5上面,只需要简单的操作即可: 继续阅读……


Chart::OFC试用

19 Dec 2011 Posted in  perl

这几天ppt看的比较多,一样一样来玩。今天先说OFC,之前有试过amcharts和fusioncharts。amcharts最全最漂亮(尤其是有scroll和map),可惜图上都自动标上了amcharts.com的字样;fusioncharts的free版本,也蛮好用的,虽然scroll怪怪的居然靠的是点击控制。比较相同的一点就是,这两都只提供了php、python等的模块,如果是perl写的网页,那只能通过提供xml/json数据给js控制的办法。稍微一点点遗憾…… 这次在cpan上终于看到一个chart控制的模块,叫Chart::OFC。这个OFC的项目地址如下: http://teethgrinder.co.uk/open-flash-chart/ 其实用法上没什么特殊,无非是省略一点点xml代码,通过OO的方式自动生成而已。让我觉得蛮好玩的是官网上作者的声明。因为他曾经在维护公司一个付费的flash chart项目时,给甲方发信要求修改bug,等了一个月没反应。于是自己现学as语言开始自己搞= =!然后念念不忘的提示说:要重视客户的反馈。。。。。。哈哈 这个项目目前用as3改写,所以新版本叫OFC2了,不过作者自己也说不太稳定,建议继续用OFC1.9.7,所以先不说Chart::OFC2,继续用Chart::OFC好了: 继续阅读……


Dancer::Plugin::SimpleCRUD模块学习

15 Dec 2011 Posted in  dancer

Dancer圣临历中介绍了一个新插件Dancer::Plugin::SimpleCRUD。可以很快的生成对数据库表的create/read/update/delete。大概阅读了一下代码。主要就是使用HTML::FromDatabase模块生成read的页面,用CGI::FormBuilder模块生成create/update/delete的页面,用Dancer::Plugin::Database::Handle模块操作数据库。因为是Simple,所以html代码都是固定的,不甚美观。但是思路可以学习,通过这两个模块,可以自己结合Dancer的template系统做CRUD了。 先来说HTML::FromDatabase模块,这个只涉及select,所以特别简单: 继续阅读……


nginx_perl试用

12 Dec 2011 Posted in  nginx

因为空闲时间比较多,所以在CPAN上乱翻,看到了nginx_perl这个项目(原名Nginx::Engine),现在托管在github.com上。地址见: https://github.com/zzzcpan/nginx-perl 继续阅读……


websocket体验

04 Nov 2011 Posted in  dancer

因为看到mojo在宣传其内置websocket支持,去CPAN上search了一下,发现Dancer也有plugin做websocket用。稍微看了一下,很显然没看mojo的内嵌代码,而dancer的plugin代码倒是相当简单。 简单的说,就是通过AnyMQ、Plack和Web::Hippie的组合完成。注意的是,因为Web::Hippie使用了AnyEvent::Handle管理websocket的fh,AnyMQ也使用AnyEvent管理message queue,所以在启动plackup的时候,必须使用AnyEvent核心的Twiggy服务器。 Plugin里硬编码很多。比较重要的地方就是”set plack_middlewares_map”,plack_middlewares_map是dancer新加的功能,这里用URLMap来mount ‘/_hippie’到Web::Hippie::Pipe和AnyMQ上。也就是说,使用websocket的访问路径,必须固定为’^/_hippie/.*‘这样。 然后像两个get方法,’/new_listener’和’/message’,这两个访问路径是Web::Hippie里写死的,不能改。好在一般应用也不会直接访问这个。 最后有三个register到Dancer的方法,’ws_on_message’、’ws_on_new_listener’和’ws_send’,前两个用来覆盖上面提到的get的两个route的具体信息,一般不用前面两个,因为这样就意味着页面的js里无法控制websocket了(个人理解,不知道对否?)后面那个类似把websocket改成普通的params方式请求响应(用curl/wget可以请求的那种)。 继续阅读……


用perl调用新浪微博API小实验

04 Nov 2011 Posted in  dancer

新浪微博API是通过OAuth方式的。perl上有现成的模块,只需要稍微调一下参数就行了。下午比较闲,试试看。。。 一般网上说的,都还是Net::OAuth模块,这个是1.0a版本的,一看perldoc那个长篇就头疼。这里我用Net::OAuth2模块,简单方便,而且正好配合dancer框架,方便做外部网站应用。 首先是安装模块: perlcpanm --mirror-only --mirror http://mirrors.163.com/cpan LWP::Protocol::https Net::OAuth2::Client 因为新浪微博的api用的是https协议,所以要加上LWP::Protocol::https模块,这样才能发起443请求。 然后在web/lib/weibo.pm里里添加如下语句: ```perluse Net::OAuth2::Client; use JSON qw(decode_json); #只需要decode_json,因为dancer自己有from_json和to_json,不要覆盖了 继续阅读……


一个perl扩展正则表达式

26 Oct 2011 Posted in  perl

今天傍晚,莫言在Q群里贴了一个他写的正则表达式,回来翻了翻perlre文档,基本算是看懂,赶紧记录下来: perlmy $ip = "192.168.0.1|192.168.0.2|192.168.0.1"; if ( $ip =~ / ^ (?: ((?:\d{1,3}\.){3}\d{1,3}) (?= (?: \|(?!\1)(?1) )* \z ) \| )* (?1) $ /x ) { print "match\n"; } 根据perlre文档的说明,一点一点解释。 继续阅读……


用Template::Tookit给squid.conf写模板

25 Oct 2011 Posted in  perl

本文纯属练习Template模块使用,是否可以运用到生产,是否有必要运用到生产,都是未知数…… 包括如下文件: ```bash[raocl@localhost tt2-test]$ tree . |– config-cdcgame.net.yml |– config-china.com.yml |– config.tt |– hostconfig.yml |– squid.layout.tt `– tt4squid.pl 继续阅读……


blog备份脚本

24 Oct 2011 Posted in  perl

之前总不重视自己的博客,上回一丢才心疼,现在重视起来,决定定期备份sql。写个小脚本如下: ```perl#!/usr/bin/perl use warnings; use strict; use MySQL::Backup; use Mail::Sender; open my $tmp_sql, ‘>’, “backup.sql”; my $mb = new MySQL::Backup(‘dbname’, ‘localhost’, ‘dbuser’, ‘dbpasswd’, {‘USE_REPLACE’ => 1, ‘SHOW_TABLE_NAMES’ => 1}); print $tmp_sql $mb->create_structure(); print $tmp_sql $mb->data_backup(); close $tmp_sql; my $sender = new Mail::Sender { smtp => ‘smtp.163.com’, from => ‘mailuser@163.com’, 继续阅读……


博客恢复了,截图纪念一下

20 Oct 2011 Posted in 

这两天折腾博客宕机问题啊~原本对阿里云的看好大幅下降……几次挂掉,甚至电话告知说数据恢复不了请自行重置……崩溃原因居然解释说“因为你没有修改grub再重启”这种解释,拜托,我要重启还不是因为突然ssh报密码错误而你们“重置密码必须重启”?死循环啊! 对了,我人格保证,作为一个用xen当工作环境一年多的运维,绝对没有犯自行升级内核导致重启失败这种错误的可能。阿里云客服能不能不要把一个客户的缘由安到别的客户头上…… 不管如何,结局还是好的。截个监控宝的告警图纪念一下: 继续阅读……


ProBIND体验笔记

17 Oct 2011 Posted in  DNS

闲的无聊,继续研究DNS周边产品,这次盯上了Probind。这是搜索结果中比较常见的bind的web管理工具。其实我是比较希望有个中文的东东方便我偷懒,可惜看sina之前的xbayDNS一直停留在了只支持FreeBSD/MAC的阶段没有更新,汗,不支持linux的项目偶见过的还真不多…… probind最近一次更新也是2003/05/24的事情了。所以也没期待它能多么适应现在的bind体系,不过作为代码看看还是可以的。 创建mysql用户和库,然后把程序解压到webroot目录,然后执行mysql -u named -p named < etc/mktables.sql,这就是install的步骤。但是这个时候访问首页是有一堆报错的,提示你dns服务器的默认配置(外部检测用dns,管理员邮箱等等)没配置。这个需要通过./tools/settings.php去添加——但是首页上没有链接点击,得自己手敲url,汗…… 然后,probind更新的时候,估计php还是以version4为主,所以里头用的还是$HTTP_GET_VARS和$HTTP_POST_VARS等全局变量。奇怪的是我把php.ini里的register_global改成On后重启httpd了,页面依然没变,不得已在./inc/lib.inc文件的开头加上了两句 php$HTTP_GET_VARS = &$_GET; $HTTP_POST_VARS = &$_POST;才好。 OK,现在正式看到probind的页面了。demo地址:点这里 主要就是一个zone的管理,有add、delete、browse三个页面,前两个就是标准的表单,倒是browse里有个test,蛮好玩的,调用bin/testns脚本,使用perl的Net::DNS模块测试zone内的正/反向解析是否正常。 然后就是record的管理,在browse zones里点进zone就可以编辑record了,主要就是主机名、解析ip。 最后是server的管理,这里管理的是真实的DNS的ip和type(master|slave)——probind在易用和性能之间取了一个平衡,他不是像mysqlbind或者mysql-dlz那样直接从db里取数据做响应,而是每次更新(这里区分开了步骤,update的时候只是更新了db,然后再去bulk update的时候才是真正update dns配置)的时候,从数据库生成文件(bin/mkzonefile),再同步到DNS服务器上(sbin/push.local|remote)并执行rndc reconfig命令。 继续阅读……


一个ddns的demo

30 Sep 2011 Posted in  perl

上回分析lbnamed的时候,开玩笑说自己也可以试试在模块基础上加点啥功能。国庆节前最后一天,没啥事情做,就写个小demo续貂。代码如下: 继续阅读……


写个同步分发系统(三)

29 Sep 2011 Posted in  dancer

上篇写的页面上,留下一个超链接,查看每条任务的具体情况。现在完成这部分。 首先修改数据库结构,上篇已经建了websync.websync_peer表,现在继续: 继续阅读……


写个同步分发系统(二)

26 Sep 2011 Posted in  dancer

接上篇,加上分发过程查看的页面。这应该是一个很典型的翻页处理。 首先创建一个数据库表如下: mysqlcreate table websync_peer ( id int not null auto_increment primary key, begin_time timestamp not null default 0, end_time timestamp on update current_timestamp, url varchar(128) not null, customer varchar(20) not null, md5_hex char(32) default null ) engine=innodb; 然后把之前的peer_query()函数修改如下: perlsub peer_query { my $url = shift; #这里的database和session都需要其他plugin的配合,见之前博客,不贴重复代码了 my $sth = database->prepare('insert into websync_peer (begin_time, url, customer) value (now(), ?, ?)'); $sth->execute($url, session->{login}); }; 然后把gearman::client的功能改到mysql的UDFs内完成,做法见。 然后写翻页函数了~ perlget '/check' => sub { my $from = params->{page} || 1; my $user = session->{login}; my @urls; my $count_sql = 'select count(id) count from websync_peer where customer = ?'; my $count_sth = database->prepare($sql); $count_sth->execute( $user ); my $count = $count_sth->fetchrow_hashref->{count}; my $total_pages = int( $count / 20 + 1 ); return 'No url has been posted to purge.' unless $count; return 'Selected page number out of range.' if $from > $total_pages; my $url_sql = 'select id,url,begin_time from websync_peer where customer = ? order by id desc limit ?, 20'; my $url_sth = database->prepare($sql); $url_sth->execute( $user, ($from - 1) * 20 ); while ( my $ref = $sth->fetchrow_hashref ) { push @urls, $ref; }; template 'check', { 'urls' => \@urls, 'prev' => $from > 1 ? $from - 1 : 1, 'next' => $from < $total_pages ? $from + 1 : $total_pages, 'last' => $total_pages, }; }; 对应的check.tt如下: ```html<html><head> 继续阅读……


linux上获取本机ip的各种perl写法

20 Sep 2011 Posted in  linux

大家讨论使用 Gearman 做分布式处理时,各机需要注册一个独立的 job 作为信息反馈,但是为了方便,Gearman::Worker 脚本 register_function 代码又要通用,于是想到了使用各自的 ip 地址作为 job 命名~ 继续阅读……


写个同步分发系统(一)

16 Sep 2011 Posted in  dancer

写程序这个事情,其实规划最麻烦。比方我其实并没留意过一个完整的同步分发系统都有哪些功能。权做练手,想到哪些写哪些好了。 最基础的部分:一个提交文件列表的页面,自动分析文件列表然后从源下载文件,中心下载完成后通知边缘节点开始; 其次:文件完整性的校验,同步和分发的进度报表页面,失败报表的重试选择和报警; 再次:系统分用户,不同用户可选节点指定分发,只查看当前用户的报表。 以上。 今天先完成最基础的部分。还是用dancer -a websync创建应用。然后创建views/websync.tt如下: ```html </head><body> 继续阅读……


lbnamed代码浅读

08 Sep 2011 Posted in  perl

群里听说lbnamed这么个东东,用perl实现的动态DNS服务器。程序包括三个perl模块:Stanford::DNSserver模块、Stanford::DNS模块、LBCD模块;三个perl程序:lbnamed主程序、poller探测程序、slbcd监控程序(这个有C语言的版本)。 继续阅读……


用nginx区分文件大小做出不同响应

25 Aug 2011 Posted in  nginx

昨晚和前21v的同事聊天,说到我离职后一些技术上的更新。其中有个给某大客户(游戏下载类)的特殊需求设计,因为文件大小差距很大——估计是大版本和补丁的区别——又走的是同一个域名,而squid在响应比较大的文件时,尤其是初次下载的时候,性能比较差,所以拆成两组服务器,squid服务于较小的文件,通过pull方式从peer层获取,nginx服务于较大的文件,通过push方式由peer层分发同步。外部发布域名一律解析到squid服务器组上,请求透传到peer层的nginx,nginx分析这个url的content-length,如果大于阈值,则不返回文件,而是302到nginx服务器组的独立域名下的相应url去。 继续阅读……


CloudForecast学习笔记(三)

18 Aug 2011 Posted in  perl

第三篇,看web部分。主程序cloudforecast_web里主要就是调用CloudForecast::Web的run()函数,接下来去看CloudForecast::Web。 照例还是加载配置,然后这里主要多了两个accessor:allowfrom和front_proxy。用来定制acl和代理的。从下文可以看到,分别是采用了Plack::Middleware::Access和Plack::Middleware::ReverseProxy两个模块进行控制。 然后是主要部分,通过Plack::Builder建立$app: 1、初始化:”my $app = $self->psgi;”,这里是调用父层”use Shirahata -base;”的psgi()函数完成的。稍后再看这个。 2、包装:取出前面说的allowfrom和front_proxy部分后,代码如下: perl $app = builder { enable 'Plack::Middleware::Lint'; enable 'Plack::Middleware::StackTrace'; enable 'Plack::Middleware::Static', path => qr{^/(favicon\.ico$|static/)}, root =>Path::Class::dir($self->root_dir, 'htdocs')->stringify; $app; }; 真实加载顺序是倒序的,先加载Static.pm,用来服务静态文件,意即url路径为^/static/.*的,实际documentroot为./htdocs/;然后加载StackTrace.pm,用于开发调试的时候,向标准输出输出错误跟踪信息;最后是Lint.pm,用于检查请求/响应的格式是否正确。 然后是加载运行,使用Plack::Loader运行上面build出来的$app。方法如下: perl my $loader = Plack::Loader->load( 'Starlet', port => $self->port || 5000, host => $self->host || 0, max_workers => 2, ); $loader->run($app); 主要是两个参数,第一个是用来运行plack的服务器模块名称,常见的有starman/twiggy/corona/perlbal等等,这里写的这个Starlet,是基于HTTP::Server::PSGI模块添加预派生(prefork)/热部署(Server::Starter)/优雅重启等功能的一个服务器模块,原来叫的名字是”Plack::Server::Standalone::Prefork::Server::Starter”(简称PSSPSS)…… 继续阅读……


CloudForecast学习笔记(二)

18 Aug 2011 Posted in  perl

接下来看radar部分,也就是探测主程序cloudforecast_radar,其中主要就是调用CloudForecast::Radar中的run()函数。 首先还是惯例,调用ConfigLoader模块加载配置文件; 然后是%SIG信号的定义,用来之后自动重运行的; 然后一个while true死循环: 1、循环里用select(undef,undef,undef,0.5)实现一个0.5秒的sleep; 2、第一个if语句,用来判断是否是父进程,并使用无阻塞的waitpid($pid,WNOHANG)等待子进程完成——即$kid==-1; 3、第二个if语句,用来强制退出死循环,条件是收到%SIG信号; 4、第三个if语句,确认当前时间超过计划中的执行时间(即离上次执行时间最近的整5分钟点),开始执行探测——采用fork()派生子进程。 5、子进程内容是从之前获取的配置文件内,轮询每一台设备,最终调用run_host()函数执行。 然后又是两个if语句,接在while里的last之后,等待子进程全部完成的。 继续阅读……


CloudForecast学习笔记(一)

17 Aug 2011 Posted in  perl

近三天学习cloudforecast,这是一个日本SA写的分布式监控的perl项目。日本的运维水平和perl水平,都让人羡慕啊…… 项目介绍: http://blog.riywo.com/2011/02/27/043646 demo网址: http://editnuki.info:5000/ 下载地址: https://github.com/kazeburo/cloudforecast 粗略的看了主要文件,主要是用Class::完成的OO,Plack::MiddleWare::完成的web,Gearman::Worker调用Data::*里的具体模块完成对服务器的监控抓取,然后调用RRDs完成监控数据图像的更新,在启动分布式的情况下,则用Gearman::Client传输监控数据给调用RRDs的worker。 继续阅读……


cdn自主监控(六):数据展示页面

02 Aug 2011 Posted in  monitor

接下来进入我不擅长的页面部分了。规划页面分为side和main,side中提供时间选择框/类型下拉选择框和提交按钮;main中展示最后形成的chart。 时间选择框是用js和css完成的,这个网上有很多,不过要同时支持多浏览器和分钟级别的选项的,目前就发现一个好用的。下载地址如下:http://chenlinux.com/images/uploads/Calendar.zip 然后创建cachemoni/public/cdn.html如下: ```html 继续阅读……


cdn自主监控(五):生成charts图像

01 Aug 2011 Posted in  monitor

上篇完成了xml的输出,这篇开始说charts图像的生成。我们采用fusioncharts的免费版,之前博客有提到另一个amcharts,不过amcharts的免费版会在图像左上角加上自己amcharts.com的广告标识…… 从fusioncharts官网下载free版的压缩包,有20MB大,不过其中对我们这个小项目有用的只有MSLine.swf/MSBar2D.swf/fusioncharts.js等。 说明: 1、官网介绍上写了支持perl,不过下载包里只有php/asp/jsp/rails的class,没有perl的。所以还是得采用js的方式; 2、js下有setDataURL和setDataXML两个方法,不过官方强烈建议使用setDataURL方法,这种方法可接受的数据量比setDataXML大很多。 页面html很简单,加如下js代码即可: javascript</script> <script type="text/javascript"> var myChart = new FusionCharts("/Charts/MSBar2D.swf", "myChartId", "600", "500"); myChart.setDataURL(escape("/xml?begin=***&end=***&type=area")); myChart.render("chartdiv"); </script> 要点在这个escape(),如果URL里带参数的话,必须用escape()转码,不然的话第一个&之后的所有参数都会丢失掉! 在调试中注意到,为了忽略缓存,setDataURL()会在url最后跟上一个随机1-4位数字参数&curr=1234然后再发起请求。 现在就可以访问页面看看了~嗯,可以看到图像中的中文字有问题。这是因为fusioncharts不认utf8的中文,必须输出gbk或者gb2312的xml数据才行。所以需要修改一些dancer的charset配置,把config.yml里的charset: UTF-8改成charset: GBK。然后重新请求,中文就正确显示了。 如下图: 继续阅读……


cdn自主监控(四):输出xml数据

28 Jul 2011 Posted in  monitor

准备使用funsioncharts绘图,其采用xml数据,在绘制line图的时候,就要从mysql里读取数据,并输出成xml格式,相关配置如下: ```perl package cachemoni; use Dancer ‘:syntax’; use Dancer::Plugin::Database; use POSIX qw(strftime); 继续阅读……