拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 使用Kubernetes API进行分页和异步调用

使用Kubernetes API进行分页和异步调用

白鹭 - 2021-11-24 812 0 0

1.简介

在本教程中,我们将继续探索Kubernetes API for Java。这次,我们将重点介绍它的两个功能:分页和异步调用

2.分页

简而言之,分页使我们能够以块(也称为页面)的形式对较大的结果集进行迭代,因此使用了此方法。在Kubernetes Java API的上下文中,此功能可用于返回资源列表的所有方法。这些方法始终包含两个可选参数,可用于迭代结果:

  • limit :单个API调用中返回的最大项目数
  • continuecontinuation token ,它告诉服务器返回的结果集的起点

使用这些参数,我们可以遍历任意数量的项目,而不会对服务器造成太大的压力。更好的是,客户端保存结果所需的内存量也受到限制。

现在,让我们看看如何使用这些参数使用此方法获取集群中所有可用吊舱的列表:

ApiClient client = Config.defaultClient();

 CoreV1Api api = new CoreV1Api(client);

 String continuationToken = null;

 do {

 V1PodList items = api.listPodForAllNamespaces(

 null,

 continuationToken,

 null,

 null,

 2,

 null,

 null,

 null,

 10,

 false);

 continuationToken = items.getMetadata().getContinue();

 items.getItems()

 .stream()

 .forEach((node) -> System.out.println(node.getMetadata()));

 } while (continuationToken != null);

listPodForAllNamespaces() API调用的第二个参数包含继续令牌,第五个是limit参数。虽然该limit通常只是一个固定值,但continue需要一些额外的努力。

对于第一个调用,我们发送一个null值,向服务器发出信号,这是分页请求序列的第一个调用。收到响应后,我们将从相应的列表元数据字段中获取要使用continue

当没有更多结果可用时,此值将为null ,因此我们使用此事实来定义迭代循环的退出条件。

2.1 分页陷阱

分页机制非常简单,但是我们必须牢记一些细节:

  • 目前,该API不支持服务器端排序。鉴于当前缺乏存储级别的排序支持,这不太可能很快改变
  • 两次调用之间的所有调用参数( continue除外)都必须相同
  • continue值必须视为不透明的句柄。我们永远不要对它的价值做任何假设
  • 迭代是单向的.我们无法使用先前收到的continue 代币
  • 即使返回的列表元数据包含remainingItemCount字段,其值也不可靠,也不为所有实现所支持

2.2 列出数据一致性

由于Kubernetes集群是一个非常动态的环境,因此与分页调用序列关联的结果集有可能在被客户端读取时被修改。在这种情况下,Kubernetes API的行为如何?

如Kubernetes文档中所述,列表API支持resourceVersion参数,该参数与resourceVersionMatch一起定义如何选择要包含的特定版本。但是,对于分页结果集的情况,其行为始终是相同的:“继续令牌,精确”。

这意味着返回的资源版本对应于分页列表调用开始时可用的资源版本。尽管此方法提供了一致性,但将不包括随后修改的结果。例如,当我们完成对大型集群中所有Pod的迭代时,其中一些可能已经终止。

3.异步呼叫

到目前为止,我们已经以同步方式使用Kubernetes API,这对于简单的程序来说很好,但是从资源使用的角度来看并不是很有效,因为它会阻塞调用线程,直到我们从集群接收到响应并对其进行处理为止。例如,如果我们开始在GUI线程中进行这些调用,则此行为将严重损害应用程序的响应能力。

幸运的是,该库支持基于回调的异步模式,该模式可立即将控件返回给调用者

在检查CoreV1Api类时,我们会注意到,对于每个同步xxx()方法,还有一个xxxAsync()变体。 listPodForAllNamespaces()的异步方法是listPodForAllNamespacesAsync() 。参数是相同的,只是为回调实现添加了一个额外的参数。

3.1 回调详细信息

回调参数对象必须实现通用接口ApiCallback<T>,该接口仅包含四个方法:

  • onSuccess:仅当呼叫成功时才调用。第一个参数类型与同步版本将返回的参数相同
  • onFailure:调用服务器时发生错误,或者答复包含错误代码
  • onUploadProgress :在上载期间调用。我们可以使用此回调在冗长的操作中向用户提供反馈
  • onDownloadProgress :同onUploadProgress ,但下载

异步调用也不会返回常规结果。相反,它们返回OkHttp的(Kubernetes API使用的底层REST客户端) Call实例,该实例用作正在进行的调用的句柄。我们可以使用该对象轮询完成状态,或者,如果需要,可以在完成之前取消它。

3.2 异步呼叫示例

可以想象,在任何地方实现回调都需要大量样板代码。为了避免这种情况,我们将使用一个调用助手来简化此任务:

// Start async call

 CompletableFuture<V1NodeList> p = AsyncHelper.doAsync(api,(capi,cb) ->

 capi.listNodeAsync(null, null, null, null, null, null, null, null, 10, false, cb)

 );

 p.thenAcceptAsync((nodeList) -> {

 nodeList.getItems()

 .stream()

 .forEach((node) -> System.out.println(node.getMetadata()));

 });

 // ... do something useful while we wait for results

在这里,帮助程序包装了异步调用调用,并将其调整为更标准的CompletableFuture 。这使我们可以将其与其他库一起使用,例如Reactor Project中的库。在此示例中,我们添加了一个完成阶段,该阶段将所有元数据打印到标准输出中。

和往常一样,在处理期货时,我们必须意识到可能会出现的并发问题。该代码的在线版本包含一些调试日志,这些日志清楚地表明,即使对于这个简单的代码,也至少使用了三个线程:

  • main线程,启动异步调用
  • OkHttp的线程用于进行实际的HTTP调用
  • 完成线程,用于处理结果

4 结论

在本文中,我们已经看到了如何在Kubernetes Java API中使用分页和异步调用。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *