- OLAP
- 数据库
- 大数据
- 流处理
【免费下载链接】pinot
Apache Pinot - A realtime distributed OLAP datastore
Apache Pinot Controller 自带一套基于 React + TypeScript 的 Web 控制台(Pinot Controller UI),用于集群管理、表与 Schema 运维、SQL 查询、任务调度和 ZooKeeper 浏览。本文围绕 pinot-controller/src/main/resources/Readme.md 中给出的开发环境搭建步骤,结合仓库内的前端源码、构建配置与 Controller 后端静态资源挂载逻辑,系统讲解如何从源码启动 UI 开发服务器、如何与后端 Controller 联调,以及生产构建产物如何被打包进 Controller 进程对外提供服务。读完本文,你将能够独立完成 Pinot Controller UI 的开发、调试与构建流程。
一、Pinot Controller UI 是什么
Pinot Controller UI 是 Apache Pinot 的官方 Web 管理界面,源码位于仓库的pinot-controller/src/main/resources目录下,是一个典型的现代前端工程:
- 技术栈:React 16 + TypeScript + Material-UI,路由使用
react-router-dom(HashRouter),请求库使用axios,代码编辑器使用 CodeMirror(用于 SQL 查询编辑); - 入口文件:app/index.tsx 负责将
App组件挂载到#app节点,外层依次包裹HashRouter、MuiThemeProvider、NotificationContextProvider和AuthProvider; - 页面结构:页面组件集中在 app/pages 目录,包括查询控制台
Query.tsx、租户管理Tenants*.tsx、实例管理Instance*、表/段管理TablesListingPage.tsx、Minion 任务管理MinionTaskManager.tsx、任务队列TaskQueue*.tsx、ZooKeeper 浏览器ZookeeperPage.tsx以及登录页LoginPage.tsx; - 后端 API 封装:所有对 Controller REST API 的调用统一收敛在 app/requests/index.ts,如
/tenants、/tables、/schemas、/segments、/instances、/tasks、/zk/*、/sql等接口都有对应的封装函数。
因此,开发 UI 的前提是理解它的目录组织:app/存放全部业务代码,webpack.config.js与tsconfig.json定义构建与开发服务器行为,package.json声明脚本与依赖,swagger/存放与后端接口定义相关的资源。
二、开发前置条件:让 Pinot 后端跑起来
UI 本身只是一个前端壳,所有数据都来自 Controller 暴露的 REST API。开发时通过 webpack-dev-server 的代理把请求转发到本机 Controller,因此在启动 UI 之前,必须保证 Pinot 后端(Controller)已经在9000 端口正常运行。
启动后端的最简方式是直接编译并运行仓库根目录下的模块(Pinot 的构建方式可参考仓库根目录 README.md 中关于构建的说明),典型流程为:
- 克隆仓库后,在根目录执行 Maven 编译相关模块(
pinot-controller及其依赖),确保mvn与 JDK 环境就绪; - 按 Pinot 的启动方式拉起 ZooKeeper 与 Controller,默认 Controller 监听
9000端口; - 确认
http://localhost:9000可以正常访问(返回 UI 首页或 API 响应)。
提示:Readme 中特别强调后端必须运行在 9000 端口,这是 webpack-dev-server 代理配置(见下文)的硬性前提;若你修改了 Controller 端口,需同步调整代理目标。
三、进入 UI 源码目录
Readme 给出的第一步是切换到 UI 源码目录。由于 UI 源码位于 Controller 模块的资源目录下,因此进入方式为:
cd pinot-controller/src/main/resources后续所有npm命令都在该目录下执行。该目录下的关键文件包括:
- package.json:npm 脚本与依赖清单;
- webpack.config.js:webpack 构建配置与开发服务器代理;
- tsconfig.json:TypeScript 编译配置;
- app/:前端业务源码根目录。
四、安装依赖:Node 版本要求与 npm install
Readme 明确要求使用Node v16 或更精确的 v16.15.0,这与本仓库 package.json 锁定的前端依赖版本直接相关——工程内使用了 webpack 4.29.6、webpack-dev-server 3.2.1、TypeScript 3.8.3、React 16.13.1 等较早期版本的工具链,Node 版本过新可能导致兼容性问题。建议使用 nvm 之类的版本管理工具切换到 Node 16.15.0 后再执行:
npm installnpm install会依据package.json与仓库中已提交的 package-lock.json 安装全部依赖。该工程的依赖主要分为两类:
- 运行时依赖(dependencies):
react、react-dom、react-router-dom、@material-ui/core(含 icons/lab)、axios、codemirror、react-codemirror2、json-bigint、jwt-decode、@fortawesome/*、@sqltools/formatter等; - 开发依赖(devDependencies):
typescript、webpack、webpack-cli、webpack-dev-server、ts-loader、css-loader、style-loader、html-webpack-plugin、copy-webpack-plugin、clean-webpack-plugin、eslint与prettier系列等。
其中json-bigint用于处理查询结果中的大整数(如超精度时间戳),jwt-decode用于解析 OIDC 登录后的 JWT access token,这两点在后续认证与查询功能中都会用到。
五、启动开发服务器:npm run dev
依赖安装完成后,执行:
npm run dev该命令实际执行的是webpack-dev-server --config ./webpack.config.js --mode development(见 package.json 的scripts段)。webpack 会从入口./app/index.tsx开始打包,然后启动开发服务器。
5.1 开发服务器端口与代理
webpack.config.js 中配置了devServer:
- 默认开发服务器监听
8080端口,因此 Readme 指出应用运行在http://localhost:8080; hot: true开启热模块替换(HMR),改代码后页面自动刷新;compress: true开启 gzip 压缩;- 关键的是
proxy配置:将/下所有请求代理到http://localhost:9000并设置changeOrigin: true。这正是前面要求后端跑在 9000 端口的原因——前端请求/tables、/sql等 API 时,webpack-dev-server 会将其转发给本机 Controller,实现前后端分离开发。
5.2 开发模式下的功能验证
启动后访问http://localhost:8080,可以看到登录页或主界面。开发模式与生产模式的主要差异包括:
- 使用
--mode development,并开启source-map(devtool: 'source-map'),方便在浏览器中直接调试 TypeScript/React 源码; - 走
webpack-dev-server的内存打包与热更新,无需手工构建产物。
六、UI 与后端是如何对接的:从请求封装到静态资源挂载
理解"UI 如何工作"对开发调试至关重要,这里从源码层面梳理两条链路。
6.1 前端请求链路
前端所有 API 请求都通过 app/utils/axios-config.ts 创建的 axios 实例发出:
baseApi:baseURL: '/',用于绝大多数 REST 调用;transformApi:配置了transformResponse: [data => data],不自动解析 JSON,用于/sql查询等需要保留原始字符串的场景;baseApiWithErrors:在 API 失败时会抛出错误,供需要显式处理错误的新增接口使用(文件中注释明确说明新增 API 建议使用它)。
所有 axios 实例都注册了请求/响应拦截器:当启用 Basic Auth 时自动附加Authorization头;当启用 OIDC 时附加 access token;当收到 401/403 时触发"未认证访问"回调(跳转登录或自动登出)。拦截器的具体逻辑见 axios-config.ts 与 app/components/auth/AuthProvider.tsx。
业务侧的接口封装集中在 app/requests/index.ts,例如getQueryResult通过transformApi.post('/sql', params)提交查询,getTableSchema拉取表 Schema,scheduleTask调度 Minion 任务等。开发新页面时,通常只需要在requests/index.ts增加封装函数,再在页面组件中调用即可。
6.2 后端如何托管 UI 产物
生产环境下,Controller 进程直接托管 UI 的静态文件。相关实现分散在 Controller 模块中:
- ControllerAdminApiApplication.java 通过
CLStaticHttpHandler将 classpath 下的/webapp/、/webapp/images/、/webapp/js/分别挂载到/index.html、/images/、/js/路径; - LandingPageHandler.java 在
/路径直接返回webapp/index.html作为首页; - ControllerConf.java 中可配置 UI 资源路径。
也就是说,npm run build产出的dist/webapp目录(见webpack.config.js的output.path)在打包进 jar 后会被 Controller 读取并对外服务。开发模式下你访问 8080 端口看到的页面,与生产环境访问 9000 端口 Controller 根路径看到的页面,是同一套代码的两种形态。
6.3 认证方式
Controller 支持三种认证工作流(见 AuthProvider.tsx 的AuthWorkflow):
- NONE:无需认证,直接进入应用;
- BASIC:由 LoginPage.tsx 提供用户名/密码表单,前端用
btoa生成Basic base64(username:password)凭据,调用/auth/verify校验后写入app_state.authToken; - OIDC:前端根据
/auth/info返回的issuer、clientId、redirectUri构造隐藏表单跳转授权端点,通过 token 方式(token id_token)获取 access token,并持久化到 localStorage 中。
开发时若后端未开启认证(默认 NONE),UI 会直接进入主界面,无需登录。
七、生产构建与常用 npm 脚本
package.json 提供的常用脚本如下:
| 脚本 | 命令 | 作用 |
|---|---|---|
dev | webpack-dev-server --config ./webpack.config.js --mode development | 启动开发服务器(默认 8080 端口,代理 9000) |
start | npm-run-all --parallel lint dev | 并行执行代码检查与开发服务器 |
build | webpack --mode production | 生产构建,产物输出到dist/webapp |
build-dev | webpack --mode development | 开发模式构建 |
build-ci | 按CI环境变量选择build或build-dev | CI 环境专用构建 |
build-analyze | webpack --mode production --analyze | 带包体积分析的构建 |
lint | eslint 'app/**/*.{js,ts,tsx,jsx}' --quiet --fix | ESLint 自动修复 |
生产构建(npm run build)会执行 webpack.config.js 中的插件链:CleanWebpackPlugin清理旧产物、CopyWebpackPlugin将favicon.ico复制到images/、HtmlWebPackPlugin以app/index.html为模板生成带 viewport 元信息的index.html。构建完成后,dist/webapp即为可被 Controller 托管的完整静态站点。
八、常见开发问题排查
- 8080 端口无法访问:确认
npm run dev未报错、Node 版本为 v16.15.0 附近;若端口被占用,可调整 webpack-dev-server 配置或释放端口。 - 页面能打开但数据加载失败:优先检查
http://localhost:9000的 Controller 是否存活、代理是否生效。可在浏览器 Network 面板确认请求是否被转发到 9000 端口;若后端未开启认证而 UI 误以为需要登录,检查/auth/info返回的workflow是否为NONE。 - 改代码后页面未热更新:确认
dev模式(非build),并检查 webpack 是否报编译错误;HMR 需要hot: true(默认已开启)。 - 构建产物未出现在预期位置:生产构建输出目录是
dist/webapp(由output.path决定),不要与dist/下的 TypeScript 编译输出(见 tsconfig.json 的outDir)混淆。 - 查询结果数字精度丢失:查询接口走
transformApi(保留原始 JSON 字符串),配合json-bigint处理大整数;不要自行改用默认 JSON 解析的baseApi。
九、小结
Pinot Controller UI 的开发链路可概括为:进入pinot-controller/src/main/resources→ 使用 Node v16.15.0 执行npm install→ 确保 Controller 运行在 9000 端口 → 执行npm run dev访问http://localhost:8080。开发模式下 webpack-dev-server 负责热更新与 API 代理,生产模式下npm run build产出dist/webapp由 Controller 静态托管。理解 webpack.config.js 的代理机制、app/requests/index.ts 的接口封装以及 ControllerAdminApiApplication.java 的资源挂载逻辑,即可在这套前后端分离架构下高效开发、调试与扩展 Pinot 的 Web 控制台。
- OLAP
- 数据库
- 大数据
- 流处理
【免费下载链接】pinot
Apache Pinot - A realtime distributed OLAP datastore
相关推荐
Locust 源码贡献与开发指南:从开发环境搭建、测试调试到 Web UI 前端开发
Locust 源码贡献与开发指南:从开发环境搭建、测试调试到 Web UI 前端开发 本文是一份面向想要为 Locust 贡献代码的开发者的完整实战指南,覆盖在
测试性能测试Komodo 开发环境搭建指南:从源码构建与调试 Core、Periphery 与 Web UI
Komodo 开发环境搭建指南:从源码构建与调试 Core、Periphery 与 Web UI 本篇技术指南围绕 Komodo 仓库中的 developmen
DevOps容器编排CI/CD运维Apache Doris Web 管理控制台(ui)开发指南:从环境搭建到构建部署
Apache Doris Web 管理控制台(ui)开发指南:从环境搭建到构建部署 本篇指南以 Apache Doris 仓库内 ui/README.md ht
OLAP数据库大数据实时分析
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考