徹底趕鴨子上架的全棧開發之旅,過程能夠說是很崩潰,作完回顧發現留坑過多,痛定思痛仍是要從新整理一下代碼結構,覆盤整個項目搞清楚到底菜在哪裏,下面是這次開發過程當中的一些具體問題的總結。javascript
項目名稱:數據分析工具化
項目描述:excel表上傳數據,系統提供模塊化的結論前端
框架選用:vue+vuex+vue-router
UI框架:element-uivue
初步考慮:一開始採用的方案是前臺處理excel數據而後post數據到後臺存儲,主要考量有二,一是去除上傳文件這一步驟,簡化實現;二是前臺對數據表格式進行校驗,若是有錯誤可直接返回,減小沒必要要的帶寬消耗。經過webworker也能夠避免瀏覽器假死。
實際問題:低估了數據量級,實際拿到的excel表甚至超過了10MB,部分sheet甚至達到了百萬條數據,瀏覽器的處理能力和內存有限,出現了out of memory
錯誤。
解決方案:將這一步驟移交給後臺處理java
初步考慮:PC站點不可避免的有站內導航和跳轉,另外一方面爲了提高體驗,頁面緩存也是須要的,綜上考慮引入了vue-router。node
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"/>
複製代碼
// 新開頁面
router.resolve({
name: "show-report-only",
query: {
url: url,
name: name
}
});
window.open(href, '_blank');
// 另外一種帶參跳轉(不能新開頁面)
router.push({ name: 'user', params: { userId: '123' }}) // 參數存儲在內存中,不在url顯示
複製代碼
初步考慮:前期考慮不足,典型的我坑我本身。如今就是後悔,很是後悔。
實際問題:vuex是在項目進行到必定程度以後才加進去的,整個項目組件之間存在不少的共享信息,包括基礎分析數據/頁面狀態等,當代碼量級上去以後,簡單的組件之間傳值已經沒法維持數據共享,並且組件之間的依賴過強,代碼可讀性嚴重降低。
解決方案:加入vuex來留存全局的狀態信息。mysql
實際問題:在實際的實現場景下,有一些功能是基本全部組件都會使用到的,好比說都存在一個按鈕,點擊以後須要進行一系列相似的操做,這個時候就須要自定義指令上場,避免成爲ctrlC/ctrlV工程師。
解決方案:加入自定義指令,統一管理相似的功能,提高可複用性,下降後期修改爲本。nginx
框架選用:express
代理服務器:nginxweb
在作這個項目以前沒有正兒八經的用nodejs作後臺開發,卻是以前在校期間,用過java和PHP,大概的思路是有的。基於這個前提下,仍是保守的選用全家桶型框架express,使用以後感受確實挺全的,可是有許多功能在實際使用中並不須要,後續考慮遷移到koa瘦個身。算法
實際問題:後端最「重」的一個功能就是存數據,正如前端存excel表數據遇到的問題,將excel表上傳到後端處理也有相似的問題,數據量過大,處理完成以後還要將幾百萬條數據存進數據庫,容易形成超時,502/504錯誤。
解決方案:首選優化sql語句,加速處理;目前的快速解決方法是將express的socket鏈接超時時間。vue-router
server.on('connection', function (socket) {
socket.setTimeout(30 * 1000); // 超時時間,此處爲30s
})
複製代碼
後續優化:將接口拆分爲2個接口異步操做,一個用於執行處理數據,另外一個接口用於獲取處理進度。
前期疏漏:前期很理所固然的將文件存儲在了服務器本地,實際上對於須要長期存儲的數據應當有專門的文件服務器來存儲,後端邏輯與存儲空間應當隔離。
解決方案:使用公司內部的oss存儲,該接口必須線上調用,本地調用可能失敗或響應時間過長。
實際問題:對於附帶身份憑證的請求,服務器端設置Access-Control-Allow-Origin
爲*
無效
解決方案:res.header('Access-Control-Allow-Origin', req.header('origin'));
做爲一個菜鳥徹底不知道docker是什麼東西怎麼用,這次部署是傻瓜式操做,徹底是大佬寫好的配置文件,直接走平臺部署。不懂就要學,後續找個時間實踐一下,目前瞭解僅限於Docker
相似於虛擬機的概念,可是Docker
虛擬的是操做系統,它將同一個操做系統上管理的應用隔離開來,能夠快速的建立和中止應用,不一樣應用之間互不影響。
mysql
實際問題:我確定是腦子瓦特了,纔會手寫SQL,是框架不夠好用仍是加班不夠久?
後續改進:爲了後續項目可以更好兼容推動,改用ORM庫來重構代碼。
數據庫真的是一門走一步要看三步的活計,前期設計做死在後面都是要還的。這一次設計過程當中,又因爲需求頻繁變更,致使數據庫修改避無可避,產生了一些非專業的感悟:
primary key
的表,能夠考慮多個字段經過md5之類的加密算法,生成惟一的ID做爲primary key
。unique
或foreign key
之類的限制性功能,後期需求誰也說不許,很容易翻車。另外如外鍵之類的功能也下降了數據添加的可控性。