FlyFish2.0版本後端原始碼學習筆記

語言: CN / TW / HK

本文是使用者Mark Wu近期在學習使用FlyFish原始碼的學習筆記,雲智慧AIOps社群徵得原作者同意後授權釋出,本文使用的是FlyFish版本2.0,目前最新版本已更新到2.1

FlyFish程式碼結構

以下是程式碼的基本結構,使用的是基於MVC的thinkJS框架,但是通篇看下來,你是不是注意到,只看到了M(Model)和C(Controller),唯獨缺少View,所以View在哪?所以就帶著這個問題繼續學習下去。
├── code-server #線上編輯器
│ ├── linux
│ └── macos
├── config #初始化資料庫配置檔案
│ ├── database.${dev}.json
│ ├── node.development.js #入口檔案
├── download #大屏模組檔案
├── log #日誌
├── migrations_init #資料庫初始化
├── runtime #執行時配置儲存
├── src #後端專案核心程式碼
│ ├── common #通用業務配置
│ │ ├── bootstrap #
│ │ ├── config #通用配置
│ │ │ ├── adapter #介面卡配置
│ │ │ ├── config #通用配置
│ │ │ ├── extend #拓展配置
│ │ │ ├── middleware #中介軟體配置
│ │ │ ├── validator #自定義複雜校驗規則,在logic中使用
│ │ ├── constants #列舉
│ │ ├── middleware #中介軟體
│ │ ├── model #Model層---M
│ │ │ ├── baseModel.js #定義了基本的CURD,其它所有的model都繼承自它
│ │ ├── service #通用邏輯方法
│ └── web #定製化業務-----實現具體業務邏輯
│ ├── config #業務配置
│ ├── controller #控制器層---C
│ ├── logic #前置後置操作---如欄位校驗、許可權控制,其它通用邏輯
│ ├── model #資料庫操作
│ ├── service #業務邏輯---資料處理、格式轉換等業務邏輯操作
├── scripts #專案部署指令碼
├── storage #
├── template #大屏、元件模板
├── view #html模板
├── www #靜態資源
│ ├── solution-platform-web
│ └── static
│ └── upload
├── Dockerfile #dockerFile
├── options.json
├── options.json
├── pm2.json
├── README.md
├── startup.sh #啟動專案指令碼

thinkJS框架

  • Config:通用配置,如上config所示,可配置專案各種配置,最後會根據執行環境合到一起;
  • Context:上下文,使用者請求、回覆資料儲存物件以及狀態透傳;
  • Middleware:中介軟體,在配置與使用上類似於webpack的plugins,可使用各項函式(內建或引入)實現各項功能,所有的使用者請求處理都是由middleware完成;
  • Logic:邏輯,其中的action與controller的action一一對應,可定義執行action的前置後置操作;
  • Controller:控制器,和.net的控制器的使用非常相似,其內會按照路由執行對應的action;
  • View:檢視(這裡就是答案了),需要使用拓展來實現檢視;
  • Router:路由,可自定義路由規則;
  • Adapter:介面卡,解決一類功能的多種實現,配合extend,如view、資料庫,view可以選擇多種模板引擎,資料庫可配置多種資料庫,通過 think-helper模組中的 parseAdapterConfig解析;
  • Extend:拓展,支援的擴充套件型別為:think、application、context、request、response、controller、logic 和 service,框架內建的很多功能也是擴充套件來實現的,如:Session、Cache。

view是如何生成的

adapter.js裡面配置view模板的目錄為view裡面的html模板,模板引擎為nunjucks,配合extend裡面引入的think-view使用。
/**
view adapter config
@type {Object}
*/
exports.view = {
type: 'nunjucks', // 這裡指定預設的模板引擎是 nunjucks
common: {
viewPath: path.join(think.ROOT_PATH, 'view'),//模板檔案的根目錄
sep: '_',//Controller 與 Action 之間的連線符
extname: '.html'
},
nunjucks: {
handle: nunjucks
}
};

 

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
...
<title>{{title}}</title>
<link rel="icon" href="{{prefix}}/static/solution_platform_web/favicon.ico">
...
<link href="{{prefix}}/static/solution_platform_web/platform/vendor.css" rel="stylesheet">
</head>

<body>
<div id="wrapper"></div>
<script src="{{prefix}}/static/solution_platform_web/config/ENV.production.js"></script>
<script src="{{prefix}}/static/solution_platform_web/platform/runtime.js"></script>
<script src="{{prefix}}/static/solution_platform_web/platform/vendor.js"></script>
<script src="{{prefix}}/static/solution_platform_web/platform/app.js"></script>
</body>

</html>

 

可以看到模板裡面有兩個 prefix、title變數,會引入載入頁面所需靜態資源。extend裡面引入了think-view,通過 view 擴充套件,框架就支援渲染模板的功能,Controller 類上就有了 assign、display 等方法,引入model(think.app) 支援模型功能,會新增方法 think.Model、think.model、ctx.model、controller.model、service.model。
 
// extend.js
const view = require('think-view');
const model = require('think-model');
const session = require('think-session');
const cache = require('think-cache');

module.exports = [
session,
cache,
view, // make application support view
model(think.app),
];

 

router裡面配置路由規則,以/pw/開頭的get請求會指向web模組的view控制器下index的一個叫platform的action;
// router.js
module.exports = [
// 代理平臺的靜態頁面
[/^\/pw\/(.*)/i, '/web/view/index/platform', 'get'],
[/^\/proxyDataHub\/(.*)/i, 'web/proxy', 'rest'],
];

// web/controller/view/index.js
module.exports = class extends think.Controller {
platformAction() {
this.assign('prefix', this.config('platformPrefix', undefined, 'web').replace(/\/$/, ''));
this.assign('title', this.config('indexTitle', undefined, 'web').replace(/\/$/, ''));
return this.display();
}
};
platformAction會根據配置以及模組改變prefix、title變數的值,這樣view模板就能正確載入靜態資源。同時middleware也配置預設模組為web,預設控制器action為platformAction
...
//路由操作
{
handle: 'router',
enable: true, //是否開啟該中介軟體
options: {
defaultModule:'web', // 預設模組
defaultController: 'view/index', // 預設控制器
defaultAction: 'platform', // 預設action
}
},
...

 

資料流

API請求資料流如下圖所示
服務端建議:可以適當增加Workers數量,以增加服務端穩定性,一個Worker出現問題後,Master會停止它,然後fork一個新的Worker出來。

部署問題

在使用飛魚2.0的過程中,遇到了很多部署方面的問題,這裡我挑幾個典型的記錄一下
 
Q:伺服器上部署docker容器,本地訪問飛魚平臺,發現登入地址請求是127.0.0.1的地址;
A:按照部署流程仔細檢查了一下,發現配置檔案www/static/solution_platform_web/config/ENV.production.js沒有正確配置。
 
Q:docker容器部署起來,做新增大屏操作的時候報錯ER_NO_SUCH_TABLE: Table 'flyfish.visual_screen_tag_view' doesn't exist, SQL: SHOW COLUMNS FROM visual_screen_tag_view
A:檢查發現數據庫沒有啟動。
 
Q:code-server 下面 ,grpc安裝失敗,一起沒有成功;
A:切換成cnpm源後成功,其實也可以試試使用yarn進行安裝;
 

寫在最後

FlyFish釋出2.1版本後,已經支援安裝包一件部署方式,極大縮減了部署流程,具體如下所示
# CentOS 7.5/7.6 x86-64
# 須使用root賬戶
mkdir -p /data/app/
cd /data/app/

git clone -b main http://github.com/CloudWise-OpenSource/FlyFish.git FlyFish
or
git clone -b main http://gitee.com/CloudWise/fly-fish.git FlyFish

cd /data/app/FlyFish
bash flyfish.sh install

# 一鍵解除安裝
bash flyfish.sh uninstall

# 一鍵更新
# FlyFish-2.1.1 升級至 FlyFish-2.1.2
git checkout main
git pull origin main

bash flyfish.sh update

作者簡介

Mark Wu( 吳銀波 )雲智慧前端工程師,精通javascript、css、React、Vue、Webpack、ThreeJS等前端技術棧,致力於雲智慧大屏產品及飛魚開源社群服務,擁有豐富的前端效能優化和開源專案經驗。

關於FlyFish

部分大屏案例:
 
微信掃描識別下方二維碼,備註【飛魚】加入AIOps社群飛魚開發者交流群,與 FlyFish 專案 PMC 面對面交流~