spring-cloud-kubernetes背后的三个关键知识点

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

/**

  • 探针检查响应类

  • @return

*/

@RequestMapping(“/health”)

public String health() {

return “health”;

}

/**

  • 返回远程调用的结果

  • @return

*/

@RequestMapping(“/getservicedetail”)

public String getUri(

@RequestParam(value = “servicename”, defaultValue = “”) String servicename) {

return “Service [” + servicename + "]'s instance list : " + JSON.toJSONString(discoveryClient.getInstances(servicename));

}

/**

  • 返回发现的所有服务

  • @return

*/

@RequestMapping(“/services”)

public String services() {

return this.discoveryClient.getServices().toString()

  • ", "

  • new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”).format(new Date());

}

}

上述代码中,我们并没有写创建DiscoveryClient实例的代码,discoveryClient从何而来?

这一切,要从DiscoveryController.java所在项目的pom.xml说起;

  1. 在pom.xml中,有对spring-cloud-kubernetes框架的依赖配置:

org.springframework.cloud

spring-cloud-kubernetes-discovery

1.0.1.RELEASE

  1. 打开spring-cloud-kubernetes-discovery的源码,地址是:https://github.com/spring-cloud/spring-cloud-kubernetes/tree/master/spring-cloud-kubernetes-discovery ,在这个工程中发现了文件spring.factories:

在这里插入图片描述

  1. spring容器启动时,会寻找classpath下所有spring.factories文件(包括jar文件中的),spring.factories中配置的所有类都会实例化,我们在开发springboot时常用到的XXX-starter.jar就用到了这个技术,效果是一旦依赖了某个starter.jar很多功能就在spring初始化时候自动执行了(例如mysql的starter,启动时会连接数据库),关于此技术的详情,请参考以下三篇文章:

《自定义spring boot starter三部曲之一:准备工作》

《自定义spring boot starter三部曲之二:实战开发》

《自定义spring boot starter三部曲之三:源码分析spring.factories加载过程》

  1. spring.factories文件中有两个类:KubernetesDiscoveryClientAutoConfiguration和KubernetesDiscoveryClientConfigClientBootstrapConfiguration都会被实例化;

  2. 先看KubernetesDiscoveryClientConfigClientBootstrapConfiguration,很简单的源码,KubernetesAutoConfiguration和KubernetesDiscoveryClientAutoConfiguration这两个类会被实例化:

/**

  • Bootstrap config for Kubernetes discovery config client.

  • @author Zhanwei Wang

*/

@Configuration

@ConditionalOnProperty(“spring.cloud.config.discovery.enabled”)

@Import({ KubernetesAutoConfiguration.class,

KubernetesDiscoveryClientAutoConfiguration.class })

public class KubernetesDiscoveryClientConfigClientBootstrapConfiguration {

}

  1. 在KubernetesAutoConfiguration的源码中,会实例化一个重要的类:DefaultKubernetesClient,如下:

@Bean

@ConditionalOnMissingBean

public KubernetesClient kubernetesClient(Config config) {

return new DefaultKubernetesClient(config);

}

  1. 再看KubernetesDiscoveryClientAutoConfiguration源码,注意kubernetesDiscoveryClient方法,这里面实例化了DiscoveryController所需的DiscoveryClient接口实现,还要重点关注的地方是KubernetesClient参数的值,是上面提到的DefaultKubernetesClient对象:

@Bean

@ConditionalOnMissingBean

@ConditionalOnProperty(name = “spring.cloud.kubernetes.discovery.enabled”, matchIfMissing = true)

public KubernetesDiscoveryClient kubernetesDiscoveryClient(KubernetesClient client,

KubernetesDiscoveryProperties properties,

KubernetesClientServicesFunction kubernetesClientServicesFunction,

DefaultIsServicePortSecureResolver isServicePortSecureResolver) {

return new KubernetesDiscoveryClient(client, properties,

kubernetesClientServicesFunction, isServicePortSecureResolver);

}

  1. 至此,第一个问题算是弄清楚了:我们编写的DiscoveryController类所需的DiscoveryClient接口实现类是KubernetesDiscoveryClient,用到的是spring规范中的spring.factories

  2. 另外有一点很重要,下面要用到的:KubernetesDiscoveryClient有个成员变量是KubernetesClient,该变量的值是DefaultKubernetesClient实例;

接下来看第二个问题;

java应用怎么能取得所在kubernetes的服务信息

  1. 看看DiscoveryController是如何获取所在kubernetes的服务信息的:

@RequestMapping(“/services”)

public String services() {

return this.discoveryClient.getServices().toString()

  • ", "

  • new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”).format(new Date());

}

如上所示,discoveryClient.getServices()方法返回了所有kubernetes的服务信息;

2. discoveryClient对应的类是spring-cloud-kubernetes项目的KubernetesDiscoveryClient.java,看方法:

public List getServices(Predicate filter) {

return this.kubernetesClientServicesFunction.apply(this.client).list().getItems()

.stream().filter(filter).map(s -> s.getMetadata().getName())

.collect(Collectors.toList());

}

这段代码的关键在于this.kubernetesClientServicesFunction.apply(this.client).list(),先看KubernetesClientServicesFunction实例的初始化过程,在KubernetesDiscoveryClientAutoConfiguration类中:

@Bean

public KubernetesClientServicesFunction servicesFunction(

KubernetesDiscoveryProperties properties) {

if (properties.getServiceLabels().isEmpty()) {

return KubernetesClient::services;

}

return (client) -> client.services().withLabels(properties.getServiceLabels());

}

KubernetesClientServicesFunction是个lambda表达式,用于KubernetesClient的时候,返回KubernetesClient.services()的结果,如果指定了标签过滤,就用指定的标签来做过滤(也就是kubernetes中的标签选择器的效果)

因此,数据来源其实就是上面的this.client,调用其services方法的返回结果;

3. KubernetesDiscoveryClient.getServices方法中的this.client是什么呢?分析前面的问题时已经提到过了,就是DefaultKubernetesClient类的实例,所以,此时要去看DefaultKubernetesClient.services方法,发现client是ServiceOperationsImpl实例:

@Override

public MixedOperation<Service, ServiceList, DoneableService, ServiceResource<Service, DoneableService>> services() {

return new ServiceOperationsImpl(httpClient, getConfiguration(), getNamespace());

}

  1. 接着看ServiceOperationsImpl.java,我们关心的是它的list方法,此方法在父类BaseOperation中找到:

public L list() throws KubernetesClientException {

try {

HttpUrl.Builder requestUrlBuilder = HttpUrl.get(getNamespacedUrl()).newBuilder();

String labelQueryParam = getLabelQueryParam();

if (Utils.isNotNullOrEmpty(labelQueryParam)) {

requestUrlBuilder.addQueryParameter(“labelSelector”, labelQueryParam);

}

String fieldQueryString = getFieldQueryParam();

if (Utils.isNotNullOrEmpty(fieldQueryString)) {

requestUrlBuilder.addQueryParameter(“fieldSelector”, fieldQueryString);

}

Request.Builder requestBuilder = new Request.Builder().get().url(requestUrlBuilder.build());

L answer = handleResponse(requestBuilder, listType);

updateApiVersion(answer);

return answer;

} catch (InterruptedException | ExecutionException | IOException e) {

throw KubernetesClientException.launderThrowable(forOperationType(“list”), e);

}

}

《MySql面试专题》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

《MySql性能优化的21个最佳实践》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

《MySQL高级知识笔记》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

关注我,点赞本文给更多有需要的人
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
B23g-1714753513722)]

[外链图片转存中…(img-G0MrVqUM-1714753513722)]

[外链图片转存中…(img-4nPQlCPp-1714753513722)]

[外链图片转存中…(img-50oa0LsA-1714753513723)]

文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图

[外链图片转存中…(img-QRBFFO2S-1714753513723)]

关注我,点赞本文给更多有需要的人
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 14
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值