12月 08

换个好阿姨

  老婆的同事送了我家小家伙一桶彩泥。小家伙非常喜欢,一天要拿出来玩狠多次。
  但是有个不好解决的问题,小家伙总是把所有的东西都拿出来扔的满地都是,还不收拾。没有办法只能想了一个办法,拿起电话假装打起来,然后告诉小家伙:“如果你不收好。阿姨就会把玩具要回去。”此招还是挺有用,小家伙会马上收拾好。但是重复了几次后,有点不灵了。我就说你不话阿姨就要拿回去给听话小朋友玩了。小家伙说:“把阿姨打扁。”我说:“你打人家,那阿姨更要拿走了。”小家伙说:“开呜呜(汽车),带回家。”。我说:“那阿姨要来家里拿。”小家伙想了一会说:“要不换个好阿姨吧!”我当时就凌乱了,难道好阿姨就喜欢不听话的小孩。哈哈哈。
  小家伙,一岁是一个月。

12月 04

python和C统计jpeg图片RGB值的效率

  测试硬件pcduino(arm),操作系统ubuntu 3.4.29+ armv7l GNU/Linux。测试文件,图片jpeg,大约1.3M。测试内容统计图片的RGB里的值,存在数据库里将来看看能不能做搜索用。
  先是用python,开发速度非常快,但是效率有点问题,所以有用C做了一下。以下是代码和两次的测试结果。C使用的jpeglib库8.0版本。

python代码

#!/bin/python
#-*- coding:utf-8 -*-
# Filename:   
# Revision:    1.0
# Date:        2013-12-04
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
### END INIT INFO
from PIL import Image
# 对RGB简历字典
R = {}
G = {}
B = {}
# 初始化值
for i in xrange(256):
    R[i] = 0
    G[i] = 0
    B[i] = 0
# 大图片需要处理很长时间,所以要用python可以按比例将图缩小
a = Image.open('123.jpg')
#a = a.resize((int(a.size[0] * 0.1), int(a.size[1] * 0.1)), Image.ANTIALIAS)
x = a.size[0]
y = a.size[1]

# 循环处理每个像素点的RGB值
for lx in xrange(x):
    for ly in xrange(y):
        rgb = a.getpixel((lx, ly))
        R[rgb[0]] += 1
        G[rgb[1]] += 1
        B[rgb[2]] += 1
# 打印最终结果
print sorted(R.items(), key=lambda R:R[1],reverse=True)[0]
print sorted(G.items(), key=lambda G:G[1],reverse=True)[0]
print sorted(B.items(), key=lambda B:B[1],reverse=True)[0] 

C代码

/*
*Filename:   
* Revision:    1.0
* Date:        2013-12-04
* Author:      simonzhang
* web:         www.simonzhang.net
* Email:       simon-zzm@163.com
*/
#include 
#include 
#include 

/* we will be using this uninitialized pointer later to store raw, uncompressd image */
//unsigned char *raw_image = NULL;
/* */
int max_num;

/* find max values*/
int sort_values(int arr[255])
{
    int largest1, largest2, temp;
    max_num = 0;
    largest1 = arr[0];
    largest2 = arr[1];
    if (largest1 < largest2)
    {
        temp = largest1;
        largest1 = largest2;
        largest2 = temp;
    }
    int i;
    for (i = 2; i < 255; i++)
    {
        if (arr[i] >= largest1)
        {
            largest2 = largest1;
            largest1 = arr[i];
            max_num = i;
        }
        else if (arr[i] > largest2)
        {
            largest2 = arr[i];
        }
    }
    return largest1;
}


read_jpeg_file(char *filename)
{
    /* these are standard libjpeg structures for reading(decompression) */
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    /* libjpeg data structure for storing one row, that is, scanline of an image */
    JSAMPROW row_pointer[1];
    FILE *infile = fopen( filename, "rb" );
    unsigned long location = 0;
    int i = 0;
    if ( !infile )
    {
        printf("Error opening jpeg file %s\n!", filename );
        return -1;
    }
    /* here we set up the standard libjpeg error handler */
    cinfo.err = jpeg_std_error( &jerr );
    /* setup decompression process and source, then read JPEG header */
    jpeg_create_decompress( &cinfo );
    /* this makes the library read from infile */
    jpeg_stdio_src( &cinfo, infile );
    /* reading the image header which contains image information */
    jpeg_read_header( &cinfo, TRUE );
    /* Uncomment the following to output image information, if needed. */
    /* Start decompression jpeg here */
    jpeg_start_decompress( &cinfo );
    /* allocate memory to hold the uncompressed image */
    //raw_image = (unsigned char*)malloc( cinfo.output_width*cinfo.output_height*cinfo.num_components );
    /* now actually read the jpeg into the raw buffer */
    row_pointer[0] = (unsigned char *)malloc( cinfo.output_width*cinfo.num_components );
    /* read one scan line at a time */
    int r[255], g[255], b[255];
    for(i=0;i<255;i++)
    {
        r[i] = 0;
        g[i] = 0;
        b[i] = 0;
    }
    while( cinfo.output_scanline < cinfo.image_height )
    {
        jpeg_read_scanlines( &cinfo, row_pointer, 1 );
        for( i=0; i

先是测试python部分
#time python countrgb.py

(12, 510858)
(17, 429677)
(9, 662996)

real 11m4.009s
user 10m42.200s
sys 0m1.090s

开始测试C的部分
首先优化编译一下
#gcc countrgb.c -l jpeg -O3 -o countrgb
#time ./countrgb 123.jpg
12,510858
17,429677
9,662996

real 0m0.750s
user 0m0.730s
sys 0m0.010s

  两次统计结果相同,说明统计方法没有问题。python用了11分钟,C用了0.75秒,看来真的不是一般的快了。C代码编译后的文件8K,静态编译500多K。不过我是喜欢用python,开发速度快,结构清晰。

11月 24

要吃棒棒

  据说小孩子吃甜食多了不好,会影响到智力。但是小糖豆对那个裹着巧克力的棒棒糖却情有独钟。道理对于一岁十一个月的小家伙也讲不通,没有办法只能骗他。告诉他有个小仙女管理着棒棒,如果小糖豆乖,妈妈下班回来就会和小仙女要棒棒给糖豆吃。当然棒棒糖是提早买好放在厨房高出,所以还有一条规则就是,糖豆要乖乖的在客厅里等。
  晚上小家伙吃了不少,估计也不想起巧克力棒棒的事情。就在家里人各忙各的事情时,小糖豆自己走进了厨房。为了防止发生危险我悄悄跟了上去,当我走到厨房门口时,便听到小糖豆说“仙女、豆豆、想吃棒棒”。我偷偷把头探进去,看到小糖豆正站在橱柜前,抬头看着高处的柜子,虔诚的又说了一遍“仙女、豆豆、想吃棒棒”。还是没有结果,小糖豆低着头,一边慢慢走一边用两个小手拍着屁股。我假装没有看到,去了趟厕所,糖豆也到沙发前开始玩自己玩具。
  

11月 19

pcduino对比测试nginx和haproxy的负载效果

  在pcduino上对比haproxy和nginx的负载效果

  安装haproxy
  下载地址
http://www.haproxy.org/download/1.4/src/haproxy-1.4.24.tar.gz

  安装如下
make TARGET=linux26 ARCH=arm PREFIX=/program/haproxy
make install PREFIX=/program/haproxy

配置如下:

global
        log 192.168.1.132   local0
        #log 127.0.0.1  local1 notice
        #log loghost    local0 info
        maxconn 4096
        chroot /program/haproxy
        uid 0                          #所属运行的用户uid
        gid 0                         #所属运行的用户组
        daemon
        nbproc 1
        pidfile /program/haproxy/run/haproxy.pid
        #debug
        #quiet

defaults
        log     global
        log     192.168.1.132       local3        #日志文件的输出定向
        mode    http                            #所处理的类别
        option  httplog                        #日志类别
        option  httpclose
        option  dontlognull
        option  forwardfor
        option  redispatch
        retries 2                      #设置多个haproxy并发进程提高性能
        maxconn 2000
        balance roundrobin                     #负载均衡算法
        stats   uri     /haproxy-stats        #haproxy 监控页面的访问地址
        # 可通过 http://localhost:1080/haproxy-stats 访问
        contimeout      5000
        clitimeout      50000
        srvtimeout      50000

listen  localhost 0.0.0.0:1080                   #运行的端口及主机名
        mode    http
        option  httpchk GET /           #健康检测地址
        server  s1 192.168.1.132:9900 weight 3 check
        server  s2 192.168.1.80:8880 weight 3 check

简单操作如下:
启动服务:
# /program/haproxy/sbin/haproxy -f /program/haproxy/haproxy.cfg

重启服务:
# /program/haproxy/sbin/haproxy -f /program/haproxy/haproxy.cfg -st `cat /program/haproxy/logs/haproxy.pid` (没有换行)

停止服务:
# killall haproxy

#./haproxy -h 说明
-v 屏蔽版本
-vv 编译选项
-V 版本
-d 前台,debug模式
-db 屏蔽后台模式
-D daemon模式启动
-q 安静模式,不输出信息
-c 对配置文件进行语法检查
-s 显示统计数据
-l 显示详细统计数据
-ds 不使用speculative epoll
-de 不使用epoll
-dp 不使用poll
-sf 程序启动后向pidlist里的进程发送FINISH信号,这个参数放在命令行的最后
-st 程序启动后向pidlist里的进程发送TERMINATE信号,这个参数放在命令行的最后

  安装nginx
  下载地址
http://nginx.org/download/nginx-1.5.6.tar.gz
  首先安装pcre。
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.33.tar.gz
然后是configure、make、make install。
最后做个软连接。
ln -s /usr/local/lib/libpcre.so.1 /usr/lib/

  开始安装nginx编译参数如下
./configure –prefix=/program/nginx –user=root –group=root –with-pcre –with-select_module –with-poll_module –with-http_stub_status_module –with-http_ssl_module –with-http_realip_module –with-http_gzip_static_module
配置如下

user  root root;
worker_processes 1;
pid        logs/nginx.pid;
events {
    use epoll;
    worker_connections  5120;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    server_tokens off;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$request_time" '
                      '"$upstream_cache_status"';
    access_log  logs/access.log  main ;
    sendfile        on;
    keepalive_timeout  120;
    tcp_nodelay on;
    tcp_nopush on;
    client_header_buffer_size 128k;
    large_client_header_buffers 4 64k;
    reset_timedout_connection on;
    proxy_ignore_client_abort on;
   ######################################
   upstream  deploy_tool {
            server 192.168.1.132:9900;
       }
   server {
        listen       80;
        server_name 192.168.1.132;
        location / {
        proxy_pass_header      Server;
        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   150m;
        proxy_connect_timeout  2000;
        proxy_send_timeout     2000;
        proxy_read_timeout     300;
        access_log off;
        proxy_pass              http://deploy_tool;
        }
        location /status {
             stub_status on;
             access_log  off;
             auth_basic_user_file    /lnmp/nginx/conf/htpasswd;
        }
     }
}

  WEB项目使用我的部署工具,只是连接到首页。python使用2.7。压力工具就是写了用urllib2多线程获取页面的代码,并发150个。测试结果如下:
haproxy:
haproxystatus
ubuntu
nginx:
nginxstatus
ubuntu-nginx

结论:
  如果只是简单反向连接,两者效率差不多。haproxy后端检测效果不错,对长连接的处理也很好,可做mysql等其他服务器的负载工作。nginx有更强大的模块,如缓存、uwsgi等功能一起用,nginx就方便了很多。以后WEB的服务使用nginx,其它需要负载的使用haproxy。

11月 18

枕巾

  小家伙一岁十个月。开始模仿大人做事情。那大人给自己不公平的待遇了,就需要自己动手丰衣足食。开始讲讲自己动手的故事。
  中午要开饭了,想先擦一下桌子,但是发现抹布不见了。在客厅里四下找了找,也没有发现抹布踪影,于是找了张纸胡乱的擦了一通。饭后准备睡个午觉,发现抹布整整齐齐的放在小家伙的枕头上。
  原来是小家伙看到我们都有枕巾,而自己只是睡在一个纯棉的、裸着的枕头上表示不公。