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 https://github.com/CloudWise-OpenSource/FlyFish.git FlyFish
or
git clone -b main https://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 地址:
https://gitee.com/CloudWise/fly-fish
部分大屏案例:

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