uwsgi 1.9+ mountpoint error

最近团队开发新产品,顺带折腾更新了服务器和整个开发环境版本。

运行python的服务uwsgi从0.9+升级到了最新的1.9+,发现一个bug,折腾了我一个通宵……

uwsgi原有的版本,vhost模式下,可以在nginx中配置SERVER_NAME来指定服务名。


location / {
    include uwsgi_params;
    uwsgi_pass unix:/var/run/uwsgi-python/sock;
    uwsgi_param UWSGI_PYHOME /usr/local/pyenv/app;
    uwsgi_param UWSGI_CHDIR  $document_root;
    uwsgi_param UWSGI_SCRIPT app_name:app;
    uwsgi_param SERVER_NAME app_name;
}

该配置会指定服务名并在uwsgi启动日志中显示

WSGI app 0 (mountpoint='app_name')

但是在最新的uwsgi v1.9.12中,该配置失效,无法正确的配置mountpoint,日志会显示

WSGI app 0 (mountpoint='')

这会导致访问指定地址时在不同的app之间跳来跳去,无法正常使用。经测试1.9.12~1.9.7均存在同样问题,1.9.5版本以下会指定server+port替代

WSGI app 2 (mountpoint='domain_name:8080|')

我在github上提交了该bug,https://github.com/unbit/uwsgi/issues/321,作者修复之前建议大家先使用1.9.5版本。

NOTE:
作者已经修复了该bug,不过仍使用了server+port的模式,不知道是出于什么理由。目前版本已更新到1.9.13,通过pip install -U uwsgi可更新安装。

PIL MemoryError with uWSGI

用PIL库处理图片,作缩略图的时候需要先裁减为正方形,再比例缩小,当裁减时不定报错。


img = img.transform((r,r), Image.EXTENT, area)

#ERROR
File "/usr/local/lib/python2.7/dist-packages/PIL/ImageFile.py", line 231, in load_prepare
    self.im = Image.core.new(self.mode, self.size)
MemoryError

google PIL+MemoryError,主要提到2个可能错误。一个是PIL库本身ctype代码问题,一个是传递裁减范围为负值导致内存问题。仔细检查了一下,都没有异常。后来考虑到上面的代码为创建新图像时内存错误,直接调整了uwsgi参数。

-M -p 2 --no-orphans --logdate --chmod-socket=666 --uid admin --gid admin --limit-as 384 --harakiri 60 --max-requests 2000

[–limit-as]参数从256调整到384,系统恢复正常。

反思查找原因,发现图片文件虽然不大仅3M+,但是该图片像素巨大为4096*5210,将该图片转换为BMP,有60M+。估计库在处理图片裁减时会将jpg文件重新读取为完整位图,再考虑到操作位图消耗和程序本身需要的内存空间,原设定256M限制肯定不足了,需要设定更大。

目前程序运行在一个虚拟机上,内存2G……看来需要尽快切换主机了……

Setup on Linode.com with ubuntu+nginx+php+fastcgi+mysql

我对Linux系统还处于初入门阶段,在配置安装Linode VPS的服务过程中学到了不少东西,了解了不少概念,特记之。

  1. 启用

    Linode的网站设计非常简洁,一个粗略认识英文的同学都可以轻易申请搞定,就不需要再介绍了。

    在选择服务器网络物理位置的时候,Linode提供了一个下载测试列表供大家测试,你可以选择访问速度最优的位置。网上其它同学很多选择Fremont,不过我测试下来(杭州ADSL4M)Newark最快,浏览器单线程下载速度稳定达到300K+,所以我选择了Newark。估计各地网络不同有所区别,大家选用建议自行测试。

    系统我选择的是ubuntu(嗯,已经提供9.10Server了),主要是出于我对ubuntu桌面版的使用习惯和偏爱。网上很多说法是ubuntu服务器版不够专业,不过我本来也不太够专业,也不知道ubuntu哪里不够专业,呵呵,也就无所谓了。

  2. 环境基本配置

    在web面板开启虚拟机以后,你就可以通过root用户和密码在客户端(推荐putty)登录。登陆后第一件事情,增加一个新账号(用你的常用名 例如myname)。

    adduser myname
    visudo
    

    在该文件中增加以下行

    myname ALL=(ALL) ALL
    

    此操作使myname用户可以使用sudo命令,如果要给其他账号提供sudo操作权限,类推。

    ok,exit命令退出putty登录再重启,通过myname账号和你设置的密码重新登录系统。Linode默认提供的ubuntu的源缺少一些开发包,所以我们先编辑一下源。

    sudo vi /etc/apt/source.list
    

    我们需要做的仅仅是将文件中已经注释掉的几行源去掉前面的“#”,重新开启即可——不需要为具体的源担心,默认的已经飞速了。然后我们需要刷新一下

    sudo apt-get update
    

    我习惯使用vim,所以先安一个

    sudo apt-get install vim
    

    我们还需要一个中文UTF的本地环境,不过这得看情况,也许你不需要?

    sudo locale-gen zh_CN.UTF-8
    sudo /usr/sbin/update-locale LANG=zh_CN.UTF-8
    

    将服务器时间设置为上海时间

    sudo cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    
  3. nginx+spawn-fastcgi+php+mysql

    我们先来安一个编译包吧

    sudo apt-get install build-essential
    

    然后php和mysql安装最方便,直接从apt源安装即可

    sudo apt-get -y install php5-common php5-mysql php5-sqlite php5-tidy php5-xmlrpc php5-xsl php5-cgi php5-mcrypt php5-curl php5-gd php5-memcache php5-mhash php5-pspell php5-sqlite libmagick9-dev php5-cli
    sudo apt-get install mysql-server mysql-client libmysqlclient15-dev
    

    php的安装命令我是copy的,然后去掉了一些不必要的包,如果你觉得不必要也可以去掉,真正基本环境必须的只有php5 php5-cgi而已。mysql在安装过程中会让你设置root的密码,不要设置太简单了,也不要和系统root密码一样。

    然后我们需要安装nginx

    cd ~
    mkdir source
    cd source
    wget http://sysoev.ru/nginx/nginx-0.7.64.tar.gz
    tar -zxvf nginx-0.7.64.tar.gz
    cd nginx-0.7.64
    sudo apt-get install libssl-dev libpre3-dev zlib1g-dev
    ./configure --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --with-md5-asm --with-md5=/usr/include --with-sha1-asm --with-sha1=/usr/include --with-http_stub_status_module
    make
    sudo make install
    

    在configure的时候可以定义很多参数,官方的参考文档在这里。我在网上看的相关的文章,定义了很多路径的参数,也许有什么特别的理由或习惯需要特别定义,我不太了解,所以我都去掉了,就用默认的路径就好。nginx默认的安装路径是/usr/local/nginx,其中包含了配置、基本的html页面、log、站点设置等。with-md5-asm和with-sha1-asm官方wiki说只建议使用一种,不过只用一种我无法通过编译,不知道问题所在。另外with-http_stub_status_module可以开通nginx内置的状态统计功能,建议都配置上,后面会开启该功能。

    然后我们来安装spawn-fcgi,这是lighttpd的fastcgi管理器,目前已经是独立项目了,当前最新版本是1.6.3。

    cd ~/source
    wget http://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.gz
    tar -zxvf spawn-fcgi-1.6.3.tar.gz
    cd spawn-fcgi-1.6.3
    sudo ./configure && make && make install
    

………

做的事情不多,要写清楚真累,太长了,休息下,明天再整理。