Add support for multiple-url-strategy configuration for clients. (#1946)

* Add support for multiple-url-strategy configuration for clients.

Add support for new property spring.cloud.config.multiple-uri-strategy.
The value must be one of: always, connection_timeout_only. The default
value is connection_timeout_only. This default setting maintains existing
behavior.

If a client has multiple URLs in the spring.cloud.config.uri property,
and if multiple-uri-strategy is set to "always", then if the client gets
any error from config server whatsoever or gets no response, the client
will try the next URL in the list.

The existing and default behavior is that the other URLs in the list will be
tried only if and when the client receives no response from config server.

This is mainly to allow for a client failing over to secondary URLs when
it receives a 404 due to config server being unable to reach its git server
(and config server does not have the requested configs in its local git cache).
With the default behavior, the client receives a 404 and never tries the
next URL in the list(which might point to a different git server that is
currently up). Another benefit is that it allows for a client failing over
to a secondary config server if the first one returns a 503 (OUT_OF_SERVICE).

Fixes gh-1845.

* Fix code style after committing change for gh-1845.

* Fix support for multiple-url-strategy configuration for clients.

Fix issue with the new multiple URI strategy behavior.
Even when strategy was ALWAYS, the client would not try
the next URL when it received server-side errors. Fixed
this by adding HttpServerErrorException to catch clause
in ConfigServicePropertySourceLocator.

Also, fix code style issues and add unit tests.
Fix existing fail-fast unit tests that were not correct.
(They were not mocking out raw status code method on
the response. The error thrown back was actually due to
RestTemplate.handleResponse being unable to to map raw
status code 0 to an HttpStatus.)

* Fix support for multiple-url-strategy configuration for clients.

Merge with dev and undo unintentional changes that were
done automatically. This is part of the pull request
fixing gh-1845.

* Fix support for multiple-url-strategy configuration for clients.

Update ConfigServerConfigDataLoader to try multiple URLs
even for server-side errors when strategy is ALWAYS. This was
missed in previous commit. This is part of the pull request
fixing gh-1845.

* Add ConfigServerConfigDataLoaderTests.

When ConfigServerConfigDataLoader was originally introduced
for the new Spring Boot 2.4 way to import configuration data
(https://github.com/spring-cloud/spring-cloud-config/pull/1656/files),
no unit test was added. I needed to add tests to cover changes
made for the new MultipleUriStrategy (gh-1845). I copied
tests from ConfigServicePropertySourceLocatorTests and modified
as needed for the new class. (There were 2-3 test cases from
ConfigServicePropertySourceLocatorTests that I did not
copy over because it wasn't clear to me expected behavior
or how to set up test case).

This is part of the pull request fixing gh-1845.

* Update the default for multiple-uri-strategy to ALWAYS.

(Per code review.) This is part of the pull request fixing
gh-1845.

* Update documentation for the new multiple-uri-strategy property.

Also, add documentation comparing behavior of multiple URLs
under spring.cloud.config.uri versus multiple URLs under
spring.config.import.

This is part of the pull request fixing gh-1845.

Co-authored-by: UPINCMA <marnee.derider@pearson.com>
This commit is contained in:
marnee01
2022-03-07 16:07:41 -06:00
committed by GitHub
parent 863285d493
commit 7f83b1f547
7 changed files with 873 additions and 34 deletions

View File

@@ -1812,9 +1812,15 @@ In that case, the items in the list are tried one by one until one succeeds.
This behavior can be useful when working on a feature branch.
For instance, you might want to align the config label with your branch but make it optional (in that case, use `spring.cloud.config.label=myfeature,develop`).
=== Specifying Multiple Urls for the Config Server
=== Specifying Multiple URLs for the Config Server
To ensure high availability when you have multiple instances of Config Server deployed and expect one or more instances to be unavailable from time to time, you can either specify multiple URLs (as a comma-separated list under the `spring.cloud.config.uri` property) or have all your instances register in a Service Registry like Eureka ( if using Discovery-First Bootstrap mode ). Note that doing so ensures high availability only when the Config Server is not running (that is, when the application has exited) or when a connection timeout has occurred. For example, if the Config Server returns a 500 (Internal Server Error) response or the Config Client receives a 401 from the Config Server (due to bad credentials or other causes), the Config Client does not try to fetch properties from other URLs. An error of that kind indicates a user issue rather than an availability problem.
To ensure high availability when you have multiple instances of Config Server deployed and expect one or more instances to be unavailable or unable to honor requests from time to time (such as if the Git server is down), you can either specify multiple URLs (as a comma-separated list under the `spring.cloud.config.uri` property) or have all your instances register in a Service Registry like Eureka (if using Discovery-First Bootstrap mode).
The URLs listed under `spring.cloud.config.uri` are tried in the order listed. By default, the Config Client will try to fetch properties from each URL until an attempt is successful to ensure high availability.
However, if you want to ensure high availability only when the Config Server is not running (that is, when the application has exited) or when a connection timeout has occurred, set `spring.cloud.config.multiple-uri-strategy` to `connection-timeout-only`. (The default value of `spring.cloud.config.multiple-uri-strategy` is `always`.) For example, if the Config Server returns a 500 (Internal Server Error) response or the Config Client receives a 401 from the Config Server (due to bad credentials or other causes), the Config Client does not try to fetch properties from other URLs. A 400 error (except possibly 404) indicates a user issue rather than an availability problem. Note that if the Config Server is set to use a Git server and the call to Git server fails, a 404 error may occur.
Several locations can be specified under a single `spring.config.import` key instead of `spring.cloud.config.uri`. Locations will be processed in the order that they are defined, with later imports taking precedence. However, if `spring.cloud.config.fail-fast` is `true`, the Config Client will fail if the first Config Server call is unsuccessful for any reason. If `fail-fast` is `false`, it will try all URLs until one call is successful, regardless of the reason for failure. (The `spring.cloud.config.multiple-uri-strategy` does not apply when specifying URLs under `spring.config.import`.)
If you use HTTP basic security on your Config Server, it is currently possible to support per-Config Server auth credentials only if you embed the credentials in each URL you specify under the `spring.cloud.config.uri` property. If you use any other kind of security mechanism, you cannot (currently) support per-Config Server authentication and authorization.