日期 | 作者 | 版本 | 备注 |
---|---|---|---|
2022-10-03 | [email protected] | v1.0 | |
本文讲述在centos 7操作系统上从无到有实现IDEA+Kibana+elasticsearch本地调试elaticsearch源码的操作过程。
1. Git
稳妥起见,升级git到比较新的版本,如git version 2.24.1。
在linux执行git clone github上开源代码会发生卡死或半天没反应等现象,一般设置如下即可:
git config --global --unset https.proxy
git config --global --unset http.proxy
git config --global http.sslVerify "false"
git config --global http.postBuffer 524288000 #最管用的
2. 下载Elasticsearch源码
本文调试的是Elasticsearch 7.10.2版本,注意后文kibana选择一定要与此版本完全一致才行。
mkdir es-source-dir
cd es-source-dir
git clone https://github.com/elastic/elasticsearch.git elasticsearch-7.10.git
cd elasticsearch-7.10.git
git branch -a | grep 7.
git tag | grep 7.10
git checkout v7.10.2
源码路径根路径记作$es_code_root,方便下文使用
3.设置 Jdk
cd $es_code_root
vim CONTRIBUTING.md 浏览得知此版本的elasticsearch运行需要jdk14
vim ~/.bashrc
export JAVA_HOME=/path/to/jdk-14.0.2
稳妥起见,我们将 jdk1.8也安装上,后续测试可能用的着。
4. 准备Maven
wget https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz --no-check-certificate
export M2_HOME=/opt/chilly/app/apache-maven-3.8.6
mvn --version
settings.xml 文件一般存在于两个位置:
全局配置: ${maven.home}/conf/settings.xml
用户配置: ${user.home}/.m2/settings.xml
注意:用户配置优先于全局配置。${user.home} 和所有其他系统属性只能在 3.0+版本上使用。请注意 windows 和 Linux 使用变量的区别。
配置优先级:局部配置优先于全局配置。
配置优先级从高到低:pom.xml > user settings > global settings
如果这些文件同时存在,在应用配置时,会合并它们的内容,如果有重复的配置,优先级高的配置会覆盖优先级低的。
1) vim ${M2_HOME}/conf/settings.xml
Default: ${user.home}/.m2/repository
2) vim ~/.m2/settings.xml
3) project pom.xml
settings.xml 重点要注意的是修改localRepository 为实际希望下载存储jar包的地方。
E:\apache\repository
true
false
false
aliyunmaven
*
阿里云公共仓库
https://maven.aliyun.com/repository/public
maven.net.cn
Mirror from Maven in china
http://maven.net.cn/content/groups/public/
central
default
true
1.8
aliyun
aliyun maven Repository
https://maven.aliyun.com/repository/public
true
false
spring-milestone
Spring Milestone Repository
http://repo.spring.io/milestone
true
false
default
spring-snapshot
Spring Snapshot Repository
http://repo.spring.io/snapshot
false
true
default
aliyun-plugin
https://maven.aliyun.com/repository/public
true
false
另外须注意:在idea中配置maven配置文件和指定本地依赖jar包存储仓库路径非常重要,尤其注意,强烈建议将多个项目的local repository 设置到同一个路径,以重复利用下载的依赖jar包。如下图所示:
5. 准备Gradle
越来越多的java项目使用gradle来管理和构建。gradle是比maven更高级的源码构建和管理方案,它不仅仅用于java,设置c++/python等多种语言都可以用来构建。安装完gradle后在命令行执行gradle init就会交互式提示用户选择语言和项目类型等帮助用户创建一个指定语言和指定类型的项目工程雏形。(有兴趣的读者可以试试,很好玩)
cd $es_root_dir
vim gradle/wrapper/gradle-wrapper.properties 发现elasticsearch源码工程用的gradle版本6.6.1
还发现配置文件里配置了:distributionBase=GRADLE_USER_HOME 和zipStoreBase=GRADLE_USER_HOME 都表明 elasticsearch 编译过程依赖的jar包都会下载到 GRADLE_USER_HOME环境变量值对应的目录下。(如果该变量未定义,gradle会默认将jar包放到 ~/.gradle下。)
5.1 原生gradle
wget https://downloads.gradle-dn.com/distributions/gradle-6.8.3-all.zip
找gradle命令是通过~/.bashrc 中export GRADLE_HOME=/path/to/gradle
而gradle 的任何命令的执行都依赖于环境变量GRADLE_USER_HOME的值,该变量值含义为gradle 配置和缓存下载所有的根目录(caches子目录)。
然后首次执行gradle -v 会发现~/.gradle目录被生成了,该目录下还有几个子目录。
此时删除.gradle目录,同时export GRADLE_USER_HOME=~/temp
再执行gradle -v,会发现~/.gradle目录不再生成,在GRADLE_USER_HOME环境变量值目录下对应生成了相关子目录。
至于gradle的配置文件都是在GRADLE_USER_HOME目录下init.gradle 以及子目录init.d下的*.gradle(按文件名字母顺序依次读取加载)。比如修改国内源就是在这些地方的配置文件里添加(本项目没有修改源)。下载的依赖jar包等都被放在GRADLE_USER_HOME下caches子目录下。
因此,强烈建议在~/.bashrc中 export GRADLE_USER_HOME=/path/to/gradle/user/home来配置gradle下载依赖包的路径。
注意:如果gradle 执行任务过程中发现Read Time out等类似报错,可采取以下两个解决方案:
1.修改国内源,方法是在GRADLE_USER_HOME 变量值对应的目录下新建init.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.执行gradle命令时加上超时参数如下:(单位ms)
-Dorg.gradle.internal.http.socketTimeout=600000
-Dorg.gradle.internal.http.connectionTimeout=600000
比如:./gradlew -Dorg.gradle.internal.http.socketTimeout=600000 -Dorg.gradle.internal.http.connectionTimeout=600000 -i clean localDistro
5.2 Gradle wrapper
有了gradle,但是不同项目需要的gradle版本可能不一样。因此有必要将特定版本的gradle与特定的项目绑定起来,这就用到了gradle wrapper。
执行gradle init 或gradle wrapper 会生成如下的目录结构:
简单解释一下: gradew和gradle.bat 分别是linux和windows下的gradle wrapper 命令名称。比如gradle -v 由gradlew -v代替。
gradle/wrapper目录下保证gradle wrapper特性能正确工作的数据组成。一个典型的gradle/wrapper/gradle-wrapper.properies内容组成如下:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
当执行gradlew脚本时会首先去读取当前目录下gradle/wrapper/gradle-wrapper.properties文件,确定要下载的gradle的url,下载的zip压缩包的根目录,解压后的目录,gradle配置的根目录即distributionBase。然后才是去读取settings.gradle和build.gradle来执行定义的任务。gradle clean/build/tasks是常见的命令。
6. 编译打包elasticsearch工程
cd $es_code_root
export GRADLE_USER_HOME=~/data/gradle_user_home 这一句如果在~/.bashrc中export设置过了就不用再设置了。
执行./gradlew localDistro 编译打包es,显示如下表明编译成功。
BUILD SUCCESSFUL in 6m 39s
如果出现诸如Read Timeout 等报错,可尝试执行如下解决:
./gradlew -Dorg.gradle.internal.http.socketTimeout=600000 -Dorg.gradle.internal.http.connectionTimeout=600000 -i clean localDistro
当前目录下的build/distribution/local/elasticsearch-7.10.2-SNAPSHOT 即时生成的发行包(大概500多MB),拷贝走改改配置可以直接启动es服务端。
注意es源码中包含lucene源码的,调试es源码就包含了调试lucene源码,不需要再单独下载lucene源码了。
7. 命令行启动/关闭elasticsearch服务
mkdir es-run-dir 记为 $es_run_dir
直接将编译打包好的build/distribution/local/elasticsearch-7.10.2-SNAPSHOT 目录拷贝到$es_run_dir
cd $es_run_dir
简单配置下eleasticsearch服务的配置文件config/elasticsearch.yml,如下:
[chilly@cent7ax config]$ diff elasticsearch.yml.old elasticsearch.yml.modified
23c23
< #node.name: node-1
---
> node.name: node-1
55c55
< #network.host: 192.168.0.1
---
> network.host: 0.0.0.0
68c68
< #discovery.seed_hosts: ["host1", "host2"]
---
> discovery.seed_hosts: ["192.168.0.210"]
72c72
< #cluster.initial_master_nodes: ["node-1", "node-2"]
---
> cluster.initial_master_nodes: ["node-1"]
88a89,95
> #
> #添加如下内容
> http.cors.enabled: true
> http.cors.allow-origin: "*"
> http.cors.allow-headers: Authorization
> xpack.security.enabled: true
> xpack.security.transport.ssl.enabled: true
变动说明如下:
放开node.name的注释,并在文件最后加上几行用于设置elastisearch服务访问密码认证的设置。注意如果想在外网访问elasticsearch服务,还需要配置一下elastcisearch.yml中的network.host 为本机实际ip或0.0.0.0,同时把discovery.seed_hosts设置为本机实际ip,设置cluster.initial_master_nodes。注意本机防火墙是否屏蔽了9200和9300等若干elasticsearch服务端口。
最后在命令上执行命令: ./bin/elasticsearch 或 ./bin/elasticsearch -d -p pid 启动elasticsearch服务。
此时如果直接在浏览器输入 127.0.0.1:9200 会发现提示要输入户名和密码。
此时注意是在elasticsearch服务启动的前提下,在命令行执行elasticsearch-setup-passwords interactive 以命令行交互方式设置密码。之后登陆时一般以用户名elastic用户登录执行查询。
命令行关闭elasticsearch服务命令为:pkill -F pid。
以下是命令行常见curl操作elasticsearch示例展示:
curl http://127.0.0.1:9200/_cat/health?v --user elastic:elastic
curl http://127.0.0.1:9200/_cat/nodes?v --user elastic:elastic
curl http://127.0.0.1:9200/_cat/indices?v --user elastic:elastic
curl -XPUT http://127.0.0.1:9200/position?pretty --user elastic:elastic
curl -XDELETE http://127.0.0.1:9200/position?pretty --user elastic:elastic
curl -XGET http://127.0.0.1:9200/_all/_mapping?pretty --user elastic:elastic
curl -XGET http://127.0.0.1:9200/position/_mapping?pretty --user elastic:elastic
curl -H "Content-Type:application/json" -XPOST 'http://localhost:9200/_all/_search?pretty' -d ' { "query":{ "match_all":{} } }' --user elastic:elastic
curl -H "Content-Type:application/json" -XPOST 'http://localhost:9200/_all/_search?pretty' -d ' { "query":{ "term":{"title":"小明"} } }' --user elastic:elastic
curl -H "Content-Type:application/json" -XPOST http://127.0.0.1:9200/position1/_doc?pretty -d ' { "title": "小", "price":10.1, "desc":"" }' --user elastic:elastic
curl -XPUT http://127.0.0.1:9200/position/?pretty -H 'content-Type:application/json' -d ' {
"mappings":{
"properties":{
"title":{
"type":"text"
},
"description":{
"type":"text"
},
"price":{
"type":"double"
},
"onSale":{
"type":"boolean"
},
"type":{
"type":"integer"
},
"createDate":{
"type":"date"
}
}
}
}' --user elastic:elastic
curl -XPUT http://127.0.0.1:9200/position2/_mappings?pretty -H 'content-Type:application/json' -d ' {
"properties":{
"title":{
"type":"text"
},
"description":{
"type":"text"
},
"price":{
"type":"double"
},
"onSale":{
"type":"boolean"
},
"type":{
"type":"integer"
},
"createDate":{
"type":"date"
}
}
}' --user elastic:elastic
注意: 后续上面这些用法都将在kibana dev-tool控制台以更精炼的方式使用,有自动提示等功能,
因此在kibana dev-tool开发控制台上执行上面curl语句是更推荐的方式。
8. 下载和安装、启动kibana
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.10.2-linux-x86_64.tar.gz 注意:kibana版本必须与elasticsearch版本一致。
vim config/kibana.yml
--- kibana.yml 2021-01-13 10:07:15.000000000 +0800
+++ kibana.yml.modified 2022-12-19 16:17:03.079294242 +0800
@@ -4,7 +4,7 @@
# Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
# The default is 'localhost', which usually means remote machines will not be able to connect.
# To allow connections from remote users, set this parameter to a non-loopback address.
-#server.host: "localhost"
+server.host: "0.0.0.0"
# Enables you to specify a path to mount Kibana at if you are running behind a proxy.
# Use the `server.rewriteBasePath` setting to tell Kibana if it should remove the basePath
@@ -38,8 +38,8 @@
# the username and password that the Kibana server uses to perform maintenance on the Kibana
# index at startup. Your Kibana users still need to authenticate with Elasticsearch, which
# is proxied through the Kibana server.
-#elasticsearch.username: "kibana_system"
-#elasticsearch.password: "pass"
+elasticsearch.username: "elastic"
+elasticsearch.password: "elastic"
# Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively.
# These settings enable SSL for outgoing requests from the Kibana server to the browser.
启动 kibana : ./bin/kibana
注意: 访问kibana主页:192.168.0.210:5601时,经常遇到一种情况,输入用户名和密码 总是提示不成功,一种经常的原因是:elasticsearch 进程的磁盘空间不足,导致elasticsearch自动切换成了只读模式。
访问http://192.168.0.210:5601/app/dev_tools#/console
9. 下载和配置idea
推荐使用经典版本2020版linux idea,地址是链接:https://pan.baidu.com/s/1JYHt... 。直接解压后执行./bin/idea.sh即可启动,第一次启动后倒入配置文件(主要是设置一些快捷键等):https://pan.baidu.com/s/1hgAx... 。注意如果要重新设置导入idea的配置文件,可删除 ~/.config/JetBrains即可。链接:https://pan.baidu.com/s/1Owuy... 可帮助以本地磁盘上插件方式导入。
注意有的时候,注意String,Path等这种jdk基础类都飘红,可能是因为jdk版本过高等造成,换一个jdk一般就能解决。
启动后比较重要的是设置好jdk和maven、gradle的配置文件和仓库等。
10. 在idea中启动elasticsearch debug模式
10.1 导入es源码到idea
启动./bin/idea.sh 导入elasticsearch工程源码,即前文下载的v7.10.2版本。配置好需要的jdk14,配置好maven和gradle。
10.2 运行es源码
idea中点击$es_code_root/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java,找到main函数,右键点击Run 'Elasticsearch main()',会运行错误,然后点击Run/Edit Configurations...,在VM options中填入以下配置,切记将$es_run_root修改为前文第7节中es服务运行的根路径:
Run/Edit Configurations...,在VM options填入以下值:
-Dlog4j2.disable.jmx=true
-Des.path.home=$es_run_root
-Des.path.conf=$es_run_root/config
-Djava.security.policy=$es_run_root/config/java.policy
-Xms2g
-Xmx2g
然后在$es_run_root/config目录下创建文件java.policy,并写入以下配置:
grant {
permission javax.management.MBeanServerPermission "createMBeanServer";
permission java.lang.RuntimePermission "createClassLoader";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "setContextClassLoader";
permission org.elasticsearch.secure_sm.ThreadPermission
"modifyArbitraryThread";
permission org.elasticsearch.secure_sm.ThreadPermission
"modifyArbitraryThreadGroup";
};
$es_run_root/config/elasticsearch.yml的配置方式保留前文第7节的对该文件的配置即可。
如果启动过程报错出现如下,你需要在Run/Edit Configurations...,在VM options填入-Xms2g -Xmx2g。
[1] bootstrap checks failed
[1]: initial heap size [327155712] not equal to maximum heap size [5217714176]; this can cause resize pauses
然后,运行Elasticsearch即可,待启动后,在浏览器输入http://localhost:9200/,显示类似第四步骤中的信息则证明启动成功:
如果出现异常信息“java.lang.NoClassDefFoundError: org/elasticsearch/plugins/ExtendedPluginsClassLoader”,则重新打开Run Configuration,勾选 include dependency with provided scope后,重新运行即可。如果还是报该异常,则可尝试修改server模块下的build.gradle中的compileOnly project(':libs:plugin-classloader')为compile project(':libs:plugin-classloader') 。
接着同时启动kibana后,在浏览器输入http://localhost:5601即可通过kibana给idea debug启动的es服务发送查询了。
最后请注意:通过kibana Dev Tool平台上发送查询到idea debug本地启动的elasticsearch上调试代码时,经常会发现kibana后台老有一些查询在不定期地进行干扰我们的调试,一种临时解决方案是 DELETE .kibana_task_manager_1 这个索引,基本能解决这个问题。