使用Flask+Gunicorn+Supervisor+Nginx把应用部署到服务器时,出现了编码问题。

File "/srv/www/biu/venv/lib/python3.4/site-packages/werkzeug/datastructures.py", 

line 2653, in save
    dst = open(dst, 'wb')

UnicodeEncodeError: 'ascii' codec can't encode characters

in position 56-60: ordinal not in range(128)

文件名的确有中文,但是在本地测试的时候没有问题啊!在本地采用的是'UTF-8'进行编码,但是在服务器怎么就是'ASCII'了?

Python How-To中,查到了以下信息:

Most of the operating systems in common use today support filenames that contain arbitrary Unicode characters. 

Usually this is implemented by converting the Unicode string into some encoding that varies depending on the system. 

For example, Mac OS X uses UTF-8 while Windows uses a configurable encoding; on Windows, Python uses the name “mbcs” to refer to whatever the currently configured encoding is.

 On Unix systems, there will only be a filesystem encoding if you’ve set the LANG or LC_CTYPE environment variables; 

if you haven’t, the default encoding is UTF-8.

在Ubuntu上存文件时,文件名是按照LANG的设定来encode的。看了看服务器上的设置为:

abuntu@abuntu:~$ echo $LANG
en_US.UTF-8
abuntu@abuntu:~$ 

没问题啊啊啊

不用Supervisor,手动启动Gunicorn,发现编码错误又没啦。那肯定就是Gunicron的问题啊。

Gunicorn的配置项中有user的配置,之前配的是www-data。尝试着将user改为当前登陆的用户abuntu,居然特么的就好了!!!

原来是www-data的LANG设置是'ASCII'。把user改成abuntu算了。

Update 03.28

昨天明明是按照上面的分析改了supervisor 的user 字段,运行了一下没问题啊。

但是今天又特么出现编码问题了。可能是昨天搞得太晚,测试时仍旧用的是手动启动的Gunicorn吧。

查到了这篇文章, 果真如其所言,手动启动的Gunicorn 的locale('en_US', 'UTF-8'), 而用Supervisor启动的是(None, None)

尝试用locale.setlocale(locale.LC_ALL,'en_US.UTF-8'),结果还是不行。

然后通过搜索关键字 gunicorn locale 查到了解决方案

Supervisor的配置文件/etc/supervisor/supervisor.conf[supervisord]项目下,加入以下内容即可解决问题

environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8,LC_LANG=en_US.UTF-8

参见官方文档