本文介绍如何使用Java、Python、Go语言连接阿里云Elasticsearch集群(ES)。
准备工作
获取集群连接地址
您可以通过VPC私网或公网地址连接到ES集群。
VPC私网连接地址:通过VPC私网地址访问ES集群,延迟低,稳定性高。该地址在集群创建成功后默认开启。
公网连接地址:通过公网访问ES集群,需手动开启。
如何开启公网访问:
登录ES控制台,进入实例基本信息页面。
单击左侧导航栏 配置与管理>安全配置,开启公网访问。待集群状态由生效中变更为生效时,表示公网访问已成功开启。
重要公网地址会降低ES集群的安全性,如果使用公网地址,请务必配置IP白名单,并在使用完毕后及时关闭公网访问。
设置IP白名单
为保障集群安全,您需要将待访问设备的IP地址加入ES集群的VPC私网或者公网白名单,该IP地址所属的设备才能访问ES集群。
获取待访问设备IP。
您可以参照以下场景,获取待访问设备的IP地址。
场景
需获取的IP地址
获取方式
在本地设备中连接ES集群
本地设备公网IP。
如果本地设备位于局域网(如家庭或公司网络)内,需将该局域网的公网出口IP地址添加到ES集群的公网白名单中。
通过
curl ipinfo.io/ip查询本地设备公网IP。在不同VPC的ECS实例中连接ES集群
ECS实例的公网IP
登录ECS控制台,在实例列表查看。
在相同VPC的ECS实例中连接ES集群
ECS实例的私网IP
登录ECS控制台,在实例列表查看。
将获取到的IP地址添加到白名单分组中。
登录ES控制台,进入实例基本信息,单击左侧导航栏 配置与管理>安全配置,单击修改在弹窗中设置VPC私网或者公网访问白名单。
单击default分组右侧的配置 ,在弹出的对话框中添加VPC私网或者公网白名单。单个集群最多可配置300个IP或者IP网段,多个IP或者IP网段之间用英文逗号隔开,且逗号前后不能有空格。
也可单击新增IP白名单分组,自定义分组名称。
白名单分组仅用于IP地址管理,不影响访问权限。所有分组内的IP地址权限相同。
配置类别
格式和示例值
重要注意事项
IPv4地址格式
单个IP:
192.168.0.1网段:
192.168.0.0/24
禁止访问:
127.0.0.1允许所有访问:
0.0.0.0/0重要存在高危风险,强烈建议不要配置
0.0.0.0/0。部分集群版本(如7.16/8.5)和地域不支持
0.0.0.0/0,请以控制台界面或者报错提示为准。
IPv6地址格式
(仅v2部署架构且所属地域为杭州的集群支持)
单个IP:
2401:XXXX:1000:24::5网段:
2401:XXXX:1000::/48
禁止所有访问:
::1允许所有访问
::/0重要存在高危风险,强烈建议不要配置
::/0。部分集群版本不支持
::/0,请以控制台界面或者配置提示信息为准。
配置完成后,单击确认。
协议与证书说明
为确保兼容性,建议客户端使用的 Java、Python 或 Go 语言版本与ES集群底层运行时的版本保持一致。
公网HTTPS:使用权威CA签发的证书,客户端无需特殊配置,直接使用
https://协议连接即可。私网HTTPS:使用自签名证书加密传输,客户端需配置跳过证书校验,详见各语言示例中的私网HTTPS配置。
连接集群
Java
安装Java JDK,JDK版本为1.8及以上。
配置pom依赖。
重要请将
version设置为正确的ES版本号,只有当version设置正确时才能拉取相关依赖,本示例ES版本为8.17.0。<dependency> <groupId>co.elastic.clients</groupId> <artifactId>elasticsearch-java</artifactId> <version>8.17.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.3</version> </dependency>配置YML参数,开启自动创建索引:
action.auto_create_index: true。以下示例将连接ES集群并创建名为hr_test的索引。
基础连接示例
以下示例适用于公网HTTPS或私网HTTP场景:
package org.example;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.cat.IndicesResponse;
import co.elastic.clients.elasticsearch.indices.*;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.*;
import java.io.IOException;
public class RestClientTest {
public static void main(String[] args) {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("{UserName}", "{YourPassword}"));
// 公网HTTPS使用 "https",私网HTTP使用 "http"
RestClient restClient = RestClient.builder(new HttpHost("{YourEsHost}", 9200, "https"))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
}).build();
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
ElasticsearchClient elasticsearchClient = new ElasticsearchClient(transport);
try {
CreateIndexResponse indexRequest = elasticsearchClient.indices().create(createIndexBuilder -> createIndexBuilder
.index("hr_test")
.aliases("foo", aliasBuilder -> aliasBuilder.isWriteIndex(true))
);
System.out.println("Index document successfully! " + indexRequest.acknowledged());
transport.close();
restClient.close();
} catch (IOException ioException) {
// 异常处理
}
}
}
私网HTTPS连接示例
私网HTTPS需额外配置跳过证书校验:
package org.example;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.ssl.SSLContexts;
import org.elasticsearch.client.*;
import javax.net.ssl.SSLContext;
public class RestClientTestPrivateHttps {
public static void main(String[] args) throws Exception {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("{UserName}", "{YourPassword}"));
// 创建信任所有证书的 SSLContext
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, (chain, authType) -> true) // 信任所有证书
.build();
RestClient restClient = RestClient.builder(new HttpHost("{YourEsHost}", 9200, "https"))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder
.setDefaultCredentialsProvider(credentialsProvider)
.setSSLContext(sslContext) // 设置 SSLContext
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE); // 跳过主机名验证
}
}).build();
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
ElasticsearchClient elasticsearchClient = new ElasticsearchClient(transport);
// 执行操作...
System.out.println(elasticsearchClient.info());
transport.close();
restClient.close();
}
}Python
以下代码以ES 8.17.0版本为例,请根据实际ES版本替换版本号。
基础连接示例
以下示例适用于公网HTTPS或私网HTTP场景:
pip install elasticsearch==8.17.0from elasticsearch import Elasticsearch
es = Elasticsearch(
hosts=['https://<YourEsHost>:9200'], # 公网HTTPS使用https://,私网HTTP使用http://
basic_auth=('<UserName>', '<YourPassword>'),
)
print(es.info())
私网HTTPS连接示例
from elasticsearch import Elasticsearch
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # 关闭SSL警告(可选)
es = Elasticsearch(
hosts=['https://<YourEsHost>:9200'],
basic_auth=('<UserName>', '<YourPassword>'),
verify_certs=False, # 跳过证书校验
ssl_show_warn=False, # 关闭SSL警告
)
print(es.info())
Go
以下以ES 8.x版本为例介绍如何通过Go连接ES,更多Go API Client的使用特性,请参见Elasticsearch Go Client。
基础连接示例
以下示例适用于公网HTTPS或私网HTTP场景:
go get github.com/elastic/go-elasticsearch/v8
package main
import (
"github.com/elastic/go-elasticsearch/v8""log"
)
func main() {
cfg := elasticsearch.Config{
Addresses: []string{"https://<YourEsHost>:9200"}, // 公网HTTPS使用https://,私网HTTP使用http://
Username: "<UserName>",
Password: "<YourPassword>",
}
es, _ := elasticsearch.NewClient(cfg)
res, _ := es.Info()
defer res.Body.Close()
log.Println(res)
}
私网HTTPS连接示例
package main
import (
"crypto/tls""net/http""github.com/elastic/go-elasticsearch/v8""log"
)
func main() {
cfg := elasticsearch.Config{
Addresses: []string{"https://<YourEsHost>:9200"},
Username: "<UserName>",
Password: "<YourPassword>",
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // 跳过证书校验
},
}
es, _ := elasticsearch.NewClient(cfg)
res, _ := es.Info()
defer res.Body.Close()
log.Println(res)
}参数说明
参数 | 说明 |
UserName | 默认访问用户名为elastic,该用户具有集群最高权限(可理解为管理员账户)。 出于安全考虑,不建议在生产环境中直接使用此默认管理员账户,您可以通过Elasticsearch X-Pack的RBAC(Role-based Access Control)机制,自定义角色并分配权限,然后将角色分配给用户,实现权限精细化管控,具体操作请参见通过Elasticsearch X-Pack角色管理实现用户权限管控。 |
YourPassword | UserName对应的密码。 |
https | 访问协议,http协议默认开启。 为了保障集群安全性,建议使用https协议,需手动开启。登录ES控制台进入实例基本信息,单击左侧导航栏 配置与管理>安全配置,开启https协议。 重要
|
YourEsHost | 准备工作中已获取的集群连接地址:
|
9200 | 集群的访问端口,VPC私网和公网默认端口号均为9200。 |