本文是用户 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
我的项目介绍:https://www.cloudwise.ai/flyF…
Github 地址:https://github.com/CloudWise-…
Gitee 地址:https://gitee.com/CloudWise/f…
行业案例:https://www.bilibili.com/vide…
局部大屏案例: