【记录】赶鸭子上架的全栈开发踩坑思考

彻底赶鸭子上架的全栈开发之旅,过程能够说是很崩溃,作完回顾发现留坑过多,痛定思痛仍是要从新整理一下代码结构,复盘整个项目搞清楚到底菜在哪里,下面是这次开发过程当中的一些具体问题的总结。javascript

项目概述

项目名称:数据分析工具化
项目描述:excel表上传数据,系统提供模块化的结论前端

前端

框架选用:vue+vuex+vue-router
UI框架:element-uivue

1. 关于在前台页面处理数据

初步考虑:一开始采用的方案是前台处理excel数据而后post数据到后台存储,主要考量有二,一是去除上传文件这一步骤,简化实现;二是前台对数据表格式进行校验,若是有错误可直接返回,减小没必要要的带宽消耗。经过webworker也能够避免浏览器假死。
实际问题:低估了数据量级,实际拿到的excel表甚至超过了10MB,部分sheet甚至达到了百万条数据,浏览器的处理能力和内存有限,出现了out of memory错误。
解决方案:将这一步骤移交给后台处理java

2. 关于vue-router的使用

初步考虑:PC站点不可避免的有站内导航和跳转,另外一方面为了提高体验,页面缓存也是须要的,综上考虑引入了vue-router。node

  • 实际问题01:贪图方便全员keepAlive了,致使页面缓存多了卡顿,懒惰是原罪
    解决方案:去除没必要要的keepAlive
    // router配置
    { 
        path: '/upload',
        name: 'upload',
        component: DataUpload,
        meta: {
            keepAlive: true // 须要被缓存
        }
    },
    {
        path: '/export',
        name: 'export',
        component: ReportExport,
        meta: {
            keepAlive: false // 不须要被缓存
        }
    }
    
    // 引入页面
    <keep-alive>
        <router-view v-if="$route.meta.keepAlive" />
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"/>
    复制代码
  • 实际问题02:须要新开页面展现某些信息
    解决方案:因为信息量级小,因此最终经过url带参的方式实现,router页面跳转
    // 新开页面
    router.resolve({
        name: "show-report-only",
        query: {
            url: url,
            name: name 
        }
    });
    window.open(href, '_blank');
    
    // 另外一种带参跳转(不能新开页面)
    router.push({ name: 'user', params: { userId: '123' }}) // 参数存储在内存中,不在url显示
    复制代码

3. 关于vuex的使用

初步考虑:前期考虑不足,典型的我坑我本身。如今就是后悔,很是后悔。
实际问题:vuex是在项目进行到必定程度以后才加进去的,整个项目组件之间存在不少的共享信息,包括基础分析数据/页面状态等,当代码量级上去以后,简单的组件之间传值已经没法维持数据共享,并且组件之间的依赖过强,代码可读性严重降低。
解决方案:加入vuex来留存全局的状态信息。mysql

4. 多复用操做的实现:Vue.directive指令

实际问题:在实际的实现场景下,有一些功能是基本全部组件都会使用到的,好比说都存在一个按钮,点击以后须要进行一系列相似的操做,这个时候就须要自定义指令上场,避免成为ctrlC/ctrlV工程师。
解决方案:加入自定义指令,统一管理相似的功能,提高可复用性,下降后期修改为本。nginx

后端

框架选用:express
代理服务器:nginxweb

0. 关于框架选择的思考

在作这个项目以前没有正儿八经的用nodejs作后台开发,却是以前在校期间,用过java和PHP,大概的思路是有的。基于这个前提下,仍是保守的选用全家桶型框架express,使用以后感受确实挺全的,可是有许多功能在实际使用中并不须要,后续考虑迁移到koa瘦个身。算法

1. post大数据超时

实际问题:后端最“重”的一个功能就是存数据,正如前端存excel表数据遇到的问题,将excel表上传到后端处理也有相似的问题,数据量过大,处理完成以后还要将几百万条数据存进数据库,容易形成超时,502/504错误。
解决方案:首选优化sql语句,加速处理;目前的快速解决方法是将express的socket链接超时时间。vue-router

server.on('connection', function (socket) {
    socket.setTimeout(30 * 1000);  // 超时时间,此处为30s
})
复制代码

后续优化:将接口拆分为2个接口异步操做,一个用于执行处理数据,另外一个接口用于获取处理进度。

2. 涉及文件云存储

前期疏漏:前期很理所固然的将文件存储在了服务器本地,实际上对于须要长期存储的数据应当有专门的文件服务器来存储,后端逻辑与存储空间应当隔离。
解决方案:使用公司内部的oss存储,该接口必须线上调用,本地调用可能失败或响应时间过长。

3. CORS问题

实际问题:对于附带身份凭证的请求,服务器端设置Access-Control-Allow-Origin*无效
解决方案res.header('Access-Control-Allow-Origin', req.header('origin'));

4. 关于Docker

做为一个菜鸟彻底不知道docker是什么东西怎么用,这次部署是傻瓜式操做,彻底是大佬写好的配置文件,直接走平台部署。不懂就要学,后续找个时间实践一下,目前了解仅限于Docker相似于虚拟机的概念,可是Docker虚拟的是操做系统,它将同一个操做系统上管理的应用隔离开来,能够快速的建立和中止应用,不一样应用之间互不影响。

数据库

mysql

1. 纯SQL语句与ORM库

实际问题:我确定是脑子瓦特了,才会手写SQL,是框架不够好用仍是加班不够久?
后续改进:为了后续项目可以更好兼容推动,改用ORM库来重构代码。

2. 数据库结构设计领悟

数据库真的是一门走一步要看三步的活计,前期设计做死在后面都是要还的。这一次设计过程当中,又因为需求频繁变更,致使数据库修改避无可避,产生了一些非专业的感悟:

  • 慎用自增ID,尤为是对于须要更新的数据,对于一些没法用单一字段做为primary key的表,能够考虑多个字段经过md5之类的加密算法,生成惟一的ID做为primary key
  • 在前期需求不明朗,或者说项目最开始设计的时候,字段最好不要作过多的限制,好比说枚举类型,能够用tinyint来替代,后续若是有增减也不须要修改。
  • 前期慎重使用uniqueforeign key之类的限制性功能,后期需求谁也说不许,很容易翻车。另外如外键之类的功能也下降了数据添加的可控性。
  • 避免或尽可能减小对一些较为特殊的内置字段类型/内置方法的使用,好比mysql的enum类型能够用varchar类型代替,timestamp类型能够用bigint存储时间戳代替,主要是考虑后续可能须要对多种数据库进行兼容。
相关文章
相关标签/搜索