领先一步
VMware 提供培训和认证,以快速提升您的进度。
了解更多Spring Cloud 最令人感兴趣的功能之一就是其可扩展性。您可以扩展它以支持其他云平台,增强已支持的云平台,支持新的服务,新的服务连接器——所有这些都不需要修改 Spring Cloud 代码本身。在本博客中,我们将探讨此功能。如果您尚未阅读,请阅读本系列的第一篇和第二篇博客以获取足够的背景知识。
Spring Cloud 沿三个正交方向提供可扩展性。您可以在这些方向之一中扩展它,并且正交性确保您可以继续从其他方向获益。
云平台:虽然 Spring Cloud 支持 Cloud Foundry、Heroku 和本地配置云(用于在类似云的环境中进行本地测试),但您并不局限于这些选择。您可以添加自己的云平台,并利用 Spring Cloud 的其他功能,例如 Spring Java Config。
云服务:云平台提供各种服务,从关系数据库到消息传递。每个云平台提供的服务差异很大,即使是同一平台的多个安装也是如此。对于 Cloud Foundry 等 PaaS 产品尤其如此,其中 Cloud Foundry 的私有实例往往具有特定于每个安装的服务。Spring Cloud 提供了一种简单的方法来扩展到其核心产品以外的服务。就像云平台可扩展性一样,您不必更改 Spring Cloud 代码即可将其扩展到新服务,并且您可以继续利用其他部分。
框架:Spring Cloud 目前通过spring-service-connector模块支持 Spring 框架。但是,除了该模块之外,Spring Cloud 中没有任何内容依赖于 Spring。因此,您应该能够从任何基于 JVM 的框架中使用其他部分,或者通过添加新模块来为框架扩展它。
在之前的博客中,我们了解了如何使用CloudFactory
和Cloud
以编程方式使用 Spring Cloud。在可扩展性方面,您不会使用这两个;相反,您将在核心模块中实现其他类型。让我们来看看它们。
要将 Spring Cloud 扩展到新的云平台,您需要熟悉的类型是CloudConnector
,它是一个简单的三方法接口。
public interface CloudConnector {
boolean isInMatchingCloud();
ApplicationInstanceInfo getApplicationInstanceInfo();
List<ServiceInfo> getServiceInfos();
}
isInMatchingCloud()
方法应该检查其环境以确定它是否在正确的环境中运行。例如,Cloud Foundry 连接器检查VCAP_APPLICATION
环境变量的存在,而 Heroku 连接器则查找DYNO
环境变量的存在。getApplicationInstanceInfo()
方法返回有关当前应用程序实例的信息(应用程序名称、主机、端口和应用程序属性)。最有趣的方法getServiceInfos()
返回一个列表,每个元素都包含足够的信息,以便应用程序知道如何连接到每个服务。每个ServiceInfo
对象中包含的确切信息取决于每个实现(ServiceInfo
本身只定义一个方法:getId()
)。
创建CloudConnector
的实现后,您需要让 Spring Cloud 了解它。对于所有扩展点,Spring Cloud 使用基于ServiceLoader的统一机制。应用于 Spring Cloud 的平台可扩展性,它归结为包含一个名为/META-INF/services/org.springframework.cloud.CloudConnector
的文件,其中包含实现类的完全限定名称的条目。通常,您会将此文件与您的实现和支持类一起打包。然后,应用程序只需将此 jar 包含在类路径中即可。
ServiceInfoCreator
接口提供了一个扩展点来处理新服务。
public interface ServiceInfoCreator<SI extends ServiceInfo, SD> {
public boolean accept(SD serviceData);
public SI createServiceInfo(SD serviceData);
}
泛型参数SI
定义了它将创建的ServiceInfo
类型,而SD
参数定义了它可以使用的原始服务数据类型。原始服务数据类型取决于云平台。例如,在 Cloud Found 中,它将基于VCAP_SERVICES
环境变量的Map
,而在 Heroku 中,它将是一对包含特定于服务的环境变量及其值的配对。由于原始数据类型取决于平台,因此ServiceInfoCreator
的实现也取决于平台。accept()
方法检查服务数据并确定它是否可以处理它。例如,它可以查看 URL 方案并确定它是否可以使用该服务数据。如果可以,createServiceInfo()
必须返回一个ServiceInfo
对象。如果这是一个全新的服务,您可能还需要为此实现ServiceInfo
,否则您可以使用现有的ServiceInfo
之一。
实现ServiceInfoCreator
后,您必须让 Spring Cloud 了解它。这遵循前面讨论的关于云平台可扩展性的相同思想。在这种情况下,您使用的文件名取决于CloudConnector
。对于 Cloud Foundry,它是/META-INF/services/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator
(理论上,CloudConnector
实现可能会决定使用另一种扩展机制,但 Spring Cloud 不推荐这样做)。
如之前的博客中所述,云应用程序开发人员可以决定直接使用ServiceInfo
对象。因此,如果您只实现ServiceInfoCreator
,您就已经提供了一些好处。但是,使用原始ServiceInfo
对象可能不会被许多专注于开发应用程序的开发人员所欣赏,因此您还将实现下一个扩展。
最后一个扩展点是ServiceConnectorCreator
。它的工作是将ServiceInfo
转换为适合在应用程序使用的框架中使用的服务连接器。例如,它可以将MysqlServiceInfo
转换为DataSource
对象。开箱即用,Spring Cloud 支持DataSource
和一些Spring Data和Spring AMQP类型的连接器。如果您希望将 Spring Cloud 扩展到其他框架,或者如果您希望支持尚未由 Spring Cloud 直接支持的其他 Spring Data 类型(例如 Neo4J、Elasticsearch、Cassandra)或与 Spring 兼容的类型(例如 S3),则这是您需要的扩展点。
public interface ServiceConnectorCreator<SC, SI extends ServiceInfo> {
SC create(SI serviceInfo, ServiceConnectorConfig serviceConnectorConfig);
...
}
还有几个方法;但是,您通常会扩展AbstractServiceConnectorCreator
,它负责实现这些方法。
ServiceConnectorCreator
的SC
泛型参数绑定到它将创建的连接器类型,例如DataSource
,而SI
参数表示它可以使用的ServiceInfo
类型。
create()
方法提供了一个ServiceInfo
对象和一个配置对象,该对象包含特定于服务的信息,例如池参数。它需要使用这些参数来创建合适的连接器。
实现准备就绪后,只需将其放在名为/META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator
的文件中即可。Spring Cloud 将使用前面描述的 Service Loader 机制。
如您所见,Spring Cloud 在云平台、服务和框架轴线上提供了强大的可扩展性。下次遇到这类新类型时,您应该能够扩展 Spring Cloud 以与它们一起工作。如果您开源您的扩展,请告知我们,以便我们可以将其展示给其他人以从中受益。如果这是一个足够常见的扩展,请考虑创建一个拉取请求。