986 lines
41 KiB
HTML
986 lines
41 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="generator" content="Asciidoctor 1.5.8">
|
|
<title>Spring Cloud Zookeeper</title>
|
|
<link rel="stylesheet" href="css/spring.css">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
|
|
<style>
|
|
.hidden {
|
|
display: none;
|
|
}
|
|
|
|
.switch {
|
|
border-width: 1px 1px 0 1px;
|
|
border-style: solid;
|
|
border-color: #7a2518;
|
|
display: inline-block;
|
|
}
|
|
|
|
.switch--item {
|
|
padding: 10px;
|
|
background-color: #ffffff;
|
|
color: #7a2518;
|
|
display: inline-block;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.switch--item:not(:first-child) {
|
|
border-width: 0 0 0 1px;
|
|
border-style: solid;
|
|
border-color: #7a2518;
|
|
}
|
|
|
|
.switch--item.selected {
|
|
background-color: #7a2519;
|
|
color: #ffffff;
|
|
}
|
|
</style>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
|
<script type="text/javascript">
|
|
function addBlockSwitches() {
|
|
$('.primary').each(function() {
|
|
primary = $(this);
|
|
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
|
primary.children('.title').remove();
|
|
});
|
|
$('.secondary').each(function(idx, node) {
|
|
secondary = $(node);
|
|
primary = findPrimary(secondary);
|
|
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
|
switchItem.content.addClass('hidden');
|
|
findPrimary(secondary).append(switchItem.content);
|
|
secondary.remove();
|
|
});
|
|
}
|
|
|
|
function createBlockSwitch(primary) {
|
|
blockSwitch = $('<div class="switch"></div>');
|
|
primary.prepend(blockSwitch);
|
|
return blockSwitch;
|
|
}
|
|
|
|
function findPrimary(secondary) {
|
|
candidate = secondary.prev();
|
|
while (!candidate.is('.primary')) {
|
|
candidate = candidate.prev();
|
|
}
|
|
return candidate;
|
|
}
|
|
|
|
function createSwitchItem(block, blockSwitch) {
|
|
blockName = block.children('.title').text();
|
|
content = block.children('.content').first().append(block.next('.colist'));
|
|
item = $('<div class="switch--item">' + blockName + '</div>');
|
|
item.on('click', '', content, function(e) {
|
|
$(this).addClass('selected');
|
|
$(this).siblings().removeClass('selected');
|
|
e.data.siblings('.content').addClass('hidden');
|
|
e.data.removeClass('hidden');
|
|
});
|
|
blockSwitch.append(item);
|
|
return {'item': item, 'content': content};
|
|
}
|
|
|
|
$(addBlockSwitches);
|
|
</script>
|
|
|
|
</head>
|
|
<body class="book toc2 toc-left">
|
|
<div id="header">
|
|
<h1>Spring Cloud Zookeeper</h1>
|
|
<div id="toc" class="toc2">
|
|
<div id="toctitle">Table of Contents</div>
|
|
<ul class="sectlevel1">
|
|
<li><a href="#spring-cloud-zookeeper-install">1. Install Zookeeper</a></li>
|
|
<li><a href="#spring-cloud-zookeeper-discovery">2. Service Discovery with Zookeeper</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#activating">2.1. Activating</a></li>
|
|
<li><a href="#registering-with-zookeeper">2.2. Registering with Zookeeper</a></li>
|
|
<li><a href="#using-the-discoveryclient">2.3. Using the DiscoveryClient</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#spring-cloud-zookeeper-netflix">3. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#ribbon-with-zookeeper">3.1. Ribbon with Zookeeper</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#spring-cloud-zookeeper-service-registry">4. Spring Cloud Zookeeper and Service Registry</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#instance-status">4.1. Instance Status</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#spring-cloud-zookeeper-dependencies">5. Zookeeper Dependencies</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#spring-cloud-zookeeper-dependencies-using">5.1. Using the Zookeeper Dependencies</a></li>
|
|
<li><a href="#spring-cloud-zookeeper-dependencies-activating">5.2. Activating Zookeeper Dependencies</a></li>
|
|
<li><a href="#spring-cloud-zookeeper-dependencies-setting-up">5.3. Setting up Zookeeper Dependencies</a></li>
|
|
<li><a href="#spring-cloud-zookeeper-dependencies-configuring">5.4. Configuring Spring Cloud Zookeeper Dependencies</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#spring-cloud-zookeeper-dependency-watcher">6. Spring Cloud Zookeeper Dependency Watcher</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#activating-2">6.1. Activating</a></li>
|
|
<li><a href="#registering-a-listener">6.2. Registering a Listener</a></li>
|
|
<li><a href="#spring-cloud-zookeeper-dependency-watcher-presence-checker">6.3. Using the Presence Checker</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#spring-cloud-zookeeper-config">7. Distributed Configuration with Zookeeper</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#activating-3">7.1. Activating</a></li>
|
|
<li><a href="#customizing">7.2. Customizing</a></li>
|
|
<li><a href="#access-control-lists-acls">7.3. Access Control Lists (ACLs)</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div id="content">
|
|
<div id="preamble">
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>This project provides Zookeeper integrations for Spring Boot applications through
|
|
autoconfiguration and binding to the Spring Environment and other Spring programming model
|
|
idioms. With a few annotations, you can quickly enable and configure the common patterns
|
|
inside your application and build large distributed systems with Zookeeper based
|
|
components. The provided patterns include Service Discovery and Configuration. Integration
|
|
with Spring Cloud Netflix provides Intelligent Routing (Zuul), Client Side Load Balancing
|
|
(Ribbon), and Circuit Breaker (Hystrix).</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="spring-cloud-zookeeper-install"><a class="anchor" href="#spring-cloud-zookeeper-install"></a><a class="link" href="#spring-cloud-zookeeper-install">1. Install Zookeeper</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>See the <a href="https://zookeeper.apache.org/doc/current/zookeeperStarted.html">installation
|
|
documentation</a> for instructions on how to install Zookeeper.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Zookeeper uses Apache Curator behind the scenes.
|
|
While Zookeeper 3.5.x is still considered "beta" by the Zookeeper development team,
|
|
the reality is that it is used in production by many users.
|
|
However, Zookeeper 3.4.x is also used in production.
|
|
Prior to Apache Curator 4.0, both versions of Zookeeper were supported via two versions of Apache Curator.
|
|
Starting with Curator 4.0 both versions of Zookeeper are supported via the same Curator libraries.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>In case you are integrating with version 3.4 you need to change the Zookeeper dependency
|
|
that comes shipped with <code>curator</code>, and thus <code>spring-cloud-zookeeper</code>.
|
|
To do so simply exclude that dependency and add the 3.4.x version like shown below.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">maven</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-starter-zookeeper-all</artifactId>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>org.apache.zookeeper</groupId>
|
|
<artifactId>zookeeper</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.apache.zookeeper</groupId>
|
|
<artifactId>zookeeper</artifactId>
|
|
<version>3.4.12</version>
|
|
<exclusions>
|
|
<exclusion>
|
|
<groupId>org.slf4j</groupId>
|
|
<artifactId>slf4j-log4j12</artifactId>
|
|
</exclusion>
|
|
</exclusions>
|
|
</dependency></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">gradle</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-groovy hljs" data-lang="groovy">compile('org.springframework.cloud:spring-cloud-starter-zookeeper-all') {
|
|
exclude group: 'org.apache.zookeeper', module: 'zookeeper'
|
|
}
|
|
compile('org.apache.zookeeper:zookeeper:3.4.12') {
|
|
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="spring-cloud-zookeeper-discovery"><a class="anchor" href="#spring-cloud-zookeeper-discovery"></a><a class="link" href="#spring-cloud-zookeeper-discovery">2. Service Discovery with Zookeeper</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>Service Discovery is one of the key tenets of a microservice based architecture. Trying to
|
|
hand-configure each client or some form of convention can be difficult to do and can be
|
|
brittle. <a href="https://curator.apache.org">Curator</a>(A Java library for Zookeeper) provides Service
|
|
Discovery through a <a href="https://curator.apache.org/curator-x-discovery/">Service Discovery
|
|
Extension</a>. Spring Cloud Zookeeper uses this extension for service registration and
|
|
discovery.</p>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="activating"><a class="anchor" href="#activating"></a><a class="link" href="#activating">2.1. Activating</a></h3>
|
|
<div class="paragraph">
|
|
<p>Including a dependency on
|
|
<code>org.springframework.cloud:spring-cloud-starter-zookeeper-discovery</code> enables
|
|
autoconfiguration that sets up Spring Cloud Zookeeper Discovery.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
For web functionality, you still need to include
|
|
<code>org.springframework.boot:spring-boot-starter-web</code>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock caution">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-caution" title="Caution"></i>
|
|
</td>
|
|
<td class="content">
|
|
When working with version 3.4 of Zookeeper you need to change
|
|
the way you include the dependency as described <a href="#spring-cloud-zookeeper-install">here</a>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="registering-with-zookeeper"><a class="anchor" href="#registering-with-zookeeper"></a><a class="link" href="#registering-with-zookeeper">2.2. Registering with Zookeeper</a></h3>
|
|
<div class="paragraph">
|
|
<p>When a client registers with Zookeeper, it provides metadata (such as host and port, ID,
|
|
and name) about itself.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following example shows a Zookeeper client:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@SpringBootApplication
|
|
@RestController
|
|
public class Application {
|
|
|
|
@RequestMapping("/")
|
|
public String home() {
|
|
return "Hello world";
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
new SpringApplicationBuilder(Application.class).web(true).run(args);
|
|
}
|
|
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
The preceding example is a normal Spring Boot application.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If Zookeeper is located somewhere other than <code>localhost:2181</code>, the configuration must
|
|
provide the location of the server, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">application.yml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yml hljs" data-lang="yml">spring:
|
|
cloud:
|
|
zookeeper:
|
|
connect-string: localhost:2181</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock caution">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-caution" title="Caution"></i>
|
|
</td>
|
|
<td class="content">
|
|
If you use <a href="#spring-cloud-zookeeper-config">Spring Cloud Zookeeper Config</a>, the
|
|
values shown in the preceding example need to be in <code>bootstrap.yml</code> instead of
|
|
<code>application.yml</code>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The default service name, instance ID, and port (taken from the <code>Environment</code>) are
|
|
<code>${spring.application.name}</code>, the Spring Context ID, and <code>${server.port}</code>, respectively.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Having <code>spring-cloud-starter-zookeeper-discovery</code> on the classpath makes the app into both
|
|
a Zookeeper “service” (that is, it registers itself) and a “client” (that is, it can
|
|
query Zookeeper to locate other services).</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you would like to disable the Zookeeper Discovery Client, you can set
|
|
<code>spring.cloud.zookeeper.discovery.enabled</code> to <code>false</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="using-the-discoveryclient"><a class="anchor" href="#using-the-discoveryclient"></a><a class="link" href="#using-the-discoveryclient">2.3. Using the DiscoveryClient</a></h3>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud has support for
|
|
<a href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign">Feign</a>
|
|
(a REST client builder),
|
|
<a href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/ascii">Spring
|
|
<code>RestTemplate</code></a> and
|
|
<a href="https://cloud.spring.io/spring-cloud-commons/reference/html/#loadbalanced-webclient">Spring WebFlux</a>, using logical service names instead of physical URLs.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>You can also use the <code>org.springframework.cloud.client.discovery.DiscoveryClient</code>, which
|
|
provides a simple API for discovery clients that is not specific to Netflix, as shown in
|
|
the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Autowired
|
|
private DiscoveryClient discoveryClient;
|
|
|
|
public String serviceUrl() {
|
|
List<ServiceInstance> list = discoveryClient.getInstances("STORES");
|
|
if (list != null && list.size() > 0 ) {
|
|
return list.get(0).getUri().toString();
|
|
}
|
|
return null;
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="spring-cloud-zookeeper-netflix"><a class="anchor" href="#spring-cloud-zookeeper-netflix"></a><a class="link" href="#spring-cloud-zookeeper-netflix">3. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Netflix supplies useful tools that work regardless of which <code>DiscoveryClient</code>
|
|
implementation you use. Feign, Turbine, Ribbon, and Zuul all work with Spring Cloud
|
|
Zookeeper.</p>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="ribbon-with-zookeeper"><a class="anchor" href="#ribbon-with-zookeeper"></a><a class="link" href="#ribbon-with-zookeeper">3.1. Ribbon with Zookeeper</a></h3>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Zookeeper provides an implementation of Ribbon’s <code>ServerList</code>. When you use
|
|
the <code>spring-cloud-starter-zookeeper-discovery</code>, Ribbon is autoconfigured to use the
|
|
<code>ZookeeperServerList</code> by default.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="spring-cloud-zookeeper-service-registry"><a class="anchor" href="#spring-cloud-zookeeper-service-registry"></a><a class="link" href="#spring-cloud-zookeeper-service-registry">4. Spring Cloud Zookeeper and Service Registry</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Zookeeper implements the <code>ServiceRegistry</code> interface, letting developers
|
|
register arbitrary services in a programmatic way.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <code>ServiceInstanceRegistration</code> class offers a <code>builder()</code> method to create a
|
|
<code>Registration</code> object that can be used by the <code>ServiceRegistry</code>, as shown in the following
|
|
example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Autowired
|
|
private ZookeeperServiceRegistry serviceRegistry;
|
|
|
|
public void registerThings() {
|
|
ZookeeperRegistration registration = ServiceInstanceRegistration.builder()
|
|
.defaultUriSpec()
|
|
.address("anyUrl")
|
|
.port(10)
|
|
.name("/a/b/c/d/anotherservice")
|
|
.build();
|
|
this.serviceRegistry.register(registration);
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="instance-status"><a class="anchor" href="#instance-status"></a><a class="link" href="#instance-status">4.1. Instance Status</a></h3>
|
|
<div class="paragraph">
|
|
<p>Netflix Eureka supports having instances that are <code>OUT_OF_SERVICE</code> registered with the
|
|
server. These instances are not returned as active service instances. This is useful for
|
|
behaviors such as blue/green deployments. (Note that the Curator Service Discovery recipe
|
|
does not support this behavior.) Taking advantage of the flexible payload has let Spring
|
|
Cloud Zookeeper implement <code>OUT_OF_SERVICE</code> by updating some specific metadata and then
|
|
filtering on that metadata in the Ribbon <code>ZookeeperServerList</code>. The <code>ZookeeperServerList</code>
|
|
filters out all non-null instance statuses that do not equal <code>UP</code>. If the instance status
|
|
field is empty, it is considered to be <code>UP</code> for backwards compatibility. To change the
|
|
status of an instance, make a <code>POST</code> with <code>OUT_OF_SERVICE</code> to the <code>ServiceRegistry</code>
|
|
instance status actuator endpoint, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-sh hljs" data-lang="sh">$ http POST http://localhost:8081/service-registry status=OUT_OF_SERVICE</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
The preceding example uses the <code>http</code> command from <a href="https://httpie.org" class="bare">httpie.org</a>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="spring-cloud-zookeeper-dependencies"><a class="anchor" href="#spring-cloud-zookeeper-dependencies"></a><a class="link" href="#spring-cloud-zookeeper-dependencies">5. Zookeeper Dependencies</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>The following topics cover how to work with Spring Cloud Zookeeper dependencies:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><a href="#spring-cloud-zookeeper-dependencies-using">Using the Zookeeper Dependencies</a></p>
|
|
</li>
|
|
<li>
|
|
<p><a href="#spring-cloud-zookeeper-dependencies-activating">Activating Zookeeper Dependencies</a></p>
|
|
</li>
|
|
<li>
|
|
<p><a href="#spring-cloud-zookeeper-dependencies-setting-up">Setting up Zookeeper Dependencies</a></p>
|
|
</li>
|
|
<li>
|
|
<p><a href="#spring-cloud-zookeeper-dependencies-configuring">Configuring Spring Cloud Zookeeper Dependencies</a></p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="spring-cloud-zookeeper-dependencies-using"><a class="anchor" href="#spring-cloud-zookeeper-dependencies-using"></a><a class="link" href="#spring-cloud-zookeeper-dependencies-using">5.1. Using the Zookeeper Dependencies</a></h3>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Zookeeper gives you a possibility to provide dependencies of your application
|
|
as properties. As dependencies, you can understand other applications that are registered
|
|
in Zookeeper and which you would like to call through
|
|
<a href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign">Feign</a>
|
|
(a REST client builder),
|
|
<a href="https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/ascii">Spring
|
|
<code>RestTemplate</code></a> and
|
|
<a href="https://cloud.spring.io/spring-cloud-commons/reference/html/#loadbalanced-webclient">Spring WebFlux</a>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>You can also use the Zookeeper Dependency Watchers functionality to control and monitor
|
|
the state of your dependencies.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="spring-cloud-zookeeper-dependencies-activating"><a class="anchor" href="#spring-cloud-zookeeper-dependencies-activating"></a><a class="link" href="#spring-cloud-zookeeper-dependencies-activating">5.2. Activating Zookeeper Dependencies</a></h3>
|
|
<div class="paragraph">
|
|
<p>Including a dependency on
|
|
<code>org.springframework.cloud:spring-cloud-starter-zookeeper-discovery</code> enables
|
|
autoconfiguration that sets up Spring Cloud Zookeeper Dependencies. Even if you provide
|
|
the dependencies in your properties, you can turn off the dependencies. To do so, set the
|
|
<code>spring.cloud.zookeeper.dependency.enabled</code> property to false (it defaults to <code>true</code>).</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="spring-cloud-zookeeper-dependencies-setting-up"><a class="anchor" href="#spring-cloud-zookeeper-dependencies-setting-up"></a><a class="link" href="#spring-cloud-zookeeper-dependencies-setting-up">5.3. Setting up Zookeeper Dependencies</a></h3>
|
|
<div class="paragraph">
|
|
<p>Consider the following example of dependency representation:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">application.yml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yml hljs" data-lang="yml">spring.application.name: yourServiceName
|
|
spring.cloud.zookeeper:
|
|
dependencies:
|
|
newsletter:
|
|
path: /path/where/newsletter/has/registered/in/zookeeper
|
|
loadBalancerType: ROUND_ROBIN
|
|
contentTypeTemplate: application/vnd.newsletter.$version+json
|
|
version: v1
|
|
headers:
|
|
header1:
|
|
- value1
|
|
header2:
|
|
- value2
|
|
required: false
|
|
stubs: org.springframework:foo:stubs
|
|
mailing:
|
|
path: /path/where/mailing/has/registered/in/zookeeper
|
|
loadBalancerType: ROUND_ROBIN
|
|
contentTypeTemplate: application/vnd.mailing.$version+json
|
|
version: v1
|
|
required: true</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The next few sections go through each part of the dependency one by one. The root property
|
|
name is <code>spring.cloud.zookeeper.dependencies</code>.</p>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="spring-cloud-zookeeper-dependencies-setting-up-aliases"><a class="anchor" href="#spring-cloud-zookeeper-dependencies-setting-up-aliases"></a><a class="link" href="#spring-cloud-zookeeper-dependencies-setting-up-aliases">5.3.1. Aliases</a></h4>
|
|
<div class="paragraph">
|
|
<p>Below the root property you have to represent each dependency as an alias. This is due to
|
|
the constraints of Ribbon, which requires that the application ID be placed in the URL.
|
|
Consequently, you cannot pass any complex path, suchas <code>/myApp/myRoute/name</code>). The alias
|
|
is the name you use instead of the <code>serviceId</code> for <code>DiscoveryClient</code>, <code>Feign</code>, or
|
|
<code>RestTemplate</code>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>In the previous examples, the aliases are <code>newsletter</code> and <code>mailing</code>. The following
|
|
example shows Feign usage with a <code>newsletter</code> alias:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@FeignClient("newsletter")
|
|
public interface NewsletterService {
|
|
@RequestMapping(method = RequestMethod.GET, value = "/newsletter")
|
|
String getNewsletters();
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="path"><a class="anchor" href="#path"></a><a class="link" href="#path">5.3.2. Path</a></h4>
|
|
<div class="paragraph">
|
|
<p>The path is represented by the <code>path</code> YAML property and is the path under which the
|
|
dependency is registered under Zookeeper. As described in the
|
|
<a href="#spring-cloud-zookeeper-dependencies-setting-up-aliases">previous section</a>, Ribbon
|
|
operates on URLs. As a result, this path is not compliant with its requirement.
|
|
That is why Spring Cloud Zookeeper maps the alias to the proper path.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="load-balancer-type"><a class="anchor" href="#load-balancer-type"></a><a class="link" href="#load-balancer-type">5.3.3. Load Balancer Type</a></h4>
|
|
<div class="paragraph">
|
|
<p>The load balancer type is represented by <code>loadBalancerType</code> YAML property.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you know what kind of load-balancing strategy has to be applied when calling this
|
|
particular dependency, you can provide it in the YAML file, and it is automatically
|
|
applied. You can choose one of the following load balancing strategies:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p>STICKY: Once chosen, the instance is always called.</p>
|
|
</li>
|
|
<li>
|
|
<p>RANDOM: Picks an instance randomly.</p>
|
|
</li>
|
|
<li>
|
|
<p>ROUND_ROBIN: Iterates over instances over and over again.</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="content-type-template-and-version"><a class="anchor" href="#content-type-template-and-version"></a><a class="link" href="#content-type-template-and-version">5.3.4. <code>Content-Type</code> Template and Version</a></h4>
|
|
<div class="paragraph">
|
|
<p>The <code>Content-Type</code> template and version are represented by the <code>contentTypeTemplate</code> and
|
|
<code>version</code> YAML properties.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you version your API in the <code>Content-Type</code> header, you do not want to add this header
|
|
to each of your requests. Also, if you want to call a new version of the API, you do not
|
|
want to roam around your code to bump up the API version. That is why you can provide a
|
|
<code>contentTypeTemplate</code> with a special <code>$version</code> placeholder. That placeholder will be filled by the value of the
|
|
<code>version</code> YAML property. Consider the following example of a <code>contentTypeTemplate</code>:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>application/vnd.newsletter.$version+json</pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Further consider the following <code>version</code>:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>v1</pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The combination of <code>contentTypeTemplate</code> and version results in the creation of a
|
|
<code>Content-Type</code> header for each request, as follows:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>application/vnd.newsletter.v1+json</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="default-headers"><a class="anchor" href="#default-headers"></a><a class="link" href="#default-headers">5.3.5. Default Headers</a></h4>
|
|
<div class="paragraph">
|
|
<p>Default headers are represented by the <code>headers</code> map in YAML.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Sometimes, each call to a dependency requires setting up of some default headers. To not
|
|
do that in code, you can set them up in the YAML file, as shown in the following example
|
|
<code>headers</code> section:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yml hljs" data-lang="yml">headers:
|
|
Accept:
|
|
- text/html
|
|
- application/xhtml+xml
|
|
Cache-Control:
|
|
- no-cache</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>That <code>headers</code> section results in adding the <code>Accept</code> and <code>Cache-Control</code> headers with
|
|
appropriate list of values in your HTTP request.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="required-dependencies"><a class="anchor" href="#required-dependencies"></a><a class="link" href="#required-dependencies">5.3.6. Required Dependencies</a></h4>
|
|
<div class="paragraph">
|
|
<p>Required dependencies are represented by <code>required</code> property in YAML.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If one of your dependencies is required to be up when your application boots, you can set
|
|
the <code>required: true</code> property in the YAML file.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If your application cannot localize the required dependency during boot time, it throws an
|
|
exception, and the Spring Context fails to set up. In other words, your application cannot
|
|
start if the required dependency is not registered in Zookeeper.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>You can read more about Spring Cloud Zookeeper Presence Checker
|
|
<a href="#spring-cloud-zookeeper-dependency-watcher-presence-checker">later in this document</a>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="stubs"><a class="anchor" href="#stubs"></a><a class="link" href="#stubs">5.3.7. Stubs</a></h4>
|
|
<div class="paragraph">
|
|
<p>You can provide a colon-separated path to the JAR containing stubs of the dependency, as
|
|
shown in the following example:</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p><code>stubs: org.springframework:myApp:stubs</code></p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>where:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><code>org.springframework</code> is the <code>groupId</code>.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>myApp</code> is the <code>artifactId</code>.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>stubs</code> is the classifier. (Note that <code>stubs</code> is the default value.)</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Because <code>stubs</code> is the default classifier, the preceding example is equal to the following
|
|
example:</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p><code>stubs: org.springframework:myApp</code></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="spring-cloud-zookeeper-dependencies-configuring"><a class="anchor" href="#spring-cloud-zookeeper-dependencies-configuring"></a><a class="link" href="#spring-cloud-zookeeper-dependencies-configuring">5.4. Configuring Spring Cloud Zookeeper Dependencies</a></h3>
|
|
<div class="paragraph">
|
|
<p>You can set the following properties to enable or disable parts of Zookeeper Dependencies
|
|
functionalities:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><code>spring.cloud.zookeeper.dependencies</code>: If you do not set this property, you cannot use
|
|
Zookeeper Dependencies.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>spring.cloud.zookeeper.dependency.ribbon.enabled</code> (enabled by default): Ribbon requires
|
|
either explicit global configuration or a particular one for a dependency. By turning on
|
|
this property, runtime load balancing strategy resolution is possible, and you can use the
|
|
<code>loadBalancerType</code> section of the Zookeeper Dependencies. The configuration that needs
|
|
this property has an implementation of <code>LoadBalancerClient</code> that delegates to the
|
|
<code>ILoadBalancer</code> presented in the next bullet.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>spring.cloud.zookeeper.dependency.ribbon.loadbalancer</code> (enabled by default): Thanks to
|
|
this property, the custom <code>ILoadBalancer</code> knows that the part of the URI passed to Ribbon
|
|
might actually be the alias that has to be resolved to a proper path in Zookeeper. Without
|
|
this property, you cannot register applications under nested paths.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>spring.cloud.zookeeper.dependency.headers.enabled</code> (enabled by default): This property
|
|
registers a <code>RibbonClient</code> that automatically appends appropriate headers and content
|
|
types with their versions, as presented in the Dependency configuration. Without this
|
|
setting, those two parameters do not work.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>spring.cloud.zookeeper.dependency.resttemplate.enabled</code> (enabled by default): When
|
|
enabled, this property modifies the request headers of a <code>@LoadBalanced</code>-annotated
|
|
<code>RestTemplate</code> such that it passes headers and content type with the version set in
|
|
dependency configuration. Without this setting, those two parameters do not work.</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="spring-cloud-zookeeper-dependency-watcher"><a class="anchor" href="#spring-cloud-zookeeper-dependency-watcher"></a><a class="link" href="#spring-cloud-zookeeper-dependency-watcher">6. Spring Cloud Zookeeper Dependency Watcher</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>The Dependency Watcher mechanism lets you register listeners to your dependencies. The
|
|
functionality is, in fact, an implementation of the <code>Observator</code> pattern. When a
|
|
dependency changes, its state (to either UP or DOWN), some custom logic can be applied.</p>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="activating-2"><a class="anchor" href="#activating-2"></a><a class="link" href="#activating-2">6.1. Activating</a></h3>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Zookeeper Dependencies functionality needs to be enabled for you to use the
|
|
Dependency Watcher mechanism.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="registering-a-listener"><a class="anchor" href="#registering-a-listener"></a><a class="link" href="#registering-a-listener">6.2. Registering a Listener</a></h3>
|
|
<div class="paragraph">
|
|
<p>To register a listener, you must implement an interface called
|
|
<code>org.springframework.cloud.zookeeper.discovery.watcher.DependencyWatcherListener</code> and
|
|
register it as a bean. The interface gives you one method:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">void stateChanged(String dependencyName, DependencyState newState);</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you want to register a listener for a particular dependency, the <code>dependencyName</code> would
|
|
be the discriminator for your concrete implementation. <code>newState</code> provides you with
|
|
information about whether your dependency has changed to <code>CONNECTED</code> or <code>DISCONNECTED</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="spring-cloud-zookeeper-dependency-watcher-presence-checker"><a class="anchor" href="#spring-cloud-zookeeper-dependency-watcher-presence-checker"></a><a class="link" href="#spring-cloud-zookeeper-dependency-watcher-presence-checker">6.3. Using the Presence Checker</a></h3>
|
|
<div class="paragraph">
|
|
<p>Bound with the Dependency Watcher is the functionality called Presence Checker. It lets
|
|
you provide custom behavior when your application boots, to react according to the state
|
|
of your dependencies.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The default implementation of the abstract
|
|
<code>org.springframework.cloud.zookeeper.discovery.watcher.presence.DependencyPresenceOnStartupVerifier</code>
|
|
class is the
|
|
<code>org.springframework.cloud.zookeeper.discovery.watcher.presence.DefaultDependencyPresenceOnStartupVerifier</code>,
|
|
which works in the following way.</p>
|
|
</div>
|
|
<div class="olist arabic">
|
|
<ol class="arabic">
|
|
<li>
|
|
<p>If the dependency is marked us <code>required</code> and is not in Zookeeper, when your application
|
|
boots, it throws an exception and shuts down.</p>
|
|
</li>
|
|
<li>
|
|
<p>If the dependency is not <code>required</code>, the
|
|
<code>org.springframework.cloud.zookeeper.discovery.watcher.presence.LogMissingDependencyChecker</code>
|
|
logs that the dependency is missing at the <code>WARN</code> level.</p>
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Because the <code>DefaultDependencyPresenceOnStartupVerifier</code> is registered only when there is
|
|
no bean of type <code>DependencyPresenceOnStartupVerifier</code>, this functionality can be
|
|
overridden.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="spring-cloud-zookeeper-config"><a class="anchor" href="#spring-cloud-zookeeper-config"></a><a class="link" href="#spring-cloud-zookeeper-config">7. Distributed Configuration with Zookeeper</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>Zookeeper provides a
|
|
<a href="https://zookeeper.apache.org/doc/current/zookeeperOver.html#sc_dataModelNameSpace">hierarchical namespace</a>
|
|
that lets clients store arbitrary data, such as configuration data. Spring Cloud Zookeeper
|
|
Config is an alternative to the
|
|
<a href="https://github.com/spring-cloud/spring-cloud-config">Config Server and Client</a>.
|
|
Configuration is loaded into the Spring Environment during the special “bootstrap”
|
|
phase. Configuration is stored in the <code>/config</code> namespace by default. Multiple
|
|
<code>PropertySource</code> instances are created, based on the application’s name and the active
|
|
profiles, to mimic the Spring Cloud Config order of resolving properties. For example, an
|
|
application with a name of <code>testApp</code> and with the <code>dev</code> profile has the following property
|
|
sources created for it:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><code>config/testApp,dev</code></p>
|
|
</li>
|
|
<li>
|
|
<p><code>config/testApp</code></p>
|
|
</li>
|
|
<li>
|
|
<p><code>config/application,dev</code></p>
|
|
</li>
|
|
<li>
|
|
<p><code>config/application</code></p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The most specific property source is at the top, with the least specific at the bottom.
|
|
Properties in the <code>config/application</code> namespace apply to all applications that use
|
|
zookeeper for configuration. Properties in the <code>config/testApp</code> namespace are available
|
|
only to the instances of the service named <code>testApp</code>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Configuration is currently read on startup of the application. Sending a HTTP <code>POST</code>
|
|
request to <code>/refresh</code> causes the configuration to be reloaded. Watching the configuration
|
|
namespace (which Zookeeper supports) is not currently implemented.</p>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="activating-3"><a class="anchor" href="#activating-3"></a><a class="link" href="#activating-3">7.1. Activating</a></h3>
|
|
<div class="paragraph">
|
|
<p>Including a dependency on
|
|
<code>org.springframework.cloud:spring-cloud-starter-zookeeper-config</code> enables
|
|
autoconfiguration that sets up Spring Cloud Zookeeper Config.</p>
|
|
</div>
|
|
<div class="admonitionblock caution">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-caution" title="Caution"></i>
|
|
</td>
|
|
<td class="content">
|
|
When working with version 3.4 of Zookeeper you need to change
|
|
the way you include the dependency as described <a href="#spring-cloud-zookeeper-install">here</a>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="customizing"><a class="anchor" href="#customizing"></a><a class="link" href="#customizing">7.2. Customizing</a></h3>
|
|
<div class="paragraph">
|
|
<p>Zookeeper Config may be customized by setting the following properties:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">bootstrap.yml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yml hljs" data-lang="yml">spring:
|
|
cloud:
|
|
zookeeper:
|
|
config:
|
|
enabled: true
|
|
root: configuration
|
|
defaultContext: apps
|
|
profileSeparator: '::'</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><code>enabled</code>: Setting this value to <code>false</code> disables Zookeeper Config.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>root</code>: Sets the base namespace for configuration values.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>defaultContext</code>: Sets the name used by all applications.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>profileSeparator</code>: Sets the value of the separator used to separate the profile name in
|
|
property sources with profiles.</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="access-control-lists-acls"><a class="anchor" href="#access-control-lists-acls"></a><a class="link" href="#access-control-lists-acls">7.3. Access Control Lists (ACLs)</a></h3>
|
|
<div class="paragraph">
|
|
<p>You can add authentication information for Zookeeper ACLs by calling the <code>addAuthInfo</code>
|
|
method of a <code>CuratorFramework</code> bean. One way to accomplish this is to provide your own
|
|
<code>CuratorFramework</code> bean, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@BoostrapConfiguration
|
|
public class CustomCuratorFrameworkConfig {
|
|
|
|
@Bean
|
|
public CuratorFramework curatorFramework() {
|
|
CuratorFramework curator = new CuratorFramework();
|
|
curator.addAuthInfo("digest", "user:password".getBytes());
|
|
return curator;
|
|
}
|
|
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Consult
|
|
<a href="https://github.com/spring-cloud/spring-cloud-zookeeper/blob/master/spring-cloud-zookeeper-core/src/main/java/org/springframework/cloud/zookeeper/ZookeeperAutoConfiguration.java">the ZookeeperAutoConfiguration class</a>
|
|
to see how the <code>CuratorFramework</code> bean’s default configuration.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Alternatively, you can add your credentials from a class that depends on the existing
|
|
<code>CuratorFramework</code> bean, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@BoostrapConfiguration
|
|
public class DefaultCuratorFrameworkConfig {
|
|
|
|
public ZookeeperConfig(CuratorFramework curator) {
|
|
curator.addAuthInfo("digest", "user:password".getBytes());
|
|
}
|
|
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The creation of this bean must occur during the boostrapping phase. You can register
|
|
configuration classes to run during this phase by annotating them with
|
|
<code>@BootstrapConfiguration</code> and including them in a comma-separated list that you set as the
|
|
value of the <code>org.springframework.cloud.bootstrap.BootstrapConfiguration</code> property in the
|
|
<code>resources/META-INF/spring.factories</code> file, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">resources/META-INF/spring.factories</div>
|
|
<div class="content">
|
|
<pre>org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
|
my.project.CustomCuratorFrameworkConfig,\
|
|
my.project.DefaultCuratorFrameworkConfig</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
|
<script type="text/javascript" src="js/toc.js"></script>
|
|
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
|
<script src="js/highlight/highlight.min.js"></script>
|
|
<script>hljs.initHighlighting()</script>
|
|
</body>
|
|
</html> |