8月 08

go语言环境准备

开始使用的是编译好的包,由于CentOS系统64位的版本过老,编译总是报错,所以最后还是使用源码编译。具体操作非常简单。
先安装需要的工具,如果已有就不用安装了。
# yum install mercurial bison gcc libc6-dev ed gawk make
解压源码包,执行编译命令,配置环境变量即可。
我使用root用户,将源码包直接放在/usr/local/目录下。操作记录如下
# tar zxvf go1.0.2.src.tar.gz
# cd go/src/
# ./all.bash
到用户的home目录里编译.bash_profile,如果要所有用户都能用,就直接编辑/etc/profile。
export GOROOT=/usr/local/go
export GOARCH=amd64
export GOOS=linux

PATH=$PATH:$HOME/bin:/usr/local/go/bin

到此已经可以用了,随便搞个hello world试试。
/etc/profile配置
export GOROOT=/usr/local/go
export GOBIN=/usr/local/go/bin
export GOARCH=amd64
export GOOS=linux
export PATH=$GOBIN:$PATH

6月 17

tornado学习笔记(一)

学习地址 http://www.tornadoweb.cn/documentation
http://sebug.net/paper/books/tornado/#tornado-walkthrough。
本文只是学习笔记

一、部署

  开始学习。服务器使用内部pc服务器,地址为192.168.1.41,操作系统为centos 5.6,python2.6。安装tornado环境太简单了,两条命令如下:
# easy_install tornado
# yum install pycurl

  环境安完,开始学习。按照说明拷贝代码命名为main.py代码如下:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

运行服务
python main.py

直接在浏览器中输入http://192.168.1.41:8888,看到了经典的东西了。tornado是单进程,在多核服务器上,我器多个进程,然后用nginx做负载。自己写了一个启停服务的脚本。

启停服务脚本如下,命名为”main.sh”,运行脚本后会在同级目录产生一个“main.port”文件,文件中记录启动的端口号列表。

#!/bin/sh
#
# Filename:    main.sh
# Revision:    1.0
# Date:        2012-06-14
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
#
### END INIT INFO

# Source function library.
. /etc/profile

# Set the base value
listen_line=4
listen_start=8880

# 
CWD=`pwd`
cd $CWD

# See how we were called.
case "$1" in
  start)
        /bin/rm -rf main.port
	for (( i=0 ; i<${listen_line} ; i++)); do
            listen_port=$[${listen_start}+${i}]
            echo ${listen_port} >> main.port
            python main.py ${listen_port} &
	done
        echo "start ok !"
        ;;
  stop)
        get_port_line=`/bin/cat main.port`
        for i in ${get_port_line};do
             now_pid=`/bin/ps -ef|grep ${i}|grep -v grep|awk ' ''{print $2}'`
             /bin/kill -9 $now_pid
        done
        echo "stop"
        ;;
  status)
        get_port_line=`/bin/cat main.port`
        for i in ${get_port_line};do
             now_pid=`/bin/ps -ef|grep ${i}|grep -v grep`
             if [ -z "${now_pid}" ] ; then
                 echo ${i} "is stop"
             else
                 echo ${now_pid}
             fi
        done
	;;
  restart)
	$0 stop
	$0 start
	;;
  *)
        echo $"Usage: $0 {start|stop|restart|status}"
        exit 1
esac

exit $rc

  将启动文件也做一下修改,mian.py代码如下:

#!/bin/python
#-*- coding:utf-8 -*-
# Filename:    main.py
# Revision:    1.0
# Date:        2012-06-14
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
### END INIT INFO
import sys
import tornado.ioloop
import tornado.web


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")


application = tornado.web.Application([
    (r"/", MainHandler),
])


if __name__ == "__main__":
    listen_port =  sys.argv[1]
    application.listen(listen_port)
    tornado.ioloop.IOLoop.instance().start()

  现在配置nginx,只列出了http中的连接配置

   #######################www.grabproxy.com
   upstream  www_test_com {
            server 192.168.1.41:8880;
            server 192.168.1.41:8881;
            server 192.168.1.41:8882;
            server 192.168.1.41:8883;
       }
   server {
        listen       80;
        server_name 192.168.1.41;
        location / {
        proxy_cache_key $host$uri$is_args$args;
        proxy_redirect          off;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        Host $http_host;
        client_max_body_size   10m;
        proxy_connect_timeout  300;
        proxy_send_timeout     300;
        proxy_read_timeout     300;
        proxy_buffer_size      16k;
        proxy_buffers          4 32k;
        proxy_busy_buffers_size 64k;
        proxy_temp_file_write_size 64k;
        access_log  logs/access.log  main ;
        access_log on;
        proxy_pass              http://www_test_com;
        }
     }

  重新加载nginx配置,在浏览器里输入http://192.168.1.41,又看到经典页面。 

简单做个压力测试,结果如下,cup主频3.0。

# ./ab -c1000 -n10000 http://192.168.1.41:8880/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.1.41 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software: TornadoServer/2.1.1
Server Hostname: 192.168.1.41
Server Port: 8880

Document Path: /
Document Length: 21 bytes

Concurrency Level: 1000
Time taken for tests: 8.013 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1790000 bytes
HTML transferred: 210000 bytes
Requests per second: 1247.92 [#/sec] (mean)
Time per request: 801.331 [ms] (mean)
Time per request: 0.801 [ms] (mean, across all concurrent requests)
Transfer rate: 218.14 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 166 680.6 0 3004
Processing: 20 115 46.5 100 873
Waiting: 20 115 46.5 100 873
Total: 47 281 686.0 100 3325

Percentage of the requests served within a certain time (ms)
50% 100
66% 101
75% 106
80% 124
90% 290
95% 3105
98% 3134
99% 3149
100% 3325 (longest request)

但是通过nginx负载后性能却下降,部分结果如下:
Failed requests: 9609
(Connect: 0, Receive: 0, Length: 9609, Exceptions: 0)
Write errors: 0
Non-2xx responses: 391
Total transferred: 2256920 bytes
HTML transferred: 274515 bytes
Requests per second: 714.81 [#/sec] (mean)

总结:tornado性能不错,但是nginx负载后直接使用proxy转发,耗费在连接上的资源比较高。这个和资料里介绍的出入较大,以后再找详细原因。如果单从性能讲nginx+uwsgi+django的组合效率不错。如果要使用tornado在多核服务器上工作,有两个方案,一使用lvs做底层的负载,二在开发中在代码里使用多线程进行处理。tornado对于wsgi文档中原文“Tornado 对 WSGI 只提供了有限的支持,即使如此,因为 WSGI 并不支持非阻塞式的请求,所以如果你使用 WSGI 代替 Tornado 自己的 HTTP 服务的话,那么你将无法使用 Tornado 的异步非阻塞式的请求处理方式。比如 @tornado.web.asynchronous、httpclient 模块、auth 模块,这些将都无法使用。”还要说明,node.js是非常快,但是node.js+express后效率并不理想,闲人可以测试一下。

听说gevent也不错,但是粗看了一下,没有看到中文文档。tornado对于个人来说,这个性能已经满足需要了。开始进一步学习。

5月 20

vsftp 自用配置

直接用yum安装vsftp非常简单,然后将配置拷贝到配置文件中重启即可,自用配置在这做个记录。
配置文件/etc/vsftpd/vsftpd.conf
配置如下
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
#chroot_local_user=YES
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
xferlog_file=/var/log/vsftpd.log
idle_session_timeout=600
data_connection_timeout=120
ls_recurse_enable=NO
pam_service_name=vsftpd
userlist_enable=YES
ftpd_banner=Welcome to blah FTP service.
max_clients=10
max_per_ip=3
use_localtime=YES
listen=YES
tcp_wrappers=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/vsftpd.chroot_list

然后手动建立/etc/vsftpd/vsftpd.chroot_list
将系统中可以用来登录ftp的账户放在里面。
注意:ftp账户也可以有操作系统登录权,所以登录用户需要规划。

12月 16

python 在linux上处理图片的错误处理

在CentOS 5.4 64位上安装了python2.6和PIL模块处理图片。
遇到问题1:
Traceback (most recent call last):
 File “aimg.py”, line 3, in
  img.save(‘/program/upload/b.jpg’,’JPEG’)
 File “/usr/local/lib/python2.6/site-packages/PIL-1.1.7-py2.6-linux-

x86_64.egg/Image.py”, line 1406, in save
 self.load()
 File “/usr/local/lib/python2.6/site-packages/PIL-1.1.7-py2.6-linux-

x86_64.egg/ImageFile.py”, line 189, in load
  d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
 File “/usr/local/lib/python2.6/site-packages/PIL-1.1.7-py2.6-linux-

x86_64.egg/Image.py”, line 385, in _getdecoder
  raise IOError(“decoder %s not available” % decoder_name)
IOError: decoder jpeg not available

处理方法:
# rm -rf /usr/local/lib/python2.6/site-packages/PIL-1.1.7-py2.6-linux-x86_64.egg
# rm -rf /usr/local/lib/python2.6/site-packages/PIL.pth
# yum install -y libjpeg* freetype* zlib*
# easy_install PIL

遇到问题2:
WARNING: ” not a valid package name; please use only.-separated package names in setup.py
_imaging.c:75:20: error: Python.h: No such file or directory
In file included from libImaging/Imaging.h:14,
from _imaging.c:77:
libImaging/ImPlatform.h:14:2: error: #error Sorry, this library requires support for ANSI prototypes.
libImaging/ImPlatform.h:17:2: error: #error Sorry, this library requires ANSI header files.
libImaging/ImPlatform.h:55:2: error: #error Cannot find required 32-bit integer type
In file included from _imaging.c:77

处理方法:
yum install python-imaging
yum install python-dev
python PIL

再次测试问题解决。

12月 11

新服务器的硬件测试

【2011-12-09 整理人:simon-zzm@163.com】
新买的服务器安装CentOS的操作系统,需要测试服务器硬件的稳定性。如果不运行服务
空跑根本没有意义,所以使用压测软件进行测试。
本次测试使用到stress软件,网站地址如下:
http://weather.ou.edu/~apw/projects/stress/
如果是服务器没有安装操作系统也可以到以下的网站下载iso或usb基本操作系统加压力软件的
集合。网站地址如下:
www.stresslinux.org

本次只是记录使用stress的过程。
stress用C编写,可以运行在x86,ppc64和PPC 32 GNU / Linux的,Tru64的,SPARC Solaris的平台。
可以自由配置参数,对cpu、内存、IO进行测试。

软件下载、编译、测试
为了避免编译失败,建议先确认已经安装gcc编译器。
# yum -y gcc*
# wget http://weather.ou.edu/~apw/projects/stress/stress-1.0.4.tar.gz
# tar zxvf stress-1.0.4.tar.gz
# cd stress-1.0.4
# ./configure && make

至此已经编译完毕,本软件不打算安装,所以直接使用。
# cd /root/stress-1.0.4/src
# ./stress –cpu 8 –io 8 –vm 8 –vm-bytes 32000M –timeout 180s

服务器的硬件为4核双cpu,32G内存,测试180秒中。所以使用以上命令,io和vm后的8为8个
进行,vm-bytes为32G的内存。

使用感受,能将所有的硬件资源耗尽,但是如果运行时间过长,就不知道是死机还是再测试了。
更主要的是测试完毕也没有测试报告生成。