10月 16

用Nginx为uwsgi后端图片服务器做缓存服务

  很早处理的问题,现在拿出来做个记录。
  需求:后端图片服务处理各种格式、尺寸的图片。使用python处理,系统为Django+uwsgi(其实直接用tornado更好,也更方便)。前端需要做缓存,直接使用nginx。当前问题nginx和uwsgi连接后就不能使用cache服务了,nginx的proxy cache服务是在upstream的流转发过程中实现。所以要做个内部转发。nginx部分配置如下:

日志部分,添加缓存记录方将来统计击中率,参数为upstream_cache_status。
日志的中表示说明
MISS 未命中,请求被传送到后端
HIT 缓存命中
EXPIRED 缓存已经过期请求被传送到后端
UPDATING 正在更新缓存,将使用旧的应答
STALE 后端将得到过期的应答

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”‘;

转发的主要部分

upstream  local_img {
   server localhost:81;
   }
server{
       listen       81;
       server_name 127.0.0.1;
       location / {
                uwsgi_pass   127.0.0.1:9000;
                client_max_body_size   10m;
                include       uwsgi_params;
                access_log  off;
                autoindex off;
                }
    }

server {
       listen       80;
       server_name imgtest.simonzhang.net ;
       location / {
                #proxy cache stat
                proxy_redirect          off;
                proxy_set_header        Host            $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_connect_timeout   15;
                proxy_send_timeout      45;
                proxy_read_timeout      45;
                proxy_buffer_size       128k;
                proxy_buffers           4 128k;
                proxy_busy_buffers_size 128k;
                proxy_temp_file_write_size 128k;
                proxy_cache cache_one;
                # 成功浏览过的图片5天过期
                proxy_cache_valid 200 5d;
                proxy_cache_valid 404 304 1m;
                proxy_cache_key $host$uri$is_args$args;
                #add_header X-Cache $upstream_cache_status;
                proxy_pass http://local_img;
                #proxy cache end
                }
    }

  重启nginx服务后查看日志,日志中已经有了HIT的日志,日志显示使用处理耗时0.000ms。收工。

10月 15

无聊的内存操作

  今天一哥们说他内存曲线是均匀锯齿状。这对python太简单了,就是对内存添写和释放就行。我无聊之下写了下面的代码。

import StringIO
import time

for i in range(100):
    context = a * 2048 * 100000
    a=StringIO.StringIO(context)
    time.sleep(2)
    a.close()
    context = b * 1024 * 10
    a=StringIO.StringIO(context)
    time.sleep(1)
    a.close()

内存图形如下:
内存图形

9月 23

python到mysql 2006问题解决

  tornado和Django框架都是使用MySQLdb,在长时间不与数据库有交互,如采集、SQL运行数据过大而数据库等待时间过短等,这时会报“Error 2006: MySQL Server has gone away”错误。收集了网上的三个解决方案是,
  一、修改数据库的参数wait_timeout,interactive_timeout到2880000,
  二、在每次连接时做判断,如果报错将再连接一次(http://xulizhao.com/blog/python_db)。

class DB:
    conn = None
    def connect(self):
        self.conn = MySQLdb.connect(localhost,root,pass,test)
    def cursor(self):
        try:
            return self.conn.cursor()
        except (AttributeError, MySQLdb.OperationalError):
            self.connect()
            return self.conn.cursor()

  三、定时进行连接,以防断开

from tornado.ioloop import PeriodicCallback

#torndb.Connection(host, database, user=None, password=None, max_idle_time=25200, connect_timeout=0, time_zone='+0:00')
db = torndb.Connection(db_ip, db_database, db_user, db_pass, db_conn_time)
# https://github.com/felinx/poweredsites/blob/master/poweredsites/db/mysql.py
# ping db periodically to avoid mysql go away
PeriodicCallback(db.query(show variables), 3600*4*1000).start()

我的测试,第一种方法比较好用,但是在某些情况下会造成其它问题。第三种效果不理想,需要继续研究。第二种正在试验中。