ElasticSearch 应用开发(二)Java Client 连接ElasticSearch集群
ElasticSearch 应用开发(三)基于commons-pool2和TransportClient的ElasticSearch连接池
上述内容,介绍java client连接Elasticsearch的方法,简单做一个对比和总结
1.对比
1.1单线程测试获取连接地址
(a)TransportClient
/**
* 单线程 创建一个简单的TransportClient连接
*/
@Test
public void testTransportClient() {
for (int i = 0; i < 10; i++) {
Client client = TransportClientBuild.getClient();
System.out.println(("连接对象————地址:" + client));
}
}
结果如下:
(b)Rest Client
@Test
public void testLowLevelClient() {
for (int i = 0; i < 10; i++) {
System.out.println(LowLevelClient.getClient().toString());
}
}
@Test
public void testHighLevelClient() {
try {
for (int i = 0; i < 10; i++) {
System.out.println(HighLevelClient.getClient().toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
结果如下:
(c)分析
简单for循环获取连接地址,经过简单对比,可知:
1.每次获取TransportClient地址是同一个,针对其做池化有一定的意义,高并发环境下,提高系统稳定性;
2.每次获取Rest Low Level Client和Rest High Level Client地址不同,针对其做做池化技术,意义并不是很大;
1.2多线程条件下 ,测试获取连接地址
(a)TransportClient
public void testTransprotClient() {
//System.out.println(TransportClientBuild.getClient());
System.setProperty("es.set.netty.runtime.available.processors", "false");
ExecutorService executorService = new ThreadPoolExecutor(10, 10,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
for (int i = 0; i < 10; i++) {
int index = i;
if (!executorService.isShutdown()) {
executorService.execute(new Runnable() {
@Override
public void run() {
Client client = TransportClientBuild.getClient();
System.out.println(("第" + index + "次获取到了连接对象————地址:" + client));
}
});
}
}
executorService.shutdown();
try {
while (!executorService.awaitTermination(10000, TimeUnit.MILLISECONDS)) {
System.out.println("10秒没有执行完,强制关闭线程池");
executorService.shutdownNow();
}
} catch (Exception e) {
e.printStackTrace();
}
}
结果:
(b)Rest Client
@Test
public void testRestClient() {
//System.out.println(TransportClientBuild.getClient());
System.setProperty("es.set.netty.runtime.available.processors", "false");
ExecutorService executorService = new ThreadPoolExecutor(10, 10,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
for (int i = 0; i < 10; i++) {
int index = i;
if (!executorService.isShutdown()) {
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(("第" + index + "次获取到了连接对象————地址:" + HighLevelClient.getClient().toString()));
}
});
}
}
executorService.shutdown();
try {
while (!executorService.awaitTermination(10000, TimeUnit.MILLISECONDS)) {
System.out.println("10秒没有执行完,强制关闭线程池");
executorService.shutdownNow();
}
} catch (Exception e) {
e.printStackTrace();
}
}
结果:
(c)分析
使用多线程条件下,获取TransportClient和Rest Client 地址,每次地址都不同。由此,可以判断多线程条件下两个连接方式都能够胜任稍微复杂的业务。
1.3 多线程条件下,测试连接池
针对 ElasticSearch 应用开发(三)基于commons-pool2和TransportClient的ElasticSearch连接池构建的连接池,在多线程环境下进行测试。
代码:
/**
* 多线程线程池测试TransportClient连接池
*/
@Test
public void testESPoolClient() {
/*配置节点熟悉*/
Set<TransportClientNodeConfig> nodeSets = TransportClientPoolConfig.getNodesConfig();
AtomicReference<Set<TransportClientNodeConfig>> nodesReference = new AtomicReference<Set<TransportClientNodeConfig>>();
nodesReference.set(nodeSets);
/*配置线程池熟悉*/
TransportClientPoolConfig transportClientPoolConfig = new TransportClientPoolConfig();
final TransportClientPool pool = new TransportClientPool(nodesReference, transportClientPoolConfig);
System.setProperty("es.set.netty.runtime.available.processors", "false");
LinkedBlockingQueue<Runnable> linkBlockingQuene = new LinkedBlockingQueue<Runnable>();
ExecutorService cachedThreadPool = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, linkBlockingQuene);
for (int i = 0; i < 15; i++) {
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
TransportClient client = null;
try {
client = pool.getResource();
System.out.println("当前线获取线程地址:" + client.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
pool.returnResource(client);
}
}
});
}
cachedThreadPool.shutdown();
try {
while (!cachedThreadPool.awaitTermination(10000, TimeUnit.MILLISECONDS)) {
System.out.println("10秒没有执行完,强制关闭线程池");
cachedThreadPool.shutdownNow();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
结果:
分析:
多线程条件下,使用线程池,测试获取连接地址,每次地址都不一样.
2.总结
2.1针对TransportClient
若业务比较简单,连接ElasticSearch集群需求比较少,可以直接连接;
业务复杂,情况下,务必注意线程的使用,尽量在不同的线程中调用client;
当然,业务的增加,也可以使用连接池的形式,可以应对高并发的需求;
2.2针对Rest Client
连接就行了,建议Elasticsearch6.x之后,开始使用,应该能够解决绝大部分业务需求;
说明,以上代码都可以在github上找得到:
https://github.com/codersfarm/elasticsearch/tree/master/elasticsearch5.x
https://github.com/codersfarm/elasticsearch/tree/master/elasticsearch6.x