提交 3828d652 编写于 作者: 茶陵後's avatar 茶陵後 👍

#13 [skip ci]

上级 0c85e0f1
Spring Cloud Documentation
==========
This section provides a brief overview of Spring Cloud reference documentation. It serves
as a map for the rest of the document.
[](#documentation-about)[1. About the Documentation](#documentation-about)
----------
The Spring Cloud reference guide is available as
* [Multi-page HTML](https://docs.spring.io/spring-cloud/docs/2021.0.1/reference/html)
* [Single-page HTML](https://docs.spring.io/spring-cloud/docs/2021.0.1/reference/htmlsingle)
* [PDF](https://docs.spring.io/spring-cloud/docs/2021.0.1/reference/pdf/spring-cloud.pdf)
Copies of this document may be made for your own use and for distribution to others,
provided that you do not charge any fee for such copies and further provided that each
copy contains this Copyright Notice, whether distributed in print or electronically.
[](#documentation-getting-help)[2. Getting Help](#documentation-getting-help)
----------
If you have trouble with Spring Cloud, we would like to help.
* Learn the Spring Cloud basics. If you are
starting out with Spring Cloud, try one of the [guides](https://spring.io/guides).
* Ask a question. We monitor [stackoverflow.com](https://stackoverflow.com) for questions
tagged with [`spring-cloud`](https://stackoverflow.com/tags/spring-cloud).
* Chat with us at [Spring Cloud Gitter](https://gitter.im/spring-cloud/spring-cloud)
| |All of Spring Cloud is open source, including the documentation. If you find<br/>problems with the docs or if you want to improve them, please get involved.|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------|
Spring Cloud Documentation.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;
} function addBlockSwitches() { for (var primary of document.querySelectorAll('.primary')) { var switchItem = createSwitchItem(primary, createBlockSwitch(primary)); switchItem.item.classList.add("selected"); var title = primary.querySelector('.title') title.remove(); } for (var secondary of document.querySelectorAll('.secondary')) { var primary = findPrimary(secondary); if (primary === null) { console.error("Found secondary block with no primary sibling"); } else { var switchItem = createSwitchItem(secondary, primary.querySelector('.switch')); switchItem.content.classList.add("hidden"); primary.append(switchItem.content); secondary.remove(); } }
} function createElementFromHtml(html) { var template = document.createElement('template'); template.innerHTML = html; return template.content.firstChild;
} function createBlockSwitch(primary) { var blockSwitch = createElementFromHtml('\<div class="switch"\>\</div\>'); primary.prepend(blockSwitch) return blockSwitch;
} function findPrimary(secondary) { var candidate = secondary.previousElementSibling; while (candidate != null && !candidate.classList.contains('primary')) { candidate = candidate.previousElementSibling; } return candidate;
} function createSwitchItem(block, blockSwitch) { var blockName = block.querySelector('.title').textContent; var content = block.querySelectorAll('.content').item(0); var colist = nextSibling(block, '.colist'); if (colist != null) { content.append(colist); } var item = createElementFromHtml('\<div class="switch--item"\>' + blockName + '\</div\>'); item.dataset.blockName = blockName; content.dataset.blockName = blockName; blockSwitch.append(item); return {'item': item, 'content': content};
} function nextSibling(element, selector) { var sibling = element.nextElementSibling; while (sibling) { if (sibling.matches(selector)) { return sibling; } sibling = sibling.nextElementSibling; }
} function globalSwitch() { document.querySelectorAll(".switch--item").forEach(function(item) { var blockId = blockIdForSwitchItem(item); var handler = function(event) { selectedText = event.target.textContent; window.localStorage.setItem(blockId, selectedText); for (var switchItem of document.querySelectorAll(".switch--item")) { if (blockIdForSwitchItem(switchItem) === blockId && switchItem.textContent === selectedText) { select(switchItem); } } } item.addEventListener("click", handler); if (item.textContent === window.localStorage.getItem(blockId)) { select(item); } });
} function select(selected) { for (var child of selected.parentNode.children) { child.classList.remove("selected"); } selected.classList.add("selected"); for (var child of selected.parentNode.parentNode.children) { if (child.classList.contains("content")) { if (selected.dataset.blockName === child.dataset.blockName) { child.classList.remove("hidden"); } else { child.classList.add("hidden"); } } } } function blockIdForSwitchItem(item) { idComponents = [] for (var switchItem of item.parentNode.querySelectorAll(".switch--item")) { idComponents.push(switchItem.textContent.toLowerCase()); } return idComponents.sort().join("-")
} window.onload = function() { addBlockSwitches(); globalSwitch();
};
# Spring Cloud Documentation
Table of Contents
* [1. About the Documentation](#documentation-about)
* [2. Getting Help](#documentation-getting-help)
This section provides a brief overview of Spring Cloud reference documentation. It serves
as a map for the rest of the document.
## [](#documentation-about)[1. About the Documentation](#documentation-about)
The Spring Cloud reference guide is available as
* [Multi-page HTML](https://docs.spring.io/spring-cloud/docs/2021.0.1/reference/html)
* [Single-page HTML](https://docs.spring.io/spring-cloud/docs/2021.0.1/reference/htmlsingle)
* [PDF](https://docs.spring.io/spring-cloud/docs/2021.0.1/reference/pdf/spring-cloud.pdf)
Copies of this document may be made for your own use and for distribution to others,
provided that you do not charge any fee for such copies and further provided that each
copy contains this Copyright Notice, whether distributed in print or electronically.
## [](#documentation-getting-help)[2. Getting Help](#documentation-getting-help)
If you have trouble with Spring Cloud, we would like to help.
* Learn the Spring Cloud basics. If you are
starting out with Spring Cloud, try one of the [guides](https://spring.io/guides).
* Ask a question. We monitor [stackoverflow.com](https://stackoverflow.com) for questions
tagged with [`spring-cloud`](https://stackoverflow.com/tags/spring-cloud).
* Chat with us at [Spring Cloud Gitter](https://gitter.im/spring-cloud/spring-cloud)
| |All of Spring Cloud is open source, including the documentation. If you find<br/>problems with the docs or if you want to improve them, please get involved.|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------|
if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1\*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}
\ No newline at end of file
Legal
==========
Legal.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;
} function addBlockSwitches() { for (var primary of document.querySelectorAll('.primary')) { var switchItem = createSwitchItem(primary, createBlockSwitch(primary)); switchItem.item.classList.add("selected"); var title = primary.querySelector('.title') title.remove(); } for (var secondary of document.querySelectorAll('.secondary')) { var primary = findPrimary(secondary); if (primary === null) { console.error("Found secondary block with no primary sibling"); } else { var switchItem = createSwitchItem(secondary, primary.querySelector('.switch')); switchItem.content.classList.add("hidden"); primary.append(switchItem.content); secondary.remove(); } }
} function createElementFromHtml(html) { var template = document.createElement('template'); template.innerHTML = html; return template.content.firstChild;
} function createBlockSwitch(primary) { var blockSwitch = createElementFromHtml('\<div class="switch"\>\</div\>'); primary.prepend(blockSwitch) return blockSwitch;
} function findPrimary(secondary) { var candidate = secondary.previousElementSibling; while (candidate != null && !candidate.classList.contains('primary')) { candidate = candidate.previousElementSibling; } return candidate;
} function createSwitchItem(block, blockSwitch) { var blockName = block.querySelector('.title').textContent; var content = block.querySelectorAll('.content').item(0); var colist = nextSibling(block, '.colist'); if (colist != null) { content.append(colist); } var item = createElementFromHtml('\<div class="switch--item"\>' + blockName + '\</div\>'); item.dataset.blockName = blockName; content.dataset.blockName = blockName; blockSwitch.append(item); return {'item': item, 'content': content};
} function nextSibling(element, selector) { var sibling = element.nextElementSibling; while (sibling) { if (sibling.matches(selector)) { return sibling; } sibling = sibling.nextElementSibling; }
} function globalSwitch() { document.querySelectorAll(".switch--item").forEach(function(item) { var blockId = blockIdForSwitchItem(item); var handler = function(event) { selectedText = event.target.textContent; window.localStorage.setItem(blockId, selectedText); for (var switchItem of document.querySelectorAll(".switch--item")) { if (blockIdForSwitchItem(switchItem) === blockId && switchItem.textContent === selectedText) { select(switchItem); } } } item.addEventListener("click", handler); if (item.textContent === window.localStorage.getItem(blockId)) { select(item); } });
} function select(selected) { for (var child of selected.parentNode.children) { child.classList.remove("selected"); } selected.classList.add("selected"); for (var child of selected.parentNode.parentNode.children) { if (child.classList.contains("content")) { if (selected.dataset.blockName === child.dataset.blockName) { child.classList.remove("hidden"); } else { child.classList.add("hidden"); } } } } function blockIdForSwitchItem(item) { idComponents = [] for (var switchItem of item.parentNode.querySelectorAll(".switch--item")) { idComponents.push(switchItem.textContent.toLowerCase()); } return idComponents.sort().join("-")
} window.onload = function() { addBlockSwitches(); globalSwitch();
};
# Legal
2021.0.1
......@@ -9,3 +24,5 @@ Copies of this document may be made for your own use and for distribution to
others, provided that you do not charge any fee for such copies and further
provided that each copy contains this Copyright Notice, whether distributed in
print or electronically.
if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1\*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}
\ No newline at end of file
Spring Cloud Build
==========
Spring Cloud Build.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;
} function addBlockSwitches() { for (var primary of document.querySelectorAll('.primary')) { var switchItem = createSwitchItem(primary, createBlockSwitch(primary)); switchItem.item.classList.add("selected"); var title = primary.querySelector('.title') title.remove(); } for (var secondary of document.querySelectorAll('.secondary')) { var primary = findPrimary(secondary); if (primary === null) { console.error("Found secondary block with no primary sibling"); } else { var switchItem = createSwitchItem(secondary, primary.querySelector('.switch')); switchItem.content.classList.add("hidden"); primary.append(switchItem.content); secondary.remove(); } }
} function createElementFromHtml(html) { var template = document.createElement('template'); template.innerHTML = html; return template.content.firstChild;
} function createBlockSwitch(primary) { var blockSwitch = createElementFromHtml('\<div class="switch"\>\</div\>'); primary.prepend(blockSwitch) return blockSwitch;
} function findPrimary(secondary) { var candidate = secondary.previousElementSibling; while (candidate != null && !candidate.classList.contains('primary')) { candidate = candidate.previousElementSibling; } return candidate;
} function createSwitchItem(block, blockSwitch) { var blockName = block.querySelector('.title').textContent; var content = block.querySelectorAll('.content').item(0); var colist = nextSibling(block, '.colist'); if (colist != null) { content.append(colist); } var item = createElementFromHtml('\<div class="switch--item"\>' + blockName + '\</div\>'); item.dataset.blockName = blockName; content.dataset.blockName = blockName; blockSwitch.append(item); return {'item': item, 'content': content};
} function nextSibling(element, selector) { var sibling = element.nextElementSibling; while (sibling) { if (sibling.matches(selector)) { return sibling; } sibling = sibling.nextElementSibling; }
} function globalSwitch() { document.querySelectorAll(".switch--item").forEach(function(item) { var blockId = blockIdForSwitchItem(item); var handler = function(event) { selectedText = event.target.textContent; window.localStorage.setItem(blockId, selectedText); for (var switchItem of document.querySelectorAll(".switch--item")) { if (blockIdForSwitchItem(switchItem) === blockId && switchItem.textContent === selectedText) { select(switchItem); } } } item.addEventListener("click", handler); if (item.textContent === window.localStorage.getItem(blockId)) { select(item); } });
} function select(selected) { for (var child of selected.parentNode.children) { child.classList.remove("selected"); } selected.classList.add("selected"); for (var child of selected.parentNode.parentNode.children) { if (child.classList.contains("content")) { if (selected.dataset.blockName === child.dataset.blockName) { child.classList.remove("hidden"); } else { child.classList.add("hidden"); } } } } function blockIdForSwitchItem(item) { idComponents = [] for (var switchItem of item.parentNode.querySelectorAll(".switch--item")) { idComponents.push(switchItem.textContent.toLowerCase()); } return idComponents.sort().join("-")
} window.onload = function() { addBlockSwitches(); globalSwitch();
};
# Spring Cloud Build
Table of Contents
* [Building and Deploying](#_building_and_deploying)
* [Contributing](#_contributing)
* [Sign the Contributor License Agreement](#_sign_the_contributor_license_agreement)
* [Code of Conduct](#_code_of_conduct)
* [Code Conventions and Housekeeping](#_code_conventions_and_housekeeping)
* [Checkstyle](#_checkstyle)
* [IDE setup](#_ide_setup)
* [Duplicate Finder](#_duplicate_finder)
* [Flattening the POMs](#_flattening_the_poms)
* [Reusing the documentation](#_reusing_the_documentation)
* [Updating the guides](#_updating_the_guides)
[![Build](https://github.com/spring-cloud/spring-cloud-build/workflows/Build/badge.svg?branch=main&style=svg)](https://github.com/spring-cloud/spring-cloud-build/actions)
Spring Cloud Build is a common utility project for Spring Cloud
to use for plugin and dependency management.
[Building and Deploying](#_building_and_deploying)
----------
## [Building and Deploying](#_building_and_deploying)
To install locally:
......@@ -40,8 +70,7 @@ $ mvn deploy -P central -DaltReleaseDeploymentRepository=sonatype-nexus-staging:
(the "central" profile is available for all projects in Spring Cloud and it sets up the gpg jar signing, and the repository has to be specified separately for this project because it is a parent of the starter parent which users in turn have as their own parent).
[Contributing](#_contributing)
----------
## [Contributing](#_contributing)
Spring Cloud is released under the non-restrictive Apache 2.0 license,
and follows a very standard Github development process, using Github
......@@ -49,7 +78,7 @@ tracker for issues and merging pull requests into master. If you want
to contribute even something trivial please do not hesitate, but
follow the guidelines below.
### [Sign the Contributor License Agreement](#_sign_the_contributor_license_agreement) ###
### [Sign the Contributor License Agreement](#_sign_the_contributor_license_agreement)
Before we accept a non-trivial patch or pull request we will need you to sign the[Contributor License Agreement](https://cla.pivotal.io/sign/spring).
Signing the contributor’s agreement does not grant anyone commit rights to the main
......@@ -57,13 +86,13 @@ repository, but it does mean that we can accept your contributions, and you will
author credit if we do. Active contributors might be asked to join the core team, and
given the ability to merge pull requests.
### [Code of Conduct](#_code_of_conduct) ###
### [Code of Conduct](#_code_of_conduct)
This project adheres to the Contributor Covenant [code of
conduct](https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc). By participating, you are expected to uphold this code. Please report
unacceptable behavior to [[email protected]](/cdn-cgi/l/email-protection#98ebe8eaf1f6ffb5fbf7fcfdb5f7feb5fbf7f6fcedfbecd8e8f1eef7ecf9f4b6f1f7).
unacceptable behavior to [[email protected]](/cdn-cgi/l/email-protection#dba8aba9b2b5bcf6b8b4bfbef6b4bdf6b8b4b5bfaeb8af9babb2adb4afbab7f5b2b4).
### [Code Conventions and Housekeeping](#_code_conventions_and_housekeeping) ###
### [Code Conventions and Housekeeping](#_code_conventions_and_housekeeping)
None of these is essential for a pull request, but they will all help. They can also be
added after the original pull request but before a merge.
......@@ -93,7 +122,7 @@ added after the original pull request but before a merge.
if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
message (where XXXX is the issue number).
### [Checkstyle](#_checkstyle) ###
### [Checkstyle](#_checkstyle)
Spring Cloud Build comes with a set of checkstyle rules. You can find them in the `spring-cloud-build-tools` module. The most notable files under the module are:
......@@ -114,7 +143,7 @@ spring-cloud-build-tools/
|**2**| File header setup |
|**3**|Default suppression rules|
#### [Checkstyle configuration](#_checkstyle_configuration) ####
#### [Checkstyle configuration](#_checkstyle_configuration)
Checkstyle rules are **disabled by default**. To add checkstyle to your project just define the following properties and plugins.
......@@ -181,9 +210,9 @@ $ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/
$ touch .springformat
```
### [IDE setup](#_ide_setup) ###
### [IDE setup](#_ide_setup)
#### [Intellij IDEA](#_intellij_idea) ####
#### [Intellij IDEA](#_intellij_idea)
In order to setup Intellij you should import our coding conventions, inspection profiles and set up the checkstyle plugin.
The following files can be found in the [Spring Cloud Build](https://github.com/spring-cloud/spring-cloud-build/tree/master/spring-cloud-build-tools) project.
......@@ -239,11 +268,11 @@ Go to `File` → `Settings` → `Other settings` → `Checkstyle`. There click o
| |Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources.|
|---|------------------------------------------------------------------------------------------------------------------|
### [Duplicate Finder](#_duplicate_finder) ###
### [Duplicate Finder](#_duplicate_finder)
Spring Cloud Build brings along the `basepom:duplicate-finder-maven-plugin`, that enables flagging duplicate and conflicting classes and resources on the java classpath.
#### [Duplicate Finder configuration](#_duplicate_finder_configuration) ####
#### [Duplicate Finder configuration](#_duplicate_finder_configuration)
Duplicate finder is **enabled by default** and will run in the `verify` phase of your Maven build, but it will only take effect in your project if you add the `duplicate-finder-maven-plugin` to the `build` section of the projecst’s `pom.xml`.
......@@ -286,8 +315,7 @@ If you need to add `ignoredClassPatterns` or `ignoredResourcePatterns` to your s
</build>
```
[Flattening the POMs](#_flattening_the_poms)
----------
## [Flattening the POMs](#_flattening_the_poms)
To avoid propagating build setup that is required to build a Spring Cloud project, we’re using the maven flatten plugin. It has the advantage of letting you use whatever features you need while publishing "clean" pom to the repository.
......@@ -304,8 +332,7 @@ In order to add it, add the `org.codehaus.mojo:flatten-maven-plugin` to your `po
</build>
```
[Reusing the documentation](#_reusing_the_documentation)
----------
## [Reusing the documentation](#_reusing_the_documentation)
Spring Cloud Build publishes its `spring-cloud-build-docs` module that contains
helpful scripts (e.g. README generation ruby script) and css, xslt and images
......@@ -415,8 +442,7 @@ Spring Cloud Build Docs comes with a set of attributes for asciidoctor that you
</attributes>
```
[Updating the guides](#_updating_the_guides)
----------
## [Updating the guides](#_updating_the_guides)
We assume that your project contains guides under the `guides` folder.
......@@ -448,3 +474,5 @@ what will happen is that for GA project versions, we will clone `gs-guide1`, `gs
You can skip this by either not adding the `guides` profile, or passing the `-DskipGuides` system property when the profile is turned on.
You can configure the project version passed to guides via the `guides-project.version` (defaults to `${project.version}`). The phase at which guides get updated can be configured by `guides-update.phase` (defaults to `deploy`).
if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1\*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}
\ No newline at end of file
Spring Cloud Bus
==========
Spring Cloud Bus.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;
} function addBlockSwitches() { for (var primary of document.querySelectorAll('.primary')) { var switchItem = createSwitchItem(primary, createBlockSwitch(primary)); switchItem.item.classList.add("selected"); var title = primary.querySelector('.title') title.remove(); } for (var secondary of document.querySelectorAll('.secondary')) { var primary = findPrimary(secondary); if (primary === null) { console.error("Found secondary block with no primary sibling"); } else { var switchItem = createSwitchItem(secondary, primary.querySelector('.switch')); switchItem.content.classList.add("hidden"); primary.append(switchItem.content); secondary.remove(); } }
} function createElementFromHtml(html) { var template = document.createElement('template'); template.innerHTML = html; return template.content.firstChild;
} function createBlockSwitch(primary) { var blockSwitch = createElementFromHtml('\<div class="switch"\>\</div\>'); primary.prepend(blockSwitch) return blockSwitch;
} function findPrimary(secondary) { var candidate = secondary.previousElementSibling; while (candidate != null && !candidate.classList.contains('primary')) { candidate = candidate.previousElementSibling; } return candidate;
} function createSwitchItem(block, blockSwitch) { var blockName = block.querySelector('.title').textContent; var content = block.querySelectorAll('.content').item(0); var colist = nextSibling(block, '.colist'); if (colist != null) { content.append(colist); } var item = createElementFromHtml('\<div class="switch--item"\>' + blockName + '\</div\>'); item.dataset.blockName = blockName; content.dataset.blockName = blockName; blockSwitch.append(item); return {'item': item, 'content': content};
} function nextSibling(element, selector) { var sibling = element.nextElementSibling; while (sibling) { if (sibling.matches(selector)) { return sibling; } sibling = sibling.nextElementSibling; }
} function globalSwitch() { document.querySelectorAll(".switch--item").forEach(function(item) { var blockId = blockIdForSwitchItem(item); var handler = function(event) { selectedText = event.target.textContent; window.localStorage.setItem(blockId, selectedText); for (var switchItem of document.querySelectorAll(".switch--item")) { if (blockIdForSwitchItem(switchItem) === blockId && switchItem.textContent === selectedText) { select(switchItem); } } } item.addEventListener("click", handler); if (item.textContent === window.localStorage.getItem(blockId)) { select(item); } });
} function select(selected) { for (var child of selected.parentNode.children) { child.classList.remove("selected"); } selected.classList.add("selected"); for (var child of selected.parentNode.parentNode.children) { if (child.classList.contains("content")) { if (selected.dataset.blockName === child.dataset.blockName) { child.classList.remove("hidden"); } else { child.classList.add("hidden"); } } } } function blockIdForSwitchItem(item) { idComponents = [] for (var switchItem of item.parentNode.querySelectorAll(".switch--item")) { idComponents.push(switchItem.textContent.toLowerCase()); } return idComponents.sort().join("-")
} window.onload = function() { addBlockSwitches(); globalSwitch();
};
# Spring Cloud Bus
Table of Contents
* [1. Quick Start](#quick-start)
* [2. Bus Endpoints](#bus-endpoints)
* [2.1. Bus Refresh Endpoint](#bus-refresh-endpoint)
* [2.2. Bus Env Endpoint](#bus-env-endpoint)
* [3. Addressing an Instance](#addressing-an-instance)
* [4. Addressing All Instances of a Service](#addressing-all-instances-of-a-service)
* [5. Service ID Must Be Unique](#service-id-must-be-unique)
* [6. Customizing the Message Broker](#customizing-the-message-broker)
* [7. Tracing Bus Events](#tracing-bus-events)
* [8. Broadcasting Your Own Events](#broadcasting-your-own-events)
* [8.1. Registering events in custom packages](#registering-events-in-custom-packages)
* [9. Configuration properties](#configuration-properties)
Spring Cloud Bus links the nodes of a distributed system with a lightweight message
broker. This broker can then be used to broadcast state changes (such as configuration
......@@ -11,8 +43,7 @@ either an AMQP broker or Kafka as the transport.
| |Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at [github](https://github.com/spring-cloud/spring-cloud-bus).|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
[](#quick-start)[1. Quick Start](#quick-start)
----------
## [](#quick-start)[1. Quick Start](#quick-start)
Spring Cloud Bus works by adding Spring Boot autconfiguration if it detects itself on the
classpath. To enable the bus, add `spring-cloud-starter-bus-amqp` or`spring-cloud-starter-bus-kafka` to your dependency management. Spring Cloud takes care of
......@@ -41,12 +72,11 @@ application’s configuration, as though they had all been pinged on their `/ref
| |The Spring Cloud Bus starters cover Rabbit and Kafka, because those are the two most<br/>common implementations. However, Spring Cloud Stream is quite flexible, and the binder<br/>works with `spring-cloud-bus`.|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
[](#bus-endpoints)[2. Bus Endpoints](#bus-endpoints)
----------
## [](#bus-endpoints)[2. Bus Endpoints](#bus-endpoints)
Spring Cloud Bus provides two endpoints, `/actuator/busrefresh` and `/actuator/busenv`that correspond to individual actuator endpoints in Spring Cloud Commons,`/actuator/refresh` and `/actuator/env` respectively.
### [](#bus-refresh-endpoint)[2.1. Bus Refresh Endpoint](#bus-refresh-endpoint) ###
### [](#bus-refresh-endpoint)[2.1. Bus Refresh Endpoint](#bus-refresh-endpoint)
The `/actuator/busrefresh` endpoint clears the `RefreshScope` cache and rebinds`@ConfigurationProperties`. See the [Refresh Scope](#refresh-scope) documentation for
more information.
......@@ -58,7 +88,7 @@ application:
management.endpoints.web.exposure.include=busrefresh
```
### [](#bus-env-endpoint)[2.2. Bus Env Endpoint](#bus-env-endpoint) ###
### [](#bus-env-endpoint)[2.2. Bus Env Endpoint](#bus-env-endpoint)
The `/actuator/busenv` endpoint updates each instances environment with the specified
key/value pair across multiple instances.
......@@ -79,8 +109,7 @@ The `/actuator/busenv` endpoint accepts `POST` requests with the following shape
}
```
[](#addressing-an-instance)[3. Addressing an Instance](#addressing-an-instance)
----------
## [](#addressing-an-instance)[3. Addressing an Instance](#addressing-an-instance)
Each instance of the application has a service ID, whose value can be set with`spring.cloud.bus.id` and whose value is expected to be a colon-separated list of
identifiers, in order from least specific to most specific. The default value is
......@@ -97,16 +126,14 @@ The HTTP endpoints accept a “destination” path parameter, such as`/busrefres
is owned by an instance on the bus, it processes the message, and all other instances
ignore it.
[](#addressing-all-instances-of-a-service)[4. Addressing All Instances of a Service](#addressing-all-instances-of-a-service)
----------
## [](#addressing-all-instances-of-a-service)[4. Addressing All Instances of a Service](#addressing-all-instances-of-a-service)
The “destination” parameter is used in a Spring `PathMatcher` (with the path separator
as a colon — `:`) to determine if an instance processes the message. Using the example
from earlier, `/busenv/customers:**` targets all instances of the
“customers” service regardless of the rest of the service ID.
[](#service-id-must-be-unique)[5. Service ID Must Be Unique](#service-id-must-be-unique)
----------
## [](#service-id-must-be-unique)[5. Service ID Must Be Unique](#service-id-must-be-unique)
The bus tries twice to eliminate processing an event — once from the original`ApplicationEvent` and once from the queue. To do so, it checks the sending service ID
against the current service ID. If multiple instances of a service have the same ID,
......@@ -115,8 +142,7 @@ port, and that port is part of the ID. Cloud Foundry supplies an index to differ
To ensure that the ID is unique outside Cloud Foundry, set `spring.application.index` to
something unique for each instance of a service.
[](#customizing-the-message-broker)[6. Customizing the Message Broker](#customizing-the-message-broker)
----------
## [](#customizing-the-message-broker)[6. Customizing the Message Broker](#customizing-the-message-broker)
Spring Cloud Bus uses [Spring Cloud Stream](https://cloud.spring.io/spring-cloud-stream) to
broadcast the messages. So, to get messages to flow, you need only include the binder
......@@ -130,8 +156,7 @@ middleware). Normally, the defaults suffice.
To learn more about how to customize the message broker settings, consult the Spring Cloud
Stream documentation.
[](#tracing-bus-events)[7. Tracing Bus Events](#tracing-bus-events)
----------
## [](#tracing-bus-events)[7. Tracing Bus Events](#tracing-bus-events)
Bus events (subclasses of `RemoteApplicationEvent`) can be traced by setting`spring.cloud.bus.trace.enabled=true`. If you do so, the Spring Boot `TraceRepository`(if it is present) shows each event sent and all the acks from each service instance. The
following example comes from the `/trace` endpoint:
......@@ -178,8 +203,7 @@ there.
| |Any Bus application can trace acks. However, sometimes, it is<br/>useful to do this in a central service that can do more complex<br/>queries on the data or forward it to a specialized tracing service.|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
[](#broadcasting-your-own-events)[8. Broadcasting Your Own Events](#broadcasting-your-own-events)
----------
## [](#broadcasting-your-own-events)[8. Broadcasting Your Own Events](#broadcasting-your-own-events)
The Bus can carry any event of type `RemoteApplicationEvent`. The default transport is
JSON, and the deserializer needs to know which types are going to be used ahead of time.
......@@ -191,7 +215,7 @@ the default strategy, which is to use the simple name of the class.
| |Both the producer and the consumer need access to the class definition.|
|---|-----------------------------------------------------------------------|
### [](#registering-events-in-custom-packages)[8.1. Registering events in custom packages](#registering-events-in-custom-packages) ###
### [](#registering-events-in-custom-packages)[8.1. Registering events in custom packages](#registering-events-in-custom-packages)
If you cannot or do not want to use a subpackage of `org.springframework.cloud.bus.event`for your custom events, you must specify which packages to scan for events of type`RemoteApplicationEvent` by using the `@RemoteApplicationEventScan` annotation. Packages
specified with `@RemoteApplicationEventScan` include subpackages.
......@@ -240,7 +264,8 @@ All of the preceding examples of `@RemoteApplicationEventScan` are equivalent, i
| |You can specify multiple base packages to scan.|
|---|-----------------------------------------------|
[](#configuration-properties)[9. Configuration properties](#configuration-properties)
----------
## [](#configuration-properties)[9. Configuration properties](#configuration-properties)
To see the list of all Bus related configuration properties please check [the Appendix page](appendix.html).
if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1\*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}
\ No newline at end of file
Spring Boot Cloud CLI
==========
Spring Boot Cloud CLI.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;
} function addBlockSwitches() { for (var primary of document.querySelectorAll('.primary')) { var switchItem = createSwitchItem(primary, createBlockSwitch(primary)); switchItem.item.classList.add("selected"); var title = primary.querySelector('.title') title.remove(); } for (var secondary of document.querySelectorAll('.secondary')) { var primary = findPrimary(secondary); if (primary === null) { console.error("Found secondary block with no primary sibling"); } else { var switchItem = createSwitchItem(secondary, primary.querySelector('.switch')); switchItem.content.classList.add("hidden"); primary.append(switchItem.content); secondary.remove(); } }
} function createElementFromHtml(html) { var template = document.createElement('template'); template.innerHTML = html; return template.content.firstChild;
} function createBlockSwitch(primary) { var blockSwitch = createElementFromHtml('\<div class="switch"\>\</div\>'); primary.prepend(blockSwitch) return blockSwitch;
} function findPrimary(secondary) { var candidate = secondary.previousElementSibling; while (candidate != null && !candidate.classList.contains('primary')) { candidate = candidate.previousElementSibling; } return candidate;
} function createSwitchItem(block, blockSwitch) { var blockName = block.querySelector('.title').textContent; var content = block.querySelectorAll('.content').item(0); var colist = nextSibling(block, '.colist'); if (colist != null) { content.append(colist); } var item = createElementFromHtml('\<div class="switch--item"\>' + blockName + '\</div\>'); item.dataset.blockName = blockName; content.dataset.blockName = blockName; blockSwitch.append(item); return {'item': item, 'content': content};
} function nextSibling(element, selector) { var sibling = element.nextElementSibling; while (sibling) { if (sibling.matches(selector)) { return sibling; } sibling = sibling.nextElementSibling; }
} function globalSwitch() { document.querySelectorAll(".switch--item").forEach(function(item) { var blockId = blockIdForSwitchItem(item); var handler = function(event) { selectedText = event.target.textContent; window.localStorage.setItem(blockId, selectedText); for (var switchItem of document.querySelectorAll(".switch--item")) { if (blockIdForSwitchItem(switchItem) === blockId && switchItem.textContent === selectedText) { select(switchItem); } } } item.addEventListener("click", handler); if (item.textContent === window.localStorage.getItem(blockId)) { select(item); } });
} function select(selected) { for (var child of selected.parentNode.children) { child.classList.remove("selected"); } selected.classList.add("selected"); for (var child of selected.parentNode.parentNode.children) { if (child.classList.contains("content")) { if (selected.dataset.blockName === child.dataset.blockName) { child.classList.remove("hidden"); } else { child.classList.add("hidden"); } } } } function blockIdForSwitchItem(item) { idComponents = [] for (var switchItem of item.parentNode.querySelectorAll(".switch--item")) { idComponents.push(switchItem.textContent.toLowerCase()); } return idComponents.sort().join("-")
} window.onload = function() { addBlockSwitches(); globalSwitch();
};
# Spring Boot Cloud CLI
Table of Contents
* [Installation](#_installation)
* [Running Spring Cloud Services in Development](#_running_spring_cloud_services_in_development)
* [Adding Additional Applications](#_adding_additional_applications)
* [Writing Groovy Scripts and Running Applications](#_writing_groovy_scripts_and_running_applications)
* [Encryption and Decryption](#_encryption_and_decryption)
Spring Boot CLI provides [Spring
Boot](https://projects.spring.io/spring-boot) command line features for [Spring
......@@ -15,8 +38,7 @@ development time).
| |Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at [github](https://github.com/spring-cloud/spring-cloud-cli).|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
[Installation](#_installation)
----------
## [Installation](#_installation)
To install, make
sure you have[Spring Boot CLI](https://github.com/spring-projects/spring-boot)(2.0.0 or better):
......@@ -43,8 +65,7 @@ $ spring install org.springframework.cloud:spring-cloud-cli:2.2.0.RELEASE
| |**Prerequisites:** to use the encryption and decryption features<br/>you need the full-strength JCE installed in your JVM (it’s not there by default).<br/>You can download the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files"<br/>from Oracle, and follow instructions for installation (essentially replace the 2 policy files<br/>in the JRE lib/security directory with the ones that you downloaded).|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
[Running Spring Cloud Services in Development](#_running_spring_cloud_services_in_development)
----------
## [Running Spring Cloud Services in Development](#_running_spring_cloud_services_in_development)
The Launcher CLI can be used to run common services like Eureka,
Config Server etc. from the command line. To list the available
......@@ -96,7 +117,7 @@ stubrunner:
- com.example:beer-api-producer:+:9876
```
### [Adding Additional Applications](#_adding_additional_applications) ###
### [Adding Additional Applications](#_adding_additional_applications)
Additional applications can be added to `./config/cloud.yml` (not`./config.yml` because that would replace the defaults), e.g. with
......@@ -124,8 +145,7 @@ source sink configserver dataflow eureka h2 kafka stubrunner zipkin
(notice the additional apps at the start of the list).
[Writing Groovy Scripts and Running Applications](#_writing_groovy_scripts_and_running_applications)
----------
## [Writing Groovy Scripts and Running Applications](#_writing_groovy_scripts_and_running_applications)
Spring Cloud CLI has support for most of the Spring Cloud declarative
features, such as the `@Enable*` class of annotations. For example,
......@@ -162,8 +182,7 @@ class Service {
}
```
[Encryption and Decryption](#_encryption_and_decryption)
----------
## [Encryption and Decryption](#_encryption_and_decryption)
The Spring Cloud CLI comes with an "encrypt" and a "decrypt"
command. Both accept arguments in the same form with a key specified
......@@ -183,3 +202,5 @@ the key value with "@" and provide the file path, e.g.
$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...
```
if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1\*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}
\ No newline at end of file
Spring Cloud for Cloud Foundry
==========
Spring Cloud for Cloud Foundry.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;
} function addBlockSwitches() { for (var primary of document.querySelectorAll('.primary')) { var switchItem = createSwitchItem(primary, createBlockSwitch(primary)); switchItem.item.classList.add("selected"); var title = primary.querySelector('.title') title.remove(); } for (var secondary of document.querySelectorAll('.secondary')) { var primary = findPrimary(secondary); if (primary === null) { console.error("Found secondary block with no primary sibling"); } else { var switchItem = createSwitchItem(secondary, primary.querySelector('.switch')); switchItem.content.classList.add("hidden"); primary.append(switchItem.content); secondary.remove(); } }
} function createElementFromHtml(html) { var template = document.createElement('template'); template.innerHTML = html; return template.content.firstChild;
} function createBlockSwitch(primary) { var blockSwitch = createElementFromHtml('\<div class="switch"\>\</div\>'); primary.prepend(blockSwitch) return blockSwitch;
} function findPrimary(secondary) { var candidate = secondary.previousElementSibling; while (candidate != null && !candidate.classList.contains('primary')) { candidate = candidate.previousElementSibling; } return candidate;
} function createSwitchItem(block, blockSwitch) { var blockName = block.querySelector('.title').textContent; var content = block.querySelectorAll('.content').item(0); var colist = nextSibling(block, '.colist'); if (colist != null) { content.append(colist); } var item = createElementFromHtml('\<div class="switch--item"\>' + blockName + '\</div\>'); item.dataset.blockName = blockName; content.dataset.blockName = blockName; blockSwitch.append(item); return {'item': item, 'content': content};
} function nextSibling(element, selector) { var sibling = element.nextElementSibling; while (sibling) { if (sibling.matches(selector)) { return sibling; } sibling = sibling.nextElementSibling; }
} function globalSwitch() { document.querySelectorAll(".switch--item").forEach(function(item) { var blockId = blockIdForSwitchItem(item); var handler = function(event) { selectedText = event.target.textContent; window.localStorage.setItem(blockId, selectedText); for (var switchItem of document.querySelectorAll(".switch--item")) { if (blockIdForSwitchItem(switchItem) === blockId && switchItem.textContent === selectedText) { select(switchItem); } } } item.addEventListener("click", handler); if (item.textContent === window.localStorage.getItem(blockId)) { select(item); } });
} function select(selected) { for (var child of selected.parentNode.children) { child.classList.remove("selected"); } selected.classList.add("selected"); for (var child of selected.parentNode.parentNode.children) { if (child.classList.contains("content")) { if (selected.dataset.blockName === child.dataset.blockName) { child.classList.remove("hidden"); } else { child.classList.add("hidden"); } } } } function blockIdForSwitchItem(item) { idComponents = [] for (var switchItem of item.parentNode.querySelectorAll(".switch--item")) { idComponents.push(switchItem.textContent.toLowerCase()); } return idComponents.sort().join("-")
} window.onload = function() { addBlockSwitches(); globalSwitch();
};
# Spring Cloud for Cloud Foundry
Table of Contents
* [1. Discovery](#discovery)
* [2. Single Sign On](#single-sign-on)
* [3. Configuration](#configuration)
Spring Cloud for Cloudfoundry makes it easy to run[Spring Cloud](https://github.com/spring-cloud) apps in[Cloud Foundry](https://github.com/cloudfoundry) (the Platform as a
Service). Cloud Foundry has the notion of a "service", which is
......@@ -23,8 +43,7 @@ can use the `DiscoveryClient` directly or via a `LoadBalancerClient`.
The first time you use it the discovery client might be slow owing to
the fact that it has to get an access token from Cloud Foundry.
[](#discovery)[1. Discovery](#discovery)
----------
## [](#discovery)[1. Discovery](#discovery)
Here’s a Spring Cloud app with Cloud Foundry discovery:
......@@ -61,8 +80,7 @@ the credentials it is authenticated with, where the space defaults to
the one the client is running in (if any). If neither org nor space
are configured, they default per the user’s profile in Cloud Foundry.
[](#single-sign-on)[2. Single Sign On](#single-sign-on)
----------
## [](#single-sign-on)[2. Single Sign On](#single-sign-on)
| |All of the OAuth2 SSO and resource server features moved to Spring Boot<br/>in version 1.3. You can find documentation in the[Spring Boot user guide](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/).|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
......@@ -74,8 +92,8 @@ service called "sso", for instance, with credentials containing
automatically to the Spring OAuth2 client that you enable with`@EnableOAuth2Sso` (from Spring Boot). The name of the service can be
parameterized using `spring.oauth2.sso.serviceId`.
[](#configuration)[3. Configuration](#configuration)
----------
## [](#configuration)[3. Configuration](#configuration)
To see the list of all Spring Cloud Sloud Foundry related configuration properties please check [the Appendix page](appendix.html).
if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1\*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}
\ No newline at end of file
Spring Cloud Contract Reference Documentation
==========
Spring Cloud Contract Reference Documentation.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;
} function addBlockSwitches() { for (var primary of document.querySelectorAll('.primary')) { var switchItem = createSwitchItem(primary, createBlockSwitch(primary)); switchItem.item.classList.add("selected"); var title = primary.querySelector('.title') title.remove(); } for (var secondary of document.querySelectorAll('.secondary')) { var primary = findPrimary(secondary); if (primary === null) { console.error("Found secondary block with no primary sibling"); } else { var switchItem = createSwitchItem(secondary, primary.querySelector('.switch')); switchItem.content.classList.add("hidden"); primary.append(switchItem.content); secondary.remove(); } }
} function createElementFromHtml(html) { var template = document.createElement('template'); template.innerHTML = html; return template.content.firstChild;
} function createBlockSwitch(primary) { var blockSwitch = createElementFromHtml('\<div class="switch"\>\</div\>'); primary.prepend(blockSwitch) return blockSwitch;
} function findPrimary(secondary) { var candidate = secondary.previousElementSibling; while (candidate != null && !candidate.classList.contains('primary')) { candidate = candidate.previousElementSibling; } return candidate;
} function createSwitchItem(block, blockSwitch) { var blockName = block.querySelector('.title').textContent; var content = block.querySelectorAll('.content').item(0); var colist = nextSibling(block, '.colist'); if (colist != null) { content.append(colist); } var item = createElementFromHtml('\<div class="switch--item"\>' + blockName + '\</div\>'); item.dataset.blockName = blockName; content.dataset.blockName = blockName; blockSwitch.append(item); return {'item': item, 'content': content};
} function nextSibling(element, selector) { var sibling = element.nextElementSibling; while (sibling) { if (sibling.matches(selector)) { return sibling; } sibling = sibling.nextElementSibling; }
} function globalSwitch() { document.querySelectorAll(".switch--item").forEach(function(item) { var blockId = blockIdForSwitchItem(item); var handler = function(event) { selectedText = event.target.textContent; window.localStorage.setItem(blockId, selectedText); for (var switchItem of document.querySelectorAll(".switch--item")) { if (blockIdForSwitchItem(switchItem) === blockId && switchItem.textContent === selectedText) { select(switchItem); } } } item.addEventListener("click", handler); if (item.textContent === window.localStorage.getItem(blockId)) { select(item); } });
} function select(selected) { for (var child of selected.parentNode.children) { child.classList.remove("selected"); } selected.classList.add("selected"); for (var child of selected.parentNode.parentNode.children) { if (child.classList.contains("content")) { if (selected.dataset.blockName === child.dataset.blockName) { child.classList.remove("hidden"); } else { child.classList.add("hidden"); } } } } function blockIdForSwitchItem(item) { idComponents = [] for (var switchItem of item.parentNode.querySelectorAll(".switch--item")) { idComponents.push(switchItem.textContent.toLowerCase()); } return idComponents.sort().join("-")
} window.onload = function() { addBlockSwitches(); globalSwitch();
};
# Spring Cloud Contract Reference Documentation
Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant
......@@ -15,3 +30,4 @@ The reference documentation consists of the following sections:
| [“How-to” Guides](howto.html#howto) | Stubs versioning, Pact integration, Debugging, and more. |
| [Appendices](appendix.html#appendix) | Properties, Metadata, Configuration, Dependencies, and more. |
if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1\*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}
\ No newline at end of file
Spring Cloud Function Reference Documentation
==========
Spring Cloud Function Reference Documentation.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;
} function addBlockSwitches() { for (var primary of document.querySelectorAll('.primary')) { var switchItem = createSwitchItem(primary, createBlockSwitch(primary)); switchItem.item.classList.add("selected"); var title = primary.querySelector('.title') title.remove(); } for (var secondary of document.querySelectorAll('.secondary')) { var primary = findPrimary(secondary); if (primary === null) { console.error("Found secondary block with no primary sibling"); } else { var switchItem = createSwitchItem(secondary, primary.querySelector('.switch')); switchItem.content.classList.add("hidden"); primary.append(switchItem.content); secondary.remove(); } }
} function createElementFromHtml(html) { var template = document.createElement('template'); template.innerHTML = html; return template.content.firstChild;
} function createBlockSwitch(primary) { var blockSwitch = createElementFromHtml('\<div class="switch"\>\</div\>'); primary.prepend(blockSwitch) return blockSwitch;
} function findPrimary(secondary) { var candidate = secondary.previousElementSibling; while (candidate != null && !candidate.classList.contains('primary')) { candidate = candidate.previousElementSibling; } return candidate;
} function createSwitchItem(block, blockSwitch) { var blockName = block.querySelector('.title').textContent; var content = block.querySelectorAll('.content').item(0); var colist = nextSibling(block, '.colist'); if (colist != null) { content.append(colist); } var item = createElementFromHtml('\<div class="switch--item"\>' + blockName + '\</div\>'); item.dataset.blockName = blockName; content.dataset.blockName = blockName; blockSwitch.append(item); return {'item': item, 'content': content};
} function nextSibling(element, selector) { var sibling = element.nextElementSibling; while (sibling) { if (sibling.matches(selector)) { return sibling; } sibling = sibling.nextElementSibling; }
} function globalSwitch() { document.querySelectorAll(".switch--item").forEach(function(item) { var blockId = blockIdForSwitchItem(item); var handler = function(event) { selectedText = event.target.textContent; window.localStorage.setItem(blockId, selectedText); for (var switchItem of document.querySelectorAll(".switch--item")) { if (blockIdForSwitchItem(switchItem) === blockId && switchItem.textContent === selectedText) { select(switchItem); } } } item.addEventListener("click", handler); if (item.textContent === window.localStorage.getItem(blockId)) { select(item); } });
} function select(selected) { for (var child of selected.parentNode.children) { child.classList.remove("selected"); } selected.classList.add("selected"); for (var child of selected.parentNode.parentNode.children) { if (child.classList.contains("content")) { if (selected.dataset.blockName === child.dataset.blockName) { child.classList.remove("hidden"); } else { child.classList.add("hidden"); } } } } function blockIdForSwitchItem(item) { idComponents = [] for (var switchItem of item.parentNode.querySelectorAll(".switch--item")) { idComponents.push(switchItem.textContent.toLowerCase()); } return idComponents.sort().join("-")
} window.onload = function() { addBlockSwitches(); globalSwitch();
};
# Spring Cloud Function Reference Documentation
Mark Fisher, Dave Syer, Oleg Zhurakousky, Anshul Mehra
......@@ -20,3 +35,4 @@ Relevant Links:
|[Reactor](https://projectreactor.io/)|Project Reactor|
|-------------------------------------|---------------|
if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1\*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}
\ No newline at end of file
Spring Cloud Sleuth Reference Documentation
==========
Spring Cloud Sleuth Reference Documentation.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;
} function addBlockSwitches() { for (var primary of document.querySelectorAll('.primary')) { var switchItem = createSwitchItem(primary, createBlockSwitch(primary)); switchItem.item.classList.add("selected"); var title = primary.querySelector('.title') title.remove(); } for (var secondary of document.querySelectorAll('.secondary')) { var primary = findPrimary(secondary); if (primary === null) { console.error("Found secondary block with no primary sibling"); } else { var switchItem = createSwitchItem(secondary, primary.querySelector('.switch')); switchItem.content.classList.add("hidden"); primary.append(switchItem.content); secondary.remove(); } }
} function createElementFromHtml(html) { var template = document.createElement('template'); template.innerHTML = html; return template.content.firstChild;
} function createBlockSwitch(primary) { var blockSwitch = createElementFromHtml('\<div class="switch"\>\</div\>'); primary.prepend(blockSwitch) return blockSwitch;
} function findPrimary(secondary) { var candidate = secondary.previousElementSibling; while (candidate != null && !candidate.classList.contains('primary')) { candidate = candidate.previousElementSibling; } return candidate;
} function createSwitchItem(block, blockSwitch) { var blockName = block.querySelector('.title').textContent; var content = block.querySelectorAll('.content').item(0); var colist = nextSibling(block, '.colist'); if (colist != null) { content.append(colist); } var item = createElementFromHtml('\<div class="switch--item"\>' + blockName + '\</div\>'); item.dataset.blockName = blockName; content.dataset.blockName = blockName; blockSwitch.append(item); return {'item': item, 'content': content};
} function nextSibling(element, selector) { var sibling = element.nextElementSibling; while (sibling) { if (sibling.matches(selector)) { return sibling; } sibling = sibling.nextElementSibling; }
} function globalSwitch() { document.querySelectorAll(".switch--item").forEach(function(item) { var blockId = blockIdForSwitchItem(item); var handler = function(event) { selectedText = event.target.textContent; window.localStorage.setItem(blockId, selectedText); for (var switchItem of document.querySelectorAll(".switch--item")) { if (blockIdForSwitchItem(switchItem) === blockId && switchItem.textContent === selectedText) { select(switchItem); } } } item.addEventListener("click", handler); if (item.textContent === window.localStorage.getItem(blockId)) { select(item); } });
} function select(selected) { for (var child of selected.parentNode.children) { child.classList.remove("selected"); } selected.classList.add("selected"); for (var child of selected.parentNode.parentNode.children) { if (child.classList.contains("content")) { if (selected.dataset.blockName === child.dataset.blockName) { child.classList.remove("hidden"); } else { child.classList.add("hidden"); } } } } function blockIdForSwitchItem(item) { idComponents = [] for (var switchItem of item.parentNode.querySelectorAll(".switch--item")) { idComponents.push(switchItem.textContent.toLowerCase()); } return idComponents.sort().join("-")
} window.onload = function() { addBlockSwitches(); globalSwitch();
};
# Spring Cloud Sleuth Reference Documentation
Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer, Jay Bryant
......@@ -14,3 +29,5 @@ The reference documentation consists of the following sections:
| [“How-to” Guides](howto.html#howto) | Add sampling, propagate remote tags, and more. |
| [Spring Cloud Sleuth Integrations](integrations.html#sleuth-integration) | Instrumentation configuration, context propagation, and more. |
| [Appendices](appendix.html#appendix) | Span definitions and configuration properties. |
if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1\*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}
\ No newline at end of file
Spring Cloud Stream Reference Documentation
==========
Spring Cloud Stream Reference Documentation.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;
} function addBlockSwitches() { for (var primary of document.querySelectorAll('.primary')) { var switchItem = createSwitchItem(primary, createBlockSwitch(primary)); switchItem.item.classList.add("selected"); var title = primary.querySelector('.title') title.remove(); } for (var secondary of document.querySelectorAll('.secondary')) { var primary = findPrimary(secondary); if (primary === null) { console.error("Found secondary block with no primary sibling"); } else { var switchItem = createSwitchItem(secondary, primary.querySelector('.switch')); switchItem.content.classList.add("hidden"); primary.append(switchItem.content); secondary.remove(); } }
} function createElementFromHtml(html) { var template = document.createElement('template'); template.innerHTML = html; return template.content.firstChild;
} function createBlockSwitch(primary) { var blockSwitch = createElementFromHtml('\<div class="switch"\>\</div\>'); primary.prepend(blockSwitch) return blockSwitch;
} function findPrimary(secondary) { var candidate = secondary.previousElementSibling; while (candidate != null && !candidate.classList.contains('primary')) { candidate = candidate.previousElementSibling; } return candidate;
} function createSwitchItem(block, blockSwitch) { var blockName = block.querySelector('.title').textContent; var content = block.querySelectorAll('.content').item(0); var colist = nextSibling(block, '.colist'); if (colist != null) { content.append(colist); } var item = createElementFromHtml('\<div class="switch--item"\>' + blockName + '\</div\>'); item.dataset.blockName = blockName; content.dataset.blockName = blockName; blockSwitch.append(item); return {'item': item, 'content': content};
} function nextSibling(element, selector) { var sibling = element.nextElementSibling; while (sibling) { if (sibling.matches(selector)) { return sibling; } sibling = sibling.nextElementSibling; }
} function globalSwitch() { document.querySelectorAll(".switch--item").forEach(function(item) { var blockId = blockIdForSwitchItem(item); var handler = function(event) { selectedText = event.target.textContent; window.localStorage.setItem(blockId, selectedText); for (var switchItem of document.querySelectorAll(".switch--item")) { if (blockIdForSwitchItem(switchItem) === blockId && switchItem.textContent === selectedText) { select(switchItem); } } } item.addEventListener("click", handler); if (item.textContent === window.localStorage.getItem(blockId)) { select(item); } });
} function select(selected) { for (var child of selected.parentNode.children) { child.classList.remove("selected"); } selected.classList.add("selected"); for (var child of selected.parentNode.parentNode.children) { if (child.classList.contains("content")) { if (selected.dataset.blockName === child.dataset.blockName) { child.classList.remove("hidden"); } else { child.classList.add("hidden"); } } } } function blockIdForSwitchItem(item) { idComponents = [] for (var switchItem of item.parentNode.querySelectorAll(".switch--item")) { idComponents.push(switchItem.textContent.toLowerCase()); } return idComponents.sort().join("-")
} window.onload = function() { addBlockSwitches(); globalSwitch();
};
# Spring Cloud Stream Reference Documentation
Sabby Anandan
Marius Bogoevici
Eric Bottard
Mark Fisher
Ilayaperumal Gopinathan
Mark Heckler
Gunnar Hillert
Mark Pollack
Patrick Peralta
Glenn Renfro
Thomas Risberg
Dave Syer
David Turanski
Janne Valkealahti
Benjamin Klein
Vinicius Carvalho
Gary Russell
Oleg Zhurakousky
Jay Bryant
Soby Chacko
Domenico Sibilio
**3.2.2**
......@@ -19,3 +56,5 @@ Relevant Links:
|--------------------------------------------------------------------------------|------------------------------------------------------|
|[Enterprise Integration Patterns](http://www.enterpriseintegrationpatterns.com/)|Patterns and Best Practices for Enterprise Integration|
| [Spring Integration](https://spring.io/projects/spring-integration) | Spring Integration framework |
if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1\*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}
\ No newline at end of file
......@@ -499,6 +499,7 @@ $ systemctl enable myapp.service
默认脚本支持以下属性替换:
| Name |说明| Gradle default | Maven default |
|--------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------|------------------------------------------------------------|
| `mode` |脚本模式。| `auto` | `auto` |
......@@ -525,15 +526,16 @@ $ systemctl enable myapp.service
默认脚本支持以下环境属性:
| Variable |说明|
|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|-----------------------|---------------|
| `MODE` |操作的“模式”。<br/>默认值取决于构建 jar 的方式,但通常是`auto`(这意味着它试图通过检查来猜测它是否是一个 init 脚本)如果它是一个名为`init.d`的目录中的符号链接)。<br/>你可以显式地将它设置为`service`,这样 `stop|start|status|restart` commands work or to `run` if you want to run the script in the foreground.|
| `RUN_AS_USER` |将用于运行该应用程序的用户。<br/>当未设置时,将使用 OWNS jar 文件的用户。|
|`USE_START_STOP_DAEMON`|是否应该使用`start-stop-daemon`命令来控制进程。<br/>默认为`true`。|
| `PID_FOLDER` |PID 文件夹的根名(默认为 `/var/run’)。|
| `LOG_FOLDER` |放置日志文件的文件夹的名称(默认情况下为“/var/log”)。|
| `CONF_FOLDER` |读取.conf 文件的文件夹的名称(默认情况下与 jar-file 文件相同)。|
| `LOG_FILENAME` |在`LOG_FOLDER`(<appname>.log` 默认情况下)中日志文件的名称。|
| `LOG_FILENAME` |在`LOG_FOLDER`(`<appname>.log` 默认情况下)中日志文件的名称。|
| `APP_NAME` |应用程序的名称。<br/>如果 jar 是从符号链接运行的,则脚本猜测应用程序的名称。<br/>如果不是符号链接,或者你希望显式设置应用程序名称,这可能是有用的。|
| `RUN_ARGS` |要传递给程序( Spring 引导应用程序)的参数。|
| `JAVA_HOME` |默认情况下,`java`可执行文件的位置是通过使用`PATH`发现的,但是如果在`$JAVA_HOME/bin/java`处有一个可执行文件,则可以显式地设置它。|
......@@ -542,8 +544,11 @@ $ systemctl enable myapp.service
| `DEBUG` |如果不是空的,则在 shell 进程上设置`-x`标志,允许你查看脚本中的逻辑。|
| `STOP_WAIT_TIME` |在强制关闭应用程序之前,停止应用程序所需的等待时间(以秒为单位)(默认为 `60’)。|
| |`PID_FOLDER`,`LOG_FOLDER`,和`LOG_FILENAME`变量仅对`init.d`服务有效。<br/>对于`systemd`,通过使用’service’脚本进行等效的自定义。<br/>有关更多详细信息,请参见[服务单元配置手册页](https://www.freedesktop.org/software/systemd/man/systemd.service.html)。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
> `PID_FOLDER`,`LOG_FOLDER`,和`LOG_FILENAME`变量仅对`init.d`服务有效。
> 对于`systemd`,通过使用’service’脚本进行等效的自定义。
> 有关更多详细信息,请参见[服务单元配置手册页](https://www.freedesktop.org/software/systemd/man/systemd.service.html)。
除了`JARFILE`和`APP_NAME`之外,可以通过使用`.conf`文件配置上一节中列出的设置。该文件预计将位于 jar 文件的旁边,并且具有相同的名称,但后缀为`.conf`,而不是`.jar`。例如,名为`/var/myapp/myapp.jar`的 jar 使用名为`/var/myapp/myapp.conf`的配置文件,如以下示例所示:
......@@ -554,8 +559,7 @@ JAVA_OPTS=-Xmx1024M
LOG_FOLDER=/custom/log/folder
```
| |如果不喜欢将配置文件放在 jar 文件旁边,则可以设置`CONF_FOLDER`环境变量来定制配置文件的位置。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
> 如果不喜欢将配置文件放在 jar 文件旁边,则可以设置`CONF_FOLDER`环境变量来定制配置文件的位置。
要了解如何适当地保护此文件,请参见[获得 init.d 服务的指导方针](#deployment.installing.nix-services.init-d.securing)。
......
# Spring 云
\ No newline at end of file
# Spring 云文档
本节提供了 Spring 云参考文档的简要概述。它是这份文件其余部分的一张地图。
## [](#documentation-about)[1.关于文档](#documentation-about)
Spring 云参考指南如下所示
* [Multi-page HTML](https://docs.spring.io/spring-cloud/docs/2021.0.1/reference/html)
* [单页 HTML](https://docs.spring.io/spring-cloud/docs/2021.0.1/reference/htmlsingle)
* [PDF](https://docs.spring.io/spring-cloud/docs/2021.0.1/reference/pdf/spring-cloud.pdf)
本文件的副本可供你自己使用并分发给他人,但前提是你不对此类副本收取任何费用,并且还需每一份副本均包含本版权声明,无论是以印刷形式还是以电子方式分发。
## [](#documentation-getting-help)[2. Getting Help](#documentation-getting-help)
如果你在云计算方面有困难,我们愿意提供帮助。
* 学习云的基础知识。如果你从 Spring Cloud 开始,请尝试使用[guides](https://spring.io/guides)中的一个。
* 问一个问题。我们监控[stackoverflow.com](https://stackoverflow.com)中带有[`spring-cloud`](https://stackoverflow.com/tags/spring-cloud)标记的问题。
*[Spring Cloud Gitter](https://gitter.im/spring-cloud/spring-cloud)与我们聊天
| |所有的云都是开源的,包括文档。如果你发现<br/>DOCS 存在问题,或者你希望改进这些问题,请参与进来。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------|
# 法律
2021.0.1
版权所有 2012-2020
本文件的副本可供你自己使用并分发给他人,但前提是你不对此类副本收取任何费用,并且还需每一份副本均包含本版权声明,无论是以印刷形式还是以电子方式分发。
此差异已折叠。
# Spring 云总线
Spring 云总线将分布式系统的节点与轻量级消息代理连接起来。然后可以使用此代理来广播状态更改(例如配置更改)或其他管理指令。一个关键的想法是,总线就像是 Spring 启动应用程序的分布式执行器,该应用程序是按比例扩展的。然而,它也可以用作应用程序之间的沟通渠道。该项目为 AMQP 代理或 Kafka 提供了作为传输的启动器。
| |Spring 云是在非限制性的 Apache2.0 许可下发布的。如果你想对文档的这一部分做出贡献,或者你发现了一个错误,请在[github](https://github.com/spring-cloud/spring-cloud-bus)上找到项目中的源代码和问题追踪器。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
## [](#quick-start)[1. Quick Start](#quick-start)
Spring 如果云总线在 Classpath 上检测到自身,则通过添加 Spring 引导自动配置来工作。要启用总线,请在依赖管理中添加`spring-cloud-starter-bus-amqp`` Spring-cloud-starter-bus-kafka`。 Spring 剩下的事由云来解决。确保代理(RabbitMQ 或 Kafka)可用并进行了配置。在 LocalHost 上运行时,你不需要做任何事情。如果远程运行,请使用 Spring Cloud Connectors 或 Spring Boot 约定来定义代理凭据,如下面的 Rabbit 示例所示:
应用程序.yml
```
spring:
rabbitmq:
host: mybroker.com
port: 5672
username: user
password: secret
```
总线目前支持将消息发送到监听的所有节点或特定服务的所有节点(由 Eureka 定义)。执行器名称空间`/bus/*`具有一些 HTTP 端点。目前,有两个项目已经实施。第一种是`/bus/env`,它发送键/值对来更新每个节点的 Spring 环境。第二种是`/bus/refresh`,它重新加载每个应用程序的配置,就好像它们都在其`/refresh`端点上被 pinged 了一样。
| |Spring 云总线启动器覆盖 Rabbit 和 Kafka,因为这是两个最<br/>的常见实现。然而, Spring 云流是相当灵活的,并且活页夹<br/>`spring-cloud-bus`一起工作。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
## [](#bus-endpoints)[2.总线端点](#bus-endpoints)
Spring 云总线提供了两个端点,`/actuator/busrefresh``/actuator/busenv`,这两个端点分别对应于 Spring 云共享空间中的各个执行器端点,`/actuator/refresh``/actuator/env`
### [](#bus-refresh-endpoint)[2.1.总线刷新端点](#bus-refresh-endpoint)
`/actuator/busrefresh`端点清除`RefreshScope`缓存并重新绑定 @configrationProperties`。有关更多信息,请参见[Refresh Scope](#refresh-scope)文档。
要公开`/actuator/busrefresh`端点,需要向应用程序添加以下配置:
```
management.endpoints.web.exposure.include=busrefresh
```
### [](#bus-env-endpoint)[2.2.总线 ENV 端点](#bus-env-endpoint)
`/actuator/busenv`端点使用跨多个实例的指定键/值对更新每个实例环境。
要公开`/actuator/busenv`端点,需要向应用程序添加以下配置:
```
management.endpoints.web.exposure.include=busenv
```
`/actuator/busenv`端点接受具有以下形状的`POST`请求:
```
{
"name": "key1",
"value": "value1"
}
```
## [](#addressing-an-instance)[3.寻址实例](#addressing-an-instance)
应用程序的每个实例都有一个服务 ID,其值可以用 ` Spring.cloud.bus.id` 设置,其值应该是一个以冒号分隔的标识符列表,顺序从最小特定到最特定。默认值是作为`spring.application.name`和 `server.port’(或`spring.application.index`,如果设置)的组合从环境构造的。ID 的默认值以`app:index:id`的形式构造,其中:
* `app``vcap.application.name`,如果它存在,或者`spring.application.name`
* `index``vcap.application.instance_index`,如果存在,` Spring.application.index``local.server.port``server.port`,或`0`(按此顺序排列)。
* `id``vcap.application.instance_id`,如果它存在,或者是一个随机值。
HTTP 端点接受一个“destination”路径参数,例如“/busrefresh/customers:9000”,其中`destination`是一个服务 ID。如果 ID 由总线上的一个实例拥有,那么它将处理消息,而所有其他实例将忽略它。
## [](#addressing-all-instances-of-a-service)[4.处理服务的所有实例](#addressing-all-instances-of-a-service)
在 Spring `PathMatcher`(路径分隔符为冒号—`:`)中使用“destination”参数来确定实例是否处理消息。使用前面的示例,`/busenv/customers:**`的目标是“Customers”服务的所有实例,而不考虑服务 ID 的其余部分。
## [](#service-id-must-be-unique)[5.服务 ID 必须是唯一的](#service-id-must-be-unique)
总线尝试两次消除处理一个事件——一次从原始的“ApplicationEvent”中删除,一次从队列中删除。为此,它会根据当前的服务 ID 检查发送服务 ID。如果一个服务的多个实例具有相同的 ID,则不会对事件进行处理。当在本地机器上运行时,每个服务都位于不同的端口上,而该端口是 ID 的一部分。Cloud Foundry 提供了一个用于区分的索引。要确保 ID 在 Cloud Foundry 之外是唯一的,请将`spring.application.index`设置为服务的每个实例都是唯一的。
## [](#customizing-the-message-broker)[6.自定义消息代理](#customizing-the-message-broker)
Spring 云总线使用[Spring Cloud Stream](https://cloud.spring.io/spring-cloud-stream)来广播消息。因此,要使消息流起来,你只需要在 Classpath 中包含你选择的绑定器实现。与 AMQP 和 Kafka(` Spring-cloud-starter-bus-[AMQP|Kafka]`)的总线有方便的启动器。一般来说, Spring Cloud Stream 依赖于 Spring Boot AutoConfiguration 约定来配置中间件。例如,可以使用 ` Spring.RabbitMQ.*` 配置属性来更改 AMQP 代理地址。 Spring Cloud Bus 在`spring.cloud.bus.*`中具有少量的本机配置属性(例如,` Spring.cloud.bus.destination` 是要用作外部中间件的主题的名称)。通常情况下,默认值就足够了。
要了解有关如何自定义 Message Broker 设置的更多信息,请参阅 Spring Cloud Stream 文档。
## [](#tracing-bus-events)[7.追踪总线事件](#tracing-bus-events)
可以通过设置 ` Spring.cloud.bus.trace.enabled=true` 来跟踪总线事件(`RemoteApplicationEvent`的子类)。如果这样做, Spring boot`TraceRepository`(如果存在)将显示发送的每个事件和来自每个服务实例的所有 ACK。以下示例来自`/trace`端点:
```
{
"timestamp": "2015-11-26T10:24:44.411+0000",
"info": {
"signal": "spring.cloud.bus.ack",
"type": "RefreshRemoteApplicationEvent",
"id": "c4d374b7-58ea-4928-a312-31984def293b",
"origin": "stores:8081",
"destination": "*:**"
}
},
{
"timestamp": "2015-11-26T10:24:41.864+0000",
"info": {
"signal": "spring.cloud.bus.sent",
"type": "RefreshRemoteApplicationEvent",
"id": "c4d374b7-58ea-4928-a312-31984def293b",
"origin": "customers:9000",
"destination": "*:**"
}
},
{
"timestamp": "2015-11-26T10:24:41.862+0000",
"info": {
"signal": "spring.cloud.bus.ack",
"type": "RefreshRemoteApplicationEvent",
"id": "c4d374b7-58ea-4928-a312-31984def293b",
"origin": "customers:9000",
"destination": "*:**"
}
}
```
前面的跟踪显示,`RefreshRemoteApplicationEvent`是从 `customers:9000’发送的,向所有服务广播,并由`customers:9000`和 `stores:8081’接收。
为了自己处理 ACK 信号,你可以为“AckRemoteApplicationEvent”添加<gtr="72"/>类型和<gtr="73"/>类型到你的应用程序(并启用跟踪)。或者,你可以利用`TraceRepository`并从那里挖掘数据。
| |任何总线应用程序都可以跟踪 ACK。然而,有时,在可以对数据执行更复杂的<br/>查询或将其转发给专门的跟踪服务的中心服务中执行此操作是很有用的。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
## [](#broadcasting-your-own-events)[8.播放自己的活动](#broadcasting-your-own-events)
总线可以承载`RemoteApplicationEvent`类型的任何事件。默认传输是 JSON,反序列化器需要提前知道将使用哪些类型。要注册一个新类型,你必须将其放入“org.springframework.cloud.bus.event”的子包中。
要自定义事件名,你可以在自定义类上使用`@JsonTypeName`,也可以使用默认策略,即使用类的简单名称。
| |生产者和消费者都需要访问类定义。|
|---|-----------------------------------------------------------------------|
### [](#registering-events-in-custom-packages)[8.1.在自定义包中注册事件](#registering-events-in-custom-packages)
如果不能或不想使用`org.springframework.cloud.bus.event`的子包处理自定义事件,则必须使用`@RemoteApplicationEventScan`注释指定要扫描 `RemoteApplicationEvent’类型事件的包。用`@RemoteApplicationEventScan`指定的包包括子包。
例如,考虑以下自定义事件,称为`MyEvent`:
```
package com.acme;
public class MyEvent extends RemoteApplicationEvent {
...
}
```
你可以通过以下方式向反序列化器注册该事件:
```
package com.acme;
@Configuration
@RemoteApplicationEventScan
public class BusConfiguration {
...
}
```
在不指定值的情况下,将注册使用`@RemoteApplicationEventScan`的类的包。在本例中,`com.acme`通过使用“BusConfiguration”包进行注册。
还可以在`@RemoteApplicationEventScan`上使用`value`、`basePackages`或`basePackageClasses`属性显式地指定要扫描的包,如以下示例所示:
```
package com.acme;
@Configuration
//@RemoteApplicationEventScan({"com.acme", "foo.bar"})
//@RemoteApplicationEventScan(basePackages = {"com.acme", "foo.bar", "fizz.buzz"})
@RemoteApplicationEventScan(basePackageClasses = BusConfiguration.class)
public class BusConfiguration {
...
}
```
上述`@RemoteApplicationEventScan`的所有示例都是等效的,因为通过在 `@remoteApplicationEventScan’上显式指定包,可以注册 `com.acme’包。
| |你可以指定要扫描的多个基包。|
|---|-----------------------------------------------|
## [](#configuration-properties)[9.配置属性](#configuration-properties)
要查看所有与总线相关的配置属性的列表,请检查[附录页](appendix.html)
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Spring 云合同参考文档
==========
Adam Dudczak,Mathias Düsterhöft,Marcin Grzejszczak,Dennis Kieselhorst,Jakub Kubry Ski,Karol Lassak,Olga Maciaszek-Sharma,Mariusz Smyku A,DAVESyer,Jay Bryant
参考文献包括以下部分:
| [Legal](legal.html#legal-information) |法律信息。|
|----------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
|[Documentation Overview](documentation-overview.html#contract-documentation)|关于文档,获得帮助,第一步,等等。|
| [Getting Started](getting-started.html#getting-started) |引入 Spring Cloud Contract,开发你的第一个 Spring 基于 Cloud Contract 的应用程序|
| [Using Spring Cloud Contract](using.html#using) |Spring 云合同使用示例和工作流程。|
| [Spring Cloud Contract Features](project-features.html#features) |Contract DSL、消息传递、 Spring Cloud Contract Stub Runner 和 Spring Cloud Contract WiRemock。|
| [Build Tools](project-features.html#features-build-tools) |Maven 插件, Gradle 插件和 Docker。|
| [“How-to” Guides](howto.html#howto) |存根版本控制,契约集成,调试等。|
| [Appendices](appendix.html#appendix) |属性、元数据、配置、依赖关系等等。|
Spring 云功能参考文档
==========
Mark Fisher,DAVESyer,Oleg Zhurakousky,Anshul Mehra
**3.2.2**
参考文献包括以下部分:
|[Reference Guide](spring-cloud-function.html)|Spring Cloud Function Reference|
|------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------|
|[Cloud Events](https://github.com/spring-cloud/spring-cloud-function/tree/master/spring-cloud-function-samples/function-sample-cloudevent)| Cloud Events |
|[RSocket](https://github.com/spring-cloud/spring-cloud-function/tree/master/spring-cloud-function-rsocket)| RSocket |
|[AWS Adapter](aws.html)| AWS Adapter Reference |
|[Azure Adapter](azure.html)| Azure Adapter Reference |
|[GCP Adapter](gcp.html)| GCP Adapter Reference |
相关链接:
|[Reactor](https://projectreactor.io/)|Project Reactor|
|-------------------------------------|---------------|
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# Spring 数据
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册