克隆 Elasticsearch 项目
首先 fork 一份 [Elasticsearch 项目] (https://github.com/elastic/elasticsearch) 的代码到自己的 github 仓库,这样看代码的时候写注释可以提交到自己的仓库。
然后将代码克隆到本地。
代码语言:javascript复制git clone https://github.com/cr7258/elasticsearch
切换到指定发布版本,这里我们基于 7.14.1 版本进行学习。
代码语言:javascript复制git checkout v7.14.1
版本要求
我们编译的是 Elasticsearch 7.14.1 版本,在源码根目录下的 CONTRIBUTING.md 文件中说明了 IntelliJ 和 JDK 的版本要求,Gradle 我们可以不必自行安装,在编译的时候会自动使用源码根目录下 gradlew 脚本进行安装。
- IntelliJ 2020.1 以上
- JDK 16
- Gradle 7.1
配置 JDK 环境
这里推荐使用 sdkman 来管理不同的 JDK 版本,sdkman 是一个用于管理多个软件开发工具包并行版本的工具,它提供了一个方便的命令行界面 (CLI) 和 API,用于列出、安装、切换、删除软件版本。
sdkman 对 Java 开发人员特别有用,支持 JVM 的 SDK,例如 Java,Groovy,Scala,Kotlin,Gradle,Maven,Spring Boot 和许多其他工具。sdkman 支持所有主要的 Unix 操作系统,可以安装在 macOS,Linux,WSL,Cygwin,Solaris,FreeBSD 等系统上,并且支持 bash 和 zsh。
你也可以按照常规的方式安装 Java,只要保证 JDK 是 16 版本即可。
安装 sdkman
执行以下命令安装 sdkman:
代码语言:javascript复制curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
查看 sdk 版本:
代码语言:javascript复制❯ sdk version
==== BROADCAST =================================================================
* 2021-09-16: leiningen 2.9.7 available on SDKMAN!
* 2021-09-11: grails 5.0.0-RC3 available on SDKMAN!
* 2021-09-07: mvnd 0.6.0 available on SDKMAN! https://git.io/Jucy6
================================================================================
SDKMAN 5.12.4
安装 JDK
查看支持的 Java 版本:
代码语言:javascript复制Available Java Versions
================================================================================
Vendor | Use | Version | Dist | Status | Identifier
--------------------------------------------------------------------------------
Corretto | | 17.0.0.35.2 | amzn | | 17.0.0.35.2-amzn
| | 17.0.0.35.1 | amzn | | 17.0.0.35.1-amzn
| | 16.0.2.7.1 | amzn | | 16.0.2.7.1-amzn
| | 11.0.12.7.2 | amzn | | 11.0.12.7.2-amzn
| | 8.302.08.1 | amzn | | 8.302.08.1-amzn
GraalVM | | 21.2.0.r16 | grl | | 21.2.0.r16-grl
| | 21.2.0.r11 | grl | | 21.2.0.r11-grl
| | 20.3.3.r11 | grl | | 20.3.3.r11-grl
| | 19.3.6.r11 | grl | | 19.3.6.r11-grl
Java.net | | 18.ea.15 | open | | 18.ea.15-open
| | 18.ea.2.lm | open | | 18.ea.2.lm-open
| | 17 | open | | 17-open
| | 17.ea.3.pma | open | | 17.ea.3.pma-open
| | 16.0.2 | open | | 16.0.2-open
| | 11.0.2 | open | | 11.0.2-open
Liberica | | 17.0.0.fx | librca | | 17.0.0.fx-librca
| | 17.0.0 | librca | | 17.0.0-librca
| | 16.0.2.fx | librca | | 16.0.2.fx-librca
| | 16.0.2 | librca | | 16.0.2-librca
| | 11.0.12.fx | librca | | 11.0.12.fx-librca
| | 11.0.12 | librca | | 11.0.12-librca
| | 8.0.302.fx | librca | | 8.0.302.fx-librca
| | 8.0.302 | librca | | 8.0.302-librca
Liberica NIK | | 21.2 | nik | | 21.2-nik
Microsoft | | 16.0.2.7.1 | ms | | 16.0.2.7.1-ms
| | 11.0.12.7.1 | ms | | 11.0.12.7.1-ms
SapMachine | | 17 | sapmchn | | 17-sapmchn
| | 16.0.2 | sapmchn | | 16.0.2-sapmchn
| | 11.0.12 | sapmchn | | 11.0.12-sapmchn
Semeru | | 16.0.2 | sem | | 16.0.2-sem
| | 11.0.12 | sem | | 11.0.12-sem
| | 8.0.302 | sem | | 8.0.302-sem
Temurin | | 16.0.2 | tem | | 16.0.2-tem
| | 11.0.12 | tem | | 11.0.12-tem
| | 8.0.302 | tem | | 8.0.302-tem
Trava | | 11.0.9 | trava | | 11.0.9-trava
| | 8.0.232 | trava | | 8.0.232-trava
Zulu | | 17.0.0 | zulu | | 17.0.0-zulu
| | 17.0.0.fx | zulu | | 17.0.0.fx-zulu
| | 16.0.2 | zulu | | 16.0.2-zulu
| | 16.0.2.fx | zulu | | 16.0.2.fx-zulu
| | 11.0.12 | zulu | | 11.0.12-zulu
| | 11.0.12.fx | zulu | | 11.0.12.fx-zulu
| | 8.0.302 | zulu | | 8.0.302-zulu
| | 8.0.302.fx | zulu | | 8.0.302.fx-zulu
| | 7.0.312 | zulu | | 7.0.312-zulu
================================================================================
Use the Identifier for installation:
$ sdk install java 11.0.3.hs-adpt
安装 OpenJDK 16 版本:
代码语言:javascript复制sdk install java 16.0.2-open
查看当前 Java 版本:
代码语言:javascript复制#查看 sdkman 管理的版本
❯ sdk current
Using:
java: 16.0.2-open
#查看当前 java 版本
❯ java -version
openjdk version "16.0.2" 2021-07-20
OpenJDK Runtime Environment (build 16.0.2 7-67)
OpenJDK 64-Bit Server VM (build 16.0.2 7-67, mixed mode, sharing)
关于 sdkman 的管理命令可以参考 sdkman usage。
源码导入 IntelliJ Idea
打开 IntelliJ Idea,点击 Open or Import。
选中 Elasticsearch 源码根目录中的 build.gradle 文件,点击 Open。
点击 OPEN AS PROJECT。
点击 Event Log,然后点击 Import Gradle Project。
- Gradle user home:选择 Elasticsearch 源码包中的 gradle 目录。
- Gradle JVM:选择安装的 JDK 16。
点击刷新,开始编译。
等待编译完成。
本地调试源码
运行 Elasticsearch 需要有包含配置文件的目录,我们可以直接下载一个同版本发行版的 Elasticsearch,然后在 IntelliJ Idea 的 VM options 中指定发行版 Elasticsearch 的目录。
Elasticsearch 发行版下载地址:https://www.elastic.co/cn/downloads/
下载 Elasticsearch 发行版,创建相关目录,darwin 是 macOS 版本的 Elasticsearch。
代码语言:javascript复制mkdir -p /Users/chengzhiwei/data/elasticsearch/
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.14.1-darwin-x86_64.tar.gz
tar -xzvf elasticsearch-7.14.1-darwin-x86_64.tar.gz -C /Users/chengzhiwei/data/elasticsearch
#创建数据存放目录
mkdir /Users/chengzhiwei/data/elasticsearch/elasticsearch-7.14.1/data
点击右上角 Edit Configurations,创建一个 Application 启动配置。
- Main class:设置启动类。
- VM options 内容如下:
#上面 Elasticsearch 发行版的路径
-Des.path.home=/Users/chengzhiwei/data/elasticsearch/elasticsearch-7.14.1
-Des.path.conf=/Users/chengzhiwei/data/elasticsearch/elasticsearch-7.14.1/config
#安全策略
-Djava.security.policy=/Users/chengzhiwei/data/elasticsearch/elasticsearch-7.14.1/config/elasticsearch.policy
-Dlog4j2.disable.jmx=true
-Xmx2g
-Xms2g
- Use classpath of module:选择启动类所在 module。
- JRE:选择安装的 JDK 16。
编辑 /Users/chengzhiwei/data/elasticsearch/elasticsearch-7.14.1/config/elasticsearch.yml 配置文件,指定集群名,节点名,数据目录,日志目录。
编辑源码包下 server/src/main/resources/org/elasticsearch/bootstrap/security.policy 文件,注释以下内容。
在 Elasticsearch 发行版的 config 目录下添加 elasticsearch.policy 文件,内容如下:
代码语言:javascript复制grant {
permission javax.management.MBeanTruxtPermission "register";
permission javax.management.MBeanServerPermission "createMBeanServer";
permission java.lang.RuntimePermission "createClassLoader";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "setContextClassLoader";
permission org.elasticsearch.ThreadPermission "modifyArbitraryThreadGroup";
};
点击启动。
看到以下输出表示 Elasticsearch 成功启动。
浏览器输入 http://localhost:9200,访问 Elasticsearch。
接下来我们 Debug 调试一下,server.main.java.org.elasticsearch.rest.action.cat.RestHealthAction 类上打一个断点,这个类是用于处理查询集群状态请求的。
客户端查询集群状态。
代码语言:javascript复制curl http://localhost:9200/_cat/health
可以清楚地看到线程调用栈和响应结果。
远程调试源码
在远程的 Elasticsearch 服务器的 config 目录下的 jvm.options 文件中加入以下配置参数,0:5005 表示在本机所有 IP 地址监听 5005 端口。
代码语言:javascript复制-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0:5005
在远程机器上启动 Elasticsearch。
代码语言:javascript复制bin/elasticsearch -d
在 IntelliJ Idea 上创建一个 Remote 远程启动配置。
启动 Remote 配置,看到以下输出说明成功连接到了远程 Elasticsearch,接下来就可以像在本地一样 Debug 调试了。
参考资料
- [idea运行es7.13.2报Unknown codebases异常] (https://elasticsearch.cn/question/11513)
- [ElasticSearch-7.8.0 源码编译调试 (详细)] (https://zhuanlan.zhihu.com/p/188725714)
- [讲得最明白的Elasticsearch源码调试环境搭建教程] (https://cloud.tencent.com/developer/article/1683325)
- [IntelliJ IDEA远程调试Elasticsearch6.1.2] (https://blog.csdn.net/boling_cavalry/article/details/89417650)