推荐几本 Unix/Linux 经典书

几天前答应过一位新 VPS 客户,推荐一点 Linux 书,今天静下来写文才发现推荐书其实不是这么容易,至少应该知道一点读书人的背景,是入门、进阶还是高级,阅读习惯啊、方式啊;有人喜欢看例子书,边看边操作学得快;有的人喜欢先读原理,后操作。

现在每年增加的信息量比过去几百年还要多,不过好书还是那么少,经过历史考验的经典书就更少了,每个领域的经典书就那么几本,作为初学者应该首先看完该领域的经典书,然后再看其他的流行好书。

选择经典书是因为,我们实在没有时间花在烂书上,好书能更快更好的帮助我们理解内容,好书是一种享受,你不会觉得读书是一种辛苦。选择英文书是因为,这些经典书的英文都写得朴实、简单,不超过大学四级的阅读水平,长时间侵淫英文书可以为自己以后学习和工作打好基础。在工作中,最新最好最权威的资料都是英文的,翻译过来的二手资料不放心,做技术这行迟早要用英语混日子~

下面是 vpsee 看过的一些好书,有些书至今还放在桌头翻阅,这些经典不管怎么过分推荐和转载都不过分。

Linux 入门

Running LinuxLinux in a Nutshell 都是很棒的 Linux 入门书,如果你是计算机专业出身,只需要这两本书就可以了,这两本书都包括一些初级系统管理内容,Linux in a Nutshell 稍微难一点,建议阅读顺序是先 Running Linux 后 Linux in a Nutshell.

系统管理和网络

UNIX System Administration Handbook 可能是系统管理方面最权威的的一本大部头百科全书式著作,第一版本是1989年发行的,以后一直是 Unix 系统管理的方面的经典,其作者在2002年发布了对应的 Linux Administration Handbook 第一版,然后又成了 Linux 系统管理的必读,终于在2010年的时候作者把这两本书合为一本 UNIX and Linux System Administration Handbook.

Essential System Administration 是另一个 Unix/Linux 系统管理的经典书,可以替代 UNIX and Linux System Administration Handbook,不过建议两本都看看。

TCP/IP Illustrated, Volume 1: The Protocols 是理解 TCP/IP 协议的必读经典,书的内容不涉及具体的网络管理命令,也不讨论如何架设各种服务器,主要讨论 TCP/IP 各层协议是如何工作的,不管你是 System Administrator, Network Administrator, DevOps 还是 System Programmer 这本书都必读,就算今天用 Django, Ruby on Rails 之类的框架编程也应该了解一下底层 HTTP 协议是如何工作的,网络包是如何一层一层的封装、解封的。TCP/IP Illustrated 三部曲的另外两本也很经典,不过太窄太具体,除非你是 TCP/IP 协议设计者或网络栈码农,看 TCP/IP Illustrated, Volume 2: The Implementation 的用处不是很大。

系统编程

The UNIX Programming Environment 是两位 UNIX 大师 Brian W. Kernighan 和 Rob Pike 的合著,UNIX/Linux 编程入门的最好读物,字里行间里浸透了 UNIX 的哲学和设计思想。

The C Programming Language 可能有人会问为啥学 Unix/Linux 要懂 C 语言,C 是 Unix/Linux 的核心,想继续深入理解 Unix/Linux 必须懂点 C 语言,不然下面一些书没法继续读,C 语言还是一种优美、高效的语言,每个程序员都应该会(个人观点)。

Advanced Programming in the Unix Environment 是 Unix/Linux 编程的经典必读书,Unix 大师级作者 Richard Stevens 的巨著,事实上 Richard Stevens 的每本书都是巨著。

Unix Network Programming 是 Richard Stevens 另一巨著,这本经典 Unix 网络编程书可看作上面那本的补充。

编程还应该包括 shell 编程,这里没有单独拿出来推荐是因为因为上面推荐的入门和系统管理书里面都或多或少包括了一些 shell 编程基础知识。

操作系统原理和内核

Operating Systems: Design and Implementation 是操作系统原理的经典书,讲系统原理的还有另一本经典恐龙书 Operating System Concepts,我个人更喜欢前一本一些,理论加实践,书的作者在大学教书的时候没能找到满意的操作系统来教学自己写了一个 Minix,Linus Torvalds 发现 Minix 太简单不实用自己写了一个 Linux,貌似牛人都有共同的特点,不满意就自己造一个~,修改 Minix 内核是很有趣的事情,换工作后一直没机会再玩 Minix.

Linux Device Drivers 是内核编程的入门读物,难得这本经典书还是免费的。

Understanding the Linux Kernel 是 Linux 内核方面的经典,看这本书之前最好看过一些上面讲操作系统原理的书,不要指望看一遍就把这本书都搞懂,理解内核难点的地方在于内核之间的子系统是独立又是交叉的,又缺少实际可运行可修改的例子,不像 web 编程,改几行代码就可以立刻看到效果,所以内核学习是个痛苦的过程,这本书有助于建立一幅完整的 Linux 内核图景。

安装和使用 Elasticsearch

Elasticsearch 是开源搜索平台的新成员,实时数据分析的神器,发展迅猛,基于 Lucene、RESTful、分布式、面向云计算设计、实时搜索、全文搜索、稳定、高可靠、可扩展、安装+使用方便,介绍都说的很好听,好不好用拿出来遛一遛。

做了个简单测试,在两台完全一样的虚拟机上,2000万条左右数据,Elasticsearch 插入数据速度比 MongoDB 慢很多(可以忍受),但是搜索/查询速度快10倍以上,这只是单机情况,多机集群情况下 Elasticsearch 表现更好一些。以下安装步骤在 Ubuntu Server 14.04 LTS 上完成。

安装 Elasticsearch

升级系统后安装 Oracle Java 7,既然 Elasticsearch 官方推荐使用 Oracle JDK 7 就不要尝试 JDK 8 和 OpenJDK 了:

$ sudo apt-get update
$ sudo apt-get upgrade

$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update

$ sudo apt-get install oracle-java7-installer

加入 Elasticsearch 官方源后安装 elasticsearch:

$ wget -O - http://packages.elasticsearch.org/GPG-KEY-elasticsearch | sudo apt-key add -
$ sudo echo "deb http://packages.elasticsearch.org/elasticsearch/1.1/debian stable main" >> /etc/apt/sources.list

$ sudo apt-get update
$ sudo apt-get install elasticsearch

加入到系统启动文件并启动 elasticsearch 服务,用 curl 测试一下安装是否成功:

$ sudo update-rc.d elasticsearch defaults 95 1

$ sudo /etc/init.d/elasticsearch start

$ curl -X GET 'http://localhost:9200'
{
  "status" : 200,
  "name" : "Fer-de-Lance",
  "version" : {
    "number" : "1.1.1",
    "build_hash" : "f1585f096d3f3985e73456debdc1a0745f512bbc",
    "build_timestamp" : "2014-04-16T14:27:12Z",
    "build_snapshot" : false,
    "lucene_version" : "4.7"
  },
  "tagline" : "You Know, for Search"
}

Elasticsearch 的集群和数据管理界面 Marvel 非常赞,可惜只对开发环境免费,如果这个工具也免费就无敌了,安装很简单,完成后重启服务访问 http://192.168.2.172:9200/_plugin/marvel/ 就可以看到界面:

$ sudo /usr/share/elasticsearch/bin/plugin -i elasticsearch/marvel/latest

$ sudo /etc/init.d/elasticsearch restart
 * Stopping Elasticsearch Server                                           [ OK ]
 * Starting Elasticsearch Server                                           [ OK ]

Elasticsearch Marvel

安装 Python 客户端驱动

和 MongoDB 一样,我们一般用程序和 Elasticsearch 交互,Elasticsearch 也支持多种语言的客户端驱动,这里仅安装 Python 驱动,其他语言可以参考官方文档。

$ sudo apt-get install python-pip
$ sudo pip install elasticsearch

写个简单程序把 gene_info.txt 的数据导入到 Elasticsearch:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os, os.path, sys, re
import csv, time, string
from datetime import datetime
from elasticsearch import Elasticsearch

def import_to_db():
    data = csv.reader(open('gene_info.txt', 'rb'), delimiter='\t')
    data.next()

    es = Elasticsearch()
    for row in data:
        doc = {
            'tax_id': row[0],
            'GeneID': row[1],
            'Symbol': row[2],
            'LocusTag': row[3],
            'Synonyms': row[4],
            'dbXrefs': row[5],
            'chromosome': row[6],
            'map_location': row[7],
            'description': row[8],
            'type_of_gene': row[9],
            'Symbol_from_nomenclature_authority': row[10],
            'Full_name_from_nomenclature_authority': row[11],
            'Nomenclature_status': row[12],
            'Other_designations': row[13],
            'Modification_date': row[14]
        }
        res = es.index(index="gene", doc_type='gene_info', body=doc)

def main():
    import_to_db()

if __name__ == "__main__":
    main()

Kibana 是一个功能强大的数据显示客户端,通过插件方式和 Elasticsearch 集成在一起,安装很容易,下载解压就可以了,然后重启 Elasticsearch 服务访问 http://192.168.2.172:9200/_plugin/kibana/ 就能看到界面:

$ wget https://download.elasticsearch.org/kibana/kibana/kibana-3.0.1.tar.gz
$ tar zxvf kibana-3.0.1.tar.gz
$ sudo mv kibana-3.0.1 /usr/share/elasticsearch/plugins/_site
$ sudo /etc/init.d/elasticsearch restart

Elasticsearch Kibana

服务器批量执行工具 PSSH

操作一台服务器的时候可以 ssh,操作多台服务器可以开多个窗口多个 ssh,那操作很多台服务器呢?

我们的一个 Oracle Gird Engine 集群上大概有60多台 Ubuntu 服务器作执行节点,这些服务器操作系统和软件配置完全一样(上线后由 puppet 统一配置),有时候我们需要在这些服务器上做同样的操作,这个时候特别适合使用 PSSH 这种 ssh 批量操作工具。

当然,如果对 Python 不恐惧的话也可以用 Fabric 批量执行服务器任务

下载和安装 pssh:

$ git clone http://code.google.com/p/parallel-ssh/
$ cd parallel-ssh/
$ sudo python setup.py install

批量执行

首先新建一个服务器列表文件,把需要操作的服务器的 hostname(或者 IP 地址)加进去,然后就可以批量执行 uptime 命令了,-l 指定登录用户名,-A 询问密码,-h 指定服务器列表文件:

$ vi grids
grid01
grid02
grid03
grid04
grid05

$ pssh -i -l root -A -h grids 'uptime'
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 05:42:09 [SUCCESS] grid01
 11:42:09 up 620 days, 20:30,  0 users,  load average: 6.09, 6.14, 6.13
[2] 05:42:09 [SUCCESS] grid03
 11:42:09 up 620 days, 20:29,  0 users,  load average: 9.01, 9.04, 9.05
[3] 05:42:09 [SUCCESS] grid05
 11:42:09 up 620 days, 20:10,  0 users,  load average: 8.46, 8.18, 8.10
[4] 05:42:09 [SUCCESS] grid04
 11:42:09 up 620 days, 20:25,  0 users,  load average: 6.00, 6.01, 6.05
[5] 05:42:10 [SUCCESS] grid02
 11:42:10 up 606 days,  2:07,  0 users,  load average: 6.03, 6.02, 6.01

批量上传

批量上传本地文件 linux-3.14.3.tar.xz 到服务器上的 /tmp 目录:

$ pscp -l root -A -h grids linux-3.14.3.tar.xz /tmp/
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 05:56:16 [SUCCESS] grid01
[2] 05:56:16 [SUCCESS] grid03
[3] 05:57:04 [SUCCESS] grid05
[4] 05:57:04 [SUCCESS] grid04
[5] 05:57:05 [SUCCESS] grid02

批量下载

批量下载服务器上的某文件到本地,不用担心重名问题,因为 pssh 已经建立了 grid01, grid02, …, grid05 目录来存放下载的文件:

$ pslurp -l root -h grids -A /tmp/linux-3.14.3.tar.xz .
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 06:06:01 [SUCCESS] grid01
[2] 06:06:01 [SUCCESS] grid03
[3] 06:06:06 [SUCCESS] grid04
[4] 06:06:06 [SUCCESS] grid02
[5] 06:06:06 [SUCCESS] grid05

$ ls
grid01  grid02  grid03  grid04  grid05  grids  linux-3.14.3.tar.xz  parallel-ssh

批量同步

有时候我们需要保持开发机上(某目录里)的数据和服务器上的数据一致:

$ prsync -l root -h grids -A -r develop/ /tmp/production/
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 06:12:52 [SUCCESS] grid05
[2] 06:12:52 [SUCCESS] grid01
[3] 06:12:52 [SUCCESS] grid04
[4] 06:12:52 [SUCCESS] grid02
[5] 06:12:52 [SUCCESS] grid03

分享一款适合程序员的字体:Source Code Pro

每个 developer/devops/sysadmin 都有自己喜爱的系统(Mac vs Linux vs Windows)、编辑器(Vi vs Emacs vs Sublime Text vs …)、终端(iTerm2 vs Terminal vs Rxvt vs Gnome Terminal vs …)、配色方案(比如 Solarized vs Tomorrow vs …)、甚至字体(Inconsolata vs Deja Vu vs Monaco vs …)~

Source Code Pro 是 Adobe 公司发布的一款开源等宽字体,看这个字体名字就知道专为程序员定制,非常适合阅读代码,支持 Mac OS X, Linux, Windows 等操作系统。

刚把 iTerm2 终端的默认字体 Monaco 换成了 Source Code Pro,感觉 Source Code Pro 要扁一点,难道这样的设计是为了看更多行的代码?!

Source Code Pro

使用 OpenVPN Access Server 轻松搭建 VPN 服务器

平时很少用 VPN,需要的时候一般用 ssh -D 搞定,或者 sshuttle 也是个不错的工具。自己配置 OpenVPN 虽然不是很麻烦,但对第一次配置 VPN 的新手来说还是挺费神费事的,如果急用或者怕麻烦的话可以选用 OpenVPN 的商业收费版本 OpenVPN Access Server,其免费的 license 可以支持2个 VPN 用户的同时在线,对个人用户来说足够用了。OpenVPN Access Server 装完即可用,无需配置。

安装

在 CentOS 6.x 上下载和安装 OpenVPN Access Server:

# yum update
# yum upgrade

# wget http://swupdate.openvpn.org/as/openvpn-as-2.0.7-CentOS6.i386.rpm

# rpm -ivh openvpn-as-2.0.7-CentOS6.i386.rpm
Preparing...                ########################################### [100%]
   1:openvpn-as             ########################################### [100%]
The Access Server has been successfully installed in /usr/local/openvpn_as
Configuration log file has been written to /usr/local/openvpn_as/init.log
Please enter "passwd openvpn" to set the initial
administrative password, then login as "openvpn" to continue
configuration here: https://173.252.243.254:943/admin
To reconfigure manually, use the /usr/local/openvpn_as/bin/ovpn-init tool.

Access Server web UIs are available here:
Admin  UI: https://173.252.243.254:943/admin
Client UI: https://173.252.243.254:943/

# passwd openvpn

在 Ubuntu 14.04 上下载和安装 OpenVPN Access Server(写这篇文章的时候 Ubuntu 14.04 刚刚发布,for Ubuntu 14.04 的官方版本还没有出来,可以使用 Ubuntu 13.10 的):

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install iptables
$ wget http://swupdate.openvpn.org/as/openvpn-as-2.0.7-Ubuntu13.i386.deb
$ sudo dpkg -i openvpn-as-2.0.7-Ubuntu12.i386.deb
$ sudo passwd openvpn

使用

打开管理界面 https://173.252.243.254:943/admin 使用用户名 openvpn 和密码登录,进去随便看一下就可以了,不用做任何配置就可以用:

OpenVPN Access Server

打开客户端界面 https://173.252.243.254:943/ 使用用户名 openvpn 和密码登录后下载 OpenVPN Connect for Mac OS X 客户端,安装后点击连接就可以用了,很方便。

OpenVPN Access Server

如果你想使用其他的 OpenVPN 客户端的话,比如 Tunnelblick,就需要下载客户端的配置文件 Yourself (user-locked profile) 或者 Anyone at this server (server-locked profile). 下载后的文件名是 client.ovpn,这个文件稍后会在配置 Tunnelblick 时用到。

Tunnelblick 是 Mac 上比较流行的一个开源 OpenVPN 客户端,另一个好用的客户端 Viscosity 是收费的。

下载 Tunnelblick 后安装,然后导入刚才下载的 client.ovpn 配置文件就可以了,导入的方法比较奇怪,桌面上会自动创建一个 Empty Tunnelblick VPN Configuration 文件夹,把 client.ovpn 拖进去后重命名文件夹(注意是文件夹不是文件)为 Empty Tunnelblick VPN Configuration.tblk 后双击文件夹导入,导入后点击 Connect 会弹出登录对话框,输入用户名 openvpn 及其密码就可以了。

OpenVPN Access Server

试玩 Microsoft Azure

期待着复活节长周末,无心恋战~

上周参加一个 workshop 从微软 speaker 那里拿到几张 Microsoft Azure 的 promo 卡片,貌似可以购买200美元的 Azure 服务。到 http://aka.ms/azurecode 输入 promo code 等待24小时等通知,然后看邮件说明就可以用了。登录 Microsoft Azure 后惊讶发现居然挺好用的,至少比 Amazon EC2 要好用得多,Amazon EC2 弄的太复杂,单是那个价格表就让人看晕,第一次试用 Amazon EC2 的时候有点摸不着北~

Microsoft Azure 界面简单清晰,要创建的服务一目了然,命名一看就知道要干什么,非常赞。虚拟机就叫虚拟机(Virtual Machine)嘛,Amazon 管虚拟机叫实例(Instance),Instances 还分什么 On-Demand Instances 和 Reserved Instances,Reserved Instances 里面又分 Light, Medium, Heavy;硬盘就是硬盘(disk)嘛,为啥 Amazon 一定要叫 Elastic Block Store (EBS) 呢,哦,还有,EBS Standard 和 EBS Provisioned 价格是不一样的,云计算一定要云里来雾里去吗?!

Microsoft Azure 平台上可以创建很多服务,网站、虚拟机、云服务、移动服务、存储、SQL 数据库、缓存、CDN 等等,几乎包括了云技术的方方面面,很强大。大家熟悉的优秀的 VPS 服务商 Linode 只相当于 Azure 里面的一个功能~

填好虚拟机的 DNS 名、选择虚拟机的操作系统和配置、记住用户名、输入密码、选择数据中心就可以了:

Microsoft Azure

创建成功后进入虚拟机的控制面板:

Microsoft Azure

虚拟机性能监控不能少:

Microsoft Azure

如果安装了 nginx/apache 之类的服务器,更改了 ssh 端口之类的别忘了在控制面板里把相应的端口打开:

Microsoft Azure

查看 Linux 系统信息的 web 面板 psdash

psdash 是一款查看 Linux 系统信息的 web 面板,和我们以前提到的另一款系统监控工具 Glances 一样,psDash 的系统信息的采集也是由 psutil 完成的。和 Glances 不同的是,psdash 没有提供 API,只带了一个基于 Flask 的 web 界面,默认每3秒刷新一次数据和界面。

升级系统后安装必要软件包:

$ sudo apt-get update
$ sudo apt-get upgrade

$ sudo apt-get install git gcc python-dev python-setuptools

下载 psdash 源代码后安装:

$ git clone https://github.com/Jahaja/psdash.git
$ cd psdash
$ sudo python setup.py install

启动 psdash:

$ sudo psdash --log /var/log/psdash.log --log /var/log/mydb.log

打开浏览器访问 http://192.168.2.99:5000/

psdash

在 FreeBSD 10.0 上安装和配置 Nginx+PHP+APC+MySQL

上月得知一位同事要退休,留下一些 BSD 机器需要接手(是的,在国外玩技术可以玩到退休~),接下来两个月讨论 FreeBSD/OpenBSD 的机会可能多一些。FreeBSD 10.0 发布的亮点不少,clang 替代了 gcc 成为默认编译器、大幅增强了对虚拟化的支持、下一代软件包管理工具 pkgng 替代了 pkg_add/pkg_delete 成为默认包管理工具、Linux 一直在虚拟化方面遥遥领先 BSD 阵营,这次的发行版本终于包括了 BSD 自己的虚拟化技术 bhyve,…

在 FreeBSD 下安装软件的传统方法是用 ports 源码安装,不过使用 ports 源码编译安装太耗时(尤其是各种库依赖多、大的时候),个人还是喜欢 pkg 这种软件包管理工具直接安装编译好的二进制软件包,不用自己编译,省时省力。

和 Linux 一样,FreeBSD 也能一行命令解决所有安装和软件包依赖问题(下面的输出要比 apt-get/yum 来的清新舒服吧~):

# pkg install nginx php55 php55-extensions pecl-APC mysql56-server
Updating repository catalogue
The following 23 packages will be installed:

	Installing nginx: 1.4.7,1
	Installing php5-session: 5.4.26
	Installing php5-xmlwriter: 5.4.26
	Installing php5-dom: 5.4.26
	Installing php5-xml: 5.4.26
	Installing php5-simplexml: 5.4.26
	Installing php5-ctype: 5.4.26
	Installing php5-posix: 5.4.26
	Installing php5-hash: 5.4.26
	Installing php5-filter: 5.4.26
	Installing php5-tokenizer: 5.4.26
	Installing php5-json: 5.4.26
	Installing php5-sqlite3: 5.4.26
	Installing php5-pdo: 5.4.26
	Installing php5-iconv: 5.4.26
	Installing php5-phar: 5.4.26
	Installing pecl-APC: 3.1.14_1
	Installing php5-xmlreader: 5.4.26
	Installing php5-pdo_sqlite: 5.4.26
	Installing php5-extensions: 1.7
	Installing mysql56-client: 5.6.16_1
	Installing mysql56-server: 5.6.16

The installation will require 149 MB more space

14 MB to be downloaded

Proceed with installing packages [y/N]: y

安装完后把服务加到系统启动文件里:

# vi /etc/rc.conf
...
nginx_enable="YES"
php_fpm_enable="YES"
mysql_enable="YES"

配置 MySQL:

# vi /usr/local/etc/my.cnf
[mysqld]
socket = /tmp/mysql.sock

skip-networking
skip-name-resolve

# service mysql-server start

# /usr/local/bin/mysqladmin -u root password 'password'

配置 PHP 和 PHP-FPM,这里不需要配啥,默认的配置就行:

# cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini

# vi /usr/local/etc/php.ini
# vi /usr/local/etc/php-fpm.conf

# service php-fpm start

配置 APC:

# echo 'apc.enabled="1"' >> /usr/local/etc/php.ini
# echo 'apc.shm_size="32M"' >> /usr/local/etc/php.ini
# service php-fpm restart

配置 Nginx:

# vi /usr/local/etc/nginx/nginx.conf
user  www;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   /usr/local/www/nginx;
            index  index.html index.htm;
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/local/www/nginx-dist;
        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
            root   /usr/local/www/nginx;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }
}

# service nginx start

写个 phpinfo() 页面测试一下 Nginx/PHP/PHP-FPM/APC 组合是否能正常工作。如果一切正常的话访问 http://localhost/info.php 能看到 PHP 环境详细信息:

# vi /usr/local/www/nginx/info.php
<?php phpinfo(); ?>

对 NetBSD 感兴趣的同学可以参考:NetBSD 上安装和配置 Nginx+PHP+FastCGI+MySQL

在 FreeBSD 10.0 上安装 SmokePing

SmokePing 是一款开源网络延迟监控工具,其作者 Tobi Oetiker 还开发了一些我们熟悉的 MRTG 和 RRDtool. SmokePing 能采用多种方式对网络延迟(性能)进行监测和警告,支持插件的方式对网络的其他指标进行监控,并且支持 Matser/Slave 分布式架构,多节点监控数据可以汇集到一起并通过颜色和阴影来展现网络延迟和丢包。以下操作在 FreeBSD 10.0 上测试通过。

在开始之前,最好升级一下系统:

# freebsd-update fetch
# freebsd-update install

现在 FreeBSD 有了一套新的软件包管理工具 pkg,目的是用来替代老的 pkg_info/pkg_create/pkg_add. 这里用新工具 pkg 来安装 smokeping,并把 smokeping 加到系统启动文件里:

# pkg install smokeping
# echo 'smokeping_enable="YES"' >> /etc/rc.conf

修改 smokeping_secrets 文件权限后启动 smokeping:

# chmod 600 /usr/local/etc/smokeping/smokeping_secrets
# /usr/local/etc/rc.d/smokeping start

smokeping 是 Perl 写的,还需要安装几个 perl 模块:

# perl -MCPAN -e shell
Terminal does not support AddHistory.

cpan shell -- CPAN exploration and modules installation (v1.9800)
Enter 'h' for help.

cpan[1]> install FCGI
cpan[1]> install CGI

要看 web 界面的话 smokeping 还需要 apache 的支持,安装 apache 并加到系统启动文件:

# pkg install apache24
# echo 'smokeping_enable="YES"' >> /etc/rc.conf

因为 pkg 里面没有 mod_fcgid,不能 pkg install mod_fcgid,所以需要使用 FreeBSD 传统的 port 编译安装:

# portsnap fetch extract
# portsnap fetch update

# cd /usr/ports/www/mod_fcgid
# make install clean

配置 apache:

# vi /usr/local/etc/apache24/Includes/smokeping.conf
LoadModule fcgid_module libexec/apache24/mod_fcgid.so


    AddHandler fcgid-script .fcgi


Alias /smokeping "/usr/local/smokeping/htdocs"

    Options Indexes FollowSymLinks ExecCGI
    AllowOverride All
    Require all granted

# vi /usr/local/etc/apache24/httpd.conf
...
#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#

    DirectoryIndex index.html smokeping.fcgi

...

配置 smokeping,在 *** Targets *** 一栏加入要监控的机器:

# vi /usr/local/etc/smokeping/config
...
*** Targets ***

probe = FPing

menu = Top
title = Network Latency Grapher
remark = Welcome to vpsee.com

+ Local

menu = Local
title = Local Network

++ node11

menu = node11
title = node11
host = node11.vpsee.com
...

做了配置后,别忘了重启服务:

# service smokeping restart
# service apache24 restart

打开浏览器访问 http://192.168.2.123/smokeping/

SmokePing

安装和使用 MongoDB

上周玩了一下 RethinkDB 发现一些性能问题,导入2000万个文档后查询起来非常慢,哪怕是最简单的查询也很慢,试着把数据分片到 RethinkDB 集群的多个节点上还是慢。相比之下,其他几个比较成熟的产品 MongoDB, CouchDB, Couchbase 就要快很多。

MongoDB 可能是当前最流行的 NoSQL 数据库,就不用多介绍了,下面的安装步骤在 Ubuntu Server 12.04.4 LTS (64-bit) 和 CentOS 6.5 Minimal (64-bit) 上完成。

安装 MongoDB 服务器

在 Ubuntu 上安装 GPG key 后添加 mongdb 源,然后安装 mongodb-10gen:

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10

$ echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list

$ sudo apt-get update
$ sudo apt-get install mongodb-10gen

在 CentOS 上使用 root 账号,添加 mongdb 源,然后安装 mongo-10gen 和 mongo-10gen-server:

$ su

# vi /etc/yum.repos.d/mongodb.repo
[mongodb]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
gpgcheck=0
enabled=1

# yum update
# yum install mongo-10gen mongo-10gen-server

# service mongod restart
# chkconfig mongod on

在 CentOS 上如果用 yum install 安装完 mongodb 发现 /etc/init.d/ 里面没有 mongod 启动脚本的话,需要从 /etc/rc.d/init.d/ 拷贝一个:

# cp /etc/rc.d/init.d/mongod /etc/init.d/
# service mongod restart

检查一下 mongodb 服务是否已经在运行,如果没有的话重启一下 mongodb 服务:

$ ps aux | grep mongod
mongodb   1165  8.2 99.9 25407520 8550164 ?    Ssl  04:02  17:10 /usr/bin/mongod --config /etc/mongodb.conf

$ sudo service mongodb restart    # 在 ubuntu 上
# service mongod restart          # 在 centos 上

如果启动 mongodb 过程报错,查看日志寻找蛛丝马迹:

$ sudo vi /var/log/mongodb/mongodb.log

如果发现日志里有如下错误,可能是因为 /tmp 权限问题,mongd 进程无权限法写 /tmp,chmod 777 就可以了:

...
Tue Mar 18 08:03:55.061 [initandlisten] ERROR: listen(): bind() failed errno:13 Permission denied for socket: /tmp/mongodb-27017.sock
...

# chmod -R 777 /tmp

使用 mongo 客户端

MongoDB 自带的 mongo 客户端程序(相当于 MySQL 的 mysql)可以用来简单的与 mongod 交互:

$ mongo
MongoDB shell version: 2.4.9
connecting to: test
> db
test
> use gene
switched to db gene
> db
gene
> help
...

安装 Python 客户端驱动

我们一般用程序和 MongoDB 交互,MongoDB 支持多种语言的客户端驱动,比如:JavaScript, Python, Ruby, PHP, Perl, C, C++, Java, Scala 等。下面的部分仅是安装 MongoDB 的 Python 驱动,其他语言可以参考官方文档

在 Ubuntu 上安装 pymongo:

$ sudo apt-get install python-pip
$ sudo apt-get install build-essential python-dev
$ sudo pip install pymongo

在 CentOS 上安装 pymongo:

# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
# yum update
# yum install python-pip
# yum install gcc python-devel
# pip install pymongo

gene_info.txt 是一个含有基因数据的文本文件,大概1000多万行记录,格式如下:

$ head -2 gene_info.txt
#Format: tax_id GeneID Symbol LocusTag Synonyms dbXrefs chromosome map_location description type_of_gene Symbol_from_nomenclature_authority Full_name_from_nomenclature_authority Nomenclature_status Other_designations Modification_date (tab is used as a separator, pound sign - start of a comment)
7       5692769 NEWENTRY        -       -       -       -       -       Record to support submission of GeneRIFs for a gene not in Gene (Azorhizobium caulinodans Dreyfus et al. 1988; Azotirhizobium caulinodans.  Use when strain, subtype, isolate, etc. is unspecified, or when different from all specified ones in Gene.).  other   -       -       -       -       20071023

写个简单程序把 gene_info.txt 的数据导入到 MongoDB 里:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os, os.path, sys, csv, string

def import_to_db():
    data = csv.reader(open('gene_info', 'rb'), delimiter='\t')
    data.next()

    import pymongo
    mongo = pymongo.Connection('127.0.0.1')
    genedb = mongo['gene']
    gene_info = genedb['geneinfo']
    for row in data:
        gene_info.insert({
            'tax_id': row[0],
            'GeneID': row[1],
            'Symbol': row[2],
            'LocusTag': row[3],
            'Synonyms': row[4],
            'dbXrefs': row[5],
            'chromosome': row[6],
            'map_location': row[7],
            'description': row[8],
            'type_of_gene': row[9],
            'Symbol_from_nomenclature_authority': row[10],
            'Full_name_from_nomenclature_authority': row[11],
            'Nomenclature_status': row[12],
            'Other_designations': row[13],
            'Modification_date': row[14]
        })

def main():
    import_to_db()

if __name__ == "__main__":
    main()