FlyFish2.0版本後端原始碼學習筆記
本文是使用者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
Gitee 地址:
http://gitee.com/CloudWise/fly-fish
部分大屏案例:

微信掃描識別下方二維碼,備註【飛魚】加入AIOps社群飛魚開發者交流群,與 FlyFish 專案 PMC 面對面交流~
「其他文章」
- 全鏈路業務追蹤落地實踐方案
- 提高效率 Or 增加成本,開發人員應如何理解結對程式設計?
- 一個老開源人的自述-如何幹好開源這件事
- 高效實踐|頻繁項集挖掘演算法在告警關聯中的應用
- 敏捷需求管理篇|如何從0-1寫好一個使用者故事
- 敏捷需求管理篇|如何從0-1寫好一個使用者故事
- 深度解析智慧運維下告警關聯頻繁項集挖掘演算法原理
- 乘風破浪,探索資料視覺化開發平臺 FlyFish 開源背後的祕密!
- 深度乾貨|輕量級統計預測演算法模型原理解析
- 深度乾貨|輕量級統計預測演算法模型原理解析
- 深度解析智慧運維下告警關聯頻繁項集挖掘演算法原理
- 僅有 0.1M 可訓引數,AIOps 日誌異常檢測新正規化
- 低程式碼平臺FlyFish在雲智慧的落地實踐探索
- 語言處理技術之中文分詞在運維領域中的探索實踐
- 運維領域告警智慧定級原理探索(含詳細實驗報告)
- 碼住!基於深度學習的時間序列預測方法總結
- 高效實踐|運維指標體系在銀行業務的應用實踐
- 高效實踐|運維指標體系在銀行業務的應用實踐
- 大咖說|Kubernetes自動伸縮實現方式深度講解
- 雲原生架構及演進