讲得最明白的Elasticsearch源码调试环境搭建教程

算法幻影
• 阅读 6222

写在前面

使用elasticsearch(以下简称ES)也有挺长时间了,一直想找机会深入源码研究下。我看源码有个习惯,就是一定要运行起来。不是只把源码下载下来看看就行的。

搭建整个调试环境几乎花了一整天的功夫,这里记录下,希望能帮到需要的人。

环境介绍

  • MAC Mojave系统
  • idea 2019.2
  • JDK版本: jdk12
  • elasticsearch 版本:7.1.0
  • gradle 版本:5.2.1

源码下载

可以直接去github下载指定release版本的源码,也可以直接clone目前的master分支,然后checkout到一个特定的版本。

git clone https://github.com/elastic/elasticsearch.git

切换到指定发布版本

git checkout v7.x

我一般会fork一份到自己的仓库,这样看代码的时候写的注释可以提交到自己的仓库。

配置gradle和jdk的环境

具体的SDK和gradle的安装步骤不在这里展开了,自行搜索吧。

我自己的电脑是通过sdkman管理不同的JDK版本,可以同时有多个JDK版本存在一台主机随时切换使用。

这里需要重点说下ES对JDK和Gradle的版本要求。ES运行和编译所需要的JDK版本是需要分开讨论的。

ES运行只要8或者以上就可以了,我自己就是本地用JDK8运行ES实例,虽然启动过程中会有相关警告版本低,但是不影响使用。比如我会收到类似下面的警告:

future versions of Elasticsearch will require Java 11; your Java version from [/Users/xxxx/.sdkman/candidates/java/8.0.242-amzn/jre] does not meet this requirement

如果是编译源码,对JDK的版本要求又高一点。一般在源码根目录下的contributing.md文件会有对于编译某个版本的ES需要的JDK的版本要求,比如我编译的版本,有这么一段说明:

JDK 12 is required to build Elasticsearch. You must have a JDK 12 installation with the environment variable JAVA_HOME referencing the path to Java home for your JDK 12 installation. 

gradle的版本要求,我们也可以在

源码根目录/buildSrc/src/main/resources/minimumGradleVersion

这个文件里找到。另外还有两个文件:minimumRuntimeVersion、minimumCompilerVersion,分别表示运行时jdk、编译时jdk最低版本要求。

源码导入idea编译

首先进入源码的根目录下,执行以下命令

./gradlew idea

这个命令是配置工程依赖的环境,在导入源码到ES之前做的。这个命令执行的时间有点长,我自己的环境跑了10多分钟。执行完后,最后会看到类似下面的输出:

Generated IDEA project at file:///Users/ponyma/idea_project/elasticsearch/elasticsearch.ipr

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.2.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 16m 47s
351 actionable tasks: 319 executed, 32 up-to-date

然后idea导入源码工程,导入的流程是:

File -> New Project From Existing Sources 选择你下载的 Elasticsearch 根目录,然后点 open ,之后 Import project from external model -> Gradle , 选中 Use auto-import。

等待编译,也要几分钟。

建议配置下面这个环境变量,因为ES在编译的中间过程会依赖这个,没有这个配置的话可能会看到相关的警告。

JAVA9_HOME=/Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents/Home
export JAVA9_HOME

调试代码

调试源码有两种方式。

一种是使用gradle的远程调试模式

gradlew run --debug-jvm

开始debug模式运行,等几分钟后启动完毕, 出现如下图所示:

讲得最明白的Elasticsearch源码调试环境搭建教程

在IDEA 里点击 Run -> Attach to Process,选择刚刚启动的ES进程连接。

讲得最明白的Elasticsearch源码调试环境搭建教程

如果第一步debug运行失败了,就gradlew clean下多试几次。

远程调试原理相当于在服务器启动了一个ES实例,只不过这个实例就是我们本地。这样你的源码编译完启动会读取ES默认的配置。

启动后,我们在浏览器输入

http://localhost:9200

应该可以看到类似如下的信息:

{
  "name" : "node-0",
  "cluster_name" : "distribution_run",
  "cluster_uuid" : "ocg6NwKBRZyeg7YqmCyGUA",
  "version" : {
    "number" : "7.1.1-SNAPSHOT",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "7a013de",
    "build_date" : "2020-08-14T22:58:40.066107Z",
    "build_snapshot" : true,
    "lucene_version" : "8.0.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

如果提示你输入用户名密码,就输入elastic/password

还有一种方式可以调试

我们直接运行源码的main函数,在server模块的

org.elasticsearch.bootstrap.Elasticsearch

如果你直接运行,发现会报下面这个错误:

ERROR: the system property [es.path.conf] must be set

这是告诉我们需要指定一个包含配置文件的目录,我们可以直接下载一个发行版的ES,然后在idea的VM Options指定这个这个发行版ES的config目录,然后同时需要指定es.path.home,配置如下:

-Des.path.conf=/usr/local/elk/elasticsearch-7.1.0/config
-Des.path.home=/usr/local/elk/elasticsearch-7.1.0

上面的路径根据自己的实际情况修改。

然后运行,有报错:

Exception in thread "main" java.lang.NullPointerException
    at org.elasticsearch.node.InternalSettingsPreparer.checkSettingsForTerminalDeprecation(InternalSettingsPreparer.java:123)
    at org.elasticsearch.node.InternalSettingsPreparer.prepareEnvironment(InternalSettingsPreparer.java:91)
    at org.elasticsearch.bootstrap.Bootstrap.createEnvironment(Bootstrap.java:257)
    at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:290)
    at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:159)
    at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:150)
    at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86)
    at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124)
    at org.elasticsearch.cli.Command.main(Command.java:90)
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:115)
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92)
Refer to the log for complete error details.

debug跟到源码里,发现是node.name这值是空导致的,那简单,在配置文件里加上就行了。修改elasticsearch.yml,加上下面这个:

node.name: node-1

然后继续运行,what? 继续报错:

main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTrustPermission" "register")
    at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
    at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:358)
    at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.checkMBeanTrustPermission(DefaultMBeanServerInterceptor.java:1805)
    at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:318)
    at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:522)
    ...

这是log4j JMX报错了。JMX是一个管理应用程序的接口,log4j提供了对JMX的支持,实现了远程动态修改配置等功能。

这个其实不是ES的核心功能,既然报错了,干脆就把它关闭吧。

-Dlog4j2.disable.jmx=true

继续运行,还是报错:

[2020-08-16T09:19:42,833][ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [node-1] fatal error in thread [main], exiting
java.lang.NoClassDefFoundError: org/elasticsearch/plugins/ExtendedPluginsClassLoader
    at org.elasticsearch.plugins.PluginsService.loadBundle(PluginsService.java:545) ~[main/:?]
    at org.elasticsearch.plugins.PluginsService.loadBundles(PluginsService.java:471) ~[main/:?]
    at org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:163) ~[main/:?]
    at org.elasticsearch.node.Node.<init>(Node.java:308) ~[main/:?]
    at org.elasticsearch.node.Node.<init>(Node.java:252) ~[main/:?]
    at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:211) ~[main/:?]
...

这个错误我查了挺久,跟idea环境有关,做了两处修改得以解决。一个是

idea > preferences > Build, Execution, Deployment > Build Tools > Gradle

Build and run using gradle 改成 Build and run using IntelliJ IDEA

另一处修改是 Edit Configuration,找到Include dependencies with Provided scope,选中。

运行,接着报错:

2020-08-16T09:29:32,101][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [node-1] uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "createClassLoader")
    at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:163) ~[main/:?]
    at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:150) ~[main/:?]
    at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[main/:?]
    at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) ~[main/:?]
    at org.elasticsearch.cli.Command.main(Command.java:90) ~[main/:?]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:115) ~[main/:?]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) ~[main/:?]
    ...

这个问题查了一些资料,解决方案如下:

在发行版的config 目录下新建 java.policy 文件,填入下面内容:

grant {
    permission java.lang.RuntimePermission "createClassLoader";
};

然后在 VM options 加入 java.security.policy 的设置,指向该文件即可

-Djava.security.policy=/usr/local/elk/elasticsearch-7.1.0/config/java.policy

好了,终于运行成功了!在浏览器里输入

http://localhost:9200

可以看到集群的信息了。

然后我们就可以愉快的debug了!

点赞
收藏
评论区
推荐文章
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
WeiSha100 WeiSha100
3年前
公司内部培训平台源码
这是一个培训平台源码,有在线学习,刷题,直播,考试以及支付功能。源码完整,搭建起来比较简单,可二次开发,源码及文档分享给大家。功能挺齐全的,公司内部做员工培训很好用,可以下载源码搭建研究哦1、在线刷题:有可批量管理上传的题库,有记笔记,收藏,错题练习等2、点播:在线点播视频,课后可上传图文资料,习题等,可灵活设置付费课程3、线上直播:对接七牛云端口,最多可容
捉虫大师 捉虫大师
4年前
Nacos注册中心之概要设计
前言在之前的文章中分析了Nacos配置中心,配置中心的核心是配置的创建、读取、推送。注册中心的核心比配置中心多一个服务探活模块,他俩的相似度非常高,甚至阿里内部的注册中心就叫ConfigServer。Nacos注册中心打算分成几个模块来分析,本文重点在于概要设计,基于2.0.0版本。环境搭建用Nacos的源码来搭建源码阅读和调试环境,可参考Nacos调试
Easter79 Easter79
4年前
Tomcat 源码分析一 :快速搭建 Debug 环境
最近不是特别忙,空闲之余就开始倒腾Tomcat源码了,之前也陆陆续续看过一点,翻过《Howtomcatworks》这本书。这次想趁着有时间,系统性的好好分析下Tomcat的源码。分析源码的第一步自己是先搭建debug环境,我之前选择的是先下载Tomcat源码,然后通过Tomcat文档里面写的方法,使用ant构建,发现中间需要用很长的时间,中间经常提
Stella981 Stella981
4年前
IntelliJ IDEA远程调试Elasticsearch6.1.2
在深入学习elasticsearch的过程中,遇到有疑惑的源码时,如果能打断点单步调试,往往会取得事半功倍的效果,今天的实战内容就是通过IntelliJIDEA远程连接运行中的elasticsearch服务,然后单步运行代码;环境信息本次实战会用到两台电脑,一台Ubuntu运行着elasticsearch6.1.2版本,另一台Win10运行
Stella981 Stella981
4年前
Kafka源码调试环境搭建
写在前面1.用到了kafka,于是借机会看看代码,顺便复习下Scala,看到一半,换电脑了,搭环境有搭了半天,所以记录下.注意这里是0.8.2.2版本,因为公司用的就是这个版本.依赖的软件1.Git2.ScalaIDE(4.4.1)3.Gradle4.ZooKeeper环
WeiSha100 WeiSha100
3年前
内部培训系统搭建源码
这是一个培训平台源码,有在线学习,刷题,直播,考试以及支付功能,可以搭建私人的内部培训系统。源码完整,搭建起来比较方便快捷,可二次开发,源码及文档分享给大家。功能挺齐全的,搭建自己内部的培训系统足够用了,可以下载源码搭建研究哦1、在线刷题:有可批量管理上传的题库,有记笔记,收藏,错题练习等2、点播:在线点播视频,课后可上传图文资料,习题等,可灵活设置付费课程
WeiSha100 WeiSha100
3年前
线上微课堂平台搭建源码
分享一个微课堂系统平台的源码,搭建好了有在线刷题,点播,直播,考试,支付功能等功能。整个系统代码完整,支持二次开发,源码和教程分享给需要的朋友功能挺全的,可以下载源码和教程搭建研究哦1、在线刷题:有可批量管理上传的题库,有记笔记,收藏,错题练习等2、点播:在线点播视频,课后可上传图文资料,习题等,可灵活设置付费课程3、线上直播:对接七牛云端口,最多可容纳千人
WeiSha100 WeiSha100
3年前
2022线上云学堂系统搭建源码职业资格企业内训
分享一个2022线上云学堂系统搭建源码,有在线刷题,点播,直播,考试,支付功能等功能。整个系统代码完整,好搭建,支持二次开发,源码和教程分享给需要的朋友功能挺全的,可以下载源码和教程搭建研究哦1、在线刷题:有可批量管理上传的题库,有记笔记,收藏,错题练习等2、点播:在线点播视频,课后可上传图文资料,习题等,可灵活设置付费课程3、线上直播:对接七牛云端口,最多
WeiSha100 WeiSha100
3年前
K12线上教育平台源码
这是一个K12在线教育平台源码,有在线学习,刷题,直播,考试以及支付功能。源码完整,搭建起来比较简单,可二次开发,源码及文档分享给大家。功能挺齐全的,可以下载源码和教程搭建使用哦1、在线刷题:有可批量管理上传的题库,有记笔记,收藏,错题练习等2、点播:在线点播视频,课后可上传图文资料,习题等,可灵活设置付费课程3、线上直播:对接七牛云端口,最多可容纳千人在线
WeiSha100 WeiSha100
3年前
线上培训考试平台源码
这是一个线上培训考试平台源码,有在线学习,刷题,直播,考试以及支付功能。源码完整,搭建起来比较简单,可二次开发,源码及文档分享给大家。功能挺齐全的,可以下载源码搭建研究哦1、在线刷题:有可批量管理上传的题库,有记笔记,收藏,错题练习等2、点播:在线点播视频,课后可上传图文资料,习题等,可灵活设置付费课程3、线上直播:对接七牛云端口,最多可容纳千人在线4、考试
算法幻影
算法幻影
Lv1
其实一个人挺好的没有顾虑没有牵绊无非是孤单了一点
文章
5
粉丝
0
获赞
0