Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
spring-cloud-netflix
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
openSource
spring-cloud-netflix
Commits
4f6b2bce
Commit
4f6b2bce
authored
Mar 02, 2016
by
Spencer Gibb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Record load balancer stats in RibbonHttpRequest.
fixes gh-731
parent
472b9d17
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
65 additions
and
38 deletions
+65
-38
RibbonAutoConfiguration.java
...amework/cloud/netflix/ribbon/RibbonAutoConfiguration.java
+2
-2
RibbonClientHttpRequestFactory.java
.../cloud/netflix/ribbon/RibbonClientHttpRequestFactory.java
+10
-9
RibbonHttpRequest.java
...ringframework/cloud/netflix/ribbon/RibbonHttpRequest.java
+6
-10
RibbonLoadBalancerClient.java
...mework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java
+9
-17
RibbonStatsRecorder.java
...ngframework/cloud/netflix/ribbon/RibbonStatsRecorder.java
+38
-0
No files found.
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java
View file @
4f6b2bce
...
...
@@ -67,7 +67,7 @@ public class RibbonAutoConfiguration {
@Bean
@ConditionalOnMissingBean
(
LoadBalancerClient
.
class
)
public
LoadBalancerClient
loadBalancerClient
()
{
public
Ribbon
LoadBalancerClient
loadBalancerClient
()
{
return
new
RibbonLoadBalancerClient
(
springClientFactory
());
}
...
...
@@ -80,7 +80,7 @@ public class RibbonAutoConfiguration {
private
SpringClientFactory
springClientFactory
;
@Autowired
private
LoadBalancerClient
loadBalancerClient
;
private
Ribbon
LoadBalancerClient
loadBalancerClient
;
@Bean
public
RestTemplateCustomizer
restTemplateCustomizer
()
{
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactory.java
View file @
4f6b2bce
...
...
@@ -19,8 +19,7 @@ package org.springframework.cloud.netflix.ribbon;
import
java.io.IOException
;
import
java.net.URI
;
import
org.springframework.cloud.client.ServiceInstance
;
import
org.springframework.cloud.client.loadbalancer.LoadBalancerClient
;
import
org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.http.client.ClientHttpRequest
;
import
org.springframework.http.client.ClientHttpRequestFactory
;
...
...
@@ -36,9 +35,9 @@ public class RibbonClientHttpRequestFactory implements ClientHttpRequestFactory
private
final
SpringClientFactory
clientFactory
;
private
LoadBalancerClient
loadBalancer
;
private
Ribbon
LoadBalancerClient
loadBalancer
;
public
RibbonClientHttpRequestFactory
(
SpringClientFactory
clientFactory
,
LoadBalancerClient
loadBalancer
)
{
public
RibbonClientHttpRequestFactory
(
SpringClientFactory
clientFactory
,
Ribbon
LoadBalancerClient
loadBalancer
)
{
this
.
clientFactory
=
clientFactory
;
this
.
loadBalancer
=
loadBalancer
;
}
...
...
@@ -51,17 +50,19 @@ public class RibbonClientHttpRequestFactory implements ClientHttpRequestFactory
if
(
serviceId
==
null
)
{
throw
new
IOException
(
"Invalid hostname in the URI ["
+
originalUri
.
toASCIIString
()
+
"]"
);
}
ServiceInstance
instance
=
loadBalancer
.
choose
(
serviceId
);
RibbonServer
instance
=
loadBalancer
.
chooseRibbonServer
(
serviceId
);
if
(
instance
==
null
)
{
throw
new
IllegalStateException
(
"No instances available for "
+
serviceId
);
}
URI
uri
=
loadBalancer
.
reconstructURI
(
instance
,
originalUri
);
URI
uri
=
this
.
loadBalancer
.
reconstructURI
(
instance
,
originalUri
);
//@formatter:off
IClientConfig
clientConfig
=
clientFactory
.
getClientConfig
(
instance
.
getServiceId
());
RestClient
client
=
clientFactory
.
getClient
(
instance
.
getServiceId
(),
RestClient
.
class
);
IClientConfig
clientConfig
=
this
.
clientFactory
.
getClientConfig
(
instance
.
getServiceId
());
RestClient
client
=
this
.
clientFactory
.
getClient
(
instance
.
getServiceId
(),
RestClient
.
class
);
HttpRequest
.
Verb
verb
=
HttpRequest
.
Verb
.
valueOf
(
httpMethod
.
name
());
RibbonLoadBalancerContext
context
=
this
.
clientFactory
.
getLoadBalancerContext
(
serviceId
);
RibbonStatsRecorder
statsRecorder
=
new
RibbonStatsRecorder
(
context
,
instance
.
getServer
());
//@formatter:on
return
new
RibbonHttpRequest
(
uri
,
verb
,
client
,
clientConfig
);
return
new
RibbonHttpRequest
(
uri
,
verb
,
client
,
clientConfig
,
statsRecorder
);
}
}
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpRequest.java
View file @
4f6b2bce
...
...
@@ -34,6 +34,7 @@ import java.util.List;
/**
* @author Spencer Gibb
*/
@SuppressWarnings
(
"deprecation"
)
public
class
RibbonHttpRequest
extends
AbstractClientHttpRequest
{
private
HttpRequest
.
Builder
builder
;
...
...
@@ -41,14 +42,16 @@ public class RibbonHttpRequest extends AbstractClientHttpRequest {
private
HttpRequest
.
Verb
verb
;
private
RestClient
client
;
private
IClientConfig
config
;
private
RibbonStatsRecorder
statsRecorder
;
private
ByteArrayOutputStream
outputStream
=
null
;
public
RibbonHttpRequest
(
URI
uri
,
HttpRequest
.
Verb
verb
,
RestClient
client
,
IClientConfig
config
)
{
IClientConfig
config
,
RibbonStatsRecorder
statsRecorder
)
{
this
.
uri
=
uri
;
this
.
verb
=
verb
;
this
.
client
=
client
;
this
.
config
=
config
;
this
.
statsRecorder
=
statsRecorder
;
this
.
builder
=
HttpRequest
.
newBuilder
().
uri
(
uri
).
verb
(
verb
);
}
...
...
@@ -71,7 +74,6 @@ public class RibbonHttpRequest extends AbstractClientHttpRequest {
}
@Override
@SuppressWarnings
(
"deprecation"
)
protected
ClientHttpResponse
executeInternal
(
HttpHeaders
headers
)
throws
IOException
{
try
{
...
...
@@ -82,18 +84,12 @@ public class RibbonHttpRequest extends AbstractClientHttpRequest {
}
HttpRequest
request
=
builder
.
build
();
HttpResponse
response
=
client
.
execute
(
request
,
config
);
statsRecorder
.
recordStats
(
response
);
return
new
RibbonHttpResponse
(
response
);
}
catch
(
Exception
e
)
{
statsRecorder
.
recordStats
(
e
);
throw
new
IOException
(
e
);
}
//TODO: fix stats, now that execute is not called
// use execute here so stats are collected
/*return loadBalancer.execute(this.config.getClientName(), new LoadBalancerRequest<ClientHttpResponse>() {
@Override
public ClientHttpResponse apply(ServiceInstance instance) throws Exception {
}
});*/
}
private
void
addHeaders
(
HttpHeaders
headers
)
{
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java
View file @
4f6b2bce
...
...
@@ -19,7 +19,6 @@ package org.springframework.cloud.netflix.ribbon;
import
java.net.URI
;
import
java.util.Collections
;
import
java.util.Map
;
import
java.util.concurrent.TimeUnit
;
import
org.springframework.cloud.client.DefaultServiceInstance
;
import
org.springframework.cloud.client.ServiceInstance
;
...
...
@@ -33,8 +32,6 @@ import com.netflix.client.config.CommonClientConfigKey;
import
com.netflix.client.config.IClientConfig
;
import
com.netflix.loadbalancer.ILoadBalancer
;
import
com.netflix.loadbalancer.Server
;
import
com.netflix.loadbalancer.ServerStats
;
import
com.netflix.servo.monitor.Stopwatch
;
/**
* @author Spencer Gibb
...
...
@@ -65,6 +62,10 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient {
@Override
public
ServiceInstance
choose
(
String
serviceId
)
{
return
this
.
chooseRibbonServer
(
serviceId
);
}
RibbonServer
chooseRibbonServer
(
String
serviceId
)
{
Server
server
=
getServer
(
serviceId
);
if
(
server
==
null
)
{
return
null
;
...
...
@@ -76,23 +77,21 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient {
@Override
public
<
T
>
T
execute
(
String
serviceId
,
LoadBalancerRequest
<
T
>
request
)
{
ILoadBalancer
loadBalancer
=
getLoadBalancer
(
serviceId
);
RibbonLoadBalancerContext
context
=
this
.
clientFactory
.
getLoadBalancerContext
(
serviceId
);
Server
server
=
getServer
(
loadBalancer
);
RibbonServer
ribbonServer
=
new
RibbonServer
(
serviceId
,
server
,
isSecure
(
server
,
serviceId
),
serverIntrospector
(
serviceId
).
getMetadata
(
server
));
ServerStats
serverStats
=
context
.
getServerStats
(
server
);
context
.
noteOpenConnection
(
serverStats
);
Stopwatch
tracer
=
context
.
getExecuteTracer
().
start
(
);
RibbonLoadBalancerContext
context
=
this
.
clientFactory
.
getLoadBalancerContext
(
serviceId
);
RibbonStatsRecorder
statsRecorder
=
new
RibbonStatsRecorder
(
context
,
server
);
try
{
T
returnVal
=
request
.
apply
(
ribbonServer
);
recordStats
(
context
,
tracer
,
serverStats
,
returnVal
,
nul
l
);
statsRecorder
.
recordStats
(
returnVa
l
);
return
returnVal
;
}
catch
(
Exception
ex
)
{
recordStats
(
context
,
tracer
,
serverStats
,
null
,
ex
);
statsRecorder
.
recordStats
(
ex
);
ReflectionUtils
.
rethrowRuntimeException
(
ex
);
}
return
null
;
...
...
@@ -116,13 +115,6 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient {
return
serverIntrospector
(
serviceId
).
isSecure
(
server
);
}
private
void
recordStats
(
RibbonLoadBalancerContext
context
,
Stopwatch
tracer
,
ServerStats
serverStats
,
Object
entity
,
Throwable
exception
)
{
tracer
.
stop
();
long
duration
=
tracer
.
getDuration
(
TimeUnit
.
MILLISECONDS
);
context
.
noteRequestCompletion
(
serverStats
,
entity
,
exception
,
duration
,
null
/* errorHandler */
);
}
protected
Server
getServer
(
String
serviceId
)
{
return
getServer
(
getLoadBalancer
(
serviceId
));
}
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonStatsRecorder.java
0 → 100644
View file @
4f6b2bce
package
org
.
springframework
.
cloud
.
netflix
.
ribbon
;
import
java.util.concurrent.TimeUnit
;
import
com.netflix.loadbalancer.Server
;
import
com.netflix.loadbalancer.ServerStats
;
import
com.netflix.servo.monitor.Stopwatch
;
/**
* @author Spencer Gibb
*/
public
class
RibbonStatsRecorder
{
private
RibbonLoadBalancerContext
context
;
private
final
ServerStats
serverStats
;
private
final
Stopwatch
tracer
;
public
RibbonStatsRecorder
(
RibbonLoadBalancerContext
context
,
Server
server
)
{
this
.
context
=
context
;
serverStats
=
context
.
getServerStats
(
server
);
context
.
noteOpenConnection
(
serverStats
);
tracer
=
context
.
getExecuteTracer
().
start
();
}
public
void
recordStats
(
Object
entity
)
{
this
.
recordStats
(
entity
,
null
);
}
public
void
recordStats
(
Throwable
t
)
{
this
.
recordStats
(
null
,
t
);
}
protected
void
recordStats
(
Object
entity
,
Throwable
exception
)
{
this
.
tracer
.
stop
();
long
duration
=
this
.
tracer
.
getDuration
(
TimeUnit
.
MILLISECONDS
);
this
.
context
.
noteRequestCompletion
(
serverStats
,
entity
,
exception
,
duration
,
null
/* errorHandler */
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment