一次完整地将项目上线的经历
Kale

之前看到计网的课程设计指导书上面写了鼓励自拟题目,想着现在正好是疫情期间,要不就写个和疫情相关的吧,所以之前就开始写计网的项目了.写了4天多吧,终于写完了,刚好撸了个服务器,就想着放到服务器,但是遇到了很多问题,现在把过程记录下来.

项目设计

既然涉及到疫情,那肯定需要疫情的数据,数据哪里来的问题,首先的想法就是从现有的百度和丁香医生等平台去爬取数据,不过百度和丁香医生的接口都没有公开,只有网易的接口是可以看到的,所以就选了网易的接口,后端爬取数据送到前端.

另外疫情部分除了疫情数据之外,也用echarts画了一张折线图,echarts的文档实在是太多了,花了很长时间才画好图片.

疫情部分结束后,项目的核心其实还是留言板,留言板最开始只设计了留言和回复功能,慢慢加上了点赞,点踩,设置头像功能.这一块最主要的就是数据库的设计,数据库设计方面,将留言板分成了三张表,一张留言表,一张回复表,一张点赞点踩记录表,这样就可以很清晰地实现需要的功能.

项目上线

其实设计部分没有什么难度,代码也主要是前端的代码太多了,后端其实没有多少,主要就是一些crud,但是由于以前没有将项目上线过,所以这一次碰到了额很多困难.

最初需要配置好服务器环境,用datagrip导出数据库,在服务器上导入,数据库同步部分没有受阻.然后根据网上的教程,首先暴力上线,也就是直接将项目上传到服务器,然后runserver,这样可以正常访问,但是却要保持ssh一直处于连接状态,只要断开,就服务器就停止运行项目了,这是因为ssh登录终端时会产生一个session,从登录到退出,在这个终端执行的程序都属于这个会话,当会话关闭,控制进程会收到退出的消息,在这个会话内产生的进程都会退出,所以当断开ssh连接后,项目也就停止运行了.解决方案是用screen解决了,screen为多重视窗管理程序,当断开连接时,项目仍将保持运行, screen -S name新建一个窗口,在这个窗口里的进程都不会随着断开连接而退出,如果只有一个screen时,可以通过screen -r -d进入窗口.

这样虽然项目的运行没什么问题了,但是本质上和在项目开发时的调试是没什么区别的,都是用的django自带的服务器,这个服务器只是供调试时用的,所以性能很差,所以需要用到nginx和uWSGI,uWSGI是后端代理服务器,是处理动态请求的,支持多进程,可以提高并发请求的处理能力,nginx主要处理静态资源,是一个反向代理服务器,可以提升安全性和性能.

在配置的过程中遇到了很多坑,首先网上的资源虽然很多,但是大多都是单后端应用,前后端不分离,所以配置起来和前后端分离的项目是有区别的,导致前期尝试了很多次都没有配置成功.其实如果django项目是前后端分离的话,在使用代理服务器前需要先收集静态资源.下面是整个配置步骤:

  • 配置setting.py文件,在里面加上STATIC_ROOT = os.path.join(BASE_DIR, "static")ALLOWED_HOSTS = ['*'],后者最好设置为指定的ip,但是为了方便就直接设置为了所有了,另外还要关闭DEBUG,将其设置为False.

  • 回到项目根目录,使用python manage.py collectstatic来收集静态资源,过程很快,收集完之后会在根目录下新建一个static文件夹.

  • 首先配置uWSGI,使用uwsgi --http xx.xx.xx.xx:8000 --file /home/kale/pythonProjects/PestMessage/PestMessage/wsgi.py --static-map=/static=static来测试项目是否正常运行,在浏览器中测试运行正常.

  • 接下来编写uwsgi配置文件,使根据配置文件运行,配置文件如下,需要注意的是这里的指定ip端口可以直接ifconfig查看ip地址,用这个ip就好,这里查到的肯定是内网ip了.输入uwsgi --ini uwsgi.ini,测试运行正常.
    avatar

  • 到这里,uWSGI的配置部分就完成了,接下来是nginx的配置部分,进入/etc/nginx/conf.d,编写配置文件,这里命名随便,在主配置文件里会引入这里的配置文件.这里值得注意的是server_name可以直接输入ip地址,或者输入域名也可以,前提是域名要做好映射关系.配置好后,重启服务,从80端口进入,可以正常登录,但是进入平台后别的接口都无法使用了,状态码500,肯定是服务器端出了问题,查看nginx日志,发现提示failed (13: Permission denied),权限问题,其实是还需要修改nginx的默认配置文件,将开头的user改为root,这样就不会有这个错误信息了.修改后,重启nginx服务,还是无法使用别的接口,再次查看日志,发现提示failed (111: Connection refused),连接被拒绝.刚开始以为是防火墙的问题,但是检查后防火墙配置没有问题,觉得还是代码出了问题,因为我现在的代码中指定了端口,runserver时是8000端口,而uWSGI也是运行在8000端口,所以直接前端发请求都是直接发到8000端口,那么既然使用nginx反向代理了,那么请求也应该发到默认的80端口才对,这样在编程的时候也比加上端口号要规范,域名同理,因为域名不能映射到指定端口,默认都是80端口,如果想端口映射,还需要配置iptables进行转发,这样显然不符合常理,所以我之前的做法是错的.
    avatar

  • 接下来就是更改代码,全部换成ip,默认80端口,然后重新上线,启动uWSGI和nginx,在浏览器中直接访问80端口,可以正常访问到项目,并且静态文件请求正常.通过chrome查看接口,也可以看到代理服务器是nginx,说明配置成功,这样就算完成了项目上线.

安全防护

这一部分其实只是做了最简单的部分,毕竟还是个小白,前端部分对密码做了hash处理,发到后端,后端存到数据库里再进行一次hash,如果不考虑hash碰撞的因素,那么密码方面应该是安全的.

另外前端加了路由守卫,在登录时后端会发一个token给前端,这个token是有时效的,存到缓存中,如果没有这个token,则不能访问其余网页,默认跳到登录页.后端也使用了login_required装饰器,就算前端有token,没有登录时访问到了别的网页,那么访问的也只是静态网页,无法获取到数据.这样就算完成了前后端的双端安全认证.不过因为水平问题,肯定还有很多部分没有考虑到,后面再慢慢加了.


更新一下,在上线后需要激活虚拟环境,source venv/bin/active,激活后,在uwsgi.ini文件中还需要指定该虚拟环境:
home = 虚拟环境地址

  • 本文标题:一次完整地将项目上线的经历
  • 本文作者:Kale
  • 创建时间:2020-02-26 01:41:44
  • 本文链接:https://kalew515.com/2020/02/26/一次完整地将项目上线的经历/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!