• Archive by category "操作系统"
  • (Page 2)

Blog Archives

用Puppet进行系统管理

Ubuntu实用工具系列文章,将介绍基于Linux ubuntu的各种工具软件的配置和使用。有些工具大家早已耳熟能详,有些工具经常用到但确依然陌生。我将记录我在使用操作系统时,安装及配置工具上面的一些方法,把使用心得记录下来也便于自己的以后查找和回忆。

关于作者:

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

转载请注明出处:
http://blog.fens.me/linux-manage-puppet/

linux-puppet

前言

系统运维本是一件枯燥,而且重复性强的工作,不停地搞命令占据了运维人员的大量时间。Puppet通过一种集中式管理的设计,让运维变得简单可控。管理员只需要在master节点修改配置,绑定的客户端节点就会自动同步配置,让命令行也能通过配置实现。

第一次尝试,从安装开始。

目录

  1. Puppet是什么?
  2. Puppet服务器安装及配置
  3. Puppet客户端安装及配置
  4. 注册puppet客户端到服务器端
  5. 例子:生成文件测试

1. Puppet是什么?

puppet是一种Linux、Unix、windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件、用户、cron任务、软件包、系统服务等。puppet把这些系统实体称之为资源,puppet的设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系。

puppet采用C/S星状的结构,所有的客户端和一个或几个服务器交互。每个客户端周期的(默认半个小时)向服务器发送请求,获得其最新的配置信息,保证和该配置信息同步。每个puppet客户端每半小时(可以设置)连接一次服务器端, 下载最新的配置文件,并且严格按照配置文件来配置服务器. 配置完成以后,puppet客户端可以反馈给服务器端一个消息. 如果出错,也会给服务器端反馈一个消息.

2台服务器的环境配置:

Master Server:

  • Linux Ubuntu 12.04.2 LTS 64bit
  • ip: 192.168.1.201
  • hostname: vm1
  • ruby: 1.8.7

Client Server:

  • Linux Ubuntu 12.04.2 LTS 64bit
  • ip: 192.168.1.202
  • hostname: vm2
  • ruby: 1.8.7

2. Puppet服务器安装及配置

  • 切换到root用户
  • 设置host
  • 安装Puppet服务器端

切换到root用户


~ sudo -i
~ whoami
root

设置host


~ hostname vm1
~ hostanme
vm1

~ vi /etc/hosts
127.0.0.1       localhost
192.168.1.201   vm1
192.168.1.202   vm2

2). 安装Puppet服务器端


#安装并启动Puppet服务器端
~ apt-get install puppetmaster

#检查端口8140
~ netstat -nlt |grep 8140
tcp        0      0 0.0.0.0:8140            0.0.0.0:*               LISTEN
   
#查看Puppet的版本
~ puppet -V
2.7.11

#启动Puppet服务器
~  puppet master --verbose --no-daemonize
notice: Starting Puppet master version 2.7.11

3). 配置Puppet服务器,在[master]标签下,增加certname设置


~ vi /etc/puppet/puppet.conf

[master]
certname=vm1 #增加服务器配置

#重启Puppet服务器
~ /etc/init.d/puppetmaster restart
* Restarting puppet master 

4). 查看Puppet服务器的证书


~ puppet cert --list --all
+ "vm1" (60:0E:1D:8F:80:0B:5D:7D:F8:8B:C7:C6:DF:CF:69:43)

+ 为已注册的证书

这样我们就完成了,服务器端的配置!接下来,继续进行客户端的配置。

3. Puppet客户端安装及配置

切换到root用户


~ sudo -i
~ whoami
root

设置host


~ hostname vm2
~ hostanme
vm2

~ vi /etc/hosts
127.0.0.1       localhost
192.168.1.201   vm1
192.168.1.202   vm2

2). 安装Puppet服务器端


#安装并启动Puppet客户端
~ apt-get install puppet
   
#查看Puppet的版本
~ puppet -V
2.7.11

3). 配置Puppet客户端,在[agent]标签下增加server设置


~ sudo vi /etc/puppet/puppet.conf

[agent]
server=vm1

4). 配置Puppet客户端default值,修改START设置


~ vi /etc/default/puppet

START=yes

设置START把no改为yes

重启Puppet客户端


~ /etc/init.d/puppet restart
* Restarting puppet agent

4. 注册puppet客户端到服务器端

1). 检查服务器端的证书


#服务器端操作
~ puppet cert --list --all
+ "vm1" (60:0E:1D:8F:80:0B:5D:7D:F8:8B:C7:C6:DF:CF:69:43)

2). 在服务器端(vm1)创建文件site.pp


#服务器端操作
~ sudo vi /etc/puppet/manifests/site.pp

node default {
  notify { "Hey ! It works !": }
}

3). 从客户端(vm2)向服务器端发起注册请求


#客户端操作
~ puppet agent -t
info: Creating a new SSL key for vm2
info: Caching certificate for ca
info: Creating a new SSL certificate request for vm2
info: Certificate Request fingerprint (md5): 15:45:D1:22:1B:97:6D:49:43:BC:93:D8:BB:4C:E1:99
Exiting; no certificate found and waitforcert is disabled

#如果之前生成发启过认证请求,则需要删除证书的目录
~ rm -rf /var/lib/puppet/ssl
~ puppet agent -t

4). 服务器端(vm1)查看客户端请求认证的列表


#服务器端操作
~ puppet cert --list
  "vm2" (15:45:D1:22:1B:97:6D:49:43:BC:93:D8:BB:4C:E1:99)

5). 服务器端(vm1)接受客户端的请求


#服务器端操作
~ puppet cert --sign vm2
notice: Signed certificate request for vm2
notice: Removing file Puppet::SSL::CertificateRequest vm2 at '/var/lib/puppet/ssl/ca/requests/vm2.pem'

#可以接受所有的请求
~ puppet cert -s -a

#查看认证后,查看服务器上公钥的位置
~ sudo ls  /var/lib/puppet/ssl/ca/signed/
vm1.pem  vm2.pem

6). 服务器端(vm1)查看的证书列表


#服务器端操作
~ puppet cert --list --all
+ "vm1" (B7:45:28:1B:AE:53:0B:D7:38:8E:66:70:6C:B8:13:A4)
+ "vm2" (FB:64:C7:38:DA:B4:C7:0B:E6:3B:85:86:9A:F4:61:C2)

7). 客户端(vm2)执行服务器设置的脚本site.pp


#客户端操作
~ puppetd --test
info: Caching certificate for vm2
info: Caching certificate_revocation_list for ca
info: Caching catalog for vm2
info: Applying configuration version '1383527011'
notice: Hey ! It works !
notice: /Stage[main]//Node[default]/Notify[Hey ! It works !]/message: defined 'message' as 'Hey ! It works !'
notice: Finished catalog run in 0.02 seconds

我们看到’Hey ! It works !’,被正常显示出来。

5. 例子:生成文件测试

1). 生成文件测试,在/tmp目录下生成一个文件hello.txt。

在服务器端修改一个文件site.pp


~ vi /etc/puppet/manifests/hello.pp

node default {
  notify { "Hey ! It works !": }
  file {
    "/tmp/hello.txt": content => "hello world";
  }
}

2). 在服务器端运行hello.pp文件


~ puppet apply /etc/puppet/manifests/site.pp
warning: Could not retrieve fact fqdn
warning: Host is missing hostname and/or domain: vm1
notice: /Stage[main]//Node[default]/File[/tmp/hello.txt]/ensure: defined content as '{md5}5eb63bbbe01eeed093cb22bb8f5acdc3'
notice: Hey ! It works !
notice: /Stage[main]//Node[default]/Notify[Hey ! It works !]/message: defined 'message' as 'Hey ! It works !'
notice: Finished catalog run in 0.02 seconds

#检查生成的文件
~ cat /tmp/hello.txt
hello world

3). 在客户端同步


~  puppet agent --test --server=vm1
info: Caching catalog for vm2
info: Applying configuration version '1383528346'
notice: /Stage[main]//Node[default]/File[/tmp/hello.txt]/ensure: defined content as '{md5}5eb63bbbe01eeed093cb22bb8f5acdc3'
notice: Hey ! It works !
notice: /Stage[main]//Node[default]/Notify[Hey ! It works !]/message: defined 'message' as 'Hey ! It works !'
notice: Finished catalog run in 0.07 seconds

#检查生成的文件
~ cat /tmp/hello.txt
hello world

这样我们就实现了第一个最简单的利用Puppet自动化运维的例子。出步尝试已经成功,接下来就像要深入研究Puppet到底能干什么,实现系统的高效运维。

转载请注明出处:
http://blog.fens.me/linux-manage-puppet/

打赏作者

Proftpd快速搭建FTP服务器

Ubuntu实用工具系列文章,将介绍基于Linux ubuntu的各种工具软件的配置和使用。有些工具大家早已耳熟能详,有些工具经常用到但确依然陌生。我将记录我在使用操作系统时,安装及配置工具上面的一些方法,把使用心得记录下来也便于自己的以后查找和回忆。

关于作者:

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

转载请注明出处:
http://blog.fens.me/linux-ftp-proftpd/

ftp-proftpd

前言

在Linux系统中,FTP服务器软件有很多,都已经成熟,像vsftpd, wu-ftp, Pure-FTPd等。但这些软件安装配置起来都比较麻烦,搭建个人的FTP服务器,还是Proftpd比较简单。

目录

  1. Proftpd介绍
  2. Proftpd安装
  3. Proftpd配置文件
  4. Proftpd使用场景
  5. 客户端访问

1. Proftpd介绍

Proftpd是一款开放源码的FTP服务器软件,它是原来世界范围使用最广泛的wu-ftpd的改进版,它修正了wu-ftpd的许多缺陷,在许多方面进行了重大的改进,其中一个重要变化就是它学习了Apache 的配置方式,使proftpd的配置和管理更加简单易懂。

有两种运行方式,独立服务器与超级服务器的子服务器。无论从安全性和稳定性,还是可配置性来说都是非常好的选择。

官方网站:http://www.proftpd.org/

2. Proftpd安装

系统环境

  • Linux Ubuntu 12.04.2 LTS 64bit server

安装Proftpd


~ sudo apt-get install proftpd

<hproftpd-install

选择“standalone”

查看proftpd状态


~ sudo /etc/init.d/proftpd status
ProFTPD is started in standalone mode, currently running.

~ ps -aux|grep ftp
proftpd   6674  0.0  0.1  94648  2092 ?        Ss   16:05   0:00 proftpd: (accepting connections)

#启动端口21
~ netstat -nltp|grep 21
tcp6       0      0 :::21                   :::*                    LISTEN      -

3. Proftpd配置文件

配置文件:/etc/proftpd/proftpd.conf


#配置服务器名
ServerName			""blog.fens.me FTP Server" 

#设置服务器运行模式,独立服务,或者被监管
ServerType			standalone 

#设置为默认服务器
DefaultServer			on 

#设置服务器进程运行使用的用户
User				proftpd

#设置服务器进程运行使用的组
Group			        nogroup

#设置关闭IPv6支持
UseIPv6			        off

#设置服务器接受请求的端口
Port				21 

#设置被动模式使用的端口范围
PassivePorts 			60000 65535

#设置用户上传文件的权限掩码
Umask				022

#设置用户被chroot锁定到的各自的Home目录
DefaultRoot			/ftp

#关闭欢迎信息显示
DeferWelcome			off 

#如果显示欢迎信息,则指定显示的文件
DisplayLogin			welcome.msg 

#指定切换文件夹时,显示的欢迎信息
DisplayChdir			.message 

#设置日志
SystemLog                       /var/log/proftp.log
TransferLog                     /var/log/proftp-transfer.log

#限定操作


<Limit SITE_CHMOD>
DenyAll
</Limit>

#设置匿名用户资源


<Anonymous "/ftp/c">
...
</Anonymous>

#配置存储目录权限


<Directory "/ftp/a/" >
<Limit ALL>
AllowUser x
AllowUser a1
DenyAll
</Limit>

<Limit CWD READ RETR DIRS>
AllowAll
</Limit>
</Directory>

Limit权限说明:

  • CWD : Change Working Directory 进入该目录
  • MKD : Make Directory 创建目录
  • RNFR : Rename from 更名
  • DELE : Delete 删除文件
  • RMD : Remove Directory 删除目录
  • READ : 可读
  • WRITE: 可写
  • STOR : 可上传
  • RETR : 可下载
  • DIRS : 允许列出目录
  • LOGIN: 允许登录
  • ALL : 全部

4. Proftpd使用场景

场景描述:某公司建立统一的FTP服务器(/ftp),公司有a部门(/ftp/a),b两个部门(/ftp/b),有独立的存储空间。

a1为a部门经理有对(/ftp/a)操作权限,a2为a部门员工只能读文件。

b1为b部门经理有对(/ftp/b)操作权限,b2为b部门员工只能读文件。

x为公司总经理,有对(/ftp)操作权限。

操作权限:


/ftp    -- x所有操作
/ftp/a  -- a1所有操作, a2只读
/ftp/b  -- b1所有操作, b2只读

命令操作:


# 创建FTP目录
sudo mkdir /ftp
sudo mkdir /ftp/a
sudo mkdir /ftp/b

# 创建用户组
sudo groupadd a
sudo groupadd b

Ubuntu系统配置nologin,与其他Linux稍有不同


~  sudo vi /etc/shells

# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/usr/bin/tmux
/usr/bin/screen
/usr/sbin/nologin

最后一行增加/usr/sbin/nologin

创建用户并设置nologin, 禁止FTP账户登陆


sudo useradd a1 -g a -s /usr/sbin/nologin
sudo useradd a2 -g a -s /usr/sbin/nologin
sudo useradd b1 -g b -s /usr/sbin/nologin
sudo useradd b2 -g b -s /usr/sbin/nologin
sudo useradd x -G a,b -s /usr/sbin/nologin

#设置账户密码
echo -e "a1:123" | sudo chpasswd
echo -e "a2:123" | sudo chpasswd
echo -e "b1:123" | sudo chpasswd
echo -e "b1:123" | sudo chpasswd
echo -e "x:123" | sudo chpasswd

#设置目录权限
sudo chown x /ftp
sudo chown a1:a /ftp/a
sudo chmod 770 /ftp/a
sudo chmod g+s /ftp/a
sudo chown b1:b /ftp/b
sudo chmod 770 /ftp/b
sudo chmod g+s /ftp/b

修改配置文件:/etc/proftpd/proftpd.conf


~ sudo vi /etc/proftpd/proftpd.conf

ServerName "blog.fens.me FTP Server"
ServerType standalone
DefaultServer on
Port 21
Umask 022
MaxInstances 30
User proftpd
Group nogroup
DefaultRoot /ftp
AllowOverwrite on

SystemLog /var/log/proftp.log
TransferLog /var/log/proftp-transfer.log

<Directory "/ftp/*">
<Limit CWD READ>
AllowAll
</Limit>
</Directory>

<Directory "/ftp/a/" >
<Limit ALL>
AllowUser x
AllowUser a1
DenyAll
</Limit>

<Limit CWD READ RETR DIRS>
AllowAll
</Limit>
</Directory>

<Directory "/ftp/b/" >
<Limit ALL>
AllowUser x
AllowUser b1
DenyAll
</Limit>

<Limit CWD READ RETR DIRS>
AllowAll
</Limit>
</Directory>

<Limit SITE_CHMOD>
DenyAll
</Limit>

重新服务器


~ sudo /etc/init.d/proftpd restart
 * Stopping ftp server proftpd        [ OK ]
 * Starting ftp server proftpd 

5. 客户端访问

客户端命令行:Win7 64bit Command

模拟a1用户登陆:


~ ftp

#建立连接
ftp> open 192.168.1.201
连接到 192.168.1.201。
220 ProFTPD 1.3.4a Server (blog.fens.me FTP Server) [::ffff:192.168.1.201]
用户(192.168.1.201:(none)): a1
331 Password required for a1
密码:
230 User a1 logged in

#查看目录 
ftp> dir
200 PORT command successful
150 Opening ASCII mode data connection for file list
drwxrws---   2 a1       a            4096 Nov  3 12:59 a
drwxrws---   2 b1       b            4096 Nov  3 12:25 b
226 Transfer complete
ftp: 收到 116 字节,用时 0.00秒 58.00千字节/秒。

ftp> cd a
250 CWD command successful

ftp> pwd
257 "/a" is the current directory

ftp> dir
200 PORT command successful
150 Opening ASCII mode data connection for file list
-rw-r--r--   1 a2       a           55723 Nov  3 12:56 36kryunjiasu.docx
-rw-r--r--   1 a1       a               4 Nov  3 12:24 test.txt
226 Transfer complete
ftp: 收到 139 字节,用时 0.00秒 69.50千字节/秒。

#上传文件
ftp> put c:\22.log
200 PORT command successful
150 Opening ASCII mode data connection for 22.log
226 Transfer complete
ftp: 发送 120 字节,用时 0.06秒 2.18千字节/秒。

#下载文件
ftp> get test.txt
200 PORT command successful
150 Opening ASCII mode data connection for test.txt (4 bytes)
226 Transfer complete
ftp: 收到 5 字节,用时 0.00秒 5000.00千字节/秒。

#尝试访问B目录,出错
ftp> cd ../b
550 ../b: No such file or directory

#退出
ftp> bye
221 Goodbye.

模拟a2用户登陆:


~ ftp

#建立连接
ftp> open 192.168.1.201
连接到 192.168.1.201。
220 ProFTPD 1.3.4a Server (blog.fens.me FTP Server) [::ffff:192.168.1.201]
用户(192.168.1.201:(none)): a2
331 Password required for a2
密码:
230 User a2 logged in

#查看目录 
ftp> dir
200 PORT command successful
150 Opening ASCII mode data connection for file list
drwxrws---   2 a1       a            4096 Nov  3 13:09 a
drwxrws---   2 b1       b            4096 Nov  3 12:25 b
226 Transfer complete
ftp: 收到 116 字节,用时 0.00秒 116.00千字节/秒。

#上传文件,出错
ftp> put c:\11.log
200 PORT command successful
550 11.log: Operation not permitted

#下载文件
ftp> get 22.log
200 PORT command successful
150 Opening ASCII mode data connection for 22.log (114 bytes)
226 Transfer complete
ftp: 收到 120 字节,用时 0.00秒 120000.00千字节/秒。

用Proftpd我们快速建立了一个公司内部的FTP服务器,比wu-ftpd要方便。

转载请注明出处:
http://blog.fens.me/linux-ftp-proftpd/

打赏作者

让Nodejs来管理定时任务later

从零开始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-cron-later/‎

nodejs-later

前言

一个完整的系统少不了定时任务,大多数情况我们都选用使用Linux CRON,通过操作系统命令进行定时任务。当我们要维护多台计算机,几十个,几百个定时任务的时候,用CRON会带来非常大的运维成本。可能写到程序中,就是一个不错的选择了。

Later提供了一个Nodejs的定时任务解决方案,让我来看看他是怎么工作的吧!!

目录

  1. 什么是定时任务?
  2. Later介绍
  3. Later安装
  4. Later基本使用
  5. Later Schedules – 设置时间表
  6. Later Time Periods – 时间定义和时间计算
  7. Later Modifiers – 行为修饰符
  8. Later Parsers – 规则解释器
  9. Later Occurrences – 时间控制
  10. Later Executing – 启动运行

1. 什么是定时任务?

定时任务(计划任务),是任务在约定的时间执行已经计划好的工作,这是表面的意思。在Linux中,我们经常用到 cron 服务器来完成这项工作。cron服务器可以根据配置文件约定的时间来执行特定的作务。比如我们可以在配置文件中约定每天早上4点,对httpd 服务器重新启动,这就是一个计划任务;

crontab文件的格式:M H D m d cmd.

  • M: 分钟(0-59)。
  • H:小时(0-23)。
  • D:天(1-31)。
  • m: 月(1-12)。
  • d: 一星期内的天(0~6,0为星期天)。

每两个小时

0 */2 * * * echo "Have a break now." >> /tmp/test.txt

晚上11点到早上8点之间每两个小时,早上八点

0 23-7/2,8 * * * echo "Have a good dream:)" >> /tmp/test.txt

每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点

0 11 4 * 1-3 command line

1月1日早上4点

0 4 1 1 * command line

关于CRON的介绍,摘自:http://baike.baidu.com/view/660015.htm

2. Later介绍

Later是一个基于Nodejs的工具库,用最简单的方式执行定时任务。Later可以运行在Node和浏览器中。

Later.js官方主页:http://bunkat.github.io/later/index.html

3. Later安装

Later可以运行在Node和浏览器中,分别用npm和bower进行依赖管理。关于NPM的介绍,请参考:快速创建基于npm的nodejs库, 关于Bower的介绍,请参考:bower解决js的依赖管理

系统环境

  • Linux: Ubuntu 12.04.2 LTS 64bit deskop
  • Nodejs: npm 1.2.21
  • node v0.11.2

安装later


~ cd /home/conan/nodejs
~ mkdir nodejs-later && cd nodejs-later

~ sudo npm install later
npm http GET https://registry.npmjs.org/later
npm http 200 https://registry.npmjs.org/later
npm http GET https://registry.npmjs.org/later/-/later-1.1.6.tgz
npm http 200 https://registry.npmjs.org/later/-/later-1.1.6.tgz
later@1.1.6 node_modules/later

没有其他包的依赖,这样就安装完成了!

4. Later基本使用

创建一个每5分钟启动的定时器规则,输出启动时间。

创建启动文件:app.js


~ vi app.js

var later = require('later');
var sched = later.parse.text('every 5 mins'),
    occurrences = later.schedule(sched).next(10);

for(var i=0;i<10;i++){
    console.log(occurrences[i]);
}

运程程序:


~ node app.js
Thu Dec 26 2013 10:45:00 GMT+0800 (CST)
Thu Dec 26 2013 10:50:00 GMT+0800 (CST)
Thu Dec 26 2013 10:55:00 GMT+0800 (CST)
Thu Dec 26 2013 11:00:00 GMT+0800 (CST)
Thu Dec 26 2013 11:05:00 GMT+0800 (CST)
Thu Dec 26 2013 11:10:00 GMT+0800 (CST)
Thu Dec 26 2013 11:15:00 GMT+0800 (CST)
Thu Dec 26 2013 11:20:00 GMT+0800 (CST)
Thu Dec 26 2013 11:25:00 GMT+0800 (CST)
Thu Dec 26 2013 11:30:00 GMT+0800 (CST)

5. Later Schedules - 设置时间表

Schedules模块用来设置定时规则,提供3种规则设置。

  • Basic schedules:基本时间表
  • Composite schedules: 组合时间表
  • Exception schedules: 异常时间表

1). Basic schedules:基本时间表

设置每日10:15am , 10:45am启动


var basic = {h: [10], m: [15,45]};

2). Composite schedules: 组合时间表

设置每日10:15am , 10:45am, 和17:40pm 启动


 var composite = [
    {h: [10], m: [15,45]},
    {h: [17], m: [30]}
  ];

3). Exception schedules: 异常时间表

用于设置一下无效的日期:设置 每年1月 和 每周一,六,日 时间表无效


var exception = [
    {M: [1]},
    {dw: [1,6,7]}
];

4). 程序实现

新建测试文件:schedules.js


~ vi schedules.js

var later = require('later');

var basic = {h: [10], m: [15,45]};
var composite = [
    basic,
    {h: [17], m: [30]}
];
var exception = [
    {M: [1]},
    {dw: [1,6,7]}
];

var sched = {
    schedules:composite,
    exceptions:exception
};

later.date.localTime();

console.log("Now:"+new Date());
var occurrences = later.schedule(sched).next(10);
for(var i = 0; i < occurrences.length; i++) {
    console.log(occurrences[i]);
}

运行程序


~ node schedules.js
Now:Thu Dec 26 2013 11:40:27 GMT+0800 (CST)
Thu Dec 26 2013 17:30:00 GMT+0800 (CST)
Mon Dec 30 2013 10:15:00 GMT+0800 (CST)
Mon Dec 30 2013 10:45:00 GMT+0800 (CST)
Mon Dec 30 2013 17:30:00 GMT+0800 (CST)
Tue Dec 31 2013 10:15:00 GMT+0800 (CST)
Tue Dec 31 2013 10:45:00 GMT+0800 (CST)
Tue Dec 31 2013 17:30:00 GMT+0800 (CST)
Mon Feb 03 2014 10:15:00 GMT+0800 (CST)
Mon Feb 03 2014 10:45:00 GMT+0800 (CST)
Mon Feb 03 2014 17:30:00 GMT+0800 (CST)

当前时间为:2013-12-26 11:40:27

从结果中看到,接下来的10个时间点。

  • 第1个:2013-12-26 17:30:00
  • 第2个:2013-12-30 10:15:00 (排除了2013-12-27,28,29的3天)
  • 第8个:2014-02-01 10:15:00 (排除了2014的1月份)

还有比这种方式,更便捷定义时间表的么!!太神奇了!

6. Later Time Periods - 时间定义和时间计算

Time Periods模块用于时间定义和时间计算。

1). 时间定义

在之前的代码中,我们是这样的定义的

{h: [17], m: [30]}

h代表小时,m代表分钟。

时间定义完整列表:

  • Second, s: 秒, 取值范围:[0-59]
  • minute, m:分, 取值范围:[0-59]
  • hour, h: 时, 取值范围:[0-23]
  • time, t: 秒每日, 取值范围:[0-86399]
  • day, D: 日, 取值范围:[1-31]
  • dayOfWeek, dw, d: 日每周, 取值范围:[1-7]
  • dayOfYear, dy: 日每年,取值范围:[1-365]
  • weekOfMonth, wm: 周每月,取值范围:[1-5]
  • weekOfYear, wy: 周每年,取值范围:[1-52]
  • month, M: 月,取值范围:[1-12]
  • year, Y: 年,取值范围:[1970-2099]

2). 时间计算

  • name: 名称
  • range: 取值范围计数
  • val(date): 当前时间段的值
  • isValid(date, value): 检验输入是否是当前时间段的值
  • extent(date): 取值范围
  • start(date): 开始时间点
  • end(date): 结束时间点
  • next(date, value): value之后的时间点
  • prev(date, value): value之前的时间点

3). 程序实现

新建测试文件:time.js


~ vi time.js

var later = require('later');
later.date.localTime();

var d = new Date();

console.log(d);
console.log(later.hour.name);
console.log(later.hour.range);
console.log(later.hour.val(d));
console.log(later.hour.isValid(d, 2));
console.log(later.hour.isValid(d, 12));
console.log(later.hour.extent());
console.log(later.hour.start(d));
console.log(later.hour.end(d));
console.log(later.hour.next(d, 5));
console.log(later.hour.prev(d, 21));

运行程序


~ node time.js

Thu Dec 26 2013 12:30:42 GMT+0800 (CST)
hour
3600
12
false
true
[ 0, 23 ]
Thu Dec 26 2013 12:00:00 GMT+0800 (CST)
Thu Dec 26 2013 12:59:59 GMT+0800 (CST)
Fri Dec 27 2013 05:00:00 GMT+0800 (CST)
Wed Dec 25 2013 21:59:59 GMT+0800 (CST)

输出结果的解释:

  • 当前时间:2013-12-26 12:30:42
  • 以小时定义时间
  • 每小时3600个计数点
  • 当前时间段的的值是12
  • 检查2不是当前时间段的值
  • 检查12不是当前时间段的值
  • 取值范围[0,23]
  • 当前时间段的开始时间点:12:00:00
  • 当前时间段的结束时间点:12:59:59
  • 下一个周期第5个时间段开始点:2013-12-27 05:00:00
  • 上一个周期第21个时间段结束点:2013-12-25 21:59:59

7. Later Modifiers - 行为修饰符

Later可以编写自定义修饰符,可以改变现有的时间周期的行为,通过 _(modifier-id) 这样的格式定义。

  • after(_a): 之后时间修饰符
  • before(_b): 之前时间修饰符

1). after(_a)

以小时定义,设置17:00pm之前都是合法的时间


var demo1_a = {schedules: [{h_a: [17]}]};

#等价定义
var demo1 = {schedules: [{h: [17,18,19,20,21,22,23]}]};

2). before(_b)

以小时定义,设置17:00pm之后都是合法的时间


var demo2_b = {schedules: [{h_b: [17]}]};

#等价定义
var demo2 = {schedules: [{h: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]}]};

3). 程序实现

新建文件:modifiers.js


~ vi modifiers.js

var later = require('later');
later.date.localTime();

console.log("Now:"+new Date());

var demo1_a = {schedules: [{h_a: [17]}]};
var demo2_b = {schedules: [{h_b: [17]}]};

var occurrences = later.schedule(demo1_a).next(3);
for(var i = 0; i < occurrences.length; i++) {
    console.log(occurrences[i]);
}

occurrences = later.schedule(demo2_b).next(3);
for(var i = 0; i < occurrences.length; i++) {
    console.log(occurrences[i]);
}

运行程序


~ node modifiers.js

Now:Thu Dec 26 2013 13:04:06 GMT+0800 (CST)
Thu Dec 26 2013 17:00:00 GMT+0800 (CST)
Thu Dec 26 2013 18:00:00 GMT+0800 (CST)
Thu Dec 26 2013 19:00:00 GMT+0800 (CST)
Thu Dec 26 2013 13:04:06 GMT+0800 (CST)
Thu Dec 26 2013 14:00:00 GMT+0800 (CST)
Thu Dec 26 2013 15:00:00 GMT+0800 (CST)

当前时间:2013-12-26 13:04:06

  • 17点后的时间表(h_a):17:00:00
  • 17点前的时间表(h_b):13:04:06

Later支持我们可以定义自己的修饰符,有兴趣的同学自己查文档吧。

8. Later Parsers - 规则解释器

Parsers模块提供了3种规则解释器,方便定义时间表。

  • Recur: 链式API定义
  • Cron Parser: CRON格式定义
  • Text Parser:自然语言定义

1). Recur: 链式API定义

设置每小时第5分0秒启动


var sched = later.parse.recur().on(5).minute();

时间定义API


  second();
  minute();
  hour();
  time();
  dayOfWeek();
  dayOfWeekCount();
  dayOfMonth();
  dayOfYear();
  weekOfMonth();
  weekOfYear();
  month();
  year();

时间计算API

  • on(vals): 设置时间值
  • first(): 最小的时间值
  • last(): 最大的时间值
  • onWeekend(): 周末,等价于on(1,7).dayOfWeek()
  • onWeekday(): 工作日,等价于on(2,3,4,5,6).dayOfWeek()
  • every(val): 循环每个时间
  • after(val): 在之后
  • before(val): 在之前
  • startingOn(val): 每个时间段开始的偏移量
  • between(start, end): 在两个时间之间
  • and():
  • except():
  • customPeriod(id):
  • customModifier(id, vals):

2). Cron Parser: CRON格式定义

通过原CRON格式进行定义。

设置每小时第5分0秒启动


var cron = later.parse.cron('5 * * * *');

3). Text Parser:自然语言定义

通过关键字格式进行定义。


var text = later.parse.text('every 5th mins');

9. Later Occurrences - 时间控制

时区设置


//默认UTF时区
later.date.UTC();

//设置本地时区
later.date.localTime();

构造对象


var schedule = {schedules: [{m: [5]}]};
var occurrences = later.schedule(schedule);

时间控制API

  • later.schedule(schedule).next(count, start, end): 取下N个有效时间点
  • later.schedule(schedule).prev(count, start, end): 取上N个有效时间点
  • later.schedule(schedule).nextRange(count, start, end): 取下N个有效时间段
  • later.schedule(schedule).prevRange(count, start, end): 取上N个有效时间段

10. Later Executing - 启动运行

Executing模块定义了setTimeout和setInterval两种方式,实现运行。

  • setTimeout: 设置一段时间后运行,只运行1次
  • setInterval: 循环运行,直到clear

1). setTimeout

定义:5秒后运行,只运行一次!

新建文件:settimeout.js


~ vi settimeout.js

var later = require('later');
later.date.localTime();

console.log("Now:"+new Date());

var sched = later.parse.recur().every(5).second(),
    t = later.setTimeout(function() {
        test(5);
    }, sched);

function test(val) {
   console.log(new Date());
   console.log(val);
}

运行程序


~ node settimeout.js
Now:Thu Dec 26 2013 14:12:36 GMT+0800 (CST)
Thu Dec 26 2013 14:12:40 GMT+0800 (CST)
5

2). setInterval

定义:2秒后运行,循环运行,直到15秒后,clear停止!

新建文件:setinterval.js


~ vi setInterval.js

var later = require('later');
later.date.localTime();

console.log("Now:"+new Date());

var sched = later.parse.recur().every(2).second(),
    t = later.setInterval(function() {
        test(Math.random(10));
    }, sched);

function test(val) {
   console.log(new Date());
   console.log(val);
}

setTimeout(function(){
   t.clear();
   console.log("Clear");
},15*1000);

运行程序


~  node setinterval.js
Now:Thu Dec 26 2013 14:17:54 GMT+0800 (CST)
Thu Dec 26 2013 14:17:56 GMT+0800 (CST)
0.5084630874916911
Thu Dec 26 2013 14:17:58 GMT+0800 (CST)
0.47506075259298086
Thu Dec 26 2013 14:18:00 GMT+0800 (CST)
0.957129133399576
Thu Dec 26 2013 14:18:02 GMT+0800 (CST)
0.7480122991837561
Thu Dec 26 2013 14:18:04 GMT+0800 (CST)
0.9212428922764957
Thu Dec 26 2013 14:18:06 GMT+0800 (CST)
0.030472515616565943
Thu Dec 26 2013 14:18:08 GMT+0800 (CST)
0.9528024469036609
Clear

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

打赏作者

tty.js打通浏览器与Linux的通道

从零开始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-linux-sh-tty/

nodejs-linux-tty

前言

长久以来,远程连接Linux服务器时,已经习惯了用SSH客户端(Putty,SshClient),黑底白字的显示方式,在记忆里留下了深深地烙印。如果有一种新的连接方式,不需要安装额外客户端软件,通过web浏览器就可以实现,那么一定会让你惊喜吧!

tty.js就实现这个功能,让编程更多乐趣,更少磨难。

目录

  1. Linux Shell介绍
  2. tty.js介绍
  3. tty.js安装
  4. tty.js使用

1. Linux Shell介绍

Linux Shell(Command Line Interface shell ,即CLI shell)是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行。

实际上Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核。不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序。Shell编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应用程序具有同样的效果。

上文介绍,摘自:http://baike.baidu.com/view/573462.htm

一般Linux作为服务器都放在机房,通过ssh远程登录Linux主机。Putty是SSH的一种客户端实现,下面我们用putty进行远程登陆。

tty-putty-login

登陆的的命令界面

tty-putty

2. tty.js介绍

tty.js是一个支持在浏览器中运行的命令行窗口,基于node.js平台,依赖socket.io库,通过websocket与Linux系统通信。

特性:

  • 支持多tab窗口模型
  • 支持vim,mc,irssi,vifm语法
  • 支持xterm鼠标事件
  • 支持265色显示
  • 支持session

github源代码:https://github.com/chjj/tty.js

3. tty.js安装

系统环境:

  • Linux: Ubuntu 12.04 LTS 64bit
  • node: v0.6.12
  • npm: 1.1.4

安装tty.js


~ mkdir /home/conan/nodejs/nodejs-tty
~ cd /home/conan/nodejs/nodejs-tty

~ sudo npm install tty.js
tty.js@0.2.13 node_modules/tty.js
├── term.js@0.0.3
├── pty.js@0.2.3
├── express@3.1.0 (methods@0.0.1, fresh@0.1.0, range-parser@0.0.4, cookie-signature@0.0.1, debug@0.7.3, buffer-crc32@0.1.1, cookie@0.0.5, commander@0.6.1, mkdirp@0.3.3, send@0.1.0, connect@2.7.2)
└── socket.io@0.9.13 (base64id@0.1.0, policyfile@0.0.4, redis@0.7.3,socket.io-client@0.9.1

配置tty.js,新建两个文件

  • tty.js:node的启动文件
  • .tty.js:参数的配置文件

1). tty.js
设置参数:

  • 登陆账号:foo
  • 登陆密码:bar
  • 脚本方言:bash
  • web访问端口:8000

~ vi tty.js

var tty = require('tty.js');

var app = tty.createServer({
  shell: 'bash',
  users: {
    foo: 'bar'
  },
  port: 8000
});

app.get('/foo', function(req, res, next) {
  res.send('bar');
});

app.listen();

2). .tty.js


~ vi .tty.js

{
  "users": {
    "hello": "world"
  },
  "https": {
    "key": "./server.key",
    "cert": "./server.crt"
  },
  "port": 8080,
  "hostname": "127.0.0.1",
  "shell": "sh",
  "shellArgs": ["arg1", "arg2"],
  "static": "./static",
  "limitGlobal": 10000,
  "limitPerUser": 1000,
  "localOnly": false,
  "cwd": ".",
  "syncSession": false,
  "sessionTimeout": 600000,
  "log": true,
  "io": { "log": false },
  "debug": false,
  "term": {
    "termName": "xterm",
    "geometry": [80, 24],
    "scrollback": 1000,
    "visualBell": false,
    "popOnBell": false,
    "cursorBlink": false,
    "screenKeys": false,
    "colors": [
      "#2e3436",
      "#cc0000",
      "#4e9a06",
      "#c4a000",
      "#3465a4",
      "#75507b",
      "#06989a",
      "#d3d7cf",
      "#555753",
      "#ef2929",
      "#8ae234",
      "#fce94f",
      "#729fcf",
      "#ad7fa8",
      "#34e2e2",
      "#eeeeec"
    ]
  }
}

4. tty.js使用

启动tty.js服务器


~ node tty.js
[tty.js] You should sha1 your user information.
[tty.js] Listening on port 8000.

打开web界面:http://192.168.1.20:8000

登陆后,我们就可以在web上使用Linux命令了,与putty是一样的

tty-console

使用起来比Putty爽多了!!

非常简单地配置,就搭建了一个WebShell服务器端程序。技术正在一点点的改变着世界,你是否发现了?!

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

打赏作者

websocket服务器监控

从零开始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-websocket-monitor/

monitor

前言
Websocket技术的强大之处在于,打通了浏览器和服务器的双向通信的高速通道。有了如此神器,我们就可以在web上面“为所欲为”了。

在web上面,模拟一个Shell窗口,已经不稀奇了。我们再通过shell获得Linux系统(CPU,IO)信息,时时返回到web端,通过Highcharts生成系统监控图,是不是很高端!?

快动起来吧,你也可以做到的。

目录

  1. 系统架构设计
  2. 通过Shell获得CPU及IO信息
  3. 创建nodejs项目
  4. 实现websocket服务器端
  5. 实现websocket客户端
  6. 用Highcharts生成时时系统监控图

1. 系统架构设计

monitor-architect

我的系统环境:

  • Linux: Ubuntu 12.04.2 LTS 64bit deskop
  • Nodejs: npm 1.2.21, node v0.11.2

~ uname -a
Linux conan-deskop 3.5.0-23-generic #35~precise1-Ubuntu SMP Fri Jan 25 17:13:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
~ cat /etc/issue
Ubuntu 12.04.2 LTS \n \l

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

2. 通过Shell获得CPU及IO信息

安装软件包sysstat

sudo apt-get install sysstat

配置sysstat


~ sudo vi /etc/default/sysstat
ENABLED="true"

~ sudo /etc/init.d/sysstat restart

查看CPU的使用情况


~ sar  1
Linux 3.5.0-23-generic (conan-deskop)   2013年08月23日  _x86_64_        (2 CPU)
18时13分39秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
18时13分40秒     all      0.52      0.00      0.52      0.00      0.00     98.96
18时13分41秒     all      0.52      0.00      0.52      0.00      0.00     98.96
18时13分42秒     all      0.00      0.00      0.52      0.00      0.00     99.48
18时13分43秒     all      0.00      0.00      1.03      0.00      0.00     98.97
18时13分44秒     all      0.00      0.00      0.52      0.00      0.00     99.48

我们只关系idle的情况。公式:CPU时间 = 100 – idle

查看内存的情况


~ sar -r 1
Linux 3.5.0-23-generic (conan-deskop)   2013年08月23日  _x86_64_        (2 CPU)
18时14分30秒 kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact
18时14分31秒    749672   1301452     63.45    123460    643808   2205152     53.18    716128    440348
18时14分32秒    749672   1301452     63.45    123460    643808   2205152     53.18    716128    440348
18时14分33秒    749672   1301452     63.45    123460    643808   2205152     53.18    716128    440348
18时14分34秒    749672   1301452     63.45    123460    643808   2205152     53.18    716128    440348

我们只关系memused的情况。公式:内存用量 = 100 – memused

3. 创建nodejs项目

创建一个express3的项目, 还没有装好nodejs环境的同学,请参考:准备Nodejs开发环境Ubuntu


~ cd /home/conan/nodejs
~ express -e nodejs-alert
~ cd nodejs-alert
~ sudo npm install

实现websocket通信,我们还需要安装socket.io


~ sudo npm install socket.io

4. 实现websocket服务器端

修改app.js文件,webscoket的实现用到socket.io,读取系统进程用到child_process。


var express = require('express')
  , path = require('path')
  , app = express()
  , server = require('http').createServer(app)
  , io = require('socket.io').listen(server)
  , worker = require('child_process');

// 其他代码省略
....

5. 实现websocket客户端

1). 首先是view/alert.html


~ vi view/alert.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Socket.io - System Alert</title>
<script src="javascripts/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="javascripts/sysAlert.js"></script>
</head>
<body>
<h1>Socket.io - System Alert</h1>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
<script src="javascripts/highcharts/highcharts.js"></script>
<script src="javascripts/highcharts/modules/exporting.js"></script>
</body>
</html>

2). 下载必须的jquery.min.js和highcharts的整个库
3). 增加 javascripts/sysAlert.js 文件,用于客户端的实现。

  • 调用socket.io实现和服务器的通信
  • 调用Highcharts生成动态图

    // highcharts部分代码
    Highcharts.setOptions({
        global: {
            useUTC: false
        }
    });

    $('#container').highcharts({
        chart: {
            type: 'spline',
            animation: Highcharts.svg,
            marginRight: 10
        },
    
    // 代码省略
    ....
    });

    //// socket.io部分代码
    var socket = io.connect('http://192.168.1.20');
    socket.on('system', function (data) {

    // 代码省略
    ...
    });

下面是生成的 系统监控动态图!

6. 用Highcharts生成时时系统监控图

alert

内存,占用情况大概为84%,保持稳定。
CPU,占用情况。每次CPU有变化时,我都在做矩阵计算。

R语言矩阵计算代码


a<-matrix(1:1000000,ncol=1000)->b
b %*% a

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

打赏作者