龍昌博客

从Pythoner转向Rubist

Mongodb集群配置实例

| Comments

Mongodb的集群有两种,一个是主从复制,另一种是副本集。

主从复制

根据 Mongodb 的官方文档说明,在生产环境中建议使用副本集代替主从复制。 http://docs.mongodb.org/manual/core/master-slave/

不过对于主从复制还是可以了解一下。假设有如下三台主机:

  • 172.17.0.4 (主)
  • 172.17.0.5 (从)
  • 172.17.0.6 (从)

要进行主从复制的配置,首先修改主服务器的配置信息:

1
2
master = true         # 以主服务器模式启动
bind_ip = 0.0.0.0

然后修改另两台从服务器配置信息:

1
2
3
slave = true
source = 172.17.0.4
bind_ip = 0.0.0.0

最后启动三台主机上的 Mongodb 服务,再通过一个简单的程序来测试一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env ruby
#-*- coding:utf-8 -*-

require "mongo"

begin
  conn = Mongo::Connection.new '172.17.0.4'
  db = conn['test']
rescue Exception=>e
  p e
  exit 1
end

i = 0
while i < 100
  d = {'no' => i}
  d = db['data'].insert(d)
  i += 1
  puts d
end

执行该脚本,向 172.17.0.4 主机的 Mongodb 中插入一些数据。然后发现数据被同步到了另外两台主机上。

主从之间安全认证:
如果启动了 auth 项,那么主从之间的认证需要使用 keyFile 选项。

执行如下命令生成 key 文件,并设置为只有 mongodb 的进程用户可读写:

1
2
3
$ openssl rand -base64 741 > /path/mongodb_keyFile
$ chmow 600 /path/mongodb_keyFile
$ chown mongodb:mongodb /path/mongodb_keyFile

将该文件复制到这三台主机中,然后分别修改主从的配置信息:

1
keyFile = /path/mongodb_keyFile

副本集

同样的对于这三台主机,我们重新修改配置设置为副本集的形式。

  • 172.17.0.4
  • 172.17.0.5
  • 172.17.0.6

首先修改配置文件,设置副本集的名字。
注意:副本集中所有主机设置的名字需要一样。这里我们设为 myrepl0
注意:设置副本集之前各个 mongodb 的数据目录必须都为空。

1
replSet = myrepl0

接着启动所有 mongodb 服务,然后对副本集进行初始化。
连接任意一台 mongodb 服务,执行如下操作:

1
2
3
4
5
> rs.initiate({'_id': 'myrepl0', 'members': [
    {'_id': 1, 'host': '172.17.0.4:27017'},
    {'_id': 2, 'host': '172.17.0.7:27017'},
    {'_id': 3, 'host': '172.17.0.8:27017'}
]})

现在副本集的初始化已完成,可以通过如下命令查看状态:

1
> rs.status()

在运行过程中可以随时添加或移除一个节点,如:

1
2
rs.add("172.17.0.8:27017")
rs.remove("172.17.0.8:27017")

可以再通过上面的程序添加一些数据。然后再连接到任意一台主机进行查询,看看数据是否已同步。

详细内容可参考文档: http://docs.mongodb.org/manual/core/replication/

安全认证:

1.禁用 auth 选项和 replSet 选项再运行 mongodb

2.连接到该 mongodb 服务并创建用户

1
2
3
4
5
6
7
8
9
10
> use admin
switched to db admin
> db.addUser('root','root')
{
        "user" : "root",
        "readOnly" : false,
        "pwd" : "2a8025f0885adad5a8ce0044070032b3",
        "_id" : ObjectId("54745351f79804bd44b596fb")
}
>

3.重新以 auth、keyFile 和 replSet 模式启动 mongodb

4.连接到刚刚创建用户的 mongodb 服务

5.跟之前的步骤一样,配置副本集

1
2
3
4
5
> rs.initiate({'_id': 'myrepl0', 'members': [
    {'_id': 1, 'host': '172.17.0.4:27017'},
    {'_id': 2, 'host': '172.17.0.7:27017'},
    {'_id': 3, 'host': '172.17.0.8:27017'}
]})

参考: http://docs.mongodb.org/manual/tutorial/deploy-replica-set-with-auth/

使用VIM进行PHP远程调试

| Comments

最近在写 PHP 时感觉它的调试不是很方便,基本都是用的 var_dump 将信息输出到页面上进行调试。最终实现是受不了这种方式,就找了一下看看有没有什么简便的方法。 于是就找到了 vdebug 这个 vim 插件,使用它可以方便的进行远程调试。

根据 vdebug 的介绍,说是它可以用来调试基于 DBGP 协议的程序,比如: PHP、Python、Ruby等。 可能只是 DBGP 协议在 PHP 中用得比较多吧,因此看到的大部分介绍都是说的 PHP 调试。 关于 DBGP 协议的详细介绍可参考: http://xdebug.org/docs-dbgp.php

使用方法:

首先是在 vim 中安装这个插件,下载地址: https://github.com/joonty/vdebug

由于它的配置信息都写死在代码中的,因此我就 fork 了一份进行自定义的修改,如快捷键设置、远程主机名和端口号。

然后是安装 PHP 的 Xdebug 扩展,并配置一些参数信息。在 php.ini 配置文件中添加如下内容:

1
2
3
4
xdebug.remote_enable=on
xdebug.remote_handler=dbgp
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9010

注意:这里的主机名和端口号要与 vdebug 中的一致。

接着使用 vim 打开一个 php 文件,按 <F5> 键启动该插件进行调试。然后在浏览器中访问该 php 程序, 并加上 XDEBUG_SESSION_START=1 参数,如: http://127.0.0.1/test.php?XDEBUG_SESSION_START=1

现在就可以在 vim 中对 php 程序进行单步调试了。

Nginx + Uwsgi + Django环境配置

| Comments

有段时间没折腾 Django 了,又有点生疏了。最近又部署了一下 Django 的环境,顺便作个笔记以便之后查阅。

首先安装 nginx、uwsgi 以及 uwsgi 的 python 插件。

然后新建一个 uwsgi 的配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
[uwsgi]
uid = www-data
chdir = /repo/django-blog
virtualenv = /repo/django-blog/pyenv2.7/    # python虚拟环境,没有可以不设置
env = DJANGO_SETTINGS_MODULE=blog.settings
module = blog.wsgi:application
master = true
plugin = python
pidfile = /tmp/blog-master.pid
socket = /tmp/blog.sock
enable-threads = true
post-buffering=1024000
post-buffering-busize=655360

这里我们的 Django 项目代码位于 /repo/django-blog ,项目的配置文件为: blog/settings.py

virtualenv 项表明我们使用的是 virtualenv 环境,也可以直接系统的 python 环境。不过还是建议使用虚拟环境,以免软件包版本冲突。

post-bufferingpost-buffering-busize 这两项设置了 POST 请求时缓冲区的大小,该值可根据自己的情况进行调整。之前遇到过由于缓冲区不足导致返回的内容不完整。

再安装对应的 python 依赖包,然后运行 uwsgi 服务。

接着修改 nginx 的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server {
  listen 80;
  server_name localhost;

  client_max_body_size 50m;

  access_log /var/log/nginx/blog-access.log;
  error_log /var/log/nginx/blog-error.log;

  location / {
    uwsgi_pass unix:///tmp/blog.sock;
    include uwsgi_params;
  }

  location /static {
    alias /repo/django-blog/static/;
  }
}

这个内容比较简单, client_max_body_size 项是用于设置 http 请求的 body 最大大小。如果你的程序中有文件上传的,那么就需要根据自身情况来设置允许上传文件的最大值。

最后再启动 nginx 服务。

配置rails的vim环境

| Comments

今天分享一款 vim 的 rails 插件: vim-rails

使用该插件可以方便的在多个文件之间进行跳转。如在控制器的 action 上按 gf 键会自动跳转到对应的视图文件。

也可以使用 :Emodel, :Eview, :Econtroller, 命令在模型、视图以及控制器之间进行跳转。

该插件还提供了对 rails 的一些关键字的高亮。

并且还可以直接在 vim 中使用 :Rails 命令。

同时还有 vim-rakevim-bundler 两个插件提供了 rakebundle 的 vim 命令接口。

如果是用的 vundle 进行插件管理的话,可以直接在 .vimrc 配置中添加如下内容即可:

1
2
3
Bundle 'tpope/vim-rails'
Bundle 'tpope/vim-rake'
Bundle 'tpope/vim-bundler'

然后再在vim执行命令 :BundleInstall 即可。

博客终于迁移完成了!

| Comments

折腾了两天,终于将博客从之前的WordPress迁移到Jekyll上来了。

我的博客是从2009年开始使用WordPress的,至今也有5年多了。最近感觉WordPress提供的文章编辑功能不是很方便,本来是想着改用别的博客系统的。但是一直纠结着始终没换。一是由于懒,感觉能用就行了,不想折腾了。二是由于找不到比较好的系统。

这样就纠结了一年多。最近突然发现了Octopress,感觉很不错。于是果断地选择迁移过来。

环境搭建好了之后,接下来就是数据的迁移了。原打算之前的数据都不要了,准备从头再来的。毕竟之前的文章也写得不咋滴。 也许是自己比较怀旧吧,最终还是写了一个脚本将WordPress的数据输出为Markdown文件。
程序地址: https://github.com/wusuopu/wordpress-to-octopress

数据输出之后发现布局全乱了,又得重新调整一下格式。唉~~~~~,只是麻烦啊!

配置elixir的vim环境

| Comments

elixir是建立在Erlang虚拟机之上的一种函数式编程语言。下面介绍elixir的两个vim插件。

首先是语法高亮支持: https://github.com/elixir-lang/vim-elixir

其次是snippets支持: https://github.com/carlosgaldino/elixir-snippets 这个需要先安装 snipMate 插件。

如果也是用的 vundle 进行插件管理的话,可以直接在 .vimrc 配置中添加如下内容即可:

Bundle 'elixir-lang/vim-elixir'
Bundle 'carlosgaldino/elixir-snippets'

au BufNewFile,BufRead *.exs set ft=elixir

然后再在vim执行命令 :BundleInstall 即可。

配置coffeescript的vim环境

| Comments

coffeescript是构建在javascript基础上一门语言,它在运行时会编译在javascript。下面介绍vim用来开发coffeescript的两个插件。

首先是语法高亮支持: https://github.com/kchmck/vim-coffee-script

其次是snippets支持: https://github.com/carlosvillu/coffeScript-VIM-Snippets 这个需要先安装 snipMate 插件。

如果也是用的 vundle 进行插件管理的话,可以直接在 .vimrc 配置中添加如下内容即可:

Bundle 'kchmck/vim-coffee-script'
Bundle 'carlosvillu/coffeScript-VIM-Snippets'

au BufNewFile,BufRead *.coffee set ft=coffee

VIM编译参数

| Comments

每次重装系统之后都要重新编译一次VIM,为了方便就将编译参数记录如下:

./configure --prefix=/opt/vim --enable-acl --enable-cscope --enable-largefile --enable-multibyte --enable-sniff --enable-mzschemeinterp --enable-xim --enable-tclinterp --enable-perlinterp --enable-python3interp --enable-pythonint
erp --enable-rubyinterp --enable-netbeans --enable-gui --enable-luainterp --enable-nls --enable-xsmp --enable-xsmp-interact --enable-fontset --with-features=huge --with-x

上面的参数中启用了对tcl、perl、python、ruby、lau的支持。同时为了使用系统的剪切板还启用了对X的支持。

我的VIM配置文件: https://github.com/wusuopu/my-vimrc

Docker使用笔记

| Comments

docker是一个Linux下的应用容器引擎。使用它可以很方便地将程序以及依赖都打包到一个可移植的容器中。最后体验了一下,使用docker配置了一个Web开发环境。这样就不用担心每次重装系统之后都要重新配置开发环境。

安装

首先是安装docker应用程序,目前只有64位系统才能使用。

$ [sudo] apt-get install apparmor apparmor-profiles apparmor-utils
$ [sudo] apt-get install aufs-tools
$ [sudo] apt-get install cgroup-lite

$ wget https://get.docker.io/builds/Linux/x86_64/docker-latest.tgz
$ [sudo] tar xf docker-latest.tgz -C /

基本用法

安装完成之后使用 [sudo] docker -d 命令启动docker的daemon进程。

以下是一些常用命令的用法介绍:

docker version            # 查看版本
docker search TERM        # 搜索镜像
docker pull NAME[:TAG]    # 下载镜像

启动镜像:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker run IMAGE -t -i /bin/bash                        # 进入镜像的shell环境
docker run IMAGE -p 12345:8000 -t -i /bin/bash          # 进入镜像的shell环境,将主机的12345端口映射到容器的8000端口

容器与镜像管理:

docker ps [OPTIONS]                              # 列出容器
docker images [OPTIONS] [NAME]                   # 列出镜像
docker rm [OPTIONS] CONTAINER [CONTAINER...]     # 删除容器
docker rmi IMAGE [IMAGE...]                      # 删除镜像

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]    # 根据修改的容器创建一个新的镜像
docker commit -m "centos" f9ccb5cef3c0 wusuopu/centos6
docker push NAME[:TAG]                                  # 上传镜像
docker inspect CONTAINER|IMAGE [CONTAINER|IMAGE...]     # 查看一个容器或者镜像的详细信息
docker logs CONTAINER     # 查看日志
docker start CONTAINER [CONTAINER...]                   # 启动镜像
docker stop CONTAINER [CONTAINER...]                    # 停止镜像
docker tag [OPTIONS] IMAGE [REGISTRYHOST/][USERNAME/]NAME[:TAG]   # 给镜像打tag
docker diff CONTAINER     # 查看容器文件系统的变化
docker cp CONTAINER:PATH HOSTPATH                       # 将文件从容器复制到主机

导入、导出:

docker export CONTAINER                                 # 导出容器到标准输出
docker export red_panda > latest.tar

docker import URL|- [REPOSITORY[:TAG]]                  # 导入文件为镜像
docker import http://example.com/exampleimage.tgz
cat exampleimage.tgz | sudo docker import - exampleimagelocal:new

Nginx + Php + FastCGI配置

| Comments

最近在弄PHP,于是乎把配置过程作一个笔记以免忘了。

PHP安装、配置

我是通过源代码编译的形式进行安装的,基本步骤如下:

$ tar xf php-5.5.12.tar.bz2
$ cd php-5.5.12
$ './configure'  '--prefix=/opt/myphp' '--with-mysql' '--enable-safe-mode' '--enable-ftp' '--enable-zip' '--with-jpeg-dir' '--with-bz2' '--with-png-dir' '--with-freetype-dir' '--with-iconv' '--with-libxml-dir' '--with-xmlrpc' '--with-zlib-dir' '--with-gd' '--enable-gd-native-ttf' '--with-curl' '--with-gettext' '--with-pear' '--enable-fpm' '--enable-fastcgi' '--with-ncurses' '--with-mcrypt' '--with-mhash' '--with-openssl' '--with-pcre-dir' '--enable-pdo' '--enable-phar' '--enable-json' '--enable-mbstring' '--with-pdo-mysql' '--with-pdo-sqlite' '--with-readline' '--enable-bcmath'
$ make
$ sudo make install

安装完成之后进入安装目录修改配置文件 lib/php.ini (没有则创建),添加时区设置:

date.timezone=Asia/Shanghai

然后运行PHP的FastCGI服务:

./bin/php-cgi -b 9000

nginx配置

nginx可以直接从仓库进行安装:

sudo pacman -S nginx

或者:

sudo apt-get install nginx

安装完成之后修改配置,添加一条新的虚拟主机:

server {
    listen 8000;
    server_name localhost;

    root /var/www;

    location / {
        index index.php;
    }

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;  
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  /var/www/$fastcgi_script_name;
    }

}

然后再创建文件 /var/www/index.php

<?php
  phpinfo();
?>

现在通过浏览器访问 http://127.0.0.1:8000/ 应该就可以看到效果了。