Cerebro全栈工作流梳理

Overview

Cerebro一直是我觉得比较好用和美观的elasticsearch web admin tool。它是独立部署的,开箱即用,输入es host即可。

囊括了前端UI,后台交互,是一个相对完整的独立应用,有很多实现上的借鉴意义。比如说自己的一个想法,如何实现前端点击->后台交互->入库保存—>返回前端渲染等都可以参考。实在是一个全栈工程师的必备良选。

代码划分

代码划分

Structure

html骨架

先来看看前端的html骨架吧,入口如下,

  • 开始登入connect.htmlloginlocalhost:9000 2

  • 登入之后,navbar.html,主要分为4个tab(overview, nodes, rest, more) 3

    • overview.html 4
    • nodes.index.html 5
    • rest.index.html 6
    • more 7

当然还有很多xxx.html,都是一些子页面,如cat.index.html等,大同小异。

css皮肤

骨架有了,下面看看css皮肤,入口如下,

8

代码比较清晰,每一栏注释对应到不同html骨架的肤色

js交互

有了静态的外表之后,需要加入一些动作,使得用户可以交互使用这个App,其实动态与静态是一一对应的,定义在app.routes.js这个路由表中, 由angularjs默认自动加载各个定义了的.whencomponents下面的controller.js和data.js。

9

js层级结构

静态 动态
connect.html connect.controller.js
navbar.html navbar.controller.js
overview.html overview.controller.js
nodes.index.html nodes.controller.js
rest.index.html rest.controller.js
cat.index.html cat.controller.js

后端

后端是基于scala-play框架搭建的web-server。

Play框架会根据模板app.view.Index.scala.html,自动注入相应的类。

整体流程,

play加载Index.scala.html -> css加载app.css -> js加载app.js -> html渲染

然后根据前端不同的URL路由定位到相应的html,及其具体scala实现类,如,

        .when('/connect', {
          templateUrl: 'connect.html',
          controller: 'ConnectController'
        })
        .when('/cat', {
          templateUrl: 'cat/index.html',
          controller: 'CatController'
        })
        .otherwise({
            redirectTo: '/connect'
          }
        )

比如cat Api,首先用户从前端选择或者输入一个api点击触发,然后传入cat.controller.js,js再传入CatController.scala,之后经由esClient发送rest req到esCluster,然后返回resp到js,js整理后再返回给cat.index.html渲染(row in data)。

工作流

下面看看playframework的工作,首先play会自动加载conf/routes这个自定义路由表。

/入手,/ -> controllers.Application.index() -> loadIndex.scala.html -> css加载app.css -> js加载app.js -> app.js里面没有定义/所以redirectTo到/connect -> 所以渲染出connect.html

10

输入localhost:9000/之后,redirectTo到localhost:9000/#/connect

11

默认在Known clusters里面展示已于application.conf配置好的hosts

此时用户可以直接点击它,然后会调起connect(host)方法

Known clusters = config.underlying.getConfigList("hosts")

此时用户也可以自己输入host,然后按回车或者点击按钮,再调起connect(host)方法

12

调用ConnectDataService.connect(host);

13

具体是发送_cluster/health到es rest

14

返回的resp

15

然后开始在overview.html里面渲染

16

首先resp渲染到static.html

17

另外resp.status这个变量是通过page.js展示到document里的

至此完成了overview.html的第一部分内容渲染,还剩的nodes区index区

18

overview.html的分区

19

node区和index区的骨架

至此overview.html全部渲染完毕。

小结

再从该页面点击其他路由入口,跳转流程与上面的connect.html -> overview.html类似,即从xxx.js调用xxx.scala具体实现,然后将resp填入xxx.html

其他

  • WSClient传入到HTTPElasticClient,以此来为该session注入一个esClient单例
  • RestHistoryDAOImpl保存了前50条rest cmd命令到本地SQLite(默认50条)

元素小结

  • models
    • 一个实体,如一条评论,一个回答
  • views
    • 一个page,如知乎这个问题是一个page,里面有很多实体,如题目实体,很多回答实体,很多评论实体
  • services
    • 具体实现的服务,如提问题,回问题,写评论
  • DAO
    • 与底层db交互,持久化page和实体
  • controllers
    • 将services的结果加以处理返回给views
    • 有时也认为是一个更高级的services,如,ClusterOverviewController里面包含了OverviewDataService

存疑

  1. src和public下面有一些重复的前端代码(不知道是不是静态与动态都需要各自加载一次,所以才在2个目录下各有一份?)
    • 静态指的是public目录
    • 动态指的是src目录
    • 静态app.css与动态app.css重复了
    • 静态app.js的routeProvider与动态的app.routes.js重复了
    • 静态app.js的具体.controller与动态component里面的具体controller.js重复了

Reference