Spring Cloud 云原生应用

时间:2022-11-30 15:22:21

Spring Cloud 云原生应用

云原生​是一种应用程序开发风格,鼓励在持续交付和价值驱动开发领域轻松采用最佳实践。 一个相关的学科是构建12 因素应用程序,其中开发实践与交付和运营目标保持一致 — 例如,通过使用声明性编程以及管理和监视。 Spring Cloud 以多种特定方式促进这些开发风格。 起点是分布式系统中的所有组件都需要轻松访问的一组功能。

其中许多功能都包含在Spring Boot中,Spring Cloud在其上构建。Spring Cloud 以两个库的形式提供了更多功能:Spring Cloud Context 和 Spring Cloud Commons。 Spring Cloud Context 为 Spring Cloud 应用程序提供实用程序和特殊服务(引导上下文、加密、刷新范围和环境端点)。Spring Cloud Commons是一组抽象和通用类,用于不同的Spring Cloud实现(如Spring Cloud Netflix和Spring Cloud Consul)。​​ApplicationContext​

如果由于“非法密钥大小”而出现异常,并且使用 Sun 的 JDK,则需要安装 Java 加密扩展 (JCE) 无限强度管辖策略文件。 有关详细信息,请参阅以下链接:

  • Java 6 JCE
  • Java 7 JCE
  • Java 8 JCE

将文件解压缩到您使用的任何版本的 JRE/JDK x64/x86 的 JDK/jre/lib/security 文件夹中。

Spring Cloud 是在非限制性 Apache 2.0 许可证下发布的。 如果您想为文档的这一部分做出贡献,或者如果您发现错误,您可以在 {docslink}[github] 找到该项目的源代码和问题跟踪器。

1. 春季云上下文:应用程序上下文服务

Spring Boot 对如何使用 Spring 构建应用程序有一个固执己见的观点。 例如,它具有用于常见配置文件的常规位置,并具有用于常见管理和监视任务的端点。 Spring Cloud在此基础上构建,并添加了一些系统中许多组件会使用或偶尔需要的功能。

​1.1. 引导应用程序上下文​

Spring Cloud 应用程序通过创建“引导”上下文来运行,该上下文是主应用程序的父上下文。 此上下文负责从外部源加载配置属性,并负责解密本地外部配置文件中的属性。 这两个上下文共享一个,这是任何 Spring 应用程序的外部属性的来源。 默认情况下,引导属性(在引导阶段加载的 notbut 属性)以高优先级添加,因此本地配置无法覆盖它们。​​Environment​​​​bootstrap.properties​

引导上下文使用与主应用程序上下文不同的约定来查找外部配置。 您可以使用 (或) 代替 (或),将引导程序和主上下文的外部配置很好地分开。 下面的清单显示了一个示例:​​application.yml​​​​.properties​​​​bootstrap.yml​

例 1.引导程序.yml

spring:
application:
name: foo
cloud:
config:
uri: ${SPRING_CONFIG_URI:http://localhost:8888}

如果您的应用程序需要来自服务器的任何特定于应用程序的配置,最好设置 (inor)。 若要将属性用作应用程序的上下文 ID,必须将其设置在 中。​​spring.application.name​​​​bootstrap.yml​​​​application.yml​​​​spring.application.name​​​​bootstrap.[properties | yml]​

如果要检索特定的配置文件配置,则还应设置。​​spring.profiles.active​​​​bootstrap.[properties | yml]​

您可以通过设置(例如,在系统属性中)完全禁用引导过程。​​spring.cloud.bootstrap.enabled=false​

1.2. 应用程序上下文层次结构

如果从 or 构建应用程序上下文,则引导程序上下文将作为父级添加到该上下文中。 Spring 的一个特性是子上下文从其父上下文继承属性源和配置文件,因此与在没有 Spring Cloud Config 的情况下构建相同的上下文相比,“主”应用程序上下文包含额外的属性源。 其他属性源包括:​​SpringApplication​​​​SpringApplicationBuilder​

  • “bootstrap”:如果在引导上下文中找到任何属性,并且它们具有非空属性,则 optional将显示具有高优先级。 一个例子是来自Spring Cloud Config Server的属性。 有关如何自定义此属性源的内容,请参阅“自定义 Bootstrap 属性源”。PropertySourceLocatorsCompositePropertySource
  • “applicationConfig: [classpath:bootstrap.yml]”(以及相关文件,如果 Spring 配置文件处于活动状态):如果您有 a(or),则这些属性用于配置引导上下文。 然后,当设置父上下文时,它们将添加到子上下文中。 它们的优先级低于在创建 Spring Boot 应用程序过程中添加到子级的 (或) 和任何其他属性源。 有关如何自定义这些属性源的内容,请参阅“更改引导程序属性的位置”。bootstrap.yml.propertiesapplication.yml.properties

由于属性源的排序规则,“引导”条目优先。 但是,请注意,它们不包含来自的任何数据,这些数据的优先级非常低,但可用于设置默认值。​​bootstrap.yml​

您可以通过设置您创建的任何内容的父上下文来扩展上下文层次结构 — 例如,通过使用其自己的接口或使用便利方法 (,and)。 引导上下文是您自己创建的*祖先的父级。 层次结构中的每个上下文都有自己的“引导”(可能是空的)属性源,以避免无意中将值从父级提升到其后代。 如果有配置服务器,则层次结构中的每个上下文也可以(原则上)具有不同的远程属性源,因此具有不同的远程属性源。 普通 Spring 应用程序上下文行为规则适用于属性解析:子上下文中的属性将覆盖 父级,按名称和属性源名称。 (如果子项具有与父项同名的属性源,则父项中的值不包括在子项中)。​​ApplicationContext​​​​SpringApplicationBuilder​​​​parent()​​​​child()​​​​sibling()​​​​spring.application.name​

请注意,您可以在整个层次结构*享这些内容,但这不是默认设置。 因此,同级上下文(特别是)不需要具有相同的配置文件或属性源,即使它们可能与其父级共享共同的值。​​SpringApplicationBuilder​​​​Environment​

1.3. 更改引导程序属性的位置

可以通过设置(默认值:)、(默认值:空)或(默认值:空)来指定(或)位置 — 例如,在系统属性中。​​bootstrap.yml​​​​.properties​​​​spring.cloud.bootstrap.name​​​​bootstrap​​​​spring.cloud.bootstrap.location​​​​spring.cloud.bootstrap.additional-location​

这些属性的行为类似于具有相同名称的变体。 默认位置将被替换,并且仅使用指定的位置。 要将位置添加到默认位置列表中,可以使用。 实际上,它们用于通过在其中设置这些属性来设置引导程序。 如果存在活动配置文件(在您正在构建的上下文中通过 API 发送),则也会加载该配置文件中的属性,与常规 Spring Boot 应用程序中的属性相同 — 例如,fromfor aprofile。​​spring.config.*​​​​spring.cloud.bootstrap.location​​​​spring.cloud.bootstrap.additional-location​​​​ApplicationContext​​​​Environment​​​​spring.profiles.active​​​​Environment​​​​bootstrap-development.properties​​​​development​

1.4. 覆盖远程属性的值

引导上下文添加到应用程序的属性源通常是“远程的”(例如,来自 Spring Cloud Config Server)。 默认情况下,无法在本地覆盖它们。 如果要让应用程序使用自己的系统属性或配置文件覆盖远程属性,则远程属性源必须通过设置授予其权限(在本地设置此选项不起作用)。 设置该标志后,两个更细粒度的设置将控制远程属性相对于系统属性和应用程序的本地配置的位置:​​spring.cloud.config.allowOverride=true​

  • ​spring.cloud.config.overrideNone=true​​:从任何本地属性源覆盖。
  • ​spring.cloud.config.overrideSystemProperties=false​​:只有系统属性、命令行参数和环境变量(而不是本地配置文件)应覆盖远程设置。

1.5. 自定义引导程序配置

引导上下文可以设置为通过在名为的键下添加条目来执行您喜欢的任何操作。 这包含用于创建上下文的 Springclasses 的逗号分隔列表。 您可以在此处创建您希望可用于自动布线的主应用程序上下文的任何 bean。 有一个特殊的合同类型。 如果要控制启动顺序,可以使用注释标记类(默认顺序为)。​​/META-INF/spring.factories​​​​org.springframework.cloud.bootstrap.BootstrapConfiguration​​​​@Configuration​​​​@Beans​​​​ApplicationContextInitializer​​​​@Order​​​​last​

添加自定义时,请注意您添加的类不会错误地放入“主”应用程序上下文中,而这些上下文可能不需要它们。 对引导配置类使用单独的包名称,并确保该名称尚未被您批注的配置类所涵盖。​​BootstrapConfiguration​​​​@ComponentScanned​​​​@ComponentScan​​​​@SpringBootApplication​

引导过程通过将初始值设定项注入主实例(这是正常的 Spring 引导启动序列,无论它是作为独立应用程序运行还是部署在应用程序服务器中)结束。 首先,从中找到的类创建引导上下文。 然后,在启动之前将 allof 类型添加到主节点中。​​SpringApplication​​​​spring.factories​​​​@Beans​​​​ApplicationContextInitializer​​​​SpringApplication​

1.6. 自定义引导属性源

引导过程添加的外部配置的默认属性源是 Spring Cloud 配置服务器,但您可以通过将类型的 bean 添加到引导上下文(通过)来添加其他源。 例如,可以从其他服务器或数据库插入其他属性。​​PropertySourceLocator​​​​spring.factories​

例如,请考虑以下自定义定位器:

@Configuration
public class CustomPropertySourceLocator implements PropertySourceLocator {

@Override
public PropertySource<?> locate(Environment environment) {
return new MapPropertySource("customProperty",
Collections.<String, Object>singletonMap("property.from.sample.custom.source", "worked as intended"));
}

}

传入的就是要创建的那个 - 换句话说,我们为其提供额外的属性源。 它已经有正常的 Spring Boot 提供的属性源,因此您可以使用它们来查找特定于此的属性源(例如,通过键入它,就像在默认的 Spring Cloud Config Server 属性源定位器中所做的那样)。​​Environment​​​​ApplicationContext​​​​Environment​​​​spring.application.name​

如果创建包含此类的 jar,然后添加包含以下设置的 jar,则在其类路径中包含该 jar 的任何应用程序中都会出现:​​META-INF/spring.factories​​​​customProperty​​​​PropertySource​

org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator

1.7. 日志配置

如果使用 Spring 引导来配置日志设置,则应将此配置放入如果您希望它应用于所有事件。​​bootstrap.[yml | properties]​

要使 Spring Cloud 正确初始化日志记录配置,您不能使用自定义前缀。 例如,初始化日志记录系统时,春云无法识别 using。​​custom.loggin.logpath​

1.8. 环境变化

应用程序侦听 anand 以几种标准方式对更改做出反应(可以按正常方式添加其他方式)。 当观察到 anis 时,它有一个已更改的键值列表,应用程序使用这些值来:​​EnvironmentChangeEvent​​​​ApplicationListeners​​​​@Beans​​​​EnvironmentChangeEvent​

  • 在上下文中重新绑定任意豆。@ConfigurationProperties
  • 为 中的任何属性设置记录器级别。logging.level.*

请注意,默认情况下,Spring 云配置客户端不会轮询 中的更改。 通常,我们不建议使用这种方法来检测更改(尽管您可以使用 aannotation 进行设置)。 如果您有横向扩展的客户端应用程序,最好将它广播到所有实例,而不是让它们轮询更改(例如,通过使用Spring Cloud Bus)。​​Environment​​​​@Scheduled​​​​EnvironmentChangeEvent​

涵盖了一大类刷新用例,只要您实际可以对事件进行更改并发布事件即可。 请注意,这些 API 是公共的,是核心 Spring 的一部分)。 您可以通过访问端点(标准的 Spring 引导执行器功能)来验证更改是否绑定到bean。 例如,acan 可以在运行时更改它(Spring Boot 创建的默认值是 abean)并动态增长容量。 重新绑定不涵盖另一类大型用例,在这些用例中,您需要对刷新进行更多控制,并且需要对整个用例进行原子更改。 为了解决这些问题,我们做到了。​​EnvironmentChangeEvent​​​​Environment​​​​@ConfigurationProperties​​​​/configprops​​​​DataSource​​​​maxPoolSize​​​​DataSource​​​​@ConfigurationProperties​​​​@ConfigurationProperties​​​​ApplicationContext​​​​@RefreshScope​

1.9. 刷新范围

当配置发生变化时,标记为特殊处理的弹簧。 此功能解决了有状态 Bean 的问题,这些 Bean 仅在初始化时注入其配置。 例如,如果ahas在通过数据库URL更改时打开连接,您可能希望这些连接的持有者能够完成他们正在执行的操作。 然后,下次某些东西从池中借用连接时,它会获得具有新 URL 的连接。​​@Bean​​​​@RefreshScope​​​​DataSource​​​​Environment​

有时,甚至可能强制要求对某些只能初始化一次的 bean 应用注释。 如果 Bean 是“不可变的”,则必须对 bean withe 进行注释,或者在属性键下指定类名:​​@RefreshScope​​​​@RefreshScope​​​​spring.cloud.refresh.extra-refreshable​

如果你哈瓦阿豆那是,它不可能是 刷新。它是 的默认值。选择一个 不同的实现,如果你需要刷新它。​​DataSource​​​​HikariDataSource​​​​spring.cloud.refresh.never-refreshable​​​​DataSource​

刷新作用域 bean 是惰性代理,在使用它们时(即调用方法时)进行初始化,作用域充当初始化值的缓存。 要强制 Bean 在下一次方法调用时重新初始化,必须使其缓存条目无效。

这是上下文中的 bean,并且有一个 public 方法,可以通过清除目标缓存来刷新范围内的所有 bean。 端点公开此功能(通过 HTTP 或 JMX)。 要按名称刷新单个 bean,还有一个方法。​​RefreshScope​​​​refreshAll()​​​​/refresh​​​​refresh(String)​

若要公开终结点,需要向应用程序添加以下配置:​​/refresh​

management:
endpoints:
web:
exposure:
include: refresh

​@RefreshScope​​​(技术上)适用于 aclass,但它可能会导致令人惊讶的行为。 例如,这并不意味着该类中的所有定义都在自己中。 具体来说,任何依赖于这些 bean 的东西都不能依赖于在启动刷新时更新它们,除非它本身在其中。 在这种情况下,它会在刷新时重新生成,并重新注入其依赖项。 此时,它们将从刷新的重新初始化)。​​@Configuration​​​​@Beans​​​​@RefreshScope​​​​@RefreshScope​​​​@Configuration​

1.10. 加密和解密

Spring Cloud有一个预处理器,用于在本地解密属性值。 它遵循与Spring Cloud Config Server相同的规则,并具有相同的外部配置。 因此,您可以以以下形式使用加密值,并且只要存在有效的密钥,它们就会在主应用程序上下文获取设置之前解密。 要在应用程序中使用加密功能,您需要在类路径中包含 Spring Security RSA(Maven 坐标:),并且还需要在 JVM 中使用全强度的 JCE 扩展。​​Environment​​​​encrypt.*​​​​{cipher}*​​​​Environment​​​​org.springframework.security:spring-security-rsa​

如果由于“非法密钥大小”而出现异常,并且使用 Sun 的 JDK,则需要安装 Java 加密扩展 (JCE) 无限强度管辖策略文件。 有关详细信息,请参阅以下链接:

  • Java 6 JCE
  • Java 7 JCE
  • Java 8 JCE

将文件解压缩到您使用的任何版本的 JRE/JDK x64/x86 的 JDK/jre/lib/security 文件夹中。

1.11. 端点

对于 Spring 引导执行器应用程序,可以使用一些额外的管理端点。您可以使用:

  • ​POST​​TOTO 更新和重新绑定和日志级别。 若要启用此终结点,必须设置。/actuator/envEnvironment@ConfigurationPropertiesmanagement.endpoint.env.post.enabled=true
  • ​/actuator/refresh​​以重新加载引导上下文并刷新 Bean。@RefreshScope
  • ​/actuator/restart​​关闭并重新启动它(默认禁用)。ApplicationContext
  • ​/actuator/pause​​并用于调用方法(安东)。/actuator/resumeLifecyclestop()start()ApplicationContext

如果禁用端点,则端点 也将被禁用,因为它们只是一个特例。​​/actuator/restart​​​​/actuator/pause​​​​/actuator/resume​​​​/actuator/restart​

2. 春云共享:常见抽象

服务发现、负载平衡和断路器等模式适合于一个通用的抽象层,所有 Spring Cloud 客户端都可以使用该抽象层,而与实现无关(例如,使用 Eureka 或 Consul 进行发现)。

2.1. 注释@EnableDiscoveryClient

Spring Cloud Commons提供注释。 这寻找与 theand 接口的实现。 发现客户端的实现在密钥下添加一个配置类。 实现示例包括Spring CloudNetflix Eureka,Spring Cloud Consul Discovery和Spring Cloud Zookeeper Discovery。​​@EnableDiscoveryClient​​​​DiscoveryClient​​​​ReactiveDiscoveryClient​​​​META-INF/spring.factories​​​​spring.factories​​​​org.springframework.cloud.client.discovery.EnableDiscoveryClient​​​​DiscoveryClient​

默认情况下,Spring Cloud 将同时提供阻塞和反应式服务发现客户端。 您可以通过设置器轻松禁用阻塞和/或反应式客户端。 要完全禁用服务发现,您只需进行设置。​​spring.cloud.discovery.blocking.enabled=false​​​​spring.cloud.discovery.reactive.enabled=false​​​​spring.cloud.discovery.enabled=false​

默认情况下,实现自动将本地 Spring 引导服务器注册到远程发现服务器。 可以通过设置来禁用此行为。​​DiscoveryClient​​​​autoRegister=false​​​​@EnableDiscoveryClient​

​@EnableDiscoveryClient​​​不再需要。 您可以在类路径上放置一个实现,以使 Spring 引导应用程序向服务发现服务器注册。​​DiscoveryClient​

2.1.1. 健康指标

共享资源自动配置以下 Spring 引导健康指示器。

发现客户端健康指示器

此运行状况指示器基于当前注册的实现。​​DiscoveryClient​

  • 要完全禁用,请设置。spring.cloud.discovery.client.health-indicator.enabled=false
  • 要禁用描述字段,请设置。 否则,它可能会像卷起一样冒泡。spring.cloud.discovery.client.health-indicator.include-description=falsedescriptionHealthIndicator
  • 要禁用服务检索,请设置。 默认情况下,指标调用客户端的方法。在具有许多注册服务的部署中,也可能 在每次检查期间检索所有服务的成本很高。这将跳过服务检索,而是使用客户端的方法。spring.cloud.discovery.client.health-indicator.use-services-query=falsegetServicesprobe
DiscoveryCompositeHealthContributor

此复合健康指标基于所有注册的豆类。要禁用, 设置。​​DiscoveryHealthIndicator​​​​spring.cloud.discovery.client.composite-indicator.enabled=false​

2.1.2. 订购发现客户端实例

​DiscoveryClient​​接口扩展。这在使用多个发现时很有用 客户端,因为它允许您定义返回的发现客户端的顺序,类似于 如何订购由 Spring 应用程序加载的 bean。默认情况下,anyis 的顺序设置为 。如果您想为自定义实现设置不同的顺序,只需覆盖 方法,以便它返回适合您的设置的值。除此之外,您还可以使用 属性,用于设置Spring Cloud等提供的实现顺序。为此,您只需要将(orfor Eureka)属性设置为所需的值。​​Ordered​​​​DiscoveryClient​​​​0​​​​DiscoveryClient​​​​getOrder()​​​​DiscoveryClient​​​​ConsulDiscoveryClient​​​​EurekaDiscoveryClient​​​​ZookeeperDiscoveryClient​​​​spring.cloud.{clientIdentifier}.discovery.order​​​​eureka.client.order​

2.1.3. 简单发现客户端

如果没有服务注册表支持,则将使用类路径,实例,该类路径使用属性来获取有关服务和实例的信息。​​DiscoveryClient​​​​SimpleDiscoveryClient​

有关可用实例的信息应按以下格式传递给 via 属性:,其中公共前缀,然后站立 表示相关服务的 ID,同时表示实例的索引号 (如示例中所示,索引以开头),然后值 实例可用的实际 URI。​​spring.cloud.discovery.client.simple.instances.service1[0].uri=http://s11:8080​​​​spring.cloud.discovery.client.simple.instances​​​​service1​​​​[0]​​​​0​​​​uri​

2.2. 服务注册表

共享资源现在提供了一个接口,该接口提供了诸如and之类的方法,使您可以提供自定义注册 services.is 标记接口。​​ServiceRegistry​​​​register(Registration)​​​​deregister(Registration)​​​​Registration​

以下示例显示了它们的用法:​​ServiceRegistry​

@Configuration
@EnableDiscoveryClient(autoRegister=false)
public class MyConfiguration {
private ServiceRegistry registry;

public MyConfiguration(ServiceRegistry registry) {
this.registry = registry;
}

// called through some external process, such as an event or a custom actuator endpoint
public void register() {
Registration registration = constructRegistration();
this.registry.register(registration);
}
}

每个实现都有自己的实现。​​ServiceRegistry​​​​Registry​

  • ​ZookeeperRegistration​​与ZookeeperServiceRegistry
  • ​EurekaRegistration​​与EurekaServiceRegistry
  • ​ConsulRegistration​​与ConsulServiceRegistry

如果您使用的是接口,则需要传递 正确实现实现你 正在使用。​​ServiceRegistry​​​​Registry​​​​ServiceRegistry​

2.2.1. 服务注册中心自动注册

默认情况下,该实现会自动注册正在运行的服务。 要禁用该行为,您可以设置: *永久禁用自动注册。 *通过配置禁用该行为。​​ServiceRegistry​​​​@EnableDiscoveryClient(autoRegister=false)​​​​spring.cloud.service-registry.auto-registration.enabled=false​

服务注册表自动注册事件

服务自动注册时将触发两个事件。调用的第一个事件在注册服务之前触发。第二个 调用的事件在注册服务后触发。您可以注册一个 () 来侦听和响应这些事件。​​InstancePreRegisteredEvent​​​​InstanceRegisteredEvent​​​​ApplicationListener​

如果属性设置为 ,则不会触发这些事件。​​spring.cloud.service-registry.auto-registration.enabled​​​​false​

2.2.2. 服务注册表执行器端点

Spring Cloud Commons提供了一个执行器端点。 此端点依赖于 Spring 应用程序上下文中的 abean。 使用 GET 调用返回的状态。 将 POST 用于具有 JSON 正文的同一终结点会将当前状态更改为新值。 JSON 正文必须包含具有首选值的字段。 请参阅更新状态时用于允许值的实现文档以及为状态返回的值。 例如,尤里卡支持的状态是,,,和。​​/service-registry​​​​Registration​​​​/service-registry​​​​Registration​​​​Registration​​​​status​​​​ServiceRegistry​​​​UP​​​​DOWN​​​​OUT_OF_SERVICE​​​​UNKNOWN​

2.3. Spring Rest模板作为负载均衡器客户端

您可以将 a配置为使用负载均衡器客户端。 若要创建负载平衡,请创建 aand 使用均衡器,如以下示例所示:​​RestTemplate​​​​RestTemplate​​​​RestTemplate​​​​@Bean​​​​@LoadBalanced​

@Configuration
public class MyConfiguration {

@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}

public class MyClass {
@Autowired
private RestTemplate restTemplate;

public String doOtherStuff() {
String results = restTemplate.getForObject("http://stores/stores", String.class);
return results;
}
}

Abean 不再通过自动配置创建。 必须由各个应用程序创建。​​RestTemplate​

URI 需要使用虚拟主机名(即服务名称,而不是主机名)。 BlockingLoadBalancerClient 用于创建完整的物理地址。

要使用负载平衡,您需要在类路径中具有负载平衡器实现。 将Spring Cloud LoadBalancer​初学者添加到您的项目中,以便使用它。​​RestTemplate​

2.4. Spring WebClient 作为负载均衡器客户端

您可以配置为自动使用负载均衡器客户端。 要创建负载平衡器,请创建 aand use 均衡器,如下所示:​​WebClient​​​​WebClient​​​​WebClient.Builder​​​​@Bean​​​​@LoadBalanced​

@Configuration
public class MyConfiguration {

@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
}

public class MyClass {
@Autowired
private WebClient.Builder webClientBuilder;

public Mono<String> doOtherStuff() {
return webClientBuilder.build().get().uri("http://stores/stores")
.retrieve().bodyToMono(String.class);
}
}

URI 需要使用虚拟主机名(即服务名称,而不是主机名)。 Spring Cloud LoadBalancer用于创建完整的物理地址。

如果要使用 a,则需要有一个负载均衡器 类路径中的实现。我们建议您将Spring Cloud LoadBalancer 初学者​添加到您的项目中。 然后,在下面使用。​​@LoadBalanced WebClient.Builder​​​​ReactiveLoadBalancer​

2.4.1. 重试失败的请求

可以将负载平衡配置为重试失败的请求。 默认情况下,此逻辑处于禁用状态。 对于非反应式版本 (with),可以通过将Spring 重试添加到应用程序的类路径来启用它。对于反应式版本(与。​​RestTemplate​​​​RestTemplate​​​​WebTestClient), you need to set `spring.cloud.loadbalancer.retry.enabled=true​

如果要在类路径上使用 Spring 重试或反应式重试来禁用重试逻辑,则可以设置。​​spring.cloud.loadbalancer.retry.enabled=false​

对于非反应式实现,如果你想在你的重试中实现,你需要创建一个类型的 bean并覆盖该方法。​​BackOffPolicy​​​​LoadBalancedRetryFactory​​​​createBackOffPolicy()​

对于反应式实现,您只需通过设置来启用它。​​spring.cloud.loadbalancer.retry.backoff.enabled​​​​false​

您可以设置:

  • ​spring.cloud.loadbalancer.retry.maxRetriesOnSameServiceInstance​​- 指示应在同一请求上重试多少次(为每个选定的实例单独计数)ServiceInstance
  • ​spring.cloud.loadbalancer.retry.maxRetriesOnNextServiceInstance​​- 指示应重试新选择的请求的次数ServiceInstance
  • ​spring.cloud.loadbalancer.retry.retryableStatusCodes​​- 始终重试失败请求的状态代码。

对于反应式实现,您可以额外设置: -- 设置最短退避持续时间(默认为 5 毫秒) -- 设置最大退避持续时间(默认情况下,最大长整型值为毫秒) -- 设置用于计算每次呼叫的实际退避持续时间的抖动(默认为 0.5)。​​spring.cloud.loadbalancer.retry.backoff.minBackoff​​​​spring.cloud.loadbalancer.retry.backoff.maxBackoff​​​​spring.cloud.loadbalancer.retry.backoff.jitter​

对于反应式实现,您还可以实现自己的实现,以便更详细地控制负载平衡的调用重试。​​LoadBalancerRetryPolicy​

可以使用与上述相同的属性单独配置各个负载均衡器客户端,但前缀是负载均衡器的名称。​​spring.cloud.loadbalancer.clients.<clientId>.*​​​​clientId​

对于负载平衡重试,默认情况下,我们将 bean 包装为选择与之前选择的实例不同的实例(如果可用)。您可以通过设置 ofto 的值来禁用此行为。​​ServiceInstanceListSupplier​​​​RetryAwareServiceInstanceListSupplier​​​​spring.cloud.loadbalancer.retry.avoidPreviousInstance​​​​false​

@Configuration
public class MyConfiguration {
@Bean
LoadBalancedRetryFactory retryFactory() {
return new LoadBalancedRetryFactory() {
@Override
public BackOffPolicy createBackOffPolicy(String service) {
return new ExponentialBackOffPolicy();
}
};
}
}

如果要向重试功能添加一个或多个实现,则需要 创建类型的 bean 并返回数组 您希望用于给定服务,如以下示例所示:​​RetryListener​​​​LoadBalancedRetryListenerFactory​​​​RetryListener​

@Configuration
public class MyConfiguration {
@Bean
LoadBalancedRetryListenerFactory retryListenerFactory() {
return new LoadBalancedRetryListenerFactory() {
@Override
public RetryListener[] createRetryListeners(String service) {
return new RetryListener[]{new RetryListener() {
@Override
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
//TODO Do you business...
return true;
}

@Override
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
//TODO Do you business...
}

@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
//TODO Do you business...
}
}};
}
};
}
}

2.5. 多个RestTemplate对象

如果你想要一个不是负载平衡的,创建abean并注入它。 若要访问负载平衡器,请在创建 时使用 thequalifier,如以下示例所示:​​RestTemplate​​​​RestTemplate​​​​RestTemplate​​​​@LoadBalanced​​​​@Bean​

@Configuration
public class MyConfiguration {

@LoadBalanced
@Bean
RestTemplate loadBalanced() {
return new RestTemplate();
}

@Primary
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}

public class MyClass {
@Autowired
private RestTemplate restTemplate;

@Autowired
@LoadBalanced
private RestTemplate loadBalanced;

public String doOtherStuff() {
return loadBalanced.getForObject("http://stores/stores", String.class);
}

public String doStuff() {
return restTemplate.getForObject("http://example.com", String.class);
}
}

请注意,在前面的示例中,在明文声明上使用注释来消除非限定注入的歧义。​​@Primary​​​​RestTemplate​​​​@Autowired​

如果您看到错误,例如,请尝试注射器设置。​​java.lang.IllegalArgumentException: Can not set org.springframework.web.client.RestTemplate field com.my.app.Foo.restTemplate to com.sun.proxy.$Proxy89​​​​RestOperations​​​​spring.aop.proxyTargetClass=true​

2.6. 多个网络客户端对象

如果你想要一个不是负载平衡的,创建abean并注入它。 若要访问负载平衡器,请在创建 时使用 thequalifier,如以下示例所示:​​WebClient​​​​WebClient​​​​WebClient​​​​@LoadBalanced​​​​@Bean​

@Configuration
public class MyConfiguration {

@LoadBalanced
@Bean
WebClient.Builder loadBalanced() {
return WebClient.builder();
}

@Primary
@Bean
WebClient.Builder webClient() {
return WebClient.builder();
}
}

public class MyClass {
@Autowired
private WebClient.Builder webClientBuilder;

@Autowired
@LoadBalanced
private WebClient.Builder loadBalanced;

public Mono<String> doOtherStuff() {
return loadBalanced.build().get().uri("http://stores/stores")
.retrieve().bodyToMono(String.class);
}

public Mono<String> doStuff() {
return webClientBuilder.build().get().uri("http://example.com")
.retrieve().bodyToMono(String.class);
}
}

2.7. Spring WebFluxWebClient作为负载均衡器客户端

Spring WebFlux 可以同时使用反应式和非反应式配置,如以下主题所述:WebClient

  • Spring WebFlux WebClient with ReactorLoadBalancerExchangeFilterFunction
  • [负载平衡器-交换-筛选器-函数负载平衡器-交换-筛选器-函数]

2.7.1. Spring WebFlux WebClient with ReactorLoadBalancerExchangeFilterFunction

您可以配置为使用。 如果您将Spring Cloud LoadBalancer 初学者添加到您的项目中 类路径上的 ifis 是自动配置的。 以下示例演示如何配置 ato 使用反应式负载均衡器:​​WebClient​​​​ReactiveLoadBalancer​​​​spring-webflux​​​​ReactorLoadBalancerExchangeFilterFunction​​​​WebClient​

public class MyClass {
@Autowired
private ReactorLoadBalancerExchangeFilterFunction lbFunction;

public Mono<String> doOtherStuff() {
return WebClient.builder().baseUrl("http://stores")
.filter(lbFunction)
.build()
.get()
.uri("/stores")
.retrieve()
.bodyToMono(String.class);
}
}

URI 需要使用虚拟主机名(即服务名称,而不是主机名)。 Theis 用于创建完整的物理地址。​​ReactorLoadBalancer​

2.7.2. 带有非反应式负载均衡器客户端的 Spring WebFluxWebClient

类路径上的 ifis 是自动配置的。但是,请注意,这 在后台使用非反应式客户端。 以下示例演示如何将 a配置为使用负载均衡器:​​spring-webflux​​​​LoadBalancerExchangeFilterFunction​​​​WebClient​

public class MyClass {
@Autowired
private LoadBalancerExchangeFilterFunction lbFunction;

public Mono<String> doOtherStuff() {
return WebClient.builder().baseUrl("http://stores")
.filter(lbFunction)
.build()
.get()
.uri("/stores")
.retrieve()
.bodyToMono(String.class);
}
}

URI 需要使用虚拟主机名(即服务名称,而不是主机名)。 Theis 用于创建完整的物理地址。​​LoadBalancerClient​

WARN:这种方法现在已经不推荐使用。 我们建议您改用WebFlux 和反应式负载均衡器。

2.8. 忽略网络接口

有时,忽略某些命名网络接口很有用,以便可以从服务发现注册中排除它们(例如,在 Docker 容器中运行时)。 可以设置正则表达式列表,以忽略所需的网络接口。 以下配置忽略接口和所有以以下内容开头的接口:​​docker0​​​​veth​

例 2.应用程序.yml

spring:
cloud:
inetutils:
ignoredInterfaces:
- docker0
- veth.*

还可以通过使用正则表达式列表强制仅使用指定的网络地址,如以下示例所示:

例 3.引导程序.yml

spring:
cloud:
inetutils:
preferredNetworks:
- 192.168
- 10.0

还可以强制仅使用站点本地地址,如以下示例所示:

例 4.应用程序.yml

spring:
cloud:
inetutils:
useOnlySiteLocalInterfaces: true

请参阅Inet4Address.html.isSiteLocalAddress() 了解有关构成站点本地地址的更多详细信息。

2.9. HTTP 客户端工厂

Spring Cloud Commons 提供了用于创建 Apache HTTP 客户端 () 和 OK HTTP 客户端 () 的 bean。 仅当 OK HTTP jar 位于类路径上时,才会创建 Thebean。 此外,Spring Cloud Commons 还提供了用于创建两个客户端使用的连接管理器的 bean:用于 Apache HTTP 客户端和 OK HTTP 客户端。 如果要自定义在下游项目中创建 HTTP 客户端的方式,则可以提供自己的这些 Bean 实现。 此外,如果提供 Bean of typeor,则默认工厂使用这些生成器作为返回到下游项目的生成器的基础。 您还可以通过 setorto 禁用这些 bean 的创建。​​ApacheHttpClientFactory​​​​OkHttpClientFactory​​​​OkHttpClientFactory​​​​ApacheHttpClientConnectionManagerFactory​​​​OkHttpClientConnectionPoolFactory​​​​HttpClientBuilder​​​​OkHttpClient.Builder​​​​spring.cloud.httpclientfactories.apache.enabled​​​​spring.cloud.httpclientfactories.ok.enabled​​​​false​

2.10. 启用的功能

Spring Cloud Commons提供了一个执行器端点。 此端点返回类路径上可用的功能以及它们是否已启用。 返回的信息包括功能类型、名称、版本和供应商。​​/features​

2.10.1. 要素类型

有两种类型的“特征”:抽象和命名。

抽象功能是定义接口或抽象类并且创建实现(例如,或)的功能。 抽象类或接口用于在上下文中查找该类型的 Bean。 显示的版本是。​​DiscoveryClient​​​​LoadBalancerClient​​​​LockService​​​​bean.getClass().getPackage().getImplementationVersion()​

命名特征是没有它们实现的特定类的功能。这些功能包括“断路器”、“API 网关”、“Spring Cloud Bus”等。这些功能需要名称和 Bean 类型。

2.10.2. 声明特性

任何模块都可以声明任意数量的 bean,如以下示例所示:​​HasFeature​

@Bean
public HasFeatures commonsFeatures() {
return HasFeatures.abstractFeatures(DiscoveryClient.class, LoadBalancerClient.class);
}

@Bean
public HasFeatures consulFeatures() {
return HasFeatures.namedFeatures(
new NamedFeature("Spring Cloud Bus", ConsulBusAutoConfiguration.class),
new NamedFeature("Circuit Breaker", HystrixCommandAspect.class));
}

@Bean
HasFeatures localFeatures() {
return HasFeatures.builder()
.abstractFeature(Something.class)
.namedFeature(new NamedFeature("Some Other Feature", Someother.class))
.abstractFeature(Somethingelse.class)
.build();
}

这些豆子中的每一个都应该放在一个适当的保护中。​​@Configuration​

2.11. 弹簧云兼容性验证

由于某些用户在设置Spring Cloud应用程序时遇到问题,我们决定 以添加兼容性验证机制。如果您当前的设置不兼容,它将中断 与Spring Cloud要求,以及一份报告,显示到底出了什么问题。

目前,我们验证哪个版本的 Spring Boot 已添加到您的类路径中。

报告示例

***************************
APPLICATION FAILED TO START
***************************

Description:

Your project setup is incompatible with our requirements due to following reasons:

- Spring Boot [2.1.0.RELEASE] is not compatible with this Spring Cloud release train


Action:

Consider applying the following actions:

- Change Spring Boot version to one of the following versions [1.2.x, 1.3.x] .
You can find the latest Spring Boot versions here [https://spring.io/projects/spring-boot#learn].
If you want to learn more about the Spring Cloud Release train compatibility, you can visit this page [https://spring.io/projects/spring-cloud#overview] and check the [Release Trains] section.

要禁用此功能,请设置。 如果要覆盖兼容的 Spring 引导版本,只需使用逗号分隔的列表设置属性 兼容的 Spring 引导版本。​​spring.cloud.compatibility-verifier.enabled​​​​false​​​​spring.cloud.compatibility-verifier.compatible-boot-versions​

3. 弹簧云负载均衡器

Spring Cloud 提供了自己的客户端负载均衡器抽象和实现。用于负载平衡 添加了机制,接口以及基于循环和随机的实现 已经为它提供了。为了获得要从反应式中进行选择的实例是使用的。目前,我们支持基于服务的实现,即使用类路径中可用的发现客户端从服务发现中检索可用实例。​​ReactiveLoadBalancer​​​​ServiceInstanceListSupplier​​​​ServiceInstanceListSupplier​

可以通过设置值 of 来禁用 Spring Cloud LoadBalancer。​​spring.cloud.loadbalancer.enabled​​​​false​

3.1. 在负载均衡算法之间切换

默认使用的实现是。要切换到其他实现(针对所选服务或所有服务),您可以使用自定义负载均衡器配置机制。​​ReactiveLoadBalancer​​​​RoundRobinLoadBalancer​

例如,可以通过注释传递以下配置以切换到使用:​​@LoadBalancerClient​​​​RandomLoadBalancer​

public class CustomLoadBalancerConfiguration {

@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
}

传递 asorconfiguration 参数的类不应使用组件注释或超出组件扫描范围。​​@LoadBalancerClient​​​​@LoadBalancerClients​​​​@Configuration​

3.2. Spring 云负载均衡器集成

为了便于使用Spring Cloud LoadBalancer,我们提供了可以与之一起使用。 您可以在以下部分中查看更多信息和用法示例:​​ReactorLoadBalancerExchangeFilterFunction​​​​WebClient​​​​BlockingLoadBalancerClient​​​​RestTemplate​

  • Spring Rest模板作为负载均衡器客户端
  • Spring WebClient 作为负载均衡器客户端
  • Spring WebFlux WebClient with ReactorLoadBalancerExchangeFilterFunction

3.3. Spring 云负载均衡器缓存

除了每次必须选择实例时检索实例的基本实现之外,我们还提供了两种缓存实现。​​ServiceInstanceListSupplier​​​​DiscoveryClient​

3.3.1.咖啡因支持的负载均衡器缓存实现

如果你在类路径中,将使用基于咖啡因的实现。 有关如何配置它的信息,请参阅负载平衡器缓存配置部分。​​com.github.ben-manes.caffeine:caffeine​

如果您使用的是咖啡因,您还可以通过在属性中传递您自己的咖啡因规范来覆盖负载均衡器的默认咖啡因缓存设置。​​spring.cloud.loadbalancer.cache.caffeine.spec​

WARN:传递您自己的 Caffeine 规范将覆盖任何其他 LoadBalancerCache 设置,包括常规 LoadBalancer Cache 配置字段,例如 and。​​ttl​​​​capacity​

3.3.2. 默认负载均衡器缓存实现

如果您的类路径中没有咖啡因,则将使用自动附带的咖啡因。 有关如何配置它的信息,请参阅负载平衡器缓存配置部分。​​DefaultLoadBalancerCache​​​​spring-cloud-starter-loadbalancer​

要使用 Caffeine 而不是默认缓存,请将依赖项添加到类路径。​​com.github.ben-manes.caffeine:caffeine​

3.3.3. 负载均衡器缓存配置

您可以设置自己的值(写入后条目应过期的时间),表示为,通过传递符合Spring 引导字符串到持续时间转换器语法。 作为属性的值。 您还可以通过设置属性的值来设置自己的负载均衡器缓存初始容量。​​ttl​​​​Duration​​​​String​​​​spring.cloud.loadbalancer.cache.ttl​​​​spring.cloud.loadbalancer.cache.capacity​

默认设置包括设置为 35 秒,默认值为 35 秒。​​ttl​​​​initialCapacity​​​​256​

您还可以通过设置 ofto 值来完全禁用负载均衡器缓存。​​spring.cloud.loadbalancer.cache.enabled​​​​false​

尽管基本的非缓存实现对于原型设计和测试很有用,但它的效率远低于缓存版本,因此我们建议始终在生产中使用缓存版本。例如,如果缓存已由实现完成,则应禁用负载平衡器缓存以防止双重缓存。​​DiscoveryClient​​​​EurekaDiscoveryClient​

3.4. 基于区域的负载均衡

为了启用基于区域的负载均衡,我们提供了。 我们使用特定于的配置(例如)来选择客户端尝试筛选可用服务实例的区域。​​ZonePreferenceServiceInstanceListSupplier​​​​DiscoveryClient​​​​zone​​​​eureka.instance.metadata-map.zone​

您还可以通过设置 属性 的值来覆盖特定的区域设置。​​DiscoveryClient​​​​spring.cloud.loadbalancer.zone​

目前,只有 Eureka 发现客户端用于设置负载均衡器区域。对于其他发现客户端,请设置该属性。更多仪器即将推出。​​spring.cloud.loadbalancer.zone​

为了确定检索到的区域,我们检查其元数据映射中键下的值。​​ServiceInstance​​​​"zone"​

筛选器检索实例,并仅返回同一区域中的实例。 如果区域是或同一区域中没有实例,则返回所有检索到的实例。​​ZonePreferenceServiceInstanceListSupplier​​​​null​

为了使用基于区域的负载平衡方法,您必须在自定义配置中实例化 abean。​​ZonePreferenceServiceInstanceListSupplier​

我们使用委托来处理豆子。 我们建议在构造函数中传递委托,然后使用 ato 利用负载均衡器缓存机制包装后者。​​ServiceInstanceListSupplier​​​​DiscoveryClientServiceInstanceListSupplier​​​​ZonePreferenceServiceInstanceListSupplier​​​​CachingServiceInstanceListSupplier​

您可以使用此示例配置进行设置:

public class CustomLoadBalancerConfiguration {

@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withZonePreference()
.withCaching()
.build(context);
}
}

3.5. 负载均衡器的实例健康检查

可以为负载均衡器启用计划的运行状况检查。泰斯为此提供了。它会定期验证委托提供的实例是否仍处于活动状态,并且仅返回正常运行的实例, 除非没有 - 否则它会返回所有检索到的实例。​​HealthCheckServiceInstanceListSupplier​​​​ServiceInstanceListSupplier​

这种机制在使用时特别有用。对于 由实际服务注册表支持的客户端,没有必要使用,因为我们已经得到 查询外部服务发现后运行正常的实例。​​SimpleDiscoveryClient​

对于每个服务实例数较少的设置,还建议使用此供应商 以避免在失败的实例上重试调用。

如果使用任何服务发现支持的供应商,通常不需要添加此运行状况检查机制,因为我们直接检索实例的运行状况状态 从服务注册表。

这就是委托通量提供的更新实例。在极少数情况下,当您想使用不刷新实例的委托时,即使实例列表可能会更改(例如我们提供的),您也可以设置由 刷新实例列表。然后,您还可以通过修改 的值来调整引用间隔,并选择通过设置为每个实例重新获取来禁用额外的运行状况检查重复 还将触发运行状况检查。​​HealthCheckServiceInstanceListSupplier​​​​DiscoveryClientServiceInstanceListSupplier​​​​spring.cloud.loadbalancer.health-check.refetch-instances​​​​true​​​​HealthCheckServiceInstanceListSupplier​​​​spring.cloud.loadbalancer.health-check.refetch-instances-interval​​​​spring.cloud.loadbalancer.health-check.repeat-health-check​​​​false​

​HealthCheckServiceInstanceListSupplier​​使用前缀为的属性。您可以为调度程序设置与。您可以通过设置 属性的值。您还可以通过设置属性的值来为任何给定服务设置特定值,并替换为服务的正确 ID。如果未指定,则默认使用。如果将 to或 空设置为值,则不会执行运行状况检查。您还可以通过设置 的 值来设置运行状况检查请求的自定义端口。如果未设置任何设置,则所请求的服务在服务实例中可用的端口。​​spring.cloud.loadbalancer.health-check​​​​initialDelay​​​​interval​​​​spring.cloud.loadbalancer.health-check.path.default​​​​spring.cloud.loadbalancer.health-check.path.[SERVICE_ID]​​​​[SERVICE_ID]​​​​[SERVICE_ID]​​​​/actuator/health​​​​[SERVICE_ID]​​​​null​​​​spring.cloud.loadbalancer.health-check.port​

如果依赖于默认路径 (),请确保添加到协作者的依赖项,除非您计划自行添加此类终结点。​​/actuator/health​​​​spring-boot-starter-actuator​

为了使用运行状况检查调度程序方法,您必须在自定义配置中实例化 abean。​​HealthCheckServiceInstanceListSupplier​

我们使用委托来处理豆子。 我们建议在构造函数中传递委托。​​ServiceInstanceListSupplier​​​​DiscoveryClientServiceInstanceListSupplier​​​​HealthCheckServiceInstanceListSupplier​

您可以使用此示例配置进行设置:

public class CustomLoadBalancerConfiguration {

@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withHealthChecks()
.build(context);
}
}

对于非反应堆栈,请使用 创建此供应商。 您还可以传递自己的实例以用于检查。​​withBlockingHealthChecks()​​​​WebClient​​​​RestTemplate​

​HealthCheckServiceInstanceListSupplier​​​有自己的基于反应堆通量的缓存机制。因此,如果正在使用它,您可能希望跳过包装该供应商。​​replay()​​​​CachingServiceInstanceListSupplier​

3.6. 负载均衡器的相同实例首选项

您可以设置负载均衡器,使其首选之前选择的实例(如果该实例可用)。

为此,您需要使用。您可以通过提供自己的 bean 来设置 oftoor 值来配置它,例如:​​SameInstancePreferenceServiceInstanceListSupplier​​​​spring.cloud.loadbalancer.configurations​​​​same-instance-preference​​​​ServiceInstanceListSupplier​

public class CustomLoadBalancerConfiguration {

@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withSameInstancePreference()
.build(context);
}
}

这也是动物园管理员的替代品。​​StickyRule​

3.7. 负载均衡器的基于请求的粘性会话

您可以设置负载均衡器,使其首选请求 Cookie 中提供的实例。如果请求通过 SC 负载均衡器交换筛选器函数和筛选器使用的任一函数传递到负载均衡器,我们目前支持此功能。​​instanceId​​​​ClientRequestContext​​​​ServerHttpRequestContext​

为此,您需要使用 .您可以通过提供自己的 bean 来设置 oftoor 值来配置它,例如:​​RequestBasedStickySessionServiceInstanceListSupplier​​​​spring.cloud.loadbalancer.configurations​​​​request-based-sticky-session​​​​ServiceInstanceListSupplier​

public class CustomLoadBalancerConfiguration {

@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withRequestBasedStickySession()
.build(context);
}
}

对于该功能,在向前发送请求之前更新选定的服务实例(如果该实例不可用,则可能与原始请求 Cookie 中的实例不同)非常有用。为此,请将值设置为 ofto。​​spring.cloud.loadbalancer.sticky-session.add-service-instance-cookie​​​​true​

默认情况下,Cookie 的名称为。您可以通过更改属性的值来修改它。​​sc-lb-instance-id​​​​spring.cloud.loadbalancer.instance-id-cookie-name​

Web 客户端支持的负载平衡当前支持此功能。

3.8. Spring 云负载均衡器提示

Spring Cloud LoadBalancer允许您设置传递给对象中的LoadBalancer的提示,并且以后可以在可以处理它们的实现中使用。​​String​​​​Request​​​​ReactiveLoadBalancer​

您可以通过设置属性的值为所有服务设置默认提示。您还可以设置特定值 通过设置属性的值来为任何给定的服务,用服务的正确 ID 替换。如果提示不是由用户设置的,则使用。​​spring.cloud.loadbalancer.hint.default​​​​spring.cloud.loadbalancer.hint.[SERVICE_ID]​​​​[SERVICE_ID]​​​​default​

3.9. 基于提示的负载均衡

我们还提供了一个,这是基于提示的实例选择的实现。​​HintBasedServiceInstanceListSupplier​​​​ServiceInstanceListSupplier​

​HintBasedServiceInstanceListSupplier​​检查提示请求标头(默认标头名称为,但您可以通过更改属性的值来修改它),如果找到提示请求标头,则使用标头中传递的提示值来筛选服务实例。​​X-SC-LB-Hint​​​​spring.cloud.loadbalancer.hint-header-name​

如果未添加提示标头,则使用属性中的提示值来筛选服务实例。​​HintBasedServiceInstanceListSupplier​

如果未按标头或属性设置提示,则返回委托提供的所有服务实例。

筛选时,查找在其键下设置了匹配值的服务实例。如果未找到匹配的实例,则返回委托提供的所有实例。​​HintBasedServiceInstanceListSupplier​​​​hint​​​​metadataMap​

您可以使用以下示例配置进行设置:

public class CustomLoadBalancerConfiguration {

@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withHints()
.withCaching()
.build(context);
}
}

3.10. 转换负载均衡的 HTTP 请求

您可以使用 selected来转换负载平衡的 HTTP 请求。​​ServiceInstance​

为此,您需要实现和定义以下内容:​​RestTemplate​​​​LoadBalancerRequestTransformer​

@Bean
public LoadBalancerRequestTransformer transformer() {
return new LoadBalancerRequestTransformer() {
@Override
public HttpRequest transformRequest(HttpRequest request, ServiceInstance instance) {
return new HttpRequestWrapper(request) {
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.putAll(super.getHeaders());
headers.add("X-InstanceId", instance.getInstanceId());
return headers;
}
};
}
};
}

为此,您需要实现和定义以下内容:​​WebClient​​​​LoadBalancerClientRequestTransformer​

@Bean
public LoadBalancerClientRequestTransformer transformer() {
return new LoadBalancerClientRequestTransformer() {
@Override
public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) {
return ClientRequest.from(request)
.header("X-InstanceId", instance.getInstanceId())
.build();
}
};
}

如果定义了多个转换器,则按定义 Bean 的顺序应用它们。 或者,您可以使用 oror 指定顺序。​​LoadBalancerRequestTransformer.DEFAULT_ORDER​​​​LoadBalancerClientRequestTransformer.DEFAULT_ORDER​

3.11. Spring 云负载均衡器入门器

我们还提供了一个入门器,允许您在Spring Boot应用程序中轻松添加Spring Cloud LoadBalancer。 为了使用它,只需在构建文件中添加您的 Spring Cloud 依赖项。​​org.springframework.cloud:spring-cloud-starter-loadbalancer​

Spring Cloud LoadBalancer 启动器包括Spring Boot Caching​和Evicer。

3.12. 传递自己的 Spring 云负载均衡器配置

您还可以使用注释传递您自己的负载均衡器客户端配置,传递负载均衡器客户端的名称和配置类,如下所示:​​@LoadBalancerClient​

@Configuration
@LoadBalancerClient(value = "stores", configuration = CustomLoadBalancerConfiguration.class)
public class MyConfiguration {

@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
}

提示

为了更轻松地处理您自己的负载均衡器配置,我们在类中添加了方法。​​builder()​​​​ServiceInstanceListSupplier​

提示

您还可以使用我们的替代预定义配置来代替默认配置,方法是设置 属性 toto 使用缓存或 toto 使用缓存。​​spring.cloud.loadbalancer.configurations​​​​zone-preference​​​​ZonePreferenceServiceInstanceListSupplier​​​​health-check​​​​HealthCheckServiceInstanceListSupplier​

您可以使用此功能实例化不同的实现 ofor,这些实现由您编写,或由我们提供作为替代方法(例如)以覆盖默认设置。​​ServiceInstanceListSupplier​​​​ReactorLoadBalancer​​​​ZonePreferenceServiceInstanceListSupplier​

您可以在此处查看自定义配置的示例。

注释参数(在上面的例子中)指定了我们应该使用给定的自定义配置向其发送请求的服务 ID。​​value​​​​stores​

您还可以通过注释传递多个配置(针对多个负载均衡器客户端),如以下示例所示:​​@LoadBalancerClients​

@Configuration
@LoadBalancerClients({@LoadBalancerClient(value = "stores", configuration = StoresLoadBalancerClientConfiguration.class), @LoadBalancerClient(value = "customers", configuration = CustomersLoadBalancerClientConfiguration.class)})
public class MyConfiguration {

@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
}

传递 asorconfiguration 参数的类不应使用组件注释或超出组件扫描范围。​​@LoadBalancerClient​​​​@LoadBalancerClients​​​​@Configuration​

3.13. Spring 云负载均衡器生命周期

使用自定义负载均衡器配置注册可能有用的一种类型的 Bean。​​LoadBalancerLifecycle​

Thebeans 提供了 nameback 方法,您应该实现这些方法来指定在负载平衡之前和之后应执行的操作。​​LoadBalancerLifecycle​​​​onStart(Request<RC> request)​​​​onStartRequest(Request<RC> request, Response<T> lbResponse)​​​​onComplete(CompletionContext<RES, T, RC> completionContext)​

​onStart(Request<RC> request)​​将对象作为参数。 它包含用于选择适当实例的数据,包括下游客户端请求和提示。还采用对象和对象作为参数。 另一方面,向方法提供了一个对象。 它包含负载均衡器,包括选定的服务实例、针对该服务实例执行的请求和(如果可用)返回到下游客户端的响应,以及(如果发生异常)相应的负载均衡器。​​Request​​​​onStartRequest​​​​Request​​​​Response<T>​​​​CompletionContext​​​​onComplete(CompletionContext<RES, T, RC> completionContext)​​​​Response​​​​Status​​​​Throwable​

该方法可用于确定所讨论的处理器是否处理所提供类型的对象。 如果未被用户覆盖,它将返回。​​supports(Class requestContextClass, Class responseClass, Class serverTypeClass)​​​​true​

在前面的方法调用中,meanstype,表示客户端响应类型,表示返回的服务器类型。​​RC​​​​RequestContext​​​​RES​​​​T​

如果您使用的是自定义 HTTP 状态代码,则会收到异常。 为了防止这种情况,您可以设置的值。 这将导致使用原始状态代码而不是枚举。 然后将使用字段输入,但您将能够从字段中获取原始状态代码。​​spring.cloud.loadbalancer.use-raw-status-code-in-response-data​​​​HttpStatus​​​​httpStatus​​​​ResponseData​​​​rawHttpStatus​

3.14. Spring 云负载均衡器统计信息

我们提供 abean called,它使用千分尺为负载平衡调用提供统计信息。​​LoadBalancerLifecycle​​​​MicrometerStatsLoadBalancerLifecycle​

为了将此 Bean 添加到您的应用程序上下文中,请设置 thetoand have aavailable 的值(例如,通过将Spring Boot Actuator添加到您的项目中)。​​spring.cloud.loadbalancer.stats.micrometer.enabled​​​​true​​​​MeterRegistry​

​MicrometerStatsLoadBalancerLifecycle​​在以下计量中注册:​​MeterRegistry​

  • ​loadbalancer.requests.active​​:允许您监视任何服务实例的当前活动请求数的仪表(可通过标记获得的服务实例数据);
  • ​loadbalancer.requests.success​​:一个计时器,用于测量以将响应传递给基础客户端而结束的任何负载平衡请求的执行时间;
  • ​loadbalancer.requests.failed​​:一个计时器,用于测量以异常结束的任何负载平衡请求的执行时间;
  • ​loadbalancer.requests.discard​​:测量丢弃的负载均衡请求数的计数器,即负载均衡器尚未检索要在其上运行请求的服务实例的请求。

有关服务实例、请求数据和响应数据的其他信息将通过标签添加到指标中(只要可用)。

对于某些实现,例如,请求和响应数据可能不可用,因为我们从参数建立泛型类型,并且可能无法确定类型和读取数据。​​BlockingLoadBalancerClient​

为给定计量添加至少一条记录时,将在注册表中注册计量。

您可以通过添加MeterFilters​ 来进一步配置这些指标的行为(例如,添加发布百分位数和直方图)。

3.15. 配置单个负载均衡器客户端

可以使用不同的前缀单独配置单个负载均衡器客户端,其中​​clientId​​​是负载均衡器的名称。默认配置值可以在​​spring.cloud.loadbalancer​​中设置。命名空间,并将与优先的客户端特定值合并​​spring.cloud.loadbalancer.clients.<clientId>.

例 5.应用程序.yml

spring:
cloud:
loadbalancer:
health-check:
initial-delay: 1s
clients:
myclient:
health-check:
interval: 30s

上面的示例将导致一个合并的运行状况检查对象与 and。​​@ConfigurationProperties​​​​initial-delay=1s​​​​interval=30s​

每客户端配置属性适用于大多数属性,但以下全局属性除外:

  • ​spring.cloud.loadbalancer.enabled​​- 全局启用或禁用负载平衡
  • ​spring.cloud.loadbalancer.retry.enabled​​- 全局启用或禁用负载平衡重试。如果全局启用它,您仍然可以使用前缀属性禁用特定客户端的重试,但不能反过来client
  • ​spring.cloud.loadbalancer.cache.enabled​​- 全局启用或禁用负载均衡器缓存。如果全局启用它,您仍可以通过创建不包括在委托层次结构中的自定义配置来禁用特定客户端的缓存,但反之则不包括。CachingServiceInstanceListSupplierServiceInstanceListSupplier
  • ​spring.cloud.loadbalancer.stats.micrometer.enabled​​- 全局启用或禁用负载均衡器千分尺指标

对于已使用映射的属性,您可以在不使用关键字(例如,,)的情况下为每个客户端指定不同的值,我们保留了该行为,以保持库向后兼容。它将在下一个主要版本中进行修改。​​clients​​​​hints​​​​health-check.path​