service discovery. spring cloud internals

199
Spring Cloud Internals Service Discovery

Upload: aleksandr-tarasov

Post on 15-Apr-2017

849 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Service Discovery. Spring Cloud Internals

Spring Cloud Internals

Service Discovery

Page 2: Service Discovery. Spring Cloud Internals

About meArchitect @

/aatarasoff

/aatarasoff

habrahabr.ru/aatarasoff

developerblog.info2

Page 3: Service Discovery. Spring Cloud Internals

AgendaToday

1. New reality - new problems

2. What service discovery means?

3. Dive into Spring Cloud service discovery pattern implementation

4. Tips and tricks during the session

5. Own experience as a conclusion

3

Page 4: Service Discovery. Spring Cloud Internals

What is the problem?

4

Page 5: Service Discovery. Spring Cloud Internals

Database

ESB (service layer)

Service Service Service Service

Hardware Load Balancer

Alfa-Click 2.0 (JSF/Weblogic)

5

Page 6: Service Discovery. Spring Cloud Internals

Big App

Static resource

Database

Remote EJB

6

Page 7: Service Discovery. Spring Cloud Internals

Simple Binding

Small number of resources

Static host and port binding

Rare reconfiguration

7

Page 8: Service Discovery. Spring Cloud Internals

insert into resources_table values (key, endpoint)

8

Page 9: Service Discovery. Spring Cloud Internals

final Properties props = new Properties();final Context context = new InitialContext(props);

// lookupFoo bean = context.lookup("ejb:myejb//Foo!org.myapp.Foo");bean.call();

9

Page 10: Service Discovery. Spring Cloud Internals

final Properties props = new Properties();final Context context = new InitialContext(props);

// lookupFoo bean = context.lookup("ejb:myejb//Foo!org.myapp.Foo");

//do somethingbean.call();

10

Page 11: Service Discovery. Spring Cloud Internals

Big Frontend App

11

Page 12: Service Discovery. Spring Cloud Internals

Big Frontend App

Small App

Small App

Small App

12

Page 13: Service Discovery. Spring Cloud Internals

Small App

UI

API 1

API 2

13

Page 14: Service Discovery. Spring Cloud Internals

ESB Services

API 1

API 2

API 4

UIMobile

Mongo DB

14

Page 15: Service Discovery. Spring Cloud Internals

API

API instance

API instance

API instance

15

Page 16: Service Discovery. Spring Cloud Internals

Some API

Another APIInstance 1

Another API Instance 2

Another APIInstance 3

?

16

Page 17: Service Discovery. Spring Cloud Internals

- hosts: dc1-rest-apiroles: - { role: api, name: transactions-api, service_port: 9081 } - { role: api, name: cards-api, port: 8081 } - { role: api, name: customers-api, port: 9091 }

dc1-rest-api<ip_address_1><ip_address_2>...

Static Configuration

17

Page 18: Service Discovery. Spring Cloud Internals

{"id": "/retail-online-bank/middle/transactions-api","cpus": 1,"mem": 1024,"instances": 5,"container": {"docker": {"image": "docker/retail-online-bank-transactions-api:1.17.0", "portMappings": [{"containerPort": 8080, "servicePort": 0

}]

}}

}

Dynamic Configuration (PAAS)

18

Page 19: Service Discovery. Spring Cloud Internals

Service Discovery

What instance we can call?

19

Page 20: Service Discovery. Spring Cloud Internals

20

Page 21: Service Discovery. Spring Cloud Internals

Remote API Calls

21

Page 22: Service Discovery. Spring Cloud Internals

Five parallel service calls

22

Page 23: Service Discovery. Spring Cloud Internals

S1 S2 S3 S4 S5

23

Page 24: Service Discovery. Spring Cloud Internals

Client

call

S1 S2 S3 S4 S5

24

Page 25: Service Discovery. Spring Cloud Internals

Client

call

S1 S2 S3 S4 S5

25

Page 26: Service Discovery. Spring Cloud Internals

Five parallel service calls

26

Page 27: Service Discovery. Spring Cloud Internals

p = 0.99

p – the probability of success for one service 27

Page 28: Service Discovery. Spring Cloud Internals

P = p5 = (0.99)5 ≈ 0.95

p – the probability of success for one service 28

Page 29: Service Discovery. Spring Cloud Internals

Service Discovery

What instance we can call?

What instance is better for call?

29

Page 30: Service Discovery. Spring Cloud Internals

Service Discovery

What instance we can call?

What instance is better for call?

How we can increase probability of success for one call?

30

Page 31: Service Discovery. Spring Cloud Internals

S1 S2 S3 S4 S5

31

Page 32: Service Discovery. Spring Cloud Internals

STATES1 S2 S3 S4 S5

S1 S2 S3 S4 S5

32

Page 33: Service Discovery. Spring Cloud Internals

STATEFILTER

S1 S2 S3

S1 S2 S3 S4 S5

S1 S2 S3 S4 S5

33

Page 34: Service Discovery. Spring Cloud Internals

STATEFILTER

S2 S4

Other DC

S1 S2 S3 S4 S5

S1 S2 S3 S4 S5

34

Page 35: Service Discovery. Spring Cloud Internals

STATEFILTER

S2 S4

Other DC

S1 S2 S3 S4 S5

S1 S2 S3 S4 S5

?

35

Page 36: Service Discovery. Spring Cloud Internals

Service Service Service Service Service

STATEFILTER

S2 S4

RULES2

S1 S2 S3 S4 S5

S1 S2 S3 S4 S5

36

Page 37: Service Discovery. Spring Cloud Internals

Service Service Service Service Service

STATEFILTER

S2 S4

RULES2

Client

S1 S2 S3 S4 S5

call

S1 S2 S3 S4 S5

37

Page 38: Service Discovery. Spring Cloud Internals

Client-Side Service Discovery

38

Page 39: Service Discovery. Spring Cloud Internals

Server-Side Service Discovery

39

Page 40: Service Discovery. Spring Cloud Internals

Server-Side Client-Side

VS

Dummy client

Language/Library tolerance

Single Responsibility Principle

More complex and smart decision implementation

Avoid point of failure

Flexibility

Hard to implement something complex and smart

One more point of failure

Very good implementation is required

Lock on libraries

Hard to make changes

40

Page 41: Service Discovery. Spring Cloud Internals

Spring Cloud

Tools for building common patterns in distributed systems

Part of Spring Boot

Implements Client-Side Service Discovery Pattern

41

Page 42: Service Discovery. Spring Cloud Internals

Rollback

42

Page 43: Service Discovery. Spring Cloud Internals

S1 S2 S3 S4 S5?

How we get them all?

43

Page 44: Service Discovery. Spring Cloud Internals

Service Registry?

Database

Properties File

Environment Variables

44

Page 45: Service Discovery. Spring Cloud Internals

Service Registry?

Database

Properties File

Environment Variables

45

Page 46: Service Discovery. Spring Cloud Internals

Service Registry

Netflix Eureka

Consul

etcd

Zookeeper

46

Page 47: Service Discovery. Spring Cloud Internals

Leader

Master Master

Leader-Election

Quorum (n + 1)/2

Distributed Locks

47

Page 48: Service Discovery. Spring Cloud Internals

Peer

Peer Peer

Eureka is not the same

48

Page 49: Service Discovery. Spring Cloud Internals

Client/Slave

Leader

Master Master

Client/Slave Client/Slave

horizontal scaling

49

Page 50: Service Discovery. Spring Cloud Internals

Service A

Leader

Master Master

Service B Service C

register

50

Page 51: Service Discovery. Spring Cloud Internals

Service A

Leader

Master Master

Service B Service C

health check

51

Page 52: Service Discovery. Spring Cloud Internals

Service A

Leader

Master Master

Service B Service C

heartbeat

52

Page 53: Service Discovery. Spring Cloud Internals

Service A

Leader

Master Master

Service B Service C

health check

53

Page 54: Service Discovery. Spring Cloud Internals

Service A

Leader

Master Master

Service B Service C

health check

54

Page 55: Service Discovery. Spring Cloud Internals

Service A

Leader

Master Master

Service B Service C

deregister

55

Page 56: Service Discovery. Spring Cloud Internals

Service A

Leader

Master Master

Service B Service C

deregister

graceful shutdown

56

Page 57: Service Discovery. Spring Cloud Internals

Spring Cloud Core

Eureka Consul Marathon

57

Page 58: Service Discovery. Spring Cloud Internals

Spring Cloud Core

Eureka Consul Marathon

Reference/Native implementation

Most complex load balancing

58

Page 59: Service Discovery. Spring Cloud Internals

Spring Cloud Core

Eureka Consul Marathon

Out of the box PaaS

59

Page 60: Service Discovery. Spring Cloud Internals

60

Page 61: Service Discovery. Spring Cloud Internals

61

{"host": "server1", "ports": [20688

], "ipAddresses": [{"ipAddress": "172.17.0.21","protocol": "IPv4"

}],"appId": "/retail-online-bank/middle/a2a-transactions-api","healthCheckResults": [{"alive": true

}]

}

Page 62: Service Discovery. Spring Cloud Internals

Spring Cloud Core

Eureka Consul Marathon

Out of the box PaaS

One tool for deployment and configuration storage

Own library

62

Page 63: Service Discovery. Spring Cloud Internals

DeepDive

1. Discovery

63

Page 64: Service Discovery. Spring Cloud Internals

[email protected] class Application {@Autowiredprivate DiscoveryClient discoveryClient;

public List<String> services() {return discoveryClient.getServices();

}}

64

Page 65: Service Discovery. Spring Cloud Internals

[email protected] class Application {@Autowiredprivate DiscoveryClient discoveryClient;

public List<String> services() {return discoveryClient.getServices();

}}

65

Page 66: Service Discovery. Spring Cloud Internals

public interface DiscoveryClient {

public ServiceInstance getLocalServiceInstance();

public List<ServiceInstance> getInstances(String serviceId);

public List<String> getServices();

}

66

Page 67: Service Discovery. Spring Cloud Internals

public interface DiscoveryClient {

public ServiceInstance getLocalServiceInstance();

public List<ServiceInstance> getInstances(String serviceId);

public List<String> getServices();

}

67

Page 68: Service Discovery. Spring Cloud Internals

public interface DiscoveryClient {

public ServiceInstance getLocalServiceInstance();

public List<ServiceInstance> getInstances(String serviceId);

public List<String> getServices();

}

68

Page 69: Service Discovery. Spring Cloud Internals

Eureka Implementation

69

Page 70: Service Discovery. Spring Cloud Internals

Eureka Cluster (Zone 1)

appname: app1virtualHostName: app

eureka:client:serviceUrl:defaultZone: ${ZONE1_EUREKA_URL}

Eureka Cluster (Zone 2)

appname: app2virtualHostName: app

serviceId -> virtualHostName

70

Page 71: Service Discovery. Spring Cloud Internals

Eureka Cluster (Zone 1)

appname: app1virtualHostName: app

eureka:client:serviceUrl:defaultZone: ${ZONE1_EUREKA_URL}zone2: ${ZONE2_EUREKA_URL}availabilityZones: zone1,zone2

Eureka Cluster (Zone 2)

appname: app2virtualHostName: app

71

Page 72: Service Discovery. Spring Cloud Internals

EurekaClientEurekaDiscoveryClient

serviceId

72

Page 73: Service Discovery. Spring Cloud Internals

virtualHostName

Applications

EurekaClientEurekaDiscoveryClient

serviceId

73

Page 74: Service Discovery. Spring Cloud Internals

Eureka Cluster (Zone 1)

appname: app1virtualHostName: app

virtualHostName

Applications

EurekaClient

fetch

EurekaDiscoveryClient

serviceId

eureka:client:registryFetchIntervalSeconds: 5 (30)

74

Page 75: Service Discovery. Spring Cloud Internals

Eureka Cluster (Zone 1)

appname: app1virtualHostName: app

virtualHostName

Applications

EurekaClient

fetch and filter

EurekaDiscoveryClient

serviceId

eureka:client:registryFetchIntervalSeconds: 5 (30)filterOnlyUpInstances: true (true)

75

Page 76: Service Discovery. Spring Cloud Internals

Marathon Implementation

76

Page 77: Service Discovery. Spring Cloud Internals

Mesos Cluster (DC 1)

taskId: {random}appId: app1

spring:cloud:marathon:host: ${MARATHON_HOST}port: ${MARATHON_PORT}

Mesos Cluster (DC 2)

taskId: {random}appId: app1

serviceId -> appId

77

Page 78: Service Discovery. Spring Cloud Internals

Mesos Cluster (DC 1)

taskId: {random}appId: app1

spring:cloud:marathon:host: ${MARATHON_HOST}port: ${MARATHON_PORT}

Mesos Cluster (DC 2)

taskId: {random}appId: app1

serviceId -> appId

<- - - - there is no failover to another dc

78

Page 79: Service Discovery. Spring Cloud Internals

Mesos Cluster (DC 1)

taskId: {random}appId: app1

task = instance

MarathonClient

fetch tasks for apps

MarathonDiscoveryClient

serviceId

spring:cloud:marathon:<no app cache><no property> only healthy tasks

79

Page 80: Service Discovery. Spring Cloud Internals

Is it success?

80

Page 81: Service Discovery. Spring Cloud Internals

@Autowiredprivate LoadBalancerClient loadBalancer;

@RequestMapping("/instance")public ServiceInstance instance() {

return loadBalancer.choose(serviceId);}

81

Page 82: Service Discovery. Spring Cloud Internals

@Autowiredprivate LoadBalancerClient loadBalancer;

@RequestMapping("/instance")public ServiceInstance instance() {

return loadBalancer.choose(serviceId);}

?

82

Page 83: Service Discovery. Spring Cloud Internals

@Autowiredprivate LoadBalancerClient loadBalancer;

@RequestMapping("/instance")public ServiceInstance instance() {

return loadBalancer.choose(serviceId);}

83

1. ServiceInstance 2. null 3. Error

Page 84: Service Discovery. Spring Cloud Internals

@Autowiredprivate LoadBalancerClient loadBalancer;

@RequestMapping("/instance")public ServiceInstance instance() {

return loadBalancer.choose(serviceId);}

84

1. ServiceInstance 2. null 3. Error

Page 85: Service Discovery. Spring Cloud Internals

Where it isused?

Hypermedia Links

Dynamic Routes for Edge Server

DiscoveryClient health check in actuator is based on it

Less than you expect, right?

85

Page 86: Service Discovery. Spring Cloud Internals

DeepDive

1. Discovery

2. Balance it

86

Page 87: Service Discovery. Spring Cloud Internals

Load BalancerClient

Based on Netflix Ribbon

Ribbon may be used with or without service registry

87

Page 88: Service Discovery. Spring Cloud Internals

Service Service Service Service Service

STATEFILTER

S2 S4

RULES2

Client

S1 S2 S3 S4 S5

call

S1 S2 S3 S4 S5

88

Page 89: Service Discovery. Spring Cloud Internals

Service Service Service Service Service

FILTERS2 S4

RULES2

Client

S1 S2 S3 S4 S5

call

S1 S2 S3 S4 S5

Server List

89

Page 90: Service Discovery. Spring Cloud Internals

Service Service Service Service Service

S2 S4

RULES2

Client

S1 S2 S3 S4 S5

call

S1 S2 S3 S4 S5

Server List

Filter Chain

90

Page 91: Service Discovery. Spring Cloud Internals

Service Service Service Service Service

S2 S4

S2

LoadBalancerClient

S1 S2 S3 S4 S5

call

S1 S2 S3 S4 S5

Server List

Filter Chain

Rule

91

Page 92: Service Discovery. Spring Cloud Internals

RibbonServer List

Static

Configuration Based

Discovery Based

92

Page 93: Service Discovery. Spring Cloud Internals

Spring CloudRibbon Configure

Bean Lifecycle

Spring native configuration

93

Page 94: Service Discovery. Spring Cloud Internals

test-service: #service nameribbon: #namespace

listOfServers: host:8080,anotherHost:8081

ConfigurationBasedServerList

94

Page 95: Service Discovery. Spring Cloud Internals

test-service: #service nameribbon: #namespace

listOfServers: host:8080,anotherHost:8081

public List<Server> getListOfServers() {return derive(

clientConfig.get(CommonClientConfigKey.ListOfServers));

}

ConfigurationBasedServerList

95

Page 96: Service Discovery. Spring Cloud Internals

@Autowiredprivate LoadBalancerClient loadBalancer;

@RequestMapping("/url")public String realUrl() throws IOException {

return loadBalancer.reconstructURI(instance, new URI("http://"+ serviceId +"/me")

).toString();}

it will be replaced with real host and port

96

Page 97: Service Discovery. Spring Cloud Internals

@Autowiredprivate LoadBalancerClient loadBalancer;

@RequestMapping("/url")public String realUrl() throws IOException {

return loadBalancer.reconstructURI(instance, new URI("http://"+ serviceId +"/me")

).toString();}

> curl service:8080/urlhttp://host:8080/me

97

Page 98: Service Discovery. Spring Cloud Internals

@Autowiredprivate LoadBalancerClient loadBalancer;

@RequestMapping("/url")public String realUrl() throws IOException {

return loadBalancer.reconstructURI(instance, new URI("http://"+ serviceId +"/me")

).toString();}

> curl service:8080/urlhttp://anotherHost:8080/me

98

Page 99: Service Discovery. Spring Cloud Internals

Copy-pastImplementation

99

Same as DiscoveryClient

Page 100: Service Discovery. Spring Cloud Internals

Is our instance alive?

100

Page 101: Service Discovery. Spring Cloud Internals

S1 S2 S3 S4 S5

S2 S4

S2

LoadBalancerClient

call

S1 S2 S3 S4 S5?

101

Server List

Filter Chain

Rule

Page 102: Service Discovery. Spring Cloud Internals

t t + 1

S1

S2

S3

102

Page 103: Service Discovery. Spring Cloud Internals

t t + 1

S1

S2

S3

ServerList

S1

S2

S3

103

Page 104: Service Discovery. Spring Cloud Internals

t t + 1

S1

S2

S3

ServerList

S1S1

S2

S3

104

Page 105: Service Discovery. Spring Cloud Internals

t t + 1

S1

S2

S3

ServerList

S1 S1S1

S2

S3

105

Page 106: Service Discovery. Spring Cloud Internals

t t + 1

S1

S2

S3

ServerList

S1 S1

t + 2

S1

S2

S3

106

Page 107: Service Discovery. Spring Cloud Internals

S1 S2 S3 S4 S5

S2 S4

S2

LoadBalancerClient

call

S1 S2 S3 S4 S5Ping ->

107

Server List

Filter Chain

Rule

Page 108: Service Discovery. Spring Cloud Internals

Pinger (background thread)

LoadBalancer

background task

force if setServerList() is called

108

Page 109: Service Discovery. Spring Cloud Internals

Pinger (background thread)

LoadBalancer

background task

force if setServerList() is called

IPingStrategy

pingServers

109

Page 110: Service Discovery. Spring Cloud Internals

Pinger (background thread)

LoadBalancer

background task

force if setServerList() is called

IPingStrategy

pingServers

isAlive(server)

IPing

110

Page 111: Service Discovery. Spring Cloud Internals

IPingStrategy SerialPingStrategy

int numCandidates = servers.length;boolean[] results = new boolean[numCandidates];

for (int i = 0; i < numCandidates; i++) {results[i] = false; /* Default answer is DEAD. */if (ping != null) {

results[i] = ping.isAlive(servers[i]);}

}return results;

And what if ping will take a long time?111

Page 112: Service Discovery. Spring Cloud Internals

NIWSDiscoveryPing(Eureka)

IPing

instance.status.equals(InstanceStatus.UP

)

ConsulPing(Consul)

MarathonPing(Marathon)

server.isPassingChecks()

server.isPassingChecks()

All are fake pings112

Page 113: Service Discovery. Spring Cloud Internals

public class MarathonPing implements IPing {@Overridepublic boolean isAlive(Server server) {

return server.isHealthChecksPassing();}

}

113

Page 114: Service Discovery. Spring Cloud Internals

public class MarathonPing implements IPing {@Overridepublic boolean isAlive(Server server) {

return server.isHealthChecksPassing();}

}

public class MarathonServer extends Server {public boolean isHealthChecksPassing() {return healthChecks.parallelStream()

.allMatch(HealthCheckResult::isAlive);}

}

114

Page 115: Service Discovery. Spring Cloud Internals

IPingStrategy ?

You may implement your own strategy at your own risk

IPing PingUrl

public boolean isAlive(Server server) {URL url = constructUrl(server);HttpResponse response = httpClient.execute(createReq(url));return response.getStatusLine().getStatusCode() == 200;

}

115

Page 116: Service Discovery. Spring Cloud Internals

Reduce fetch interval

116

Page 117: Service Discovery. Spring Cloud Internals

S1 S2 S3 S4 S5

S2 S4

S2

LoadBalancerClient

call

S1 S2 S3 S4 S5

Server List

Filter Chain ->

Rule

117

Page 118: Service Discovery. Spring Cloud Internals

Eureka Cluster (Zone 1)

S1

S2

S3

Eureka Cluster (Zone 2)

S4

S5

S6

Client(Zone 1)

118

Page 119: Service Discovery. Spring Cloud Internals

Eureka Cluster (Zone 1)

S1

S2

S3

Eureka Cluster (Zone 2)

S4

S5

S6

Client(Zone 1)

cheap call

119

Page 120: Service Discovery. Spring Cloud Internals

Eureka Cluster (Zone 1)

S1

S2

S3

Eureka Cluster (Zone 2)

S4

S5

S6

Client(Zone 1)

expensive call

120

Page 121: Service Discovery. Spring Cloud Internals

Eureka Cluster (Zone 1)

S2

S3

Eureka Cluster (Zone 2)

S4

S5

S6

Client(Zone 1)

unpredictable

S1

121

Page 122: Service Discovery. Spring Cloud Internals

Eureka Cluster (Zone 1)

S1

S2

S3

Eureka Cluster (Zone 2)

S4

S5

S6

Client(Zone 1)

more guaranteed result

122

Page 123: Service Discovery. Spring Cloud Internals

FilterZonePreferenceFilter

List servers = super.getFilteredServers();List local = servers.filter(server ->

server.zone == zoneFromConfig);

if (!local.isEmpty()) {return local;

}return servers;

super.getFilteredServers()

DynamicServerListLoadBalancer

default (local) zone

123

Page 124: Service Discovery. Spring Cloud Internals

ZoneAffinityFilterZonePreferenceFilter

super.getFilteredServers(servers)

LoadBalancerStats

getZoneSnaphot(servers)

124

Page 125: Service Discovery. Spring Cloud Internals

S1 S2 S3 S4 S5

S2 S4

S2

LoadBalancerClient

call

S1 S2 S3 S4 S5LB Stats ->

Server List

Filter Chain

Rule

125

Page 126: Service Discovery. Spring Cloud Internals

S1 S2 S3 S4 S5

S2 S4

S2

LoadBalancerClient

call

S1 S2 S3 S4 S5LB Stats ->

Server Stats

Server List

Filter Chain

Rule

126

Page 127: Service Discovery. Spring Cloud Internals

S1

S2

S3

Zone Snapshot

Server Stats

127

Page 128: Service Discovery. Spring Cloud Internals

S1

S2

S3

Zone Snapshot

activeConnections

activeServers

circuitBreakerTrippedCount

128

Page 129: Service Discovery. Spring Cloud Internals

ZoneAffinityFilterZonePreferenceFilter

super.getFilteredServers(servers)

LoadBalancerStats

enableZoneAffinity?

zoneAffinity:maxLoadPerServer: 0.6maxBlackOutServersPercentage: 0.8minAvailableServers: 2

129

Page 130: Service Discovery. Spring Cloud Internals

ZoneAffinityFilterZonePreferenceFilter

super.getFilteredServers(servers)

ZoneAffinityPredicate

filter out instancesfrom other zones

130

zoneAffinity:maxLoadPerServer: 0.6maxBlackOutServersPercentage: 0.8minAvailableServers: 2

Page 131: Service Discovery. Spring Cloud Internals

Eureka Cluster (Zone 1)

S1

S2

S3

Eureka Cluster (Zone 2)

S4

S5

S6

Client(Zone 1)

cheap call

131

Page 132: Service Discovery. Spring Cloud Internals

ZoneAffinityFilterZonePreferenceFilter

super.getFilteredServers(servers)

ZoneAffinityPredicate

no filter

132

zoneAffinity:maxLoadPerServer: 0.6maxBlackOutServersPercentage: 0.8minAvailableServers: 2

Page 133: Service Discovery. Spring Cloud Internals

Eureka Cluster (Zone 1)

S1

Eureka Cluster (Zone 2)

S4

S5

S6

Client(Zone 1)

133

S2

S3

Page 134: Service Discovery. Spring Cloud Internals

Use Eureka. Use zones

134

Page 135: Service Discovery. Spring Cloud Internals

Define your rules

135

Page 136: Service Discovery. Spring Cloud Internals

S1 S2 S3 S4 S5

S2 S4

S2

LoadBalancerClient

call

S1 S2 S3 S4 S5

?

136

Server List

Filter Chain

Rule

Page 137: Service Discovery. Spring Cloud Internals

IRule

RoundRobin

ZoneAvoidance

default

Weighted Random

BestAvailability AvailabilityFilter

137

Page 138: Service Discovery. Spring Cloud Internals

IRule

RoundRobin

ZoneAvoidance

Weighted Random

BestAvailability AvailabilityFiltering

138

Page 139: Service Discovery. Spring Cloud Internals

upstream test-marathon-app {server host1 weight=3;server host2 weight=1;server host3 weight=1;

}

Weighted typically is predefined

139

Page 140: Service Discovery. Spring Cloud Internals

Weight Task (background thread)

Weighted Rule

background task

LoadBalancerStats

calculate

serverWeight = summ(avgServerResponseTime)- avgServerResponseTime

140

Page 141: Service Discovery. Spring Cloud Internals

Weight Task (background thread)

Weighted Rule

background task

LoadBalancerStats

calculate

serverWeight = summ(avgServerResponseTime)- avgServerResponseTime

141

More response time -> less weight

Page 142: Service Discovery. Spring Cloud Internals

142

Slow Instance Fast Instance

100 ms 10 ms

Page 143: Service Discovery. Spring Cloud Internals

143

Slow Instance Fast Instance

100 ms 10 ms5 000 requests

Page 144: Service Discovery. Spring Cloud Internals

144

Slow Instance Fast Instance

100 ms 10 ms5 000 requests

Round Robin RuleSlow: 2500 and Fast: 2500Average time: 70

Page 145: Service Discovery. Spring Cloud Internals

145

Slow Instance Fast Instance

100 ms 10 ms5 000 requests

Round Robin RuleSlow: 2500 and Fast: 2500Average time: 70

Page 146: Service Discovery. Spring Cloud Internals

146

Slow Instance Fast Instance

100 ms 10 ms5 000 requests

Round Robin RuleSlow: 2500 and Fast: 2500Average time: 70

Weighted RuleSlow: 634 and Fast: 4366Average time: 27

Page 147: Service Discovery. Spring Cloud Internals

147

Slow Instance Fast Instance

100 ms 10 ms1 000 requests

Round Robin RuleSlow: 500 and Fast: 500Average time: 70

Weighted Rule??

Page 148: Service Discovery. Spring Cloud Internals

148

Slow Instance Fast Instance

100 ms 10 ms1 000 requests

Round Robin RuleSlow: 500 and Fast: 500Average time: 70

Weighted RuleSlow: 500 and Fast: 500Average time: 72

Page 149: Service Discovery. Spring Cloud Internals

149

Slow Instance Fast Instance

100 ms 10 ms1 000 requests

Round Robin RuleSlow: 500 and Fast: 500Average time: 70

Weighted RuleSlow: 500 and Fast: 500Average time: 72

Page 150: Service Discovery. Spring Cloud Internals

test-service: #service nameribbon: #namespace

ServerWeightTaskTimerInterval: 30000 #ms

Let’s explain

150

Page 151: Service Discovery. Spring Cloud Internals

test-service: #service nameribbon: #namespace

ServerWeightTaskTimerInterval: 30000 #ms

Weigths [0.0, 0.0]

Let’s explain

151

Page 152: Service Discovery. Spring Cloud Internals

test-service: #service nameribbon: #namespace

ServerWeightTaskTimerInterval: 1000 #ms

Let’s explain

152

Page 153: Service Discovery. Spring Cloud Internals

test-service: #service nameribbon: #namespace

ServerWeightTaskTimerInterval: 1000 #ms

Weigths [12.285123016785462, 120.30885719400065]

Let’s explain

153

Page 154: Service Discovery. Spring Cloud Internals

IRule

RoundRobin

ZoneAvoidance

Weighted Random

BestAvailability AvailabilityFiltering

154

Page 155: Service Discovery. Spring Cloud Internals

Best Available Rule LoadBalancerStats

calculate

chosen -> activeConnections == min(activeConnections)

155

Page 156: Service Discovery. Spring Cloud Internals

Best Available Rule LoadBalancerStats

calculate

chosen -> activeConnections == min(activeConnections)

156

Less active connections -> more chance to success

Page 157: Service Discovery. Spring Cloud Internals

157

Slow Instance Fast Instance

100 ms 10 ms1 000 requests

Round Robin RuleSlow: 500 and Fast: 500Average time: 70

Weighted RuleSlow: 500 and Fast: 500Average time: 72

Best Available RuleSlow: 152 and Fast: 847 Average time: 38

Page 158: Service Discovery. Spring Cloud Internals

Don’t use round robin rule

158

Page 159: Service Discovery. Spring Cloud Internals

IRule

RoundRobin

ZoneAvoidance

Weighted Random

BestAvailability AvailabilityFiltering

159

Page 160: Service Discovery. Spring Cloud Internals

Availability Filtering Rule

LoadBalancerStats

calculate

filtered -> activeConnections < maxActiveConnections

filtered -> !isCircuitBreakerTripped

Availability Predicatefilter

160

Like a round robin

Page 161: Service Discovery. Spring Cloud Internals

IRule

RoundRobin

ZoneAvoidance

Weighted Random

BestAvailability AvailabilityFiltering

161

Page 162: Service Discovery. Spring Cloud Internals

Zone Avoidance Rule Composite Predicatefilter

Zone Predicate Availability Predicate

162

Page 163: Service Discovery. Spring Cloud Internals

Zone Avoidance Rule Composite Predicatefilter

Zone Predicate Availability Predicate

CompositePredicateBuilderint minimalFilteredServers = 1float minimalFilteredPercentage = 0

predicate.filter(servers)

163

Page 164: Service Discovery. Spring Cloud Internals

Zone Avoidance Rule Composite Predicatefilter

Zone Predicate Availability Predicate

CompositePredicateBuilderint minimalFilteredServers = 1float minimalFilteredPercentage = 0

int count = predicate.filter(servers).size() //2

164

Page 165: Service Discovery. Spring Cloud Internals

Zone Avoidance Rule Composite Predicatefilter

Zone Predicate Availability Predicate

CompositePredicateBuilderint minimalFilteredServers = 1float minimalFilteredPercentage = 0

int count = predicate.filter(servers).size() //2

count >= minimalFilteredServerscount >= minimalFilteredPercentage * count

165

Page 166: Service Discovery. Spring Cloud Internals

Zone Avoidance Rule Composite Predicatefilter

Zone Predicate Availability Predicate

CompositePredicateBuilderint minimalFilteredServers = 1float minimalFilteredPercentage = 0

int count = predicate.filter(servers).size() //0

count >= minimalFilteredServerscount >= minimalFilteredPercentage * count

166

Page 167: Service Discovery. Spring Cloud Internals

Zone Avoidance Rule Composite Predicatefilter

Zone Predicate Availability Predicate

next

167

Page 168: Service Discovery. Spring Cloud Internals

triggeringLoadPerServerThreshold: 0.2avoidZoneWithBlackoutPercetage: 0.99999d

worstZone -> loadPerServer > max(loadPerServer) &&loadPerServer > triggeringLoadPerServerThreshold

zones.remove(worstZone)

Zone Avoidance Rule Composite Predicatefilter

Zone Predicate Availability Predicate

168

Page 169: Service Discovery. Spring Cloud Internals

triggeringLoadPerServerThreshold: 0.2avoidZoneWithBlackoutPercetage: 0.99999d

zoneToAvoid -> circuitBreakerTrippedCount / instanceCount >= avoidZoneWithBlackoutPercetage

zones.remove(zoneToAvoid)

Zone Avoidance Rule Composite Predicatefilter

Zone Predicate Availability Predicate

169

Page 170: Service Discovery. Spring Cloud Internals

IRule

RoundRobin

ZoneAvoidance

Weighted Random

BestAvailability AvailabilityFiltering

170

Page 171: Service Discovery. Spring Cloud Internals

If you don’t use zones then don’t use default rule

171

Page 172: Service Discovery. Spring Cloud Internals

DeepDive

1. Discovery

2. Balance it

3. Lifecycle

172

Page 173: Service Discovery. Spring Cloud Internals

Service Service Service Service Service

S2 S4

S2

LoadBalancerClient

S1 S2 S3 S4 S5

S1 S2 S3 S4 S5

New Service

register/deregister

173

Page 174: Service Discovery. Spring Cloud Internals

How todo it?

3rd party registration pattern- dynamic- static

Self-registration pattern (Lifecycle)

174

Page 175: Service Discovery. Spring Cloud Internals

Docker Engine

175

Page 176: Service Discovery. Spring Cloud Internals

Docker Engine

Service

register/deregister

176

Page 177: Service Discovery. Spring Cloud Internals

Docker Engine

Service

register/deregister

177

Registrator

emit event

Page 178: Service Discovery. Spring Cloud Internals

Docker Engine

Service

register/deregister

178

Registrator

emit event

Service Registry

native event

Page 179: Service Discovery. Spring Cloud Internals

What islifecycle?

Allow automatically register and deregister service in service registry

Implements Spring Lifecycle interface

179

Page 180: Service Discovery. Spring Cloud Internals

SmartLifecycle

DiscoveryLifecycle EurekaDiscoveryClientConfiguration

ConsulLifecycle

180

Page 181: Service Discovery. Spring Cloud Internals

DiscoveryLifecycle

LifecycleProcessor

autoStartup on refresh

startBeans on start

Service Registry

register

emit InstanceRegisteredEvent

DiscoveryClientHealthIndicator

181

Page 182: Service Discovery. Spring Cloud Internals

DiscoveryLifecycle

LifecycleProcessor

on RefreshScope event

stopBeans on stop

Service Registry

deregister

close or shutdown

Real service discovery client

182

Page 183: Service Discovery. Spring Cloud Internals

Something about docker

183

Page 184: Service Discovery. Spring Cloud Internals

Docker container

Internal IP External IP

184

Page 185: Service Discovery. Spring Cloud Internals

> ifconfig

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280stf0: flags=0<> mtu 1280en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500en1: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500en2: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304awdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500

185

Page 186: Service Discovery. Spring Cloud Internals

> ifconfig

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280stf0: flags=0<> mtu 1280en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500en1: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500en2: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304awdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500

?

186

Page 187: Service Discovery. Spring Cloud Internals

> ifconfig

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280stf0: flags=0<> mtu 1280en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500en1: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500en2: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304awdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500

Low index

187

Page 188: Service Discovery. Spring Cloud Internals

Docker container

Internal IP External IP

188

Page 189: Service Discovery. Spring Cloud Internals

spring:cloud:

consul:discovery:lifecycle:enabled: false

189

Registrator

Page 190: Service Discovery. Spring Cloud Internals

spring:cloud:

inetutils:ignored-interfaces:- vbox*- bridge*- lo*

190

Page 191: Service Discovery. Spring Cloud Internals

spring:cloud:

inetutils:ignored-interfaces:- vbox*- bridge*- lo*

191

Page 192: Service Discovery. Spring Cloud Internals

spring:cloud:

inetutils:ignored-interfaces:- vbox*- bridge*- lo*

consul:discovery:preferIpAddress: true (false)

192

Page 193: Service Discovery. Spring Cloud Internals

Instead of a conclusion

193

Page 194: Service Discovery. Spring Cloud Internals

Ownexperience

194

Page 195: Service Discovery. Spring Cloud Internals

Ownexperience

195

We use both patterns: server and client side

• Consul + Registrator + Nginx

• Marathon + MarathonLB

• Eureka

Page 196: Service Discovery. Spring Cloud Internals

Ownexperience

Use client side pattern for API and Edge server

Use server side for NodeJS front apps and non-standard API (Python)

196

Page 197: Service Discovery. Spring Cloud Internals

Ownexperience

Spring Cloud is production-ready and very customizable

Minimum number of settings are needed to be changed, but for better results there are some of them that should be changed

There are some issues that make you sad

197

Page 198: Service Discovery. Spring Cloud Internals

198

Spring Cloud Marathon (Proof of Concept)https://github.com/aatarasoff/spring-cloud-marathon

Spring Cloudhttp://projects.spring.io/spring-cloud

Service Discovery Patternshttp://microservices.io/patterns/server-side-discovery.htmlhttp://microservices.io/patterns/client-side-discovery.html

Page 199: Service Discovery. Spring Cloud Internals

/aatarasoff

/aatarasoff

habrahabr.ru/aatarasoff

developerblog.info

Questions and Answers

Architect @

199