设为首页 加入收藏

TOP

java与es8实战之三:Java API Client有关的知识点串讲(一)
2023-09-09 10:26:02 】 浏览:107
Tags:java es8 Java API Client 关的知

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

  • 本篇是《java与es8实战》系列的第三篇,将一些重要的知识点在这里梳理清楚,为后面的实践奠定基础
  • 一共有七个与Java API Client有关的重要知识点
  1. 关于namespace:每个feature都有自己的package
  2. 命名规则:介绍Java API Client中对象的方法的命名规则
  3. 集合不为空:Java API Client中对象返回的集合,到底要不要做判空?
  4. variant type:繁多的场景和对象,可以通过variant type进行简化
  5. 通过JSON字符串创建API对象:通过builder创建复杂的对象,会导致代码也很复杂,这里提供了一种更简单的方式
  6. 关于异常:有哪些异常类型,各自会在什么场景抛出
  • 接下来逐个去看

命名空间

  • 在REST API文档中,数量众多API是按照特性(feature)来分组的,如下图
    在这里插入图片描述

  • 在ES的Java库Java API Client中,上图中的各种feature被称为namespace

  • 在ES的Java库Java API Client中,与REST API对应的的类和接口都在统一的包名co.elastic.clients.elasticsearch之下,然后再通过下一级package进行分类,这个分类与上图的feature相对应,例如索引相关的,在REST API中的feature是Index APIs,那么在Java API Client中,完整的package就是co.elastic.clients.elasticsearch.indices,这里面有索引操作所需的请求、响应、服务等各种类,如下图
    在这里插入图片描述

  • 每一个namespace(也就是REST API中的feature),都有自己的client,例如索引相关的操作都有索引专用的client类负责,实例代码如下,client.indices()返回的是ElasticsearchIndicesClient对象,这是索引操作专用的实例

ElasticsearchClient client = ...
client.indices().create(c -> c.index("products"));
  • 展开上述代码的indices()方法,看看其内部实现,如下所示,每次调用indices方法,都会创建一个ElasticsearchIndicesClient对象,对于其他namespace,例如ingest、license亦是如此,都会创建新的实例
    在这里插入图片描述
  • 看到这里,经验丰富的您应该发现了问题:在大量并发频繁执行各种namespace操作时,会创建大量client对象,这样会影响系统性能吗?
  • es预判了咱们的预判,如下图,官方说这是轻量级对象(very lightweight),所以,理论上可以放心创建,不必担心其对系统造成的压力
    在这里插入图片描述
  • 尽管每个namespace都有自己的client,但也有例外,就是searchdocument,它们的代码不在search或者document这样的package下面,而是在core下面,而且可以通过ElasticsearchClient来操作,如下图
    在这里插入图片描述

命名规则

  • Java API Client是个库,也是个java工程,工程里有自己的内部设计,这算是Java API Client自己的框架部分(framework),另一部分就是专门为使用者提供的大量API
  • 对于API部分,方法的命名规则都是驼峰式(camelCaseNaming),例如查询请求ElasticsearchClient.search()、查询结果的最高评分SearchResponse.maxScore()
  • 对于framework部分,方法命令是下划线作为前缀,例如获取查询类型Query._kind()

五种对象

  • 官方将Java API Client中的对象分为五种
  1. Object mapper:序列化和反序列化工具,这类对象是线程安全、无状态的,通常是单例模式存在于应用中,常在启动时创建
  2. Transport:传输工具,此类对象线程安全,借助底层HTTP客户端工具维护着网络资源,例如负责与es服务端建立连接,在需要关闭连接的时候负责释放所有底层网络资源
  3. Clients:实际处理每个namespace的客户端类,例如负责索引的是ElasticsearchIndicesClient,它们的特点:不可变对象、无状态、线程安全、轻量级(类似于普通bean的资源开销),之所以轻量级,是因为其结构实际上就是对一些API endpoint的包装
  4. Builders:这个在《开篇》中已经详细说明了,就不多赘述,用过builder的您应该会发现,builder当然是可变类,至于是否线程安全似乎和builder没什么关系,因为每创建一次实例时,都要创建一个builder实例,而且,一旦执行完build方法后,这个builder实例就没用了
  5. Requests & other API objects:和请求相关的对象,都是不可变的、线程安全的

集合不会为空

  • 对于单值属性,我们在使用的时候判断是否为空是个常规操作,这样是为了避免直接使用时可能出现的空指针异常
  • 而对于集合,Java API Client 已经确保了API返回的集合非空,我们只需要检查集合中是否有内容,而不必担心集合自身是否等于null的问题,官方给出的演示代码如下
NodeStatistics stats = NodeStatistics.of(b -> b
    .total(1)
    .failed(0)
    .successful(1)
);

// The `failures` list was not provided.
// - it's not null
assertNotNull(stats.failures());
  • 出于好奇,去看看NodeStatistics源码,构造方法如下,failures来自ApiTypeHelper.unmodifiable
	private NodeStatistics(Builder builder) {

		this.failures = ApiTypeHelper.unmodifiable(builder.failures);
		this.total = ApiTypeHelper.requireNonNull(builder.total, this, "total");
		this.successful = ApiTypeHelper.requireNonNull(builder.successful, this, "successful");
		this.failed = ApiTypeHelper.requireNonNull(builder.failed, this, "failed");

	}
  • 再去看ApiTypeHelper.unmodifiable,如下,已确保了failures不为空
    public static <T> List<T> unmo
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【教程分享】Docker搭建Zipkin,.. 下一篇Kafka为什么这么快?

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目