【記錄】趕鴨子上架的全棧開發踩坑思考

徹底趕鴨子上架的全棧開發之旅,過程能夠說是很崩潰,作完回顧發現留坑過多,痛定思痛仍是要從新整理一下代碼結構,覆盤整個項目搞清楚到底菜在哪裏,下面是這次開發過程當中的一些具體問題的總結。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存儲時間戳代替,主要是考慮後續可能須要對多種數據庫進行兼容。
相關文章
相關標籤/搜索