最近在调研BI报表相关的工具,最后决定深入调研下metabase,于是就有了这篇文章。

之所以选择metabase是因为一下几点:

  1. 低门槛,对无sql基础的人员友好
  2. 分析功能较全,支持join
  3. 图表功能OK
  4. 部署方便
    对于我来说,唯一不足的是它是由clojure开发的,二开成本有点高,这才是这篇文章的诞生的真正原因,因为导入IDE编译成功就用了好几天。

环境准备

metabase前端依赖node,后端以来jdk和clojure。

我是在mac环境下的,下面的命令都是基于mac的。

1、安装node
之前在电脑上装过node,使用tar安装的,只是版本比较老,于是用tar包升级了node,版本如下:

1
2
3
4
5
➜ cnpm -v
cnpm@7.1.0
npm@6.14.15
node@16.13.0
npminstall@5.2.2

2、安装yarn
node安装好之后,再安装yarn,安装时要选择全局安装,使用命令
npm install --global yarn

3、安装jdk
jdk的安装只强调一点,一定要jdk11、jdk11、jdk11

4、安装clojure
利用brew安装
brew install clojure/tools/clojure

由于Clojure也依赖maven,默认的maven源在国内经常无法访问,所以需要替换maven源

在Clojure的安装目录中找到deps.edn,修改内容如下:

1
2
3
4
:mvn/repos {
"central" {:url "http://maven.aliyun.com/nexus/content/repositories/central/"}
"clojars" {:url "https://repo.clojars.org/"}
}

在命令行输入clj 或者 clojure,即可进入交互界面。

5、IDE开发环境设置
我使用的是intellij idea,安装插件cursive即可,不过需要注意的是cursive与一些插件有冲突,而且对IDE的版本也有要求。(可以说是为了搞这套环境,我把我的老古董开发环境全都升级了一下。)

cursive插件与La Clojure、 clojure-kit、 Leiningen冲突,需要IDE为2018.x, 2019.x, 2020.1 and the 2020.2

本地编译

1、准备源码
从github上clone最新的代码git clone git@github.com:metabase/metabase.git
clone下来的代码默认上master分支,我切了下分支,切到了最新的release版本,git checkout -b 1.41.2 v1.41.2

2、导入IDE
选择File -> Open -> 在metabase目录中选择deps.edn -> Open an Project
剩下的就是自动加载依赖。

3、编译uberjar
在metabase_home目录下执行clojure -X:deps prep
成功之后执行cd modules/drivers && clojure -X:deps prep

以上两个命令执行一次就行

再次到metabase_home目录下,执行./bin/build进行编译,在target/uberjar目录下会出现一个jar包,最后执行java -jar metabase.jar即可启动。

本地调试

deps.edn中找到程序的入口

1
2
3
4
5
:run
{:main-opts ["-m" "metabase.core"]
:jvm-opts ["-Dmb.run.mode=dev"
"-Djava.awt.headless=true" ; prevent Java icon from randomly popping up in macOS dock
"-Dmb.jetty.port=3000"]}

main-opts就是程序的入口,是metabase包的core,相关代码如下:

1
2
3
4
5
6
7
8
9
10
;;; ------------------------------------------------ App Entry Point -------------------------------------------------

(defn -main
"Launch Metabase in standalone mode."
[& [cmd & args]]
(maybe-enable-tracing)
(if cmd
(run-cmd cmd args) ; run a command like `java -jar metabase.jar migrate release-locks` or `clojure -M:run migrate release-locks`
(start-normally))) ; with no command line args just start Metabase normally

到这就可以跟读调试代码了。

遇到的问题

接触一个新事物,其过程没有一帆风顺的,这次也不例外,这里记录下遇到的问题及解决方案。
1、方向性错误
在着手本地编译时做了些调研工作,网上也有些相关教程,不过这些导入IDE的教程都是基于Leiningen的,metabase之前是基于Leiningen,但是在前段时间从Leiningen切到了tools.deps,这就导致网上所有的教程都过时了。具体信息见官方信息

Leiningentools.deps的明显区别是代码中的project.clj文件变成了deps.edn文件(当初傻傻的以为project.clj中project只是个变量呢。。。)

后来意识到project.clj就是一个文件时,查看源码的提交记录发现了其从Leiningen切到了tools.deps,所以IDE的插件需要变为cursive

2、使用Clojure时maven源报UnknownHostException
安装完Clojure之后,验证是否可用时,在终端输入clj,报UnknownHostException: repo.maven.apache.org
第一感觉去修改本机的maven配置,修改之后依然报同样的错。
去Clojure的安装目录中关键字检索repo.maven.apache.org,发现在deps.edn中配置的,改成国内的源即可,具体修改方式见上面的安装步骤。

3、本地编译报SSL_ERROR_SYSCALL in connection to github.com:443
是因为github通过http链接时需要安全认证,所以执行git config --global http.sslVerify false关闭,(有时间好用有时间不好用,多次几次,随缘吧)。

4、运行jar包报错,错误内容:

1
2
2021-11-30 00:24:59,891 WARN servicelocator.DefaultPackageScanClassResolver :: Cannot search jar file '/Users/metabase/target/uberjar/metabase.jar' for classes due to an IOException: invalid code lengths set
java.util.zip.ZipException: invalid code lengths set

网上并没有什么解决方案,想到我的代码拉的是master分支,是不是代码的问题,于是切到了最新的release版本,打包之后依然报错。
下载了官方release版本的jar包,在本地正常运行,排除代码问题,那问题就出在编译环境上,此时想到文档上要求jdk版本为11,升级jdk为11之后,再次打包运行成功。