Elasticsearch 源码学习(1)源码编译调试

2021-10-09 16:28:01 浏览数 (1)

克隆 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 内容如下:
代码语言:javascript复制
#上面 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)

0 人点赞