关于Pillow安装不当导致Server Error(500)问题的解决

关于Pillow安装不当导致Server Error(500)问题的解决

基于Python的Web框架Django,完成个人博客(https://www.solutionworks.cn)开发,目前已经成功部署到阿里云服务器ECS,主要是基于CentOS系统和Nginx和Uwsgi进行部署,目前博客前端可以正常访问,后台大部分功能也可以正常访问(博客分类、友情链接、推荐位置、文章标签等增加修改功能均正常),唯独文章发布模块的增加文章和已发布文章的修改功能不能正常运作(页面错误提示信息:Server Error (500)))。本文记录了问题的发现与排查解决过程。

一、  基本条件

本文使用的Django版本为3.0版,python版本为3.8.3,MySQL为5.7.26,uWSGI版本为2.0.19.1,Nginx版本为1.14.1,Pillow版本为7.2.0,系统为CentOS 8.0。

二、  问题描述

进入博客管理后台,如下图所示:

image.png

分别点击博客分类友情链接推荐位置文章标签等内容增加修改功能均正常,点击发布文章功能进入如下页面

image.png

随后点击“增加发布文章”出现如下错误信息:

image.png

点击ID号为2、已经发布文章的标题,出现错误信息如下:

image.png

为了进一步比对及定位问题,提供功能正常模块(如博客分类)对应部分(如增加功能)的信息,运行正常,信息如下:

image.png

通过比对,运行正常模块和不正常模块的区别在于:

运行正常的模块,动态代码及访问路径下会同时生成index和jsi18n子目录和index文件;而运行出现异常的模块,不会生成jsi18n子目录和index文件。

在服务器端文章发布环节,选择文章对应缩略图,完成文章编写并提交保存时,发生错误,在浏览器中的错误信息为:Server Error(500)。发布文章时,如果不选择文章对应缩略图,点击保存按钮,一切正常;在本地选择文章对应缩略图后,发布文章时并不存在上述问题。显然,问题很可能出在文件上传保存环节(此时并没有意识到是支持包安装错误导致的问题)。

既然在本地环境测试文章发布功能一起正常,那么很大概率在代码、环境设置、文件上传路径方面应该不会存在问题。但是,还是进行了核实,核实的环节包括:

1.  上传目录设置

在服务器端,建立了media目录,settings.py文件中也进行了相应的设置。

2.  Article的Model声明部分

content = UEditorField('内容', width=800, height=500,
               
toolbars="full", imagePath="upimg/", filePath="upfile/",
               
upload_settings={"imageMaxSize": 1204000},
               
settings={}, command=None, blank=True
               
)

代码正常,应该没有问题。

3.  服务器端文件存放目录核查

服务器端文件目录media下的子目录 article_img 用来存放每一个文章对应的图片(类似文章封面预览图),目前无法保存。

服务器端文件目录media下的子目录upimg 用来存放每一篇文章内容里面的图片,文章保存之后,文章内容里面的图片目前可以保存至upimg目录下。目录 article_img和upimg 读写权限是一致。

三、    解决方法

1. 查看Nginx访问记录文件

在Nginx访问记录文件(access.log)中,发现如下相关信息:

XXX.XXX.XXX.XXX - - [26/Aug/2020:11:41:35 +0800] "GET /admin/jsi18n/HTTP/1.1"200 7722 "http://xxx.xxx.xxx.xxx/admin/blog/article/3/change/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"

XXX.XXX.XXX.XXX - - [26/Aug/2020:11:41:35 +0800] "GET /ueditor/controller/?imageMaxSize=1204000&imagePathFormat=upimg%2F&filePathFormat=upfile%2F&action=config&&noCache=1598413295748 HTTP/1.1" 200 2171 "http://xxx.xxx.xxx.xxx/admin/blog/article/3/change/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"

XXX.XXX.XXX.XXX - - [26/Aug/2020:11:42:11 +0800] "POST /admin/blog/article/3/change/ HTTP/1.1" 500 145 "http://xxx.xxx.xxx.xxx/admin/blog/article/3/change/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"

error.log中的信息为:2020/08/26 11:41:14 [error] 208449#0: *1 directory index of "/home/iblog/media/" is forbidden, client: XXX.XXX.XXX.XXX, server: xxx.xxx.xxx.xxx, request: "GET /media/ HTTP/1.1", host: "xxx.xxx.xxx.xxx", referrer: http://xxx.xxx.xxx.xxx/

2. 数据库记录查看确认

在服务器端,连接MySQL数据库,通过执行如下SQL语句:

select itle,img,status,views,created_time,modified_time from  blog_article;

查询服务器数据库中数据表blog_article的内容,结果如下:

image.png

(1)上图中绿色方框内, img 字段的2条记录内容是在本地测试时生成的记录,在本地导出数据库内容,在服务器端通过 source 命令导入数据库,表明在本地写入数据表 blog_article 的字段 img 是没有问题的;

(2)上图中黄色方框内, img字段没有内容,是在部署到服务器后进行测试,表明在服务器端,上传图片的名称(含路径)根本没有写入到数据表 blog_article 的 img 字段中 。

由此,可以猜测:

(1)在服务器端,写入数据表 blog_article 的字段 img 产生异常;

(2)产生字段写入异常之后,估计导致保存文章的过程中止,因此,在服务器端的目录media/article_img/2020/08/01中没有存入文章对应封面图片。

3. 排查服务器端支持包的安装情况

登录服务器端,进入虚拟环境,查看支持包的安装情况。

指令:workon py3.8-venv,pip list

发现在虚拟环境下,Pillow已经安装,退出虚拟环境。执行pip list命令,发现Pillow并没有安装。

该不是在虚拟环境中安装了Pillow,而在CentOS系统中没有安装Pillow的原因吧?简直无语了……

到此,问题基本明朗了,执行如下命令:

pip install pillow

完成Pillow 安装,重新启动Nginx和uWSGI Web服务器,重新测试,功能一切正常。

重新进入虚拟环境,卸载Pillow 后,再次测试,功能正常。

四、    结论

1. 表明只在 CentOS系统中安装 Pillow 即可,虚拟环境中根本不需要安装 Pillow

2. 始终要明确开发应用过程中所用到的支持包,确保在部署应用时全部安装,否在在后续部署测试过程中导致的问题以及解决问题的成本比较高。


  • 用户名:test001 评论时间:2020年10月28日 00:14

    基础不扎实,很容出问题啊