+
diff --git a/images/spring-cloud-launcher-eureka-dashboard.png b/images/spring-cloud-launcher-eureka-dashboard.png new file mode 100644 index 00000000..dbd12c59 Binary files /dev/null and b/images/spring-cloud-launcher-eureka-dashboard.png differ diff --git a/images/spring-cloud-launcher-log.png b/images/spring-cloud-launcher-log.png new file mode 100644 index 00000000..916ce243 Binary files /dev/null and b/images/spring-cloud-launcher-log.png differ diff --git a/spring-cloud.html b/spring-cloud.html index a79ab9f5..4857ffe0 100644 --- a/spring-cloud.html +++ b/spring-cloud.html @@ -434,6 +434,8 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
The application will listen for an EnvironmentChangedEvent and react
+
The application will listen for an EnvironmentChangeEvent and react
to the change in a couple of standard ways (additional
ApplicationListeners can be added as @Beans by the user in the
-normal way). When an EnvironmentChangedEvent is observed it will
+normal way). When an EnvironmentChangeEvent is observed it will
have a list of key values that have changed, and the application will
use those to:
Environment, and generally we would not recommend that approach
for detecting changes (although you could set it up with a
@Scheduled annotation). If you have a scaled-out client application
-then it is better to broadcast the EnvironmentChangedEvent to all
+then it is better to broadcast the EnvironmentChangeEvent to all
the instances instead of having them polling for changes (e.g. using
the Spring Cloud
Bus).
The EnvironmentChangedEvent covers a large class of refresh use
+
The EnvironmentChangeEvent covers a large class of refresh use
cases, as long as you can actually make a change to the Environment
and publish the event (those APIs are public and part of core
Spring). You can verify the changes are bound to
@@ -1286,6 +1294,27 @@ the full strength JCE extensions in your JVM.
Patterns such as service discovery, load balancing and circuit breakers lend themselves to a common abstraction layer that can be consumed by all Spring Cloud clients, independent of the implementation (e.g. discovery via Eureka or Consul).
Commons provides the @EnableDiscoveryClient annotation. This looks for implementations of the DiscoveryClient interface via META-INF/spring.factories. Implementations of Discovery Client will add a configuration class to spring.factories under the org.springframework.cloud.client.discovery.EnableDiscoveryClient key. Examples of DiscoveryClient implementations: are Spring Cloud Netflix Eureka, Spring Cloud Consul Discovery and Spring Cloud Zookeeper Discovery.
By default, implementations of DiscoveryClient will auto-register the local Spring Boot server with the remote discovery server. This can be disabled by setting autoRegister=false in @EnableDiscoveryClient.
Commons now provides a ServiceRegistry interface which provides methods like register(Registration) and deregister(Registration) which allow you to provide custom registered services. Registration is a marker interface.
A /service-registry actuator endpoint is provided by Commons. This endpoint relys on a Registration bean in the Spring Application Context. Calling /service-registry/instance-status via a GET will return the status of the Registration. A POST to the same endpoint with a String body will change the status of the current Registration to the new value. Please see the documentation of the ServiceRegistry implementation you are using for the allowed values for updating the status and the values retured for the status.
RestTemplate can be automatically configured to use ribbon. To create a load balanced RestTemplate create a RestTemplate @Bean and use the @LoadBalanced qualifier.
RestTemplate is set up.
A load balanced RestTemplate can be configured to retry failed requests.
+By default this logic is disabled, you can enable it by setting
+spring.cloud.loadbalancer.retry.enabled=true. The load balanced RestTemplate will
+honor some of the Ribbon configuration values related to retrying failed requests.
+The properties you can use are client.ribbon.MaxAutoRetries,
+client.ribbon.MaxAutoRetriesNextServer, and client.ribbon.OkToRetryOnAllOperations.
+See the Ribbon documentation
+for a description of what there properties do.
|
+ Note
+ |
+
+client in the above examples should be replaced with your Ribbon client’s
+name.
+ |
+
+
+
Altogether there are 10 spans . If you go to traces in Zipkin you will see this number:
+Altogether there are 7 spans . If you go to traces in Zipkin you will see this number in the second trace:
+
However if you pick a particular trace then you will see 7 spans:
+However if you pick a particular trace then you will see 4 spans:
+
In the image depicting the visualization of what Span and Trace is you can see 20 -colorful labels. How does it happen that in Zipkin 10 spans are received?
+Why is there a difference between the 7 and 4 spans in this case?
2 span A labels signify span started and closed. Upon closing a single span is sent to Zipkin.
+2 spans come from http:/start span. It has the Server Received (SR) and Server Sent (SS) annotations.
4 span B labels are in fact are single span with 4 annotations. However this span is composed of -two separate instances. One sent from service 1 and one from service 2. So in fact two span instances will be sent -to Zipkin and merged there.
+2 spans come from the RPC call from service1 to service2 to the http:/foo endpoint. It has the Client Sent (CS)
+and Client Received (CR) annotations on service1 side. It also has Server Received (SR) and Server Sent (SS) annotations
+on the service2 side. Physically there are 2 spans but they form 1 logical span related to an RPC call.
2 span C labels signify span started and closed. Upon closing a single span is sent to Zipkin.
+2 spans come from the RPC call from service2 to service3 to the http:/bar endpoint. It has the Client Sent (CS)
+and Client Received (CR) annotations on service2 side. It also has Server Received (SR) and Server Sent (SS) annotations
+on the service3 side. Physically there are 2 spans but they form 1 logical span related to an RPC call.
4 span B labels are in fact are single span with 4 annotations. However this span is composed of -two separate instances. One sent from service 2 and one from service 3. So in fact two span instances will be sent -to Zipkin and merged there.
-2 span E labels signify span started and closed. Upon closing a single span is sent to Zipkin.
-4 span B labels are in fact are single span with 4 annotations. However this span is composed of -two separate instances. One sent from service 2 and one from service 4. So in fact two span instances will be sent -to Zipkin and merged there.
-2 span G labels signify span started and closed. Upon closing a single span is sent to Zipkin.
+2 spans come from the RPC call from service2 to service4 to the http:/baz endpoint. It has the Client Sent (CS)
+and Client Received (CR) annotations on service2 side. It also has Server Received (SR) and Server Sent (SS) annotations
+on the service4 side. Physically there are 2 spans but they form 1 logical span related to an RPC call.
So 1 span from A, 2 spans from B, 1 span from C, 2 spans from D, 1 span from E, 2 spans from F and 1 from G. -Altogether 10 spans.
+So if we count the physical spans we have 1 from http:/start, 2 from service1 calling service2, 2 form service2
+calling service3 and 2 from service2 calling service4. Altogether 7 spans.
Logically we see the information of Total Spans: 4 because we have 1 span related to the incoming request
+to service1 and 3 spans related to RPC calls.
Zipkin allows you to visualize errors in your trace. When an exception was thrown and wasn’t caught then we’re +setting proper tags on the span which Zipkin can properly colorize. You could see in the list of traces one + trace that was in red color. That’s because there was an exception thrown.
+If you click that trace then you’ll see a similar picture
Then if you click on one of the spans you’ll see the following
+
+As you can see you can easily see the reason for an error and the whole stacktrace related to it.
+
+
+
groupId:artifactId:versionLogback setup
Below you can find an example of a Logback configuration (file named logback-spring.xml) that:
Below you can find an example of a Logback configuration (file named logback-spring.xml) that:
Marcin Grzejszczak talking about Spring Cloud Sleuth and Zipkin
+PercentageBasedSampler is the default if you are using
spring-cloud-sleuth-zipkin or spring-cloud-sleuth-stream. You can
-configure the exports using spring.sleuth.sampler.percentage.
+configure the exports using spring.sleuth.sampler.percentage. The passed
+value needs to be a double from 0.0 to 1.0 so it’s not a percentage.
+For backwards compatibility reasons we’re not changing the property name.
For HTTP these are the beans responsible for creation of a Span from a HttpServletRequest
- and filling in the HttpServletResponse with tracing information.
For HTTP these are the beans responsible for creation of a Span from a HttpServletRequest.
@Bean
public SpanExtractor<HttpServletRequest> httpServletRequestSpanExtractor() {
...
-}
-
-@Bean
-public SpanInjector<HttpServletResponse> httpServletResponseSpanInjector() {
- ...
}
The following SpanInjector could be created
And you could register it like this:
+@Bean
+@Primary
+SpanExtractor<HttpServletRequest> customHttpServletRequestSpanExtractor() {
+ return new CustomHttpServletRequestSpanExtractor();
+}
+Spring Cloud Sleuth does not add trace/span related headers to the Http Response for security reasons. If you need the headers then a custom SpanInjector
+that injects the headers into the Http Response and a Servlet filter which makes use of this can be added the following way:
@Bean
-@Primary
-SpanExtractor<HttpServletRequest> customHttpServletRequestSpanExtractor() {
- return new CustomHttpServletRequestSpanExtractor();
+SpanInjector<HttpServletResponse> customHttpServletResponseSpanInjector() {
+ return new CustomHttpServletResponseSpanInjector();
}
@Bean
-@Primary
-SpanInjector<HttpServletResponse> customHttpServletResponseSpanInjector() {
- return new CustomHttpServletResponseSpanInjector();
+HttpResponseInjectingTraceFilter responseInjectingTraceFilter(Tracer tracer) {
+ return new HttpResponseInjectingTraceFilter(tracer, customHttpServletResponseSpanInjector());
}
peer.service tag and the SA t
By default Sleuth assumes that when you send a span to Zipkin, you want the span’s service name
+ to be equal to spring.application.name value. That’s not always the case though. There
+ are situations in which you want to explicitly provide a different service name for all spans coming
+ from your application. To achieve that it’s enough to just pass the following property
+ to your application to override that value (example for foo service name):
spring.zipkin.service.name: foo
+RestTemplate instance with a new keywo
|
+ Important
+ |
+
+A traced version of an AsyncRestTemplate bean is registered for you out of the box. If you
+have your own bean you have to wrap it in a TraceAsyncRestTemplate representation. The best solution
+is to only customize the ClientHttpRequestFactory and / or AsyncClientHttpRequestFactory.
+If you have your own AsyncRestTemplate and you don’t wrap it your calls WILL NOT GET TRACED.
+ |
+
Custom instrumentation is set to create and close Spans upon sending and receiving requests. You can customize the ClientHttpRequestFactory
and the AsyncClientHttpRequestFactory by registering your beans. Remember to use tracing compatible implementations (e.g. don’t forget to
@@ -9664,6 +9814,18 @@ by setting the value of spring.sleuth.scheduled.enabled to fa
spring.sleuth.scheduled.skipPattern with a regular expression that will match the fully qualified name of the
@Scheduled annotated class.
|
+ Tip
+ |
+
+If you are using spring-cloud-sleuth-stream and spring-cloud-netflix-hystrix-stream together, Span will be created for each Hystrix metrics and sent to Zipkin. This may be annoying. You can prevent this by setting spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask
+ |
+
To install, make sure you have Spring Boot CLI -(1.3.5 or better):
+(1.4.1 or better):$ spring version -Spring CLI v1.3.5.RELEASE+Spring CLI v1.4.1.RELEASE
$ sdk install springboot 1.3.5.RELEASE
-$ sdk use springboot 1.3.5.RELEASE
+$ sdk install springboot 1.4.1.RELEASE
+$ sdk use springboot 1.4.1.RELEASE
and install the Spring Cloud plugins (they are independent, so you can install one or the other or both):
+and install the Spring Cloud plugin
$ mvn install
-$ spring install org.springframework.cloud:spring-cloud-cli:1.2.0.BUILD-SNAPSHOT
-$ spring install org.springframework.cloud.launcher:spring-cloud-launcher-cli:1.2.0.BUILD-SNAPSHOT
+$ spring install org.springframework.cloud:spring-cloud-cli:1.2.3.BUILD-SNAPSHOT
Each of these apps can be configured using a local YAML file with the same name (in the current
-working directory or a subdirectory called "config"). E.g. in configserver.yml you might want to
+working directory or a subdirectory called "config" or in ~/.spring-cloud). E.g. in configserver.yml you might want to
do something like this to locate a local git repository for the backend:
Additional applications can be added to ./config/cloud.yml (not
+./config.yml because that would replace the defaults), e.g. with
spring:
+ cloud:
+ launcher:
+ deployables:
+ source:
+ coordinates: maven://com.example:source:0.0.1-SNAPSHOT
+ port: 7000
+ sink:
+ coordinates: maven://com.example:sink:0.0.1-SNAPSHOT
+ port: 7001
+when you list the apps:
+$ spring cloud --list
+source sink configserver dataflow eureka h2 hystrixdashboard kafka zipkin
+(notice the additional apps at the start of the list).
+|
+ Note
+ |
+
+Spring Boot (1.4.1) does not create an
+OAuth2ProtectedResourceDetails automatically if you are using
+client_credentials tokens. In that case you need to create your own
+ClientCredentialsResourceDetails and configure it with
+@ConfigurationProperties("security.oauth2.client").
+ |
+