422.375fe09b.js 51.6 KB
Newer Older
茶陵後's avatar
茶陵後 已提交
1
(window.webpackJsonp=window.webpackJsonp||[]).push([[422],{852:function(e,n,t){"use strict";t.r(n);var r=t(56),a=Object(r.a)({},(function(){var e=this,n=e.$createElement,t=e._self._c||n;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"spring-cloud-consul"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#spring-cloud-consul"}},[e._v("#")]),e._v(" Spring Cloud-Consul")]),e._v(" "),t("p",[t("strong",[e._v("3.1.0")])]),e._v(" "),t("p",[e._v("该项目通过自动配置和绑定到 Spring 环境和其他 Spring 编程模型习惯用法,为 Spring 引导应用程序提供 Consul 集成。通过一些简单的注释,你可以快速启用和配置应用程序内的公共模式,并使用基于 Consul 的组件构建大型分布式系统。所提供的模式包括服务发现、控制总线和配置。智能路由和客户端负载平衡、断路器是通过与其他 Spring Cloud项目集成来提供的。")]),e._v(" "),t("h2",{attrs:{id:"_1-快速启动"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-快速启动"}},[e._v("#")]),e._v(" 1.快速启动")]),e._v(" "),t("p",[e._v("这一快速启动将使用 Spring Cloud Consul 进行服务发现和分布式配置。")]),e._v(" "),t("p",[e._v("首先,在你的机器上运行领事代理。然后,你可以访问它,并将其作为服务注册中心和配置源使用 Spring Cloud Consul。")]),e._v(" "),t("h3",{attrs:{id:"_1-1-发现客户端使用情况"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-发现客户端使用情况"}},[e._v("#")]),e._v(" 1.1.发现客户端使用情况")]),e._v(" "),t("p",[e._v("要在应用程序中使用这些特性,你可以将其构建为依赖于"),t("code",[e._v("spring-cloud-consul-core")]),e._v("的 Spring 引导应用程序。添加依赖项最方便的方法是使用 Spring 引导启动器:"),t("code",[e._v("org.springframework.cloud:spring-cloud-starter-consul-discovery")]),e._v("。我们建议使用依赖管理和"),t("code",[e._v("spring-boot-starter-parent")]),e._v("。下面的示例显示了典型的 Maven 配置:")]),e._v(" "),t("p",[e._v("POM.xml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("<project>\n<parent>\n    <groupId>org.springframework.boot</groupId>\n    <artifactId>spring-boot-starter-parent</artifactId>\n    <version>{spring-boot-version}</version>\n    <relativePath/> \x3c!-- lookup parent from repository --\x3e\n  </parent>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.springframework.cloud</groupId>\n      <artifactId>spring-cloud-starter-consul-discovery</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework.boot</groupId>\n      <artifactId>spring-boot-starter-test</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n  <dependencyManagement>\n    <dependencies>\n      <dependency>\n        <groupId>org.springframework.cloud</groupId>\n        <artifactId>spring-cloud-dependencies</artifactId>\n        <version>${spring-cloud.version}</version>\n        <type>pom</type>\n        <scope>import</scope>\n      </dependency>\n    </dependencies>\n  </dependencyManagement>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n")])])]),t("p",[e._v("下面的示例显示了一个典型的 Gradle 设置:")]),e._v(" "),t("p",[e._v("建造。 Gradle")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("plugins {\n  id 'org.springframework.boot' version ${spring-boot-version}\n  id 'io.spring.dependency-management' version ${spring-dependency-management-version}\n  id 'java'\n}\n\nrepositories {\n  mavenCentral()\n}\n\ndependencies {\n  implementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery'\n  testImplementation 'org.springframework.boot:spring-boot-starter-test'\n}\ndependencyManagement {\n  imports {\n    mavenBom \"org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}\"\n  }\n}\n")])])]),t("p",[e._v("现在,你可以创建一个标准的 Spring 启动应用程序,例如下面的 HTTP 服务器:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@SpringBootApplication\n@RestController\npublic class Application {\n\n    @GetMapping("/")\n    public String home() {\n        return "Hello World!";\n    }\n\n    public static void main(String[] args) {\n        SpringApplication.run(Application.class, args);\n    }\n\n}\n')])])]),t("p",[e._v("当这个 HTTP 服务器运行时,它会连接到运行在默认的本地 8500 端口的 Consul 代理。要修改启动行为,可以使用"),t("code",[e._v("应用程序.属性")]),e._v("更改 Consul 代理的位置,如下例所示:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring:\n  cloud:\n    consul:\n      host: localhost\n      port: 8500\n")])])]),t("p",[e._v("你现在可以使用"),t("code",[e._v("DiscoveryClient")]),e._v(""),t("code",[e._v("@LoadBalanced RestTemplate")]),e._v(""),t("code",[e._v("@LoadBalanced WebClient.Builder")]),e._v("从 Consul 检索服务和实例数据,如以下示例所示:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@Autowired\nprivate DiscoveryClient discoveryClient;\n\npublic String serviceUrl() {\n    List<ServiceInstance> list = discoveryClient.getInstances("STORES");\n    if (list != null && list.size() > 0 ) {\n        return list.get(0).getUri().toString();\n    }\n    return null;\n}\n')])])]),t("h3",{attrs:{id:"_1-2-分布式配置使用"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-分布式配置使用"}},[e._v("#")]),e._v(" 1.2.分布式配置使用")]),e._v(" "),t("p",[e._v("要在应用程序中使用这些特性,你可以将其构建为依赖于"),t("code",[e._v("spring-cloud-consul-core")]),e._v(""),t("code",[e._v("spring-cloud-consul-config")]),e._v("的 Spring 引导应用程序。添加依赖项最方便的方法是使用 Spring 引导启动器:"),t("code",[e._v("org.springframework.cloud:spring-cloud-starter-consul-config")]),e._v("。我们建议使用依赖管理和"),t("code",[e._v("spring-boot-starter-parent")]),e._v("。下面的示例显示了典型的 Maven 配置:")]),e._v(" "),t("p",[e._v("POM.xml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("<project>\n<parent>\n    <groupId>org.springframework.boot</groupId>\n    <artifactId>spring-boot-starter-parent</artifactId>\n    <version>{spring-boot-version}</version>\n    <relativePath/> \x3c!-- lookup parent from repository --\x3e\n  </parent>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.springframework.cloud</groupId>\n      <artifactId>spring-cloud-starter-consul-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework.boot</groupId>\n      <artifactId>spring-boot-starter-test</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n  <dependencyManagement>\n    <dependencies>\n      <dependency>\n        <groupId>org.springframework.cloud</groupId>\n        <artifactId>spring-cloud-dependencies</artifactId>\n        <version>${spring-cloud.version}</version>\n        <type>pom</type>\n        <scope>import</scope>\n      </dependency>\n    </dependencies>\n  </dependencyManagement>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n")])])]),t("p",[e._v("下面的示例显示了一个典型的 Gradle 设置:")]),e._v(" "),t("p",[e._v("构建。 Gradle")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("plugins {\n  id 'org.springframework.boot' version ${spring-boot-version}\n  id 'io.spring.dependency-management' version ${spring-dependency-management-version}\n  id 'java'\n}\n\nrepositories {\n  mavenCentral()\n}\n\ndependencies {\n  implementation 'org.springframework.cloud:spring-cloud-starter-consul-config'\n  testImplementation 'org.springframework.boot:spring-boot-starter-test'\n}\ndependencyManagement {\n  imports {\n    mavenBom \"org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}\"\n  }\n}\n")])])]),t("p",[e._v("现在,你可以创建一个标准的 Spring 启动应用程序,例如下面的 HTTP 服务器:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@SpringBootApplication\n@RestController\npublic class Application {\n\n    @GetMapping("/")\n    public String home() {\n        return "Hello World!";\n    }\n\n    public static void main(String[] args) {\n        SpringApplication.run(Application.class, args);\n    }\n\n}\n')])])]),t("p",[e._v("应用程序从 Consul 检索配置数据。")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("如果使用 Spring Cloud Consul Config,则需要设置"),t("code",[e._v("spring.config.import")]),e._v("属性才能绑定到 Consul。"),t("br"),e._v("你可以在"),t("a",{attrs:{href:"#config-data-import"}},[e._v("Spring Boot Config Data Import section")]),e._v("中阅读有关它的更多信息。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("h2",{attrs:{id:"_2-安装领事"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-安装领事"}},[e._v("#")]),e._v(" 2.安装领事")]),e._v(" "),t("p",[e._v("有关如何安装 Consul 的说明,请参见"),t("a",{attrs:{href:"https://www.consul.io/intro/getting-started/install.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("安装文档"),t("OutboundLink")],1),e._v("")]),e._v(" "),t("h2",{attrs:{id:"_3-领事代理人"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-领事代理人"}},[e._v("#")]),e._v(" 3.领事代理人")]),e._v(" "),t("p",[e._v("Consul 代理客户端必须可用于所有 Spring Cloud Consul 应用程序。默认情况下,代理客户机应该位于"),t("code",[e._v("localhost:8500")]),e._v("。有关如何启动代理客户机以及如何连接到 Consul 代理服务器集群的详细信息,请参见"),t("a",{attrs:{href:"https://consul.io/docs/agent/basics.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("代理文档"),t("OutboundLink")],1),e._v("。为了进行开发,在安装了 Consul 之后,可以使用以下命令启动 Consul 代理:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("./src/main/bash/local_run_consul.sh\n")])])]),t("p",[e._v("这将在端口 8500 上以服务器模式启动一个代理,其 UI 位于"),t("a",{attrs:{href:"http://localhost:8500",target:"_blank",rel:"noopener noreferrer"}},[e._v("本地主机:8500"),t("OutboundLink")],1),e._v("")]),e._v(" "),t("h2",{attrs:{id:"_4-与领事的服务发现"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-与领事的服务发现"}},[e._v("#")]),e._v(" 4.与领事的服务发现")]),e._v(" "),t("p",[e._v("服务发现是基于微服务的体系结构的关键原则之一。尝试手动配置每个客户机或某种形式的约定可能非常困难,并且可能非常脆弱。领事通过"),t("a",{attrs:{href:"https://www.consul.io/docs/agent/http.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("HTTP API"),t("OutboundLink")],1),e._v(""),t("a",{attrs:{href:"https://www.consul.io/docs/agent/dns.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("DNS"),t("OutboundLink")],1),e._v("提供服务发现服务。 Spring Cloud Consul 利用 HTTP API 进行服务注册和发现。这并不妨碍非 Spring Cloud应用程序利用 DNS 接口。Consul 代理服务器在"),t("a",{attrs:{href:"https://www.consul.io/docs/internals/architecture.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("cluster"),t("OutboundLink")],1),e._v("中运行,该服务器通过"),t("a",{attrs:{href:"https://www.consul.io/docs/internals/gossip.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("八卦协议"),t("OutboundLink")],1),e._v("进行通信,并使用"),t("a",{attrs:{href:"https://www.consul.io/docs/internals/consensus.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("RAFT 共识协议"),t("OutboundLink")],1),e._v("")]),e._v(" "),t("h3",{attrs:{id:"_4-1-如何激活"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-1-如何激活"}},[e._v("#")]),e._v(" 4.1.如何激活")]),e._v(" "),t("p",[e._v("要激活 Consul 服务发现,请使用分组"),t("code",[e._v("org.springframework.cloud")]),e._v("和工件 ID"),t("code",[e._v("spring-cloud-starter-consul-discovery")]),e._v("的启动器。请参阅"),t("a",{attrs:{href:"https://projects.spring.io/spring-cloud/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Cloud Project page"),t("OutboundLink")],1),e._v("以获取有关使用当前 Spring Cloud发布列设置构建系统的详细信息。")]),e._v(" "),t("h3",{attrs:{id:"_4-2-向领事登记"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-向领事登记"}},[e._v("#")]),e._v(" 4.2.向领事登记")]),e._v(" "),t("p",[e._v("当客户机向 Consul 注册时,它提供有关自身的元数据,如主机和端口、ID、名称和标记。默认情况下,创建一个 HTTP,Consul 每 10 秒钟点击端点。如果健康检查失败,服务实例将被标记为“关键”。")]),e._v(" "),t("p",[e._v("示例领事客户:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@SpringBootApplication\n@RestController\npublic class Application {\n\n    @RequestMapping("/")\n    public String home() {\n        return "Hello world";\n    }\n\n    public static void main(String[] args) {\n        new SpringApplicationBuilder(Application.class).web(true).run(args);\n    }\n\n}\n')])])]),t("p",[e._v("(即完全正常的引导应用程序)。如果 Consul 客户机位于"),t("code",[e._v("localhost:8500")]),e._v("以外的地方,则需要配置来定位客户机。示例:")]),e._v(" "),t("p",[e._v("应用程序.yml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring:\n  cloud:\n    consul:\n      host: localhost\n      port: 8500\n")])])]),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("如果你使用"),t("a",{attrs:{href:"#spring-cloud-consul-config"}},[e._v("Spring Cloud Consul Config")]),e._v(",并且你已经设置了"),t("code",[e._v("spring.cloud.bootstrap.enabled=true")]),e._v(""),t("code",[e._v("spring.config.use-legacy-processing=true")]),e._v("或使用"),t("code",[e._v("spring-cloud-starter-bootstrap")]),e._v(",那么上述值将需要放置在"),t("code",[e._v("bootstrap.yml")]),e._v("而不是"),t("code",[e._v("应用程序.yml")]),e._v("中。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("p",[e._v("默认的服务名、实例 ID 和端口(取自"),t("code",[e._v("Environment")]),e._v(")分别是"),t("code",[e._v("${spring.application.name}")]),e._v("、 Spring 上下文 ID 和"),t("code",[e._v("${server.port}")]),e._v("")]),e._v(" "),t("p",[e._v("要禁用 Consul Discovery 客户端,你可以将"),t("code",[e._v("spring.cloud.consul.discovery.enabled")]),e._v("设置为"),t("code",[e._v("false")]),e._v("。当"),t("code",[e._v("spring.cloud.discovery.enabled")]),e._v("设置为"),t("code",[e._v("false")]),e._v("时,Consul Discovery 客户端也将被禁用。")]),e._v(" "),t("p",[e._v("要禁用服务注册,你可以将"),t("code",[e._v("spring.cloud.consul.discovery.register")]),e._v("设置为"),t("code",[e._v("false")]),e._v("")]),e._v(" "),t("h4",{attrs:{id:"_4-2-1-将管理注册为一项单独的服务"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-1-将管理注册为一项单独的服务"}},[e._v("#")]),e._v(" 4.2.1.将管理注册为一项单独的服务")]),e._v(" "),t("p",[e._v("当管理服务器端口被设置为与应用程序端口不同的东西时,通过设置"),t("code",[e._v("management.server.port")]),e._v("属性,管理服务将被注册为独立于应用程序服务的服务。例如:")]),e._v(" "),t("p",[e._v("应用程序.yml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring:\n  application:\n    name: myApp\nmanagement:\n  server:\n    port: 4452\n")])])]),t("p",[e._v("上述配置将注册以下 2 项服务:")]),e._v(" "),t("ul",[t("li",[e._v("应用程序服务:")])]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("ID: myApp\nName: myApp\n")])])]),t("ul",[t("li",[e._v("管理服务:")])]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("ID: myApp-management\nName: myApp-management\n")])])]),t("p",[e._v("管理服务将从应用程序服务继承其"),t("code",[e._v("instanceId")]),e._v(""),t("code",[e._v("serviceName")]),e._v("。例如:")]),e._v(" "),t("p",[e._v("应用程序.yml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring:\n  application:\n    name: myApp\nmanagement:\n  server:\n    port: 4452\nspring:\n  cloud:\n    consul:\n      discovery:\n        instance-id: custom-service-id\n        serviceName: myprefix-${spring.application.name}\n")])])]),t("p",[e._v("上述配置将注册以下 2 项服务:")]),e._v(" "),t("ul",[t("li",[e._v("应用程序服务:")])]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("ID: custom-service-id\nName: myprefix-myApp\n")])])]),t("ul",[t("li",[e._v("管理服务:")])]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("ID: custom-service-id-management\nName: myprefix-myApp-management\n")])])]),t("p",[e._v("可以通过以下属性进行进一步的定制:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('/** Port to register the management service under (defaults to management port) */\nspring.cloud.consul.discovery.management-port\n\n/** Suffix to use when registering management service (defaults to "management" */\nspring.cloud.consul.discovery.management-suffix\n\n/** Tags to use when registering management service (defaults to "management" */\nspring.cloud.consul.discovery.management-tags\n')])])]),t("h4",{attrs:{id:"_4-2-2-http-健康检查"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-2-http-健康检查"}},[e._v("#")]),e._v(" 4.2.2.HTTP 健康检查")]),e._v(" "),t("p",[e._v("Consul 实例的健康检查默认为“/actuator/health”,这是 Spring 引导执行器应用程序中健康端点的默认位置。如果使用非默认的上下文路径或 Servlet 路径(例如"),t("code",[e._v("server.servletPath=/foo")]),e._v(")或管理端点路径(例如"),t("code",[e._v("management.server.servlet.context-path=/admin")]),e._v("),则即使对于执行器应用程序,也需要对此进行更改。")]),e._v(" "),t("p",[e._v("Consul 用于检查健康端点的间隔也可以配置。“10 秒”和“1 米”分别代表 10 秒和 1 分钟。")]),e._v(" "),t("p",[e._v("此示例演示了上面的内容(有关更多选项,请参见"),t("RouterLink",{attrs:{to:"/spring-cloud/appendix.html"}},[e._v("附录页")]),e._v("中的"),t("code",[e._v("spring.cloud.consul.discovery.health-check-*")]),e._v("属性)。")],1),e._v(" "),t("p",[e._v("应用程序.yml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring:\n  cloud:\n    consul:\n      discovery:\n        healthCheckPath: ${management.server.servlet.context-path}/actuator/health\n        healthCheckInterval: 15s\n")])])]),t("p",[e._v("你可以通过设置"),t("code",[e._v("spring.cloud.consul.discovery.register-health-check=false")]),e._v("完全禁用 HTTP 健康检查。")]),e._v(" "),t("h5",{attrs:{id:"应用头文件"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#应用头文件"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"#applying-headers"}}),t("a",{attrs:{href:"#applying-headers"}},[e._v("应用头文件")])]),e._v(" "),t("p",[e._v("头可以应用于健康检查请求。例如,如果你试图注册一个"),t("a",{attrs:{href:"https://cloud.spring.io/spring-cloud-config/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Cloud Config"),t("OutboundLink")],1),e._v("服务器,该服务器使用"),t("a",{attrs:{href:"https://github.com/spring-cloud/spring-cloud-config/blob/master/docs/src/main/asciidoc/spring-cloud-config.adoc#vault-backend",target:"_blank",rel:"noopener noreferrer"}},[e._v("保险库后端"),t("OutboundLink")],1),e._v(":")]),e._v(" "),t("p",[e._v("应用程序.yml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring:\n  cloud:\n    consul:\n      discovery:\n        health-check-headers:\n          X-Config-Token: 6442e58b-d1ea-182e-cfa5-cf9cddef0722\n")])])]),t("p",[e._v("根据 HTTP 标准,每个头可以有多个值,在这种情况下,可以提供一个数组:")]),e._v(" "),t("p",[e._v("应用程序.yml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('spring:\n  cloud:\n    consul:\n      discovery:\n        health-check-headers:\n          X-Config-Token:\n            - "6442e58b-d1ea-182e-cfa5-cf9cddef0722"\n            - "Some other value"\n')])])]),t("h4",{attrs:{id:"_4-2-3-执行器健康指示器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-3-执行器健康指示器"}},[e._v("#")]),e._v(" 4.2.3.执行器健康指示器")]),e._v(" "),t("p",[e._v("如果服务实例是 Spring 启动致动器应用程序,则可以提供以下致动器的健康指示器。")]),e._v(" "),t("h5",{attrs:{id:"发现潜在的指示剂"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#发现潜在的指示剂"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"#discoveryclienthealthindicator"}}),t("a",{attrs:{href:"#discoveryclienthealthindicator"}},[e._v("发现潜在的指示剂")])]),e._v(" "),t("p",[e._v("当 Consul 服务发现是活动的时,"),t("a",{attrs:{href:"https://cloud.spring.io/spring-cloud-commons/2.2.x/reference/html/#health-indicator",target:"_blank",rel:"noopener noreferrer"}},[e._v("发现客户状态指示器"),t("OutboundLink")],1),e._v("被配置并使致动器健康端点可用。有关配置选项,请参见"),t("a",{attrs:{href:"https://cloud.spring.io/spring-cloud-commons/2.2.x/reference/html/#health-indicator",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1),e._v("")]),e._v(" "),t("h5",{attrs:{id:"健康咨询指示器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#健康咨询指示器"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"#consulhealthindicator"}}),t("a",{attrs:{href:"#consulhealthindicator"}},[e._v("健康咨询指示器")])]),e._v(" "),t("p",[e._v("配置了一个指示器,用于验证"),t("code",[e._v("ConsulClient")]),e._v("的健康状况。")]),e._v(" "),t("p",[e._v("默认情况下,它检索 Consul Leader 节点状态和所有已注册的服务。在具有许多注册服务的部署中,在每次健康检查中检索所有服务的成本可能很高。跳过服务检索,只检查 leader 节点状态集"),t("code",[e._v("spring.cloud.consul.health-indicator.include-services-query=false")]),e._v("")]),e._v(" "),t("p",[e._v("禁用指示器集"),t("code",[e._v("management.health.consul.enabled=false")]),e._v("")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("当应用程序在"),t("a",{attrs:{href:"https://cloud.spring.io/spring-cloud-commons/2.2.x/reference/html/#the-bootstrap-application-context",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bootstrap 上下文模式"),t("OutboundLink")],1),e._v("(默认值)中运行时,"),t("br"),e._v("此指示器将被加载到 BootStrap 上下文中,并且不对 Actuator Health 端点可用。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("h4",{attrs:{id:"_4-2-4-元数据"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-4-元数据"}},[e._v("#")]),e._v(" 4.2.4.元数据")]),e._v(" "),t("p",[e._v("Consul 支持服务的元数据。 Spring Cloud的"),t("code",[e._v("ServiceInstance")]),e._v("具有一个"),t("code",[e._v("Map<String, String> metadata")]),e._v("字段,该字段由服务"),t("code",[e._v("meta")]),e._v("字段填充。在"),t("code",[e._v("spring.cloud.consul.discovery.metadata")]),e._v(""),t("code",[e._v("spring.cloud.consul.discovery.management-metadata")]),e._v("属性上填充"),t("code",[e._v("meta")]),e._v("字段集值。")]),e._v(" "),t("p",[e._v("应用程序.yml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring:\n  cloud:\n    consul:\n      discovery:\n        metadata:\n          myfield: myvalue\n          anotherfield: anothervalue\n")])])]),t("p",[e._v("上述配置将导致一个服务的元字段包含"),t("code",[e._v("myfield→myvalue")]),e._v(""),t("code",[e._v("anotherfield→anothervalue")]),e._v("")]),e._v(" "),t("h5",{attrs:{id:"生成的元数据"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#生成的元数据"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"#generated-metadata"}}),t("a",{attrs:{href:"#generated-metadata"}},[e._v("生成的元数据")])]),e._v(" "),t("p",[e._v("领事自动注册将自动生成一些条目。")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("Key")]),e._v(" "),t("th",[e._v("价值")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("'group'")]),e._v(" "),t("td",[e._v("属性"),t("code",[e._v("spring.cloud.consul.discovery.instance-group")]),e._v("。只有当"),t("code",[e._v("instance-group")]),e._v("不为空时,才会生成该值。")])]),e._v(" "),t("tr",[t("td",[e._v("'secure'")]),e._v(" "),t("td",[e._v("如果属性"),t("code",[e._v("spring.cloud.consul.discovery.scheme")]),e._v("等于“HTTPS”,则为真,否则为假。")])]),e._v(" "),t("tr",[t("td",[e._v("Property "),t("code",[e._v("spring.cloud.consul.discovery.default-zone-metadata-name")]),e._v(", defaults to 'zone'")]),e._v(" "),t("td",[e._v("属性"),t("code",[e._v("spring.cloud.consul.discovery.instance-zone")]),e._v("。只有当"),t("code",[e._v("instance-zone")]),e._v("不为空时,才会生成该值。")])])])]),e._v(" "),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("Spring Cloud Consul 的旧版本通过解析"),t("code",[e._v("spring.cloud.consul.discovery.tags")]),e._v("属性填充了 Spring Cloud Commons 中的"),t("code",[e._v("ServiceInstance.getMetadata()")]),e._v("方法。这不再受支持,请迁移到使用"),t("code",[e._v("spring.cloud.consul.discovery.metadata")]),e._v("映射。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("h4",{attrs:{id:"_4-2-5-使-consul-实例-id-是唯一的"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-5-使-consul-实例-id-是唯一的"}},[e._v("#")]),e._v(" 4.2.5.使 Consul 实例 ID 是唯一的")]),e._v(" "),t("p",[e._v("默认情况下,Consul 实例注册的 ID 等于其 Spring 应用程序上下文 ID。默认情况下, Spring 应用程序上下文 ID 是"),t("code",[e._v("${spring.application.name}:comma,separated,profiles:${server.port}")]),e._v("。对于大多数情况,这将允许在一台机器上运行一个服务的多个实例。如果需要进一步的唯一性,那么使用 Spring Cloud,你可以通过在"),t("code",[e._v("spring.cloud.consul.discovery.instanceId")]),e._v("中提供唯一的标识符来覆盖这一点。例如:")]),e._v(" "),t("p",[e._v("应用程序.yml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring:\n  cloud:\n    consul:\n      discovery:\n        instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}\n")])])]),t("p",[e._v("有了这个元数据,以及在 LocalHost 上部署的多个服务实例,随机值就会在其中发挥作用,从而使实例具有唯一性。在 CloudFoundry 中,"),t("code",[e._v("vcap.application.instance_id")]),e._v("将在 Spring 引导应用程序中自动填充,因此不需要随机值。")]),e._v(" "),t("h3",{attrs:{id:"_4-3-查询服务"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-3-查询服务"}},[e._v("#")]),e._v(" 4.3.查询服务")]),e._v(" "),t("h4",{attrs:{id:"_4-3-1-使用负载均衡器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-3-1-使用负载均衡器"}},[e._v("#")]),e._v(" 4.3.1.使用负载均衡器")]),e._v(" "),t("p",[e._v("Spring Cloud具有对"),t("a",{attrs:{href:"https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign",target:"_blank",rel:"noopener noreferrer"}},[e._v("Feign"),t("OutboundLink")],1),e._v("(一个 REST 客户机构建器)和[[ Spring "),t("code",[e._v("RestTemplate")]),e._v("](https://DOCS. Spring.io/ Spring-cloud-commons/DOCS/current/reference/html/#rest-template-loadbalancer-client)的支持,用于使用逻辑服务名称/ID 而不是物理 URL 查找服务。Feign 和支持发现的 RESTTemplate 都利用"),t("a",{attrs:{href:"https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#spring-cloud-loadbalancer",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Cloud LoadBalancer"),t("OutboundLink")],1),e._v("实现客户端负载平衡。")]),e._v(" "),t("p",[e._v("如果你想使用 RESTTemplate 访问服务存储,只需声明:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("@LoadBalanced\n@Bean\npublic RestTemplate loadbalancedRestTemplate() {\n     return new RestTemplate();\n}\n")])])]),t("p",[e._v("并像这样使用它(注意我们如何使用来自 Consul 的 Stores Service Name/ID,而不是一个完全限定的域名):")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@Autowired\nRestTemplate restTemplate;\n\npublic String getFirstProduct() {\n   return this.restTemplate.getForObject("https://STORES/products/1", String.class);\n}\n')])])]),t("p",[e._v("如果你在多个数据中心中拥有 Consul 集群,并且希望访问另一个数据中心中的服务,那么仅使用服务名称/ID 是不够的。在这种情况下,你使用属性"),t("code",[e._v("spring.cloud.consul.discovery.datacenters.STORES=dc-west")]),e._v(",其中"),t("code",[e._v("STORES")]),e._v("是服务名称/ID,"),t("code",[e._v("dc-west")]),e._v("是存储服务生命的数据中心。")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("Spring Cloud 现在还提供对"),t("a",{attrs:{href:"https://cloud.spring.io/spring-cloud-commons/reference/html/#_spring_resttemplate_as_a_load_balancer_client",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Cloud LoadBalancer"),t("OutboundLink")],1),e._v("的支持。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("h4",{attrs:{id:"_4-3-2-使用-discoveryclient"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-3-2-使用-discoveryclient"}},[e._v("#")]),e._v(" 4.3.2.使用 DiscoveryClient")]),e._v(" "),t("p",[e._v("你也可以使用"),t("code",[e._v("org.springframework.cloud.client.discovery.DiscoveryClient")]),e._v(",它为非特定于 Netflix 的发现客户端提供了一个简单的 API,例如。")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v('@Autowired\nprivate DiscoveryClient discoveryClient;\n\npublic String serviceUrl() {\n    List<ServiceInstance> list = discoveryClient.getInstances("STORES");\n    if (list != null && list.size() > 0 ) {\n        return list.get(0).getUri();\n    }\n    return null;\n}\n')])])]),t("h3",{attrs:{id:"_4-4-领事目录表"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_4-4-领事目录表"}},[e._v("#")]),e._v(" 4.4.领事目录表")]),e._v(" "),t("p",[e._v("领事编目表利用领事的能力"),t("a",{attrs:{href:"https://www.consul.io/docs/agent/watches.html#services",target:"_blank",rel:"noopener noreferrer"}},[e._v("手表服务"),t("OutboundLink")],1),e._v("。Catalog Watch 进行一个阻塞的 Consul HTTP API 调用,以确定是否有任何服务发生了更改。如果有新的服务数据,则会发布心跳事件。")]),e._v(" "),t("p",[e._v("要改变配置手表的频率时,调用 change"),t("code",[e._v("spring.cloud.consul.config.discovery.catalog-services-watch-delay")]),e._v("。默认值是 1000,以毫秒为单位。延迟是上一次调用结束后和下一次调用开始后的时间量。")]),e._v(" "),t("p",[e._v("要禁用目录手表集"),t("code",[e._v("spring.cloud.consul.discovery.catalogServicesWatch.enabled=false")]),e._v("")]),e._v(" "),t("p",[e._v("手表使用 Spring "),t("code",[e._v("TaskScheduler")]),e._v("来安排与领事的通话。默认情况下,它是一个"),t("code",[e._v("ThreadPoolTaskScheduler")]),e._v(",其"),t("code",[e._v("poolSize")]),e._v("为 1。要更改"),t("code",[e._v("TaskScheduler")]),e._v(",请创建一个类型为"),t("code",[e._v("TaskScheduler")]),e._v("的 Bean,该类型以"),t("code",[e._v("ConsulDiscoveryClientConfiguration.CATALOG_WATCH_TASK_SCHEDULER_NAME")]),e._v("常数命名。")]),e._v(" "),t("h2",{attrs:{id:"_5-与-consul-的分布式配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-与-consul-的分布式配置"}},[e._v("#")]),e._v(" 5.与 Consul 的分布式配置")]),e._v(" "),t("p",[e._v("Consul 提供了"),t("a",{attrs:{href:"https://consul.io/docs/agent/http/kv.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("键/值存储"),t("OutboundLink")],1),e._v("用于存储配置和其他元数据。 Spring Cloud Consul Config 是"),t("a",{attrs:{href:"https://github.com/spring-cloud/spring-cloud-config",target:"_blank",rel:"noopener noreferrer"}},[e._v("配置服务器和客户端"),t("OutboundLink")],1),e._v("的一种替代方案。在特殊的“引导”阶段,将配置加载到 Spring 环境中。默认情况下,配置存储在"),t("code",[e._v("/config")]),e._v("文件夹中。多个"),t("code",[e._v("PropertySource")]),e._v("实例是根据应用程序的名称和模拟解析属性的 Spring Cloud配置顺序的活动配置文件创建的。例如,一个名为“TestApp”、配置文件为“Dev”的应用程序将创建以下属性源:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("config/testApp,dev/\nconfig/testApp/\nconfig/application,dev/\nconfig/application/\n")])])]),t("p",[e._v("最具体的属性源位于顶部,而最不具体的属性源位于底部。"),t("code",[e._v("config/application")]),e._v("文件夹中的属性适用于使用 Consul 进行配置的所有应用程序。"),t("code",[e._v("config/testApp")]),e._v("文件夹中的属性仅对名为“TestApp”的服务实例可用。")]),e._v(" "),t("p",[e._v("当前在启动应用程序时读取配置。将 HTTP POST 发送到"),t("code",[e._v("/refresh")]),e._v("将导致重新加载配置。"),t("a",{attrs:{href:"#spring-cloud-consul-config-watch"}},[e._v("配置手表")]),e._v("还将自动检测更改并重新加载应用程序上下文。")]),e._v(" "),t("h3",{attrs:{id:"_5-1-如何激活"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-如何激活"}},[e._v("#")]),e._v(" 5.1.如何激活")]),e._v(" "),t("p",[e._v("要开始使用 Consul 配置,请使用带有组"),t("code",[e._v("org.springframework.cloud")]),e._v("和工件 ID"),t("code",[e._v("spring-cloud-starter-consul-config")]),e._v("的启动器。请参阅"),t("a",{attrs:{href:"https://projects.spring.io/spring-cloud/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Cloud Project page"),t("OutboundLink")],1),e._v("以获取有关使用当前 Spring Cloud发布列设置构建系统的详细信息。")]),e._v(" "),t("h3",{attrs:{id:"_5-2-spring-boot-config-data-import"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-2-spring-boot-config-data-import"}},[e._v("#")]),e._v(" 5.2. Spring Boot Config Data Import")]),e._v(" "),t("p",[e._v("Spring Boot2.4 引入了一种通过"),t("code",[e._v("spring.config.import")]),e._v("属性导入配置数据的新方法。这是现在从 Consul 获得配置的默认方式。")]),e._v(" "),t("p",[e._v("可选地连接到 Consul,请在应用程序中设置以下属性:")]),e._v(" "),t("p",[e._v("应用程序.属性")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring.config.import=optional:consul:\n")])])]),t("p",[e._v("这将在默认位置“http://localhost:8500”连接到 Consul 代理。如果无法连接到 Consul,删除"),t("code",[e._v("optional:")]),e._v("前缀将导致 Consul Config 失败。要更改 Consul Config 的连接属性,可以设置"),t("code",[e._v("spring.cloud.consul.host")]),e._v(""),t("code",[e._v("spring.cloud.consul.port")]),e._v(",或者将主机/端口对添加到"),t("code",[e._v("spring.config.import")]),e._v("语句中,例如,"),t("code",[e._v("spring.config.import=optional:consul:myhost:8500")]),e._v("。导入属性中的位置优先于主机和端口属性。")]),e._v(" "),t("p",[e._v("Consul Config 将尝试基于"),t("code",[e._v("spring.cloud.consul.config.name")]),e._v("(默认为"),t("code",[e._v("spring.application.name")]),e._v("属性的值)和"),t("code",[e._v("spring.cloud.consul.config.default-context")]),e._v("(默认为"),t("code",[e._v("application")]),e._v(")从四个自动上下文加载值。如果你希望指定上下文而不是使用计算的上下文,那么可以将该信息添加到"),t("code",[e._v("spring.config.import")]),e._v("语句中。")]),e._v(" "),t("p",[e._v("application.properties")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring.config.import=optional:consul:myhost:8500/contextone;/context/two\n")])])]),t("p",[e._v("这将可选地只从"),t("code",[e._v("/contextone")]),e._v(""),t("code",[e._v("/context/two")]),e._v("加载配置。")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("通过"),t("code",[e._v("spring.config.import")]),e._v("导入 Spring 引导配置数据方法所需的"),t("code",[e._v("bootstrap")]),e._v("文件(属性或 YAML)是"),t("strong",[e._v("不是")]),e._v("")])])]),e._v(" "),t("tbody")]),e._v(" "),t("h3",{attrs:{id:"_5-3-定制"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-3-定制"}},[e._v("#")]),e._v(" 5.3.定制")]),e._v(" "),t("p",[e._v("Consul Config 可以使用以下属性进行自定义:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring:\n  cloud:\n    consul:\n      config:\n        enabled: true\n        prefix: configuration\n        defaultContext: apps\n        profileSeparator: '::'\n")])])]),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("如果你已经设置了"),t("code",[e._v("spring.cloud.bootstrap.enabled=true")]),e._v(""),t("code",[e._v("spring.config.use-legacy-processing=true")]),e._v(",或者包含了"),t("code",[e._v("spring-cloud-starter-bootstrap")]),e._v(",那么上述值将需要放置在"),t("code",[e._v("bootstrap.yml")]),e._v("中,而不是"),t("code",[e._v("application.yml")]),e._v("中。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("ul",[t("li",[t("p",[t("code",[e._v("enabled")]),e._v("将该值设置为“false”会禁用 Consul Config")])]),e._v(" "),t("li",[t("p",[t("code",[e._v("prefix")]),e._v("设置配置值的基础文件夹")])]),e._v(" "),t("li",[t("p",[t("code",[e._v("defaultContext")]),e._v("设置所有应用程序使用的文件夹名")])]),e._v(" "),t("li",[t("p",[t("code",[e._v("profileSeparator")]),e._v("设置用于在具有配置文件的属性源中分隔配置文件名称的分隔符的值")])])]),e._v(" "),t("h3",{attrs:{id:"_5-4-配置手表"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-4-配置手表"}},[e._v("#")]),e._v(" 5.4.配置手表")]),e._v(" "),t("p",[e._v("领事配置手表利用领事的能力"),t("a",{attrs:{href:"https://www.consul.io/docs/agent/watches.html#keyprefix",target:"_blank",rel:"noopener noreferrer"}},[e._v("观看一个键的前缀"),t("OutboundLink")],1),e._v("。Config Watch 进行一个阻塞的 Consul HTTP API 调用,以确定当前应用程序的任何相关配置数据是否已更改。如果有新的配置数据,将发布刷新事件。这相当于调用"),t("code",[e._v("/refresh")]),e._v("执行器端点。")]),e._v(" "),t("p",[e._v("要更改配置手表时的频率,请调用 change"),t("code",[e._v("spring.cloud.consul.config.watch.delay")]),e._v("。默认值是 1000,以毫秒为单位。延迟是上一次调用结束后和下一次调用开始后的时间量。")]),e._v(" "),t("p",[e._v("要禁用配置手表集"),t("code",[e._v("spring.cloud.consul.config.watch.enabled=false")]),e._v("")]),e._v(" "),t("p",[e._v("手表使用 Spring "),t("code",[e._v("TaskScheduler")]),e._v("来安排对领事的拜访。默认情况下,它是一个"),t("code",[e._v("ThreadPoolTaskScheduler")]),e._v(",其"),t("code",[e._v("poolSize")]),e._v("为 1。要更改"),t("code",[e._v("TaskScheduler")]),e._v(",请创建 Bean 类型的"),t("code",[e._v("TaskScheduler")]),e._v(",该类型的名称为"),t("code",[e._v("ConsulConfigAutoConfiguration.CONFIG_WATCH_TASK_SCHEDULER_NAME")]),e._v("常数。")]),e._v(" "),t("h3",{attrs:{id:"_5-5-具有配置的-yaml-或属性"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-5-具有配置的-yaml-或属性"}},[e._v("#")]),e._v(" 5.5.具有配置的 YAML 或属性")]),e._v(" "),t("p",[e._v("以 YAML 或 Properties 格式存储一组属性可能更方便,而不是单独的键/值对。将"),t("code",[e._v("spring.cloud.consul.config.format")]),e._v("属性设置为"),t("code",[e._v("YAML")]),e._v(""),t("code",[e._v("PROPERTIES")]),e._v("。例如,使用 YAML:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring:\n  cloud:\n    consul:\n      config:\n        format: YAML\n")])])]),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("如果你已经设置了"),t("code",[e._v("spring.cloud.bootstrap.enabled=true")]),e._v(""),t("code",[e._v("spring.config.use-legacy-processing=true")]),e._v(",或者包含了"),t("code",[e._v("spring-cloud-starter-bootstrap")]),e._v(",那么上述值将需要放置在"),t("code",[e._v("bootstrap.yml")]),e._v("中,而不是"),t("code",[e._v("application.yml")]),e._v("中。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("p",[e._v("YAML 必须设置在相应的"),t("code",[e._v("data")]),e._v("键中。使用键上面的默认值将看起来像:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("config/testApp,dev/data\nconfig/testApp/data\nconfig/application,dev/data\nconfig/application/data\n")])])]),t("p",[e._v("你可以在上面列出的任何键中存储 YAML 文档。")]),e._v(" "),t("p",[e._v("你可以使用"),t("code",[e._v("spring.cloud.consul.config.data-key")]),e._v("更改数据键。")]),e._v(" "),t("h3",{attrs:{id:"_5-6-git2config-领事"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-6-git2config-领事"}},[e._v("#")]),e._v(" 5.6.Git2config 领事")]),e._v(" "),t("p",[e._v("Git2Consul 是一个 Consul 社区项目,它将文件从 Git 存储库加载到 Consul 中的各个密钥。默认情况下,键的名称是文件的名称。YAML 和 Properties 文件分别支持"),t("code",[e._v(".yml")]),e._v(""),t("code",[e._v(".properties")]),e._v("的文件扩展名。将"),t("code",[e._v("spring.cloud.consul.config.format")]),e._v("属性设置为"),t("code",[e._v("FILES")]),e._v("。例如:")]),e._v(" "),t("p",[e._v("bootstrap.yml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring:\n  cloud:\n    consul:\n      config:\n        format: FILES\n")])])]),t("p",[e._v("给定"),t("code",[e._v("/config")]),e._v("中的以下键,"),t("code",[e._v("development")]),e._v("配置文件和"),t("code",[e._v("foo")]),e._v("的应用程序名称:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v(".gitignore\napplication.yml\nbar.properties\nfoo-development.properties\nfoo-production.yml\nfoo.properties\nmaster.ref\n")])])]),t("p",[e._v("将创建以下财产来源:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("config/foo-development.properties\nconfig/foo.properties\nconfig/application.yml\n")])])]),t("p",[e._v("每个键的值需要是一个格式正确的 YAML 或 Properties 文件。")]),e._v(" "),t("h3",{attrs:{id:"_5-7-快速失败"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_5-7-快速失败"}},[e._v("#")]),e._v(" 5.7.快速失败")]),e._v(" "),t("p",[e._v("在某些情况下(如本地开发或某些测试场景),如果 Consul 不能用于配置,那么不失败可能是很方便的。设置"),t("code",[e._v("spring.cloud.consul.config.fail-fast=false")]),e._v("将导致配置模块记录警告,而不是抛出异常。这将允许应用程序继续正常启动。")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("如果你已经设置了"),t("code",[e._v("spring.cloud.bootstrap.enabled=true")]),e._v(""),t("code",[e._v("spring.config.use-legacy-processing=true")]),e._v(",或者包含了"),t("code",[e._v("spring-cloud-starter-bootstrap")]),e._v(",那么上述值将需要放置在"),t("code",[e._v("bootstrap.yml")]),e._v("中,而不是"),t("code",[e._v("application.yml")]),e._v("中。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("h2",{attrs:{id:"_6-执政官重试"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_6-执政官重试"}},[e._v("#")]),e._v(" 6.执政官重试")]),e._v(" "),t("p",[e._v("如果你预计,当你的应用程序启动时,Consul Agent 可能会偶尔无法使用,那么你可以要求它在出现故障后继续尝试。你需要在 Classpath 中添加"),t("code",[e._v("spring-retry")]),e._v(""),t("code",[e._v("spring-boot-starter-aop")]),e._v("。默认的行为是重试 6 次,初始退避间隔为 1000ms,后续退避的指数乘数为 1.1。你可以使用"),t("code",[e._v("spring.cloud.consul.retry.*")]),e._v("配置属性来配置这些属性(以及其他属性)。这对 Spring Cloud Consul Config 和 Discovery 注册都有效。")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th"),e._v(" "),t("th",[e._v("若要完全控制重试,请添加"),t("code",[e._v("@Bean")]),e._v("类型的"),t("code",[e._v("RetryOperationsInterceptor")]),e._v(",ID 为“consulretryInterceptor”。 Spring "),t("br"),e._v("重试有一个"),t("code",[e._v("RetryInterceptorBuilder")]),e._v(",这使得很容易创建一个。")])])]),e._v(" "),t("tbody")]),e._v(" "),t("h2",{attrs:{id:"_7-spring-cloud-bus-with-consul"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_7-spring-cloud-bus-with-consul"}},[e._v("#")]),e._v(" 7. Spring Cloud Bus with Consul")]),e._v(" "),t("h3",{attrs:{id:"_7-1-如何激活"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_7-1-如何激活"}},[e._v("#")]),e._v(" 7.1.如何激活")]),e._v(" "),t("p",[e._v("要开始使用 Consul 总线,请使用分组"),t("code",[e._v("org.springframework.cloud")]),e._v("和工件 ID"),t("code",[e._v("spring-cloud-starter-consul-bus")]),e._v("的启动器。请参阅"),t("a",{attrs:{href:"https://projects.spring.io/spring-cloud/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Cloud Project page"),t("OutboundLink")],1),e._v("以获取有关使用当前 Spring Cloud发布列设置构建系统的详细信息。")]),e._v(" "),t("p",[e._v("有关可用的执行器端点和 HOWTO 发送自定义消息,请参见"),t("a",{attrs:{href:"https://cloud.spring.io/spring-cloud-bus/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Cloud Bus"),t("OutboundLink")],1),e._v("文档。")]),e._v(" "),t("h2",{attrs:{id:"_8-带-hystrix-的断路器"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_8-带-hystrix-的断路器"}},[e._v("#")]),e._v(" 8.带 hystrix 的断路器")]),e._v(" "),t("p",[e._v("应用程序可以通过在 POM.xml:"),t("code",[e._v("spring-cloud-starter-hystrix")]),e._v("项目中包含此启动器来使用 Spring Cloud Netflix 项目提供的 Hystrix 断路器。Hystrix 并不依赖于 Netflix 的 Discovery 客户端。"),t("code",[e._v("@EnableHystrix")]),e._v("注释应该放在配置类(通常是主类)上。然后可以用"),t("code",[e._v("@HystrixCommand")]),e._v("注释方法来由断路器进行保护。有关更多详细信息,请参见"),t("a",{attrs:{href:"https://projects.spring.io/spring-cloud/spring-cloud.html#_circuit_breaker_hystrix_clients",target:"_blank",rel:"noopener noreferrer"}},[e._v("文件"),t("OutboundLink")],1),e._v("")]),e._v(" "),t("h2",{attrs:{id:"_9-基于涡轮机和-consul-的-hystrix-度量聚合"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_9-基于涡轮机和-consul-的-hystrix-度量聚合"}},[e._v("#")]),e._v(" 9.基于涡轮机和 consul 的 hystrix 度量聚合")]),e._v(" "),t("p",[e._v("Turbine(由 Spring Cloud Netflix 项目提供)聚合了多个实例 Hystrix Metrics 流,因此仪表板可以显示聚合视图。Turbine 使用"),t("code",[e._v("DiscoveryClient")]),e._v("接口来查找相关实例。要使用具有 Spring Cloud领事的涡轮机,以类似于以下示例的方式配置涡轮机应用程序:")]),e._v(" "),t("p",[e._v("POM.xml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("<dependency>\n    <groupId>org.springframework.cloud</groupId>\n    <artifactId>spring-cloud-netflix-turbine</artifactId>\n</dependency>\n<dependency>\n    <groupId>org.springframework.cloud</groupId>\n    <artifactId>spring-cloud-starter-consul-discovery</artifactId>\n</dependency>\n")])])]),t("p",[e._v("请注意,涡轮机依赖项不是启动器。涡轮启动器包括对 Netflix Eureka 的支持。")]),e._v(" "),t("p",[e._v("application.yml")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("spring.application.name: turbine\napplications: consulhystrixclient\nturbine:\n  aggregator:\n    clusterConfig: ${applications}\n  appConfig: ${applications}\n")])])]),t("p",[t("code",[e._v("clusterConfig")]),e._v(""),t("code",[e._v("appConfig")]),e._v("节必须匹配,因此将以逗号分隔的服务 ID 列表放入单独的配置属性中非常有用。")]),e._v(" "),t("p",[e._v("Turbine.java")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("@EnableTurbine\n@SpringBootApplication\npublic class Turbine {\n    public static void main(String[] args) {\n        SpringApplication.run(DemoturbinecommonsApplication.class, args);\n    }\n}\n")])])]),t("h2",{attrs:{id:"_10-配置属性"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_10-配置属性"}},[e._v("#")]),e._v(" 10.配置属性")]),e._v(" "),t("p",[e._v("要查看所有 consul 相关配置属性的列表,请检查"),t("RouterLink",{attrs:{to:"/spring-cloud/appendix.html"}},[e._v("附录页")]),e._v("")],1)])}),[],!1,null,null,null);n.default=a.exports}}]);