• 粉丝日志首页

玩转Nodejs日志管理log4js

从零开始nodejs系列文章

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

张丹(Conan), 程序员Java,R,PHP,Javascript
weibo:@Conan_Z
blog: http://blog.fens.me
email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/nodejs-log4js/

前言

日志对任何的应用来说都是至关重要的。在Nodejs中使用express框架并没有自带的日志模块,我们可以选择log4js来完成日志记录的功能。

如果用过JAVA中log4j的同学,肯定对日志并不陌生,学习log4js会更得心应手的。

log4js

文章目录:

  1. 默认的控制台输出
  2. 通过log4js输出日志
  3. 配置log4js与express框架集成
  4. 根据项目配置log4js
  5. 优化log4js结构

 

1. 默认的控制台输出

我们使用express框架时,开发模式用node或者supervisor启动nodejs应用时,控制台都是显示如下的日志。


GET /css/bootstrap.min.css 304 1ms
GET /css/my.css 304 0ms
GET /js/bootstrap.min.js 304 4ms
GET /js/jquery-1.9.1.min.js 304 6ms
GET /js/holder.js 304 3ms
GET /cat/json/latest 200 6ms
GET /cat/json/master 200 4ms
GET /cat/json/classic 200 2ms
GET /about 200 6ms
GET /css/bootstrap.min.css 304 2ms
GET /css/my.css 304 2ms
GET /js/bootstrap.min.js 304 2ms
GET /js/jquery-1.9.1.min.js 304 1ms
GET /js/holder.js 304 1ms
GET /js/bootstrap.min.js 304 1ms
GET / 304 6ms
GET /js/jquery-1.9.1.min.js 304 2ms
GET /css/my.css 304 1ms
GET /css/bootstrap.min.css 304 1ms
GET /js/bootstrap.min.js 304 2ms
GET /js/holder.js 304 2ms
GET /cat/json/latest 200 3ms
GET /cat/json/master 200 2ms
GET /cat/json/classic 200 2ms
GET /admin/ 304 13ms
GET /css/bootstrap.min.css 304 3ms
GET /js/jquery-1.9.1.min.js 304 2ms
GET /css/my.css 304 2ms
GET /js/bootstrap.min.js 304 1ms
GET /js/holder.js 304 2ms

我们也可以在代码中,用console.log()打印一些控制台日志。

修改routes/index.js


exports.index = function(req, res){
	console.log("This is an index page!");
	res.render('index', {
  		title:'首页|moive.me',
  		page:'index'
  	});
};

访问页面,结果如下。


This is an index page!
GET / 304 19ms
GET /css/bootstrap.min.css 304 4ms
GET /css/my.css 304 2ms
GET /js/jquery-1.9.1.min.js 304 38ms
GET /js/holder.js 304 29ms
GET /js/bootstrap.min.js 304 28ms

这样的输出的结果,都是在控制台显示,一旦server重启日志就丢失了。对于程序开发来说,这样的输出已经够用了。但是在生产环境上,我们希望能把控制台的输出,保存到文件中,而且需要更多的信息,不仅仅是默认的简化的日志信息。

由于express框架没有日志功能,我们需要引入log4js包来完成这个功能。

2. 通过log4js输出日志

我们先可看一下,通过log4js输出的日志是什么样子的,下一节再介绍具体的配置。


This is an index page!
GET / 304 17ms
[2013-06-19 17:45:55.981] [INFO] normal - 127.0.0.1 - - "GET / HTTP/1.1" 304 - "http://localhost:3000/admin/" "Mozilla/5
.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"
GET /css/bootstrap.min.css 304 10ms
[2013-06-19 17:45:56.015] [INFO] normal - 127.0.0.1 - - "GET /css/bootstrap.min.css HTTP/1.1" 304 - "http://localhost:30
00/admin/crawler/youku" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110
 Safari/537.36"
GET /css/my.css 304 8ms
[2013-06-19 17:45:56.017] [INFO] normal - 127.0.0.1 - - "GET /css/my.css HTTP/1.1" 304 - "http://localhost:3000/admin/cr
awler/youku" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537
.36"
GET /js/jquery-1.9.1.min.js 304 19ms
[2013-06-19 17:45:56.031] [INFO] normal - 127.0.0.1 - - "GET /js/jquery-1.9.1.min.js HTTP/1.1" 304 - "http://localhost:3
000/admin/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.
36"
GET /js/bootstrap.min.js 304 13ms
[2013-06-19 17:45:56.037] [INFO] normal - 127.0.0.1 - - "GET /js/bootstrap.min.js HTTP/1.1" 304 - "http://localhost:3000
/admin/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

GET /js/holder.js 304 20ms
[2013-06-19 17:45:56.040] [INFO] normal - 127.0.0.1 - - "GET /js/holder.js HTTP/1.1" 304 - "http://localhost:3000/admin/
" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

相同的请求,控制台输出的结果多了很多,完整的web服务器的日志格式。
这才是生产环境需要的!信息更丰富,并且与nginx和apache是一样的格式。

3. 配置log4js与express框架集成

下载log4js包


~ npm install log4js
log4js@0.6.6 node_modules\log4js
├── dequeue@1.0.3
├── semver@1.1.4
├── async@0.1.15
└── readable-stream@1.0.2

修改app.js


~ vi app.js

var log4js = require('log4js');
log4js.configure({
  appenders: [
    { type: 'console' }, //控制台输出
    {
      type: 'file', //文件输出
      filename: 'logs/access.log', 
      maxLogSize: 1024,
      backups:3,
      category: 'normal' 
    }
  ]
});
var logger = log4js.getLogger('normal');
logger.setLevel('INFO');
...
//app.use(...)
//app.use(...)
app.use(log4js.connectLogger(logger, {level:log4js.levels.INFO}));
app.use(app.router);

我需要在app.js中进行log4js的配置。

appenders中配置了两个输出,一个是控制台输出,一个是文件输出。

appenders.type=file的对象,指定文件输出位置及文件大小,当超过maxLogSize大小时,会自动生成一个新文件。logs的文件目录要动手创建。
level:log4js.levels.INFO, 设置默认日志输出级别是INFO。

log4js的输出级别6个: trace, debug, info, warn, error, fatal

  • logger.trace(‘Entering cheese testing’);
  • logger.debug(‘Got cheese.’);
  • logger.info(‘Cheese is Gouda.’);
  • logger.warn(‘Cheese is quite smelly.’);
  • logger.error(‘Cheese is too ripe!’);
  • logger.fatal(‘Cheese was breeding ground for listeria.’);

如果输出级别是INFO,则不会打印出低于info级别的日志trace,debug,只打印info,warn,error,fatal。这样做的好处在于,在生产环境中我们可能只关心异常和错误,并不关心调试信息。从而大大减少日志的输出,能减少磁盘写入。而在开发环境中,我们可以需要打印非常多的信息,帮助开发人员定位错误,调试代码。

还有一个好处就是,代码中可以混有各种的日志打印代码。我们只要在一个配置文件中,修改输出级别,日志输出就会发生变化,不用修改所有的代码。如果所有地方都是console.log(),那么上线的时候,改动这个东西就要花很多时间。

 

4. 根据项目配置log4js

上一节中,介绍了log4js和express集成。但默认的配置可能并不合适我们的项目,还需要对log4js的参数进行一些调整。

1. 代替console.log()
增加replaceConsole配置,让所有console输出到日志中,以[INFO] console代替console默认样式。


~ vi app.js
var log4js = require('log4js');
log4js.configure({
  appenders: [
    { type: 'console' },{
      type: 'file', 
      filename: 'logs/access.log', 
      maxLogSize: 1024,
      backups:4,
      category: 'normal' 
    }
  ],
  replaceConsole: true
});

查看输出结果:


[2013-06-19 18:18:41.997] [INFO] console - This is an index page!
GET / 304 15ms
[2013-06-19 18:18:42.010] [INFO] normal - 127.0.0.1 - - "GET / HTTP/1.1" 304 - "http://localhost:3000/admin/" "Mozilla/5
.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"
GET /css/bootstrap.min.css 304 5ms
[2013-06-19 18:18:42.042] [INFO] normal - 127.0.0.1 - - "GET /css/bootstrap.min.css HTTP/1.1" 304 - "http://localhost:30
00/admin/crawler/youku" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110
 Safari/537.36"
GET /css/my.css 304 11ms
[2013-06-19 18:18:42.051] [INFO] normal - 127.0.0.1 - - "GET /css/my.css HTTP/1.1" 304 - "http://localhost:3000/admin/cr
awler/youku" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537
.36"
GET /js/jquery-1.9.1.min.js 304 35ms
[2013-06-19 18:18:42.089] [INFO] normal - 127.0.0.1 - - "GET /js/jquery-1.9.1.min.js HTTP/1.1" 304 - "http://localhost:3
000/admin/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.
36"
GET /js/holder.js 304 42ms
[2013-06-19 18:18:42.098] [INFO] normal - 127.0.0.1 - - "GET /js/holder.js HTTP/1.1" 304 - "http://localhost:3000/admin/
" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"
GET /js/bootstrap.min.js 304 11ms
[2013-06-19 18:18:42.101] [INFO] normal - 127.0.0.1 - - "GET /js/bootstrap.min.js HTTP/1.1" 304 - "http://localhost:3000
/admin/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"

2. 调整日志输出的格式


 app.use(log4js.connectLogger(logger, {level: level:log4js.levels.INFO, format:':method :url'}));

输出结果:

[2013-06-19 18:23:25.230] [INFO] console - This is an index page!
GET / 304 28ms
[2013-06-19 18:23:25.251] [INFO] normal - GET /
GET /css/bootstrap.min.css 304 5ms
[2013-06-19 18:23:25.287] [INFO] normal - GET /css/bootstrap.min.css
GET /css/my.css 304 3ms
[2013-06-19 18:23:25.292] [INFO] normal - GET /css/my.css
GET /js/jquery-1.9.1.min.js 304 15ms
[2013-06-19 18:23:25.310] [INFO] normal - GET /js/jquery-1.9.1.min.js
GET /js/holder.js 304 9ms
[2013-06-19 18:23:25.321] [INFO] normal - GET /js/holder.js
GET /js/bootstrap.min.js 304 17ms
[2013-06-19 18:23:25.338] [INFO] normal - GET /js/bootstrap.min.js

3. 自动调整日志输出级别

日志级别对应规则:
http responses 3xx, level = WARN
http responses 4xx & 5xx, level = ERROR
else, level = INFO

设置level为auto

 app.use(log4js.connectLogger(logger, {level: 'auto', format:':method :url'}));

下面日志为了对比方便我多打出了几行。

[2013-06-19 18:24:56.040] [INFO] console - This is an index page!
GET / 304 16ms
[2013-06-19 18:24:56.053] [WARN] normal - GET /
GET /css/bootstrap.min.css 304 9ms
[2013-06-19 18:24:56.086] [WARN] normal - GET /css/bootstrap.min.css
GET /css/my.css 304 9ms
[2013-06-19 18:24:56.097] [WARN] normal - GET /css/my.css
GET /js/jquery-1.9.1.min.js 304 26ms
[2013-06-19 18:24:56.128] [WARN] normal - GET /js/jquery-1.9.1.min.js
GET /js/holder.js 304 32ms
[2013-06-19 18:24:56.164] [WARN] normal - GET /js/holder.js
GET /js/bootstrap.min.js 304 1ms
[2013-06-19 18:24:56.166] [WARN] normal - GET /js/bootstrap.min.js
[2013-06-19 18:24:56.204] [INFO] normal - GET /cat/json/latest
GET /cat/json/latest 200 10ms
[2013-06-19 18:24:56.211] [INFO] normal - GET /cat/json/master
GET /cat/json/master 200 4ms
[2013-06-19 18:24:56.219] [INFO] normal - GET /cat/json/classic
GET /cat/json/classic 200 9ms
GET /img/movie/emptySmall.png 304 1ms
[2013-06-19 18:24:56.263] [WARN] normal - GET /img/movie/emptySmall.png

5. 优化log4js结构

应该有同学发现了,我们在配置log4js时会有一个问题。就是所有配置信息都是在app.js中做的,logger也是在这里直接定义的。如果在控制器(routes)想用log4js进行输出,我们现在拿不到logger的句柄。

修改app.js,

~ vi app.js

var log4js = require('log4js');
log4js.configure({
  appenders: [
    { type: 'console' },{
      type: 'file', 
      filename: 'logs/access.log', 
      maxLogSize: 1024,
      backups:4,
      category: 'normal' 
    }
  ],
  replaceConsole: true
});
//var logger = log4js.getLogger(name);
//logger.setLevel('INFO');
....
app.use(log4js.connectLogger(this.logger('normal'), {level:'auto', format:':method :url'}));
....

exports.logger=function(name){
  var logger = log4js.getLogger(name);
  logger.setLevel('INFO');
  return logger;
}

我们把logger单独定义出来,并且做为API暴露出来。

在index.js中使用logger输出

~ vi routes/index.js
var logger = require('../app').logger('index');
exports.index = function(req, res){
	console.log("This is an index page!");
	logger.info("This is an index page! -- log4js");

	res.render('index', {
  		title:'首页|moive.me',
  		page:'index'
  	});
};

打印出来结果

[2013-06-19 18:56:51.924] [INFO] console - This is an index page!
[2013-06-19 18:56:51.925] [INFO] index - This is an index page! -- log4js
GET / 304 17ms
[2013-06-19 18:56:51.938] [WARN] [default] - GET /
GET /css/bootstrap.min.css 304 5ms
[2013-06-19 18:56:51.978] [WARN] [default] - GET /css/bootstrap.min.css
GET /css/my.css 304 2ms
[2013-06-19 18:56:51.981] [WARN] [default] - GET /css/my.css
GET /js/jquery-1.9.1.min.js 304 2ms
[2013-06-19 18:56:51.984] [WARN] [default] - GET /js/jquery-1.9.1.min.js
GET /js/holder.js 304 3ms
[2013-06-19 18:56:51.989] [WARN] [default] - GET /js/holder.js
GET /js/bootstrap.min.js 304 9ms
[2013-06-19 18:56:52.002] [WARN] [default] - GET /js/bootstrap.min.js

这样我们就已经玩转log4js了,为部署到生产环境,做好了日志的准备工作。

 

转载请注明出处:
http://blog.fens.me/nodejs-log4js/

打赏作者

Dataguru北京线下聚会圆满成功

跨界知识聚会系列文章,“知识是用来分享和传承的”,各种会议、论坛、沙龙都是分享知识的绝佳场所。我也有幸作为演讲嘉宾参加了一些国内的大型会议,向大家展示我所做的一些成果。从听众到演讲感觉是不一样的,把知识分享出来,你才能收获更多。

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/dataguru-beijing-meeting-20130616/

title

嘉宾PPT分享下载:

感谢活动团队:

  • 发起人、组织者:张丹
  • 报名统计:于双海,何青
  • 场地赞助:何青
  • 通         知:张丹 
  • 主   持  人:李阳
  • 维持秩序 :于双海,何青
  • 摄   影  师:张丹,于双海

01

 

参加活动的同学:

姓名 公司 dataguruID 参加课程
张丹
bsspirit R, R展现,SAS,Hadoop, NoSQL,Oracle,Openstack, Kettle
李阳 中科辅龙 casliyang hadoop1
于双海  博彦科技 sunev_yu hadoop1
何青 微课网 heqingcool hadoop1
张宣彬 Oracle linou hadoop1
刘盛 金融机构 leonarding oracle系列
王非  当当网
阮宏博  浙江和仁科技有限公司 976073363@qq.com
李雪峰  浙江和仁科技有限公司
丁波  zejia 独角兽老头 R1
董红磊 董红磊
梁胜和  oracle海量架构、性能优化、SAS、R
邓奕 板凳总 Hadoop、NoSQL
马光东  亚信联创 27112 oracle深入课程

 

02

活动现场视频:

自我介绍

Nginx fastdfs图片系统–王非

大数据解决方案之基于用户位置分析的应用 – 张宣彬

Oracle 索引优化思路–案例分享 — 刘盛

数据分析平台规划–课程贯穿 — 张丹

转载请注明出处:
http://blog.fens.me/dataguru-beijing-meeting-20130616/

打赏作者

自己搭建VPS系列文章 之 动态IP解析

自己搭建VPS系列文章,介绍了如何利用自己的计算机资源,通过虚拟化技术搭建VPS。

在互联网2.0时代,每个人都有自己的博客,还有很多专属于自己的互联网应用。这些应用大部分都是互联网公司提供的。对于一些有能力的开发人员(geek)来说,他们希望做一些自己的应用,可以用到最新最炫的技术,并且有自己的域名,有自己的服务器。这时就要去租一些互联网上的VPS主机。VPS主机就相当于是一台远程的计算机,可以部署自己的应用程序,然后申请一个域名,就可以正式发布在互联网上了。本站“@晒粉丝” 就使用的Linode主机VPS在美国达拉斯机房。

其实,VPS还可以自己搭建的。只要我们有一台高性能的服务器,一个IP地址,一个路由。可以把一台高性能的服务器,很快的变成5台,10台,20台的虚拟VPS。我们就可以在自己的VPS上面的,发布各种的应用,还可以把剩余的服务器资源租给其他的互联网使用者。 本系列文章将分为以下几个部分介绍:“虚拟化技术选型”,“动态IP解析”,“在Ubuntu上安装KVM并搭建虚拟环境”,“VPS内网的网络架构设计”,“VPS租用云服务”。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/vps-ip-dns

vps-ip-dns

目录

  1. 什么时候会用到动态IP解析
  2. 环境准备
  3. 实现原理
  4. 动手实践

1. 什么时候会用到动态IP解析?

家用PC通过PPPoE(宽带连接)拨号上网,如果一天二天没有关机,我们会神奇的发现IP变了。通过PPPoE获得的IP并不是固定的,每隔一段时间IP会被重新分配一次。

创业初期租不起外面的服务器,所以只好把服务器放在家中,面向互联网用户提供服务。但如果IP天天变,我们总不能天天盯着,发现变了人工去修改对应用的域名重新绑定新IP。这个时候,就会想到动态IP解析技术了。这个领域最有名的程序就是“花生壳”。其实这个技术实现起来并不复杂,接下来我们自己开发一套动态IP解析的程序。

2. 环境准备:

  • 1台内网服务器A (拨号上网) (xx.xx.xx.xx),linux(cron, bash, curl)
  • 1台固定IP的外网服务器B(173.255.193.179) :  linux(bind9, PHP)
  • 1个域名:wtmart.com

动态IP解析

3. 实现原理:

  1. 把域名绑定到服务器B: ip.wtmart.com ==> 173.255.193.179
  2. 在服务器B创建一个web应用收集请求,并写入本地文件
  3. 服务器A每分钟向服务器B发送请求,告诉服务器B,服务器A的IP是什么。
  4. 服务器B收到A的IP,发现变化写入本地文件存储,并更新本地域名服务器(bind9),用新IP指向lin.wtmart.com
  5. 客户端机器C,手动选择DNS服务设置173.255.193.179。
  6. 客户端机器C,SSH远程登陆服务器A,ssh root@lin.wtmart.com

4. 下面我们一步一步实践一下:

1). 把域名绑定到服务器B: ip.wtmart.com ==> 173.255.193.179

wtmart.com的域名是从godaddy.com上面购买的,通过dnspod做域名解析,难得的好服务。

wtmart

注: 这里我们只需要关注ip.wtmart.com 其他的设置不用关心。

2). 在服务器B创建一个web应用收集请求,并写入本地文件

创建PHP程序


~ /deploy/dyip# pwd
/root/deploy/dyip
~ /deploy/dyip# ls -l
-rw-r--r-- 1 root root 38 Jun 2 13:40 getip.php
-rw-r--r-- 1 root root 13 Jun 12 03:52 ip
-rw-r--r-- 1 root root 807 Jun 2 15:52 sendip.php

接收IP的PHP脚本,sendip.php

~ vi sendip.php

<?php
#http://lin.wtmart.com/sendip.php?pwd=xxx
$content = file_get_contents('ip');
if ($_GET["pwd"] == 'xxx'){//简单认证
$ip = $_SERVER["REMOTE_ADDR"];
if ($content != $ip) {
$file = fopen('ip', 'w');
$result = fwrite($file, $ip);
fclose($file);

if ($fwrite === false) {
echo "update error!<br/>";
} else {
echo "Change to " . $ip;
echo "<br/>Write to DNS server";
}
} else {
echo "No change " . $ip;
}

} else {
echo "Sorry,you don't have permission<br/>";
echo "Server ip: " . $content;
}

简单认证是防止其他人,访问时IP被修改。

查看IP的PHP脚本,getip.php


~ vi getip.php
<?php
echo file_get_contents('ip');

IP写入到本地文件,ip


~ vi ip
116.24.133.86

现在116.24.133.86就是服务器A,所用的IP地址,这个地址每天都会改变。

配置PHP环境,我在这里就跳过了,也可以使用其他语言的程序。

 

3). 服务器A每分钟向服务器B发送请求,告诉服务器B,服务器A的IP是什么 

在服务器A,设置cron定时器。

*/1 * * * * curl http://ip.wtmart.com/sendip.php?pwd=xxx

通过curl实现每分钟,发送一次请求。

 

4). 服务器B收到A的IP,发现变化写入本地文件存储,并更新本地域名服务器(bind9),用新IP指向lin.wtmart.com

刚才的 sendip.php的脚本已经实现了,写入本地文件存储,接下来我们改一下sendip.php实现配置本地域名服务器(bind9)

修改sendip.php,增加rebind方法


~ vi sendip.php

<?php
#http://lin.wtmart.com/sendip.php?pwd=xxx
$content = file_get_contents('ip');
if ($_GET["pwd"] == 'xxx'){//简单认证
$ip = $_SERVER["REMOTE_ADDR"];
if ($content != $ip) {
$file = fopen('ip', 'w');
$result = fwrite($file, $ip);
fclose($file);

if ($fwrite === false) {
echo "update error!<br/>";
} else {
echo "Change to " . $ip;
echo "<br/>Write to DNS server";
rebind($ip);
}
} else {
echo "No change " . $ip;
}

} else {
echo "Sorry,you don't have permission<br/>";
echo "Server ip: " . $content;
}

# lin 在最后一行
function rebind($ip){
$f = "/etc/bind/db.wtmart.com";
$str=file_get_contents($f);
$a=preg_replace('/\\nlin(.+?)\\n/',"\nlin IN A ".$ip."\n",$str);
echo $a;
file_put_contents($f,$a);
exec('/etc/init.d/bind9 restart');
}

安装并配置域名服务器bind9


~ sudo apt-get install bind9

~ cd /etc/bind

# 打开域名转身的配置
~ vi named.conf.options
forwarders {
      8.8.8.8;
      8.8.4.4;
};

# 设置wtmart.com域
~ vi named.conf.local
zone "wtmart.com" {
     type master;
     file "/etc/bind/db.wtmart.com";
};

# 增加ip域名指向本地IP(服务器B),lin的域名指向服务器A的IP
~ vi db.wtmart.com
$TTL    604800
@       IN      SOA     wtmart.com. root.wtmart.com. (
                              2         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      wtmart.com.
@       IN      A       173.255.193.179
@       IN      AAAA    ::1

ip      IN      A       173.255.193.179

lin    IN    A    116.24.133.86

注: lin的域名,必须写到最后一行,并且上下都有空行。sendip.php中rebind方法。

重启bind9域名服务器


sudo /etc/init.d/bind9 restart

5). 客户端机器C,手动选择DNS服务设置173.255.193.179
linux配置DNS
linux-dns

win7配置DNS
win-dns

6). 客户端机器C,SSH远程登陆服务器A,ssh root@lin.wtmart.com
win7中命令行登陆
win-ssh

我们完成了 动态IP解析。 通过域名服务器(bind9),我们把动态IP和域名进行绑定。

另外,可能还有一些更简单的需求,比如服务器A的web工程,像这个功能我们在服务器B,配置一个nginx反向代理就可以实现了。

对于创业初期服务器放在家里的同学,希望对你们有用。

转载请注明出处:
http://blog.fens.me/vps-ip-dns

打赏作者

nodejs豆瓣爬虫

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/nodejs-crawler-douban/

node-crawler

目录:

  1. 类库介绍
  2. win7安装jquery – 失败
  3. ubuntu安装jQuery – 成功
  4. 豆瓣爬虫

1. 类库介绍

1. web项目,基于express3, ejs模板
2. 通过request抓取网页
3. 通过jQuery, jsdom, htmlparser提取网页内容

crawler

2. win7安装node-jquery – 失败

由于win7安装node-jquery的包报错,直接改成ubuntu下开发。
Ubuntu的Nodejs安装请参考:准备Nodejs开发环境Ubuntu


~ npm install jquery
D:\workspace\project\moiveme\node_modules\jquery\node_modules\contextify>node "D:\toolkit\nodejs\node_modules\npm\bin\no
de-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild
npm http 304 https://registry.npmjs.org/cssom
npm http GET https://registry.npmjs.org/cssom/-/cssom-0.2.5.tgz
npm http 304 https://registry.npmjs.org/request
npm http 304 https://registry.npmjs.org/cssstyle
npm http GET https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.3.tgz
npm http GET https://registry.npmjs.org/request/-/request-2.21.0.tgz
npm http 200 https://registry.npmjs.org/cssom/-/cssom-0.2.5.tgz
npm http 200 https://registry.npmjs.org/request/-/request-2.21.0.tgz
npm http 200 https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.3.tgz
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.Cpp.InvalidPlatform.Targets(23,7): error MSB8007: 项目“cont
ex
tify.vcxproj”的平台无效。平台为“x64”。您会看到此消息的可能原因是,您尝试在没有解决方案文件的情况下生成项目,并且为此
项目指定了并不存在的非默认平台。 [D:\workspace\project\moiveme\node_
modules\jquery\node_modules\contextify\build\contextify.vcxproj]
gyp ERR! build error
gyp ERR! stack Error: `C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe` failed with exit code: 1
gyp ERR! stack at ChildProcess.onExit (D:\toolkit\nodejs\node_modules\npm\node_modules\node-gyp\lib\build.js:267:23)
gyp ERR! stack at ChildProcess.EventEmitter.emit (events.js:98:17)
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:784:12)
gyp ERR! System Windows_NT 6.1.7601
gyp ERR! command "node" "D:\\toolkit\\nodejs\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild"
gyp ERR! cwd D:\workspace\project\moiveme\node_modules\jquery\node_modules\contextify
gyp ERR! node -v v0.10.5
gyp ERR! node-gyp -v v0.9.5
gyp ERR! not ok
npm ERR! weird error 1
npm ERR! not ok code 0

3. ubuntu安装node-jquery

ubuntu安装node-jquery还是有一些安装过程中的问题

  1. jsdom的依赖版本问题
  2. jQuery非jquery,两个包一字之差,其实是不一样的。

~ sudo npm install jsdom

安装可能会有错误,jsdom依赖的问题。修改packages.json文件,指定jsdom版本。


~ vi packages.json
"dependencies": {
"jsdom" : "https://github.com/tmpvar/jsdom/tarball/4cf155a1624b3fb54b2eec536a0c060ec1bab4ab"
}

继续安装依赖包,这里请使用jQuery包,不要用jquery会有错误。


~ sudo npm install jQuery
~ sudo npm install xmlhttprequest
~ sudo npm install request
~ sudo npm install htmlparser

安装完成。

4. 豆瓣爬虫

设计场景:对豆瓣电影进行爬取。
http://movie.douban.com/subject/11529526/
1

项目目录:


~ pwd
/home/conan/workspace/nodejs/nodejs-demo
~ ll
drwxr-xr-x 6 conan conan 4096 Jun 6 18:02 ./
drwxrwxr-x 4 conan conan 4096 Jun 6 14:19 ../
-rw-rw-r-- 1 conan conan 842 Jun 6 14:19 app.js
drwxr-xr-x 10 conan conan 4096 Jun 6 18:01 node_modules/
-rw-rw-r-- 1 conan conan 283 Jun 6 16:44 package.json
drwxr-xr-x 5 conan conan 4096 Jun 6 14:19 public/
drwxr-xr-x 2 conan conan 4096 Jun 6 15:59 routes/
drwxr-xr-x 2 conan conan 4096 Jun 6 14:19 views/

增加myUtil.js文件


~ vi myUtil.js
var MyUtil = function () {
};
var http = require('http');
var request = require('request');
MyUtil.prototype.get=function(url,callback){
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
callback(body,response.statusCode);
}
})
}
module.exports = new MyUtil();

修改控制器 routes/index.js


~ vi routes/index.js
var myUtil = require('../myUtil.js');
var $ = require('jQuery');
exports.index = function(req, res){
var url="http://movie.douban.com/subject/11529526";
console.log(url);
myUtil.get(url,function(content,status){
console.log("status:="+status);
res.send(content);
});
};

这里我们已经把content内容,输出到了本地程序里。
打开浏览器:http://192.168.1.104:3000

2

用jQuery提出红色的文字:


~ vi routes/index.js
var myUtil = require('../myUtil.js');
var $ = require('jQuery');
exports.index = function(req, res){
var url="http://movie.douban.com/subject/11529526";
console.log(url);
myUtil.get(url,function(content,status){
console.log("status:="+status);
var movie={}
movie.name = $(content).find('span[property="v:itemreviewed"]').text();
movie.director = $(content).find('#info span:nth-child(1) a').text();
console.log(movie);
res.send(content);
});
};

查看server的日志输出

http://movie.douban.com/subject/11529526
status:=200
{ name: '中国合伙人', director: '陈可辛' }
GET / 200 4480ms - 72.55kb

通过jQuery的xpath,我们很容易分析出“电影名”和“导演”的字段。
用Nodejs写爬虫代码几有短短几行,比起JAVA动一下就千行的代码量来说,让我们轻松了很多。

效率上,终于可以达到以1人顶100人的目的了。

希望我的介绍对你用处。

转载请注明出处:
http://blog.fens.me/nodejs-crawler-douban/

打赏作者

准备Nodejs开发环境Ubuntu

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

张丹(Conan), 程序员Java,R,PHP,Javascript
weibo:@Conan_Z
blog: http://blog.fens.me
email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/nodejs-enviroment/

 

nodejs-env

目录:

  1. 通过apt-get安装nodejs –  失败
  2. 从github下载源代码安装 –  成功
  3. 建立express工程,启动第一个项目

 

系统环境:

Ubuntu 12.04 LTS 64bit

1. 通过apt-get安装nodejs – 失败:


~ sudo apt-get install nodejs
~ sudo apt-get install npm

~ node -v
v0.6.12

~ npm -v
1.1.4

创建工作目录


~ mkdir workspace
~ mkdir workspace/nodejs
~ cd workspace/nodejs
~ pwd
/home/conan/workspace/nodejs

安装失败


sudo npm install express -g
npm http GET https://registry.npmjs.org/express
npm http 304 https://registry.npmjs.org/express
npm http GET https://registry.npmjs.org/connect/2.7.11
npm http GET https://registry.npmjs.org/commander/0.6.1
npm http GET https://registry.npmjs.org/range-parser/0.0.4
npm http GET https://registry.npmjs.org/mkdirp/0.3.4
npm http GET https://registry.npmjs.org/cookie/0.1.0
npm http GET https://registry.npmjs.org/buffer-crc32/0.2.1
npm http GET https://registry.npmjs.org/fresh/0.1.0
npm http GET https://registry.npmjs.org/methods/0.0.1
npm http GET https://registry.npmjs.org/send/0.1.0
npm http GET https://registry.npmjs.org/cookie-signature/1.0.1
npm http GET https://registry.npmjs.org/debug
npm http 304 https://registry.npmjs.org/commander/0.6.1
npm http 304 https://registry.npmjs.org/connect/2.7.11
npm http 304 https://registry.npmjs.org/range-parser/0.0.4
npm http 304 https://registry.npmjs.org/mkdirp/0.3.4
npm http 304 https://registry.npmjs.org/cookie/0.1.0
npm http 304 https://registry.npmjs.org/buffer-crc32/0.2.1
npm http 304 https://registry.npmjs.org/fresh/0.1.0
npm http 304 https://registry.npmjs.org/methods/0.0.1
npm http 304 https://registry.npmjs.org/send/0.1.0
npm http 304 https://registry.npmjs.org/cookie-signature/1.0.1
npm http 304 https://registry.npmjs.org/debug
npm ERR! error installing express@3.2.6
npm ERR! error rolling back express@3.2.6 Error: UNKNOWN, unknown error '/usr/local/lib/node_modules/express'

npm ERR! Unsupported
npm ERR! Not compatible with your version of node/npm: connect@2.7.11
npm ERR! Required: {"node":">= 0.8.0"}
npm ERR! Actual: {"npm":"1.1.4","node":"0.6.12"}
npm ERR!
npm ERR! System Linux 3.5.0-23-generic
npm ERR! command "node" "/usr/bin/npm" "install" "express" "-g"
npm ERR! cwd /home/conan/workspace/nodejs
npm ERR! node -v v0.6.12
npm ERR! npm -v 1.1.4
npm ERR! code ENOTSUP
npm ERR! message Unsupported
npm ERR! errno {}
npm http GET https://registry.npmjs.org/mime/1.2.6
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/conan/workspace/nodejs/npm-debug.log
npm not ok

系统提示, node和npm版本不兼容。可能是终于apt-get源没有更新造成的问题。

2. 从github下载源代码安装 – 成功

下面要找到兼容的版本,手动安装。
先卸载刚刚装的node和npm


~ sudo apt-get autoremove npm
~ sudo apt-get autoremove nodejs

找到nodejs的官方发布下载:https://github.com/joyent/node

在ubuntu中,先安装git


~ sudo apt-get install git

然后,从github下载nodejs源代码


~ git clone git://github.com/joyent/node.git
Cloning into 'node'...
remote: Counting objects: 100200, done.
remote: Compressing objects: 100% (28074/28074), done.
remote: Total 100200 (delta 78807), reused 90936 (delta 70473)
Receiving objects: 100% (100200/100200), 61.81 MiB | 698 KiB/s, done.
Resolving deltas: 100% (78807/78807), done.

进入node目录


~ cd node
~ pwd
/home/conan/workspace/nodejs/node

切换最新的release的版本v0.11.2-release


~ git checkout v0.11.2-release
Branch v0.11.2-release set up to track remote branch v0.11.2-release from origin.
Switched to a new branch 'v0.11.2-release'

进行安装


./configure
make
sudo make install

安装完成,查看node版本


~ node -v
-bash: /usr/bin/node: No such file or directory

提示错误,没有找到node,查一下node安装位置


~ whereis node
node: /usr/local/bin/node

增加软链接:node和npm到/usr/bin


~ sudo ln -s /usr/local/bin/node /usr/bin/node
~ sudo ln -s /usr/local/bin/npm /usr/bin/npm

我们再查看node和npm版本


~ node -v
v0.11.2
~ npm -v
1.2.21

下面安装express


~ sudo npm install express -g
express@3.2.6 /usr/local/lib/node_modules/express
├── methods@0.0.1
├── fresh@0.1.0
├── range-parser@0.0.4
├── cookie-signature@1.0.1
├── buffer-crc32@0.2.1
├── cookie@0.1.0
├── debug@0.7.2
├── commander@0.6.1
├── mkdirp@0.3.4
├── send@0.1.0 (mime@1.2.6)
└── connect@2.7.11 (pause@0.0.1, qs@0.6.5, bytes@0.2.0, cookie@0.0.5, formidable@1.0.14, send@0.1.1)

安装成功。

3. 建立express工程,启动第一个项目


~ express -e nodejs-demo
create : nodejs-demo
create : nodejs-demo/package.json
create : nodejs-demo/app.js
create : nodejs-demo/public
create : nodejs-demo/public/javascripts
create : nodejs-demo/public/images
create : nodejs-demo/public/stylesheets
create : nodejs-demo/public/stylesheets/style.css
create : nodejs-demo/routes
create : nodejs-demo/routes/index.js
create : nodejs-demo/routes/user.js
create : nodejs-demo/views
create : nodejs-demo/views/index.ejs
install dependencies:
$ cd nodejs-demo && npm install
run the app:
$ node app

安装依赖包


~ cd nodejs-demo
~ sudo npm install
express@3.2.6 node_modules/express
├── methods@0.0.1
├── fresh@0.1.0
├── range-parser@0.0.4
├── cookie-signature@1.0.1
├── buffer-crc32@0.2.1
├── cookie@0.1.0
├── debug@0.7.2
├── commander@0.6.1
├── mkdirp@0.3.4
├── send@0.1.0 (mime@1.2.6)
└── connect@2.7.11 (pause@0.0.1, qs@0.6.5, bytes@0.2.0, cookie@0.0.5, formidable@1.0.14, send@0.1.1)

启动程序


~ node app.js
Express server listening on port 3000

测试是否启动成功curl


~ sudo apt-get install curl
~ curl localhost:3000

<!DOCTYPE html>
<html>
<head>
<title>Express</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1>Express</h1>
<p>Welcome to Express</p>
</body>
</html>

nodejs的服务器日志:


GET / 200 6ms - 206b

好了,我们已经成功的在ubuntu中,准备好了nodejs的开发环境。下面就可以享受开发的乐趣了。

进阶的内容请继续看
从零开始nodejs系列文章
http://blog.fens.me/series-nodejs/

转载请注明出处:
http://blog.fens.me/nodejs-enviroment/

打赏作者