《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 https://www.iocoder.cn/Elasticsearch/build-debugging-environment/ 「芋道源码」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

友情提示:如果胖友对 Elasticsearch 的使用不是很了解,可以后续阅读艿艿写的这三篇文章。

今儿,我们来搭建一个 Elasticsearch 调试环境,目标是:

  • 启动 Elasticsearch 服务,成功断点调试它的启动过程。
  • 发起新建索引、创建文档、搜索文档的操作,成功断点调试它的执行过程。

视频可见 B 站:https://www.bilibili.com/video/BV1py4y157c1/

😝 艿艿比较腼腆,大家给个三连支持一下,感恩 1024~

1. 依赖工具

1.1 IDEA

当然是 Jetbrains 出品的 IDEA 工具,相信绝大多数胖友都使用的它。

艿艿使用的是 2021.2 版本,胖友尽量保证不低于该版本哈。

友情提示:如果不知道怎么激活 IDEA 的胖友,可以访问 《IDEA 激活指南》 地址,花 5 分钟学习!支持所有版本~

因为稍后要使用到的 JDK 版本 是 16 ,要求最低的 IDEA 版本是 2021.1

1.2 JDK

《Contributing to elasticsearch》 文档中,提到需要使用 JDK 16 版本,编译 Elasticsearch 的代码。

使用 IDEA 下载 JDK 16 版本。如下图所示:

选择 JDK 16 版本

稍微耐心等待 JDK 16 下载完成。如下图所示:

下载 JDK 16 版本

友情提示:需要一丢丢耐心,可以打开 B 站刷一会视频啊~

设置项目使用 JDK 16 版本。

项目使用 JDK 16 版本

设置 Gradle 使用 JDK 16 版本。

Gradle 使用 JDK 16 版本

在 Gradle 的 user home 目录,添加 init.gradle 文件,设置 Gralde 使用阿里云的 Maven 源。

至于 user home 的目录在哪呢?我们回看上一个黄色框框,可以获得到。这里,可以看到艿艿的目录是 /Users/yunai/.gradle。下面,我们来操作下,如下图所示:

设置  文件

内容如下:

allprojects{
repositories {
def ALIYUN_REPOSITORY_URL = 'https://maven.aliyun.com/repository/public/'
def ALIYUN_GRADLE_PLUGIN_URL = 'https://maven.aliyun.com/repository/gradle-plugin/'
all { ArtifactRepository repo ->
if(repo instanceof MavenArtifactRepository){
def url = repo.url.toString()
if (url.startsWith('https://repo1.maven.org/maven2/')) {
project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_REPOSITORY_URL."
remove repo
}
if (url.startsWith('https://jcenter.bintray.com/')) {
project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_REPOSITORY_URL."
remove repo
}
if (url.startsWith('https://plugins.gradle.org/m2/')) {
project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_GRADLE_PLUGIN_URL."
remove repo
}
}
}
maven { url ALIYUN_REPOSITORY_URL }
maven { url ALIYUN_GRADLE_PLUGIN_URL }
}
}

2. 源码拉取

使用 IDEA 从官方仓库 https://github.com/elastic/elasticsearch 克隆项目。

友情提示:如果网络不是很好的胖友,可以选择和艿艿一样,使用 Gitee 提供的镜像仓库 https://gitee.com/mirrors/elasticsearch.git

这里,我们使用的 Elasticsearch 版本是 8.0.0-SNAPSHOT

友情提示:胖友可以考虑 Fork 下官方仓库,为什么呢?

既然开始阅读、调试源码,我们可能会写一些注释,有了自己的仓库,可以进行自由的提交。😜

3. 下载依赖

克隆完成 Elasticsearch 项目之后,IDEA 会自动下载需要的 Gradle 工具。如下图所示:

下载 Gradle 工具

这里,我们使用的 Gradle 版本是 7.2

友情提示:由于是从国外的网址下载,所以需要耐心等待一会,不过艿艿只花了 23 秒,啊哈哈哈。

下载完 Gradle 工具之后,IDEA 就会使用它自动下载相关的依赖库。如下图所示:

下载依赖

友情提示:下载依赖会蛮慢的,艿艿自己是开了全局代码解决的。

尝试设置了 Gradle 使用阿里云的源,但是貌似没啥效果,等后面再找时间折腾一波。

保持耐心...

成功换了阿里云的 Maven 源后,速度杠杠的。艿艿差不多下载了 11 分钟多一丢丢。

下载时间

可能下载完后,IDEA 会 index 下,做下依赖库的索引,再耐心等待一会会哈。

4. 构建 Elasticsearch 发布包

根据胖友的操作系统,选择对应的 no-jdk-*-tar 的 build 按钮,构建 Elasticsearch 发布包。艿艿自己 build 构建,大概 2 分钟左右。

友情提示:

  • Windows 胖友,选择 no-jdk-windows-tar
  • Linux 胖友,选择 no-jdk-linux-tar
  • MacOS 胖友,选择 no-jdk-darwin-tar
  • MacOS M1 胖友,选择 no-jdk-darwin-aarch64-tar

执行 build 构建

为什么要构建发布包呢?在 modules 目录下,我们可以看到大量的功能模块,如下图所示:

 说明

例如说,transport-netty4 模块是 Elasticsearch 基于 Netty 实现网络通讯,我们常用的 9200 或 9300 就是由它提供的。

友情提示:因为 Elasticsearch 采用模块化,所以我们在改动到 modules 模块的代码时,都需要重新 build 一次,即使只添加了代码注释。否则,IDEA Debug 调试时,代码行号会对应不上哈。

5. 启动 Elasticsearch 服务

打开 Elasticsearch.java 类,在 #main(...) 方法的开头,添加如下代码:

修改  类

String esHome = "/Users/yunai/Java/elasticsearch/distribution/archives/no-jdk-darwin-tar/build/install/elasticsearch-8.0.0-SNAPSHOT";
System.setProperty("es.path.home", esHome); // 设置 Elasticsearch 的【根】目录
System.setProperty("es.path.conf", esHome + "/config"); // 设置 Elasticsearch 的【配置】目录
System.setProperty("log4j2.disable.jmx", "true"); // 禁用 log4j2 的 JMX 监控,避免报错
System.setProperty("java.security.policy", esHome + "/config/java.policy"); // 设置 Java 的安全策略

esHome 变量,需要设置为刚构建的 Elasticsearch 发布包的地址。如下图所示:

获得  变量

打开 config 目录下的 elasticsearch.yml 配置文件,添加配置如下:

修改  配置文件

node.name: node-1 # 设置 ES 节点名
xpack.security.enabled: false # 禁用 X-Pack 提供的安全认证功能,方便测试

config 目录下,创建 java.policy 文件,内容如下:

添加  文件

grant {
permission java.security.AllPermission;
};

打开 server 项目下的 security.policy 文件,删除与 codeBase 相关的授权,避免报错。如下图所示:

修改  文件

回到 Elasticsearch.java 类,在 #main(...) 方法的开头,打上断点。然后 Debug 调试运行,如下图所示:

调试 Elasticsearch 断点

成功进入断点!点击跳过断点,耐心等待 Elasticsearch 启动完成,预计要 1 分钟左右,加载的插件比较多。启动完成后,我们可以看到 publish_address {127.0.0.1:9200}, bound_addresses {[::1]:9200}, {127.0.0.1:9200} 日志,如下图所示:

启动 Elasticsearch 成功日志

使用浏览器访问 http://127.0.0.1:9200/ 地址,可以看到我们熟悉的 Elasticsearch 节点信息。如下图所示:

Elasticsearch 节点信息


至此,我们已经完成了我们的第一个小目标“启动 Elasticsearch 服务,成功断点调试它的启动过程。”。

6. 调试 Elasticsearch 操作

下面,我们来带胖友执行 Elasticsearch 常用的三个操作,并断点到对应的源码:

  • 新建索引
  • 创建文档
  • 搜索文档

友情提示:操作的索引名是 users

Elasticsearch 提供 RESTful API,对应到源码就是 server 项目下的 action 包。如下图所示:

 包

每个 API 转发到对应的 TransportAction实现类,进行相应的代码逻辑。而 TransportAction 需要在 ActionModule 中进行注册,如下图所示:

友情提示:可以把一个 TransportAction 类,理解成 SpringMVC Controller 里的一个方法。

Action 类

所以,如果我们想知道某个 API 对应的 TransportAction 的实现类,可以在 ActionModule 中寻找。

6.1 新建索引 API

对应 TransportCreateIndexAction 类。

#masterOperation(...) 方法中,打上调试断点。如下所示:

TransportCreateIndexAction

使用 Postman 请求该 API,具体参数如下图:

Postman 模拟请求

PUT http://127.0.0.1:9200/users

{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
}
}

打开 IDEA,可以看到成功进入 Debug 断点。

友情提示:具体的源码,咱就先不解析了!

6.2 创建文档 API

对应 TransportShardBulkAction 类。

#dispatchedShardOperationOnPrimary(...) 方法中,打上调试断点。如下所示:

TransportShardBulkAction

使用 Postman 请求该 API,具体参数如下图:

Postman 模拟请求

POST http://127.0.0.1:9200/users/_doc

{
"username": "yudaoyuanma",
"nickname": "芋道源码"
}

6.3 搜索文档 API

对应 TransportSearchAction 类。

#doExecute(...) 方法中,打上调试断点。如下所示:

TransportSearchAction

使用 Postman 请求该 API,具体参数如下图:

Postman 模拟请求

GET http://127.0.0.1:9200/users/_search

7. 源码解析

Elasticsearch 的代码量,艿艿使用 IDEA 的 Statistic 插件统计了下,200w 行代码!!!看到秃头,哈哈哈?

代码统计

Elasticsearch 源码相关解析的书籍,只有 《Elasticsearch源码解析与优化实战》 一本,豆瓣评分 7.5 分。至于 Elasticsearch 的版本,艿艿也不确定,没看过,啊哈哈哈!

Elasticsearch源码解析与优化实战

文章目录
  1. 1. 1. 依赖工具
    1. 1.1. 1.1 IDEA
    2. 1.2. 1.2 JDK
  2. 2. 2. 源码拉取
  3. 3. 3. 下载依赖
  4. 4. 4. 构建 Elasticsearch 发布包
  5. 5. 5. 启动 Elasticsearch 服务
  6. 6. 6. 调试 Elasticsearch 操作
    1. 6.1. 6.1 新建索引 API
    2. 6.2. 6.2 创建文档 API
    3. 6.3. 6.3 搜索文档 API
  7. 7. 7. 源码解析