SlideShare una empresa de Scribd logo
1 de 158
Descargar para leer sin conexión
Где мой сервис,
чувак?
Việt
[вьет]
2
Việt
[вьет]
3
‣ Пишу код больше 10 лет

‣ Начинал как фронтендер

‣ Написал распределенный
компилятор - полюбил бекенд

‣ Больше 6 лет на Java
Việt
[вьет]
4
‣ Пишу код больше 10 лет

‣ Начинал как фронтендер

‣ Написал распределенный
компилятор - полюбил бекенд

‣ Больше 6 лет на Java
Việt
[вьет]
5
‣ Пишу код больше 10 лет

‣ Начинал как фронтендер

‣ Написал распределенный
компилятор - полюбил бекенд

‣ Больше 6 лет на Java
6
7
DevOps
8
Конфиги!
Они везде
@EnableEverything
@FixThis
@FixThat
@DoWhatever
public class App {
// no code - no cry
}
9
:(
О чём доклад?
‣ Обновление микросервисов 

без недоступности

‣ Тулзы
‣ Конфиги

‣ Заклятья
10
О чём доклад?
‣ Обновление микросервисов 

без недоступности

‣ Тулзы 

‣ Конфиги

‣ Заклятья
11
12
Монолит Микросервисы
13
UI UI UI
14
UI UI UI
API
API
API
API
API
API
API
API
API
15
UI UI UI
API
API
API
API
API
API
API
API
API
API
API
API
API
16
UI UI UI
API
API
API
API
API
API
API
API
API
API
API
API
API
DB
DB
DB
17
UI UI UI
API
API
API
API
API
API
API
API
API
API
API
API
API
DB
DB
DB
18
UI UI UI
API
API
API
API
API
API
API
API
API
API
API
API
API
DB
DB
DB
19
UI UI UI
API
API
API
API
API
API
API
API
API
API
API
API
API
DB
DB
DB
А за окном…
‣ Сеть отваливается

‣ Серваки отваливаются

‣ Отвечают с задержкой

‣ Все такое неоднородное

‣ Толпа вредных админов
20
А за окном…
‣ Сеть отваливается

‣ Серваки отваливаются

‣ Отвечают с задержкой

‣ Все такое неоднородное

‣ Толпа вредных админов
21
А за окном…
‣ Сеть отваливается

‣ Серваки отваливаются

‣ Отвечают с задержкой

‣ Все такое неоднородное

‣ Толпа вредных админов
22
А за окном…
‣ Сеть отваливается

‣ Серваки отваливаются

‣ Отвечают с задержкой

‣ Все такое неоднородное

‣ Толпа вредных админов
23
?
?
?
Следствия
‣ В распределенных системах 

отказы - обычное дело

‣ Нужно воспринимать это 

как естественный атрибут системы

‣ Принять и осознанно проектировать систему
24
“Hope 

is not 

a strategy”
25
KISS FTW
27
cards API
transactions
API
:8081
:8080
Client
KISS FTW
28
cards API
transactions
API
:8081
:8080
Client
Где мои деньги?!
KISS FTW
30
cards API
transactions
API
:8081
:8080
Client
Катимся к успеху
‣ In-place update

‣ Proxy

‣ Resource management

‣ Client side LB
31
vegeta
KISS FTW
32
cards API:8081
:8080
ansible
transactions
API
vegeta
$ echo "GET http://localhost” 
| vegeta attack 
| vegeta report
33
vegeta
$ echo "GET http://localhost” 
| vegeta attack 
| vegeta report
34
vegeta
$ echo "GET http://localhost” 
| vegeta attack 
| vegeta report
35
vegeta
$ echo "GET http://localhost” | vegeta attack | vegeta report


Requests [total, rate] 500, 50.10
Duration [total, attack, wait] 9.9s, 9.9s, 8.2ms
Latencies [mean, 50, 95, 99, max] 9.7ms, 7.4ms, …
Bytes In [total, mean] 73260, 146.52
Bytes Out [total, mean] 0, 0.00
Success [ratio] 84.20%
Status Codes [code:count] 500:79 200:421
36
ansible
$ ansible-playbook 
-i inventory 
playbook.yml
37
ansible
$ ansible-playbook 
-i inventory 
playbook.yml
38
ansible
$ ansible-playbook 
-i inventory 
playbook.yml
39
ansible inventory
[frontend]
server1
server2
[backend]
server3
[backend:vars]
timeout = 2s
40
ansible inventory
[frontend]
server1
server2
[backend]
server3
[backend:vars]
timeout = 2s
41
ansible inventory
[frontend]
server1
server2
[backend]
server3
[backend:vars]
timeout = 2s
42
ansible inventory
[frontend]
server1
server2
[backend]
server3
[backend:vars]
timeout = 2s
43
ansible playbook
- hosts: frontend
tasks:
- apt:
name: haproxy
update_cache: yes
- service:
name: haproxy
enabled: yes
state: started
44
ansible playbook
- hosts: frontend
tasks:
- apt:
name: haproxy
update_cache: yes
- service:
name: haproxy
enabled: yes
state: started
45
ansible playbook
- hosts: frontend
tasks:
- apt:
name: haproxy
update_cache: yes
- service:
name: haproxy
enabled: yes
state: started
46
В прод!
Упс
48
t
:(
old
new
Клиенты уходят!
Катимся к успеху
‣ In-place update

‣ Proxy

‣ Resource management

‣ Client side LB
50
Катимся к успеху
‣ In-place update

‣ Proxy

‣ Resource management

‣ Client side LB
51
Proxy has arrived
52
cards API
transactions
API 

oldHAProxy
:8080
:8082
Временная избыточность
53
cards API
transactions
API 

oldHAProxy
transactions
API

new
:8080
:8082
:8083
Временная избыточность
54
cards API
transactions
API 

oldHAProxy
transactions
API

new
:8080
:8082
:8083
Ну норм чо
55
cards API
HAProxy
transactions
API

new
:8080
:8083
HAProxy
56
haproxy -f /my.conf -D -p /my.pid
HAProxy
57
haproxy -f /my.conf -D -p /my.pid
HAProxy
58
haproxy -f /my.conf -D -p /my.pid
Обновляем конфиг HAProxy
59
haproxy -f /my.conf -D -p /my.pid
haproxy -f /my.conf -D -p /my.pid 
-sf $(cat /my.pid)
Обновляем конфиг HAProxy
60
haproxy -f /my.conf -D -p /my.pid
haproxy -f /my.conf -D -p /my.pid 
-sf $(cat /my.pid)
Обновляем конфиг HAProxy
61
haproxy -f /my.conf -D -p /my.pid
haproxy -f /my.conf -D -p /my.pid 
-sf $(cat /my.pid)
finish, please
Обновляем конфиг HAProxy
62
haproxy -f /my.conf -D -p /my.pid
haproxy -f /my.conf -D -p /my.pid 
-sf $(cat /my.pid)
finish, please
OK!
Обновляем конфиг HAProxy
63
haproxy -f /my.conf -D -p /my.pid
haproxy -f /my.conf -D -p /my.pid 
-sf $(cat /my.pid)
finish, please
OK!
Unbind ports
Обновляем конфиг HAProxy
64
haproxy -f /my.conf -D -p /my.pid
haproxy -f /my.conf -D -p /my.pid 
-sf $(cat /my.pid)
finish, please
OK!
Unbind ports
Serve last connections
Обновляем конфиг HAProxy
65
haproxy -f /my.conf -D -p /my.pid 
-sf $(cat /my.pid)
Катай!
Ну почемууу?
67
t
old
new
haproxy
1 2
3 4
Ну почемууу?
68
t
old
new
haproxy
1 2
3 4
Ну почемууу?
69
t
old
new
haproxy
1 2
3 4
Ну почемууу?
70
t
old
new
haproxy
1 2
3 4
Ну почемууу?
71
t
old
new
haproxy
1 2
3 4
Ну почемууу?
72
t
old
new
haproxy
1 2
3 4
Ну почемууу?
73
t
old
new
haproxy
1 2
3 4
Ну почемууу?
74
t
old
new
haproxy
1 2
3 4
Ну почемууу?
75
t
old
new
haproxy
1 2
3 4
Healthcheck идёт на помощь!
@RequestMapping("/health")

public String getHealth() {

return "OK";

}
76
Вжух!
Как получилось
‣ Победили недоступность :)

‣ Приложения потребовали только добавления
healthcheck’ов :)
‣ Не валим приложения на старте :)

‣ Усложнился deployment :(
78
Как получилось
‣ Победили недоступность :)

‣ Приложения потребовали только добавления
healthcheck’ов :)
‣ Не валим приложения на старте :)

‣ Усложнился deployment :(
79
80
cards API transactions API
HAProxy
:8080
:8082
81
cards API transactions API
HAProxy
:8080
:8082
82
UI UI UI
API
API
API
API
API
API
API
API
API
API
API
API
API
DB
DB
DB
Катимся к успеху
‣ In-place update

‣ Proxy

‣ Resource management

‣ Client side LB
83
Катимся к успеху
‣ In-place update

‣ Proxy

‣ Resource management

‣ Client side LB
84
Mesos, Marathon & Co.
85
Host 1
Host 2
Host 5 Host 4
Host 3
Mesos, Marathon & Co.
86
Host 1
Host 2
Host 5
Host 3
Host 4
a
a
a
a
a
a = mesos agent
Mesos, Marathon & Co.
87
Host 1
Host 2
Host 5
Host 3
Host 4
a
mesos

master
a
a
a
a
Mesos, Marathon & Co.
88
Host 1
Host 2
Host 5
Host 3
Host 4
a
mesos

master
a
a
a
a
marathon
Mesos, Marathon & Co.
89
Host 1
Host 2
Host 5
Host 3
Host 4
a
mesos

master
a
a
a
a
marathon
app
manifest
Mesos, Marathon & Co.
90
Host 1
Host 2
Host 5
Host 3
Host 4
a
mesos

master
a
a
a
a
marathon
app
app
app
А HAProxy кто будет настраивать?
91
marathon
marathon-lb
marathon_lb.py
HAProxy
Ставь!
HAProxy socket flags
‣ SO_REUSEADDR - ignore TIME_WAIT

‣ SO_REUSEPORT - bind same IP:PORT
93
94
spring-boot-starter-web
95
<project …>
<artifactId>spring-boot-starter-web</artifactId>
<!-- … -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
</dependencies>
</project>
spring-boot-starter-web
96
<project …>
<artifactId>spring-boot-starter-web</artifactId>
<!-- … -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
</dependencies>
</project>
Tomcat
97
public void bind() throws Exception {
this.serverSock = ServerSocketChannel.open();
this.socketProperties.setProperties(this.serverSock.socket());
InetSocketAddress addr = // …;
this.serverSock.socket().bind(addr, this.getBacklog());
// …
}
Tomcat
98
public void bind() throws Exception {
this.serverSock = ServerSocketChannel.open();
this.socketProperties.setProperties(this.serverSock.socket());
InetSocketAddress addr = // …;
this.serverSock.socket().bind(addr, this.getBacklog());
// …
}
Tomcat
99
public void bind() throws Exception {
this.serverSock = ServerSocketChannel.open();
this.socketProperties.setProperties(this.serverSock.socket());
InetSocketAddress addr = // …;
this.serverSock.socket().bind(addr, this.getBacklog());
// …
}
Tomcat
100
public void bind() throws Exception {
this.serverSock = ServerSocketChannel.open();
this.socketProperties.setProperties(this.serverSock.socket());
InetSocketAddress addr = // …;
this.serverSock.socket().bind(addr, this.getBacklog());
// …
}
Tomcat
101
public void bind() throws Exception {
this.serverSock = ServerSocketChannel.open();
this.socketProperties.setProperties(this.serverSock.socket());
InetSocketAddress addr = // …;
this.serverSock.socket().bind(addr, this.getBacklog());
// …
}
Tomcat
102
public void setProperties(ServerSocket socket) throws SocketException {
if (this.soReuseAddress != null) {
socket.setReuseAddress(this.soReuseAddress.booleanValue());
}
// …
}
Tomcat
103
public void setProperties(ServerSocket socket) throws SocketException {
if (this.soReuseAddress != null) {
socket.setReuseAddress(true);
}
if (this.soReusePort != null) {
socket.setReusePort(true);
}
// …
}
Копай глубже!
linux/net/core/sock_reuseport.c
105
linux/net/core/sock_reuseport.c
106
struct sock *reuseport_select_sock(hash, …)
{
// …
struct sock *sk2 = NULL;
reuse = rcu_dereference(sk->sk_reuseport_cb);
socks = READ_ONCE(reuse->num_socks);
sk2 = reuse->socks[reciprocal_scale(hash, socks)];
// …
return sk2;
}
linux/net/core/sock_reuseport.c
107
struct sock *reuseport_select_sock(hash, …)
{
// …
struct sock *sk2 = NULL;
reuse = rcu_dereference(sk->sk_reuseport_cb);
socks = READ_ONCE(reuse->num_socks);
sk2 = reuse->socks[reciprocal_scale(hash, socks)];
// …
return sk2;
}
linux/net/core/sock_reuseport.c
108
struct sock *reuseport_select_sock(hash, …)
{
// …
struct sock *sk2 = NULL;
reuse = rcu_dereference(sk->sk_reuseport_cb);
socks = READ_ONCE(reuse->num_socks);
sk2 = reuse->socks[reciprocal_scale(hash, socks)];
// …
return sk2;
}
linux/net/core/sock_reuseport.c
109
struct sock *reuseport_select_sock(hash, …)
{
// …
struct sock *sk2 = NULL;
reuse = rcu_dereference(sk->sk_reuseport_cb);
socks = READ_ONCE(reuse->num_socks);
sk2 = reuse->socks[reciprocal_scale(hash, socks)];
// …
return sk2;
}
linux/net/core/sock_reuseport.c
110
struct sock *reuseport_select_sock(hash, …)
{
// …
struct sock *sk2 = NULL;
reuse = rcu_dereference(sk->sk_reuseport_cb);
socks = READ_ONCE(reuse->num_socks);
sk2 = reuse->socks[reciprocal_scale(hash, socks)];
// …
return sk2;
}
linux/net/core/sock_reuseport.c
111
struct sock *reuseport_select_sock(hash, …)
{
// …
struct sock *sk2 = NULL;
reuse = rcu_dereference(sk->sk_reuseport_cb);
socks = READ_ONCE(reuse->num_socks);
sk2 = reuse->socks[reciprocal_scale(hash, socks)];
// …
return sk2;
}
linux/net/core/sock_reuseport.c
112
struct sock *reuseport_select_sock(hash, …)
{
// …
struct sock *sk2 = NULL;
reuse = rcu_dereference(sk->sk_reuseport_cb);
socks = READ_ONCE(reuse->num_socks);
sk2 = reuse->socks[reciprocal_scale(hash, socks)];
// …
return sk2;
}
struct sock *__inet_lookup_listener(…)
{
u32 phash = 0;
struct sock *result = NULL;
phash = inet_ehashfn(net, daddr, hnum, saddr, sport);
result = reuseport_select_sock(phash, …);
// …
return result;
}
linux/net/ipv4/inet_hashtables.c
113
struct sock *__inet_lookup_listener(…)
{
u32 phash = 0;
struct sock *result = NULL;
phash = inet_ehashfn(net, daddr, hnum, saddr, sport);
result = reuseport_select_sock(phash, …);
// …
return result;
}
linux/net/ipv4/inet_hashtables.c
114
struct sock *__inet_lookup_listener(…)
{
u32 phash = 0;
struct sock *result = NULL;
phash = inet_ehashfn(net, daddr, hnum, saddr, sport);
result = reuseport_select_sock(phash, …);
// …
return result;
}
linux/net/ipv4/inet_hashtables.c
115
static u32 inet_ehashfn(const struct net *net,
const __be32 laddr, const __u16 lport,
const __be32 faddr, const __be16 fport)
{
// …
return __inet_ehashfn(laddr, lport, faddr, fport,
inet_ehash_secret + net_hash_mix(net));
}
linux/net/ipv4/inet_hashtables.c
116
static u32 inet_ehashfn(const struct net *net,
const __be32 laddr, const __u16 lport,
const __be32 faddr, const __be16 fport)
{
// …
return __inet_ehashfn(laddr, lport, faddr, fport,
inet_ehash_secret + net_hash_mix(net));
}
linux/net/ipv4/inet_hashtables.c
117
static u32 inet_ehashfn(const struct net *net,
const __be32 laddr, const __u16 lport,
const __be32 faddr, const __be16 fport)
{
// …
return __inet_ehashfn(laddr, lport, faddr, fport,
inet_ehash_secret + net_hash_mix(net));
}
linux/net/ipv4/inet_hashtables.c
118
struct sock *__inet_lookup_listener(const __be32 saddr,
__be16 sport, …)
{
u32 phash = 0;
struct sock *result = NULL;
phash = inet_ehashfn(net, daddr, hnum, saddr, sport);
result = reuseport_select_sock(phash, …);
// …
return result;
}
linux/net/ipv4/inet_hashtables.c
119
Here comes the pain
‣ Запросы на соединение приходят на случайный socket

‣ Старый процесс HAProxy тоже получает запросы на connect

‣ При большом RPS соединения кладутся в очередь

‣ Старый HAProxy может завершиться, 

когда в очереди уже есть соединения :(
120
Here comes the pain
‣ Запросы на соединение приходят на случайный socket

‣ Старый процесс HAProxy тоже получает запросы на connect

‣ При большом RPS соединения кладутся в очередь

‣ Старый HAProxy может завершиться, 

когда в очереди уже есть соединения :(
121
Here comes the pain
‣ Запросы на соединение приходят на случайный socket

‣ Старый процесс HAProxy тоже получает запросы на connect

‣ При большом RPS соединения кладутся в очередь

‣ Старый HAProxy может завершиться, 

когда в очереди уже есть соединения :(
122
Here comes the pain
‣ Запросы на соединение приходят на случайный socket

‣ Старый процесс HAProxy тоже получает запросы на connect

‣ При большом RPS соединения кладутся в очередь

‣ Старый HAProxy может завершиться, 

когда в очереди уже есть соединения :(
123
Решения?
‣ Ничего не делать

‣ Низкоуровневые заклятья для HAProxy

‣ Отказаться от HAProxy
124
Решения?
‣ Ничего не делать

‣ Низкоуровневые заклятья для HAProxy

‣ Отказаться от HAProxy
125
Решения?
‣ Ничего не делать

‣ Низкоуровневые заклятья для HAProxy

‣ Отказаться от HAProxy
126
Катимся к успеху
‣ In-place update

‣ Proxy

‣ Resource management

‣ Client side LB
127
We are server side
128
app 1
app 2
proxy
Лишнее звено
129
app 1
app 2
proxy
Client side!
130
app 1
app 2
A piece of proxy
‣ Список сервисов

‣ Балансировщик
131
A piece of proxy
‣ Список сервисов

‣ Балансировщик
132
Netflix Ribbon
133
HttpResourceGroup resourceGroup = Ribbon

.createHttpResourceGroup(
“transactionsClient",
ClientOptions.create()
.withConfigurationBasedServerList(“srv1:8080, srv2:8088”)
);
Netflix Ribbon
134
HttpRequestTemplate requestTemplate = resourceGroup
.newTemplateBuilder("requestTemplate")
.withMethod(“POST")
.withUriTemplate("/transactions")
.build();
Netflix Ribbon
135
public class BaseLoadBalancer extends AbstractLoadBalancer ... {
protected IRule rule = new RoundRobinRule();
protected volatile List<Server> allServerList = Collections
.synchronizedList(new ArrayList<Server>());
protected volatile List<Server> upServerList = Collections
.synchronizedList(new ArrayList<Server>());
}
Netflix Ribbon
136
public class BaseLoadBalancer extends AbstractLoadBalancer ... {
protected IRule rule = new RoundRobinRule();
protected volatile List<Server> allServerList = Collections
.synchronizedList(new ArrayList<Server>());
protected volatile List<Server> upServerList = Collections
.synchronizedList(new ArrayList<Server>());
}
Netflix Ribbon
137
public class BaseLoadBalancer extends AbstractLoadBalancer ... {
protected IRule rule = new RoundRobinRule();
protected volatile List<Server> allServerList = Collections
.synchronizedList(new ArrayList<Server>());
protected volatile List<Server> upServerList = Collections
.synchronizedList(new ArrayList<Server>());
}
Netflix Ribbon
138
public class BaseLoadBalancer extends AbstractLoadBalancer ... {
protected IRule rule = new RoundRobinRule();
protected volatile List<Server> allServerList = Collections
.synchronizedList(new ArrayList<Server>());
protected volatile List<Server> upServerList = Collections
.synchronizedList(new ArrayList<Server>());
}
Netflix Ribbon
139
Timer lbTimer = // …;
void setupPingTask() {
lbTimer.schedule(
new PingTask(),
0,
pingIntervalSeconds * 1000);
}
Netflix Ribbon
140
public Server chooseServer(Object key) {
try {
return rule.choose(key);
} catch (Exception e) {
log.warn("LoadBalancer: Error choosing server for key {}”,
key, e);
return null;
}
}
Netflix Ribbon
141
public Server chooseServer(Object key) {
try {
return rule.choose(key);
} catch (Exception e) {
log.warn("LoadBalancer: Error choosing server for key {}”,
key, e);
return null;
}
}
Netflix Ribbon
142
public class RoundRobinRule extends AbstractLoadBalancerRule {
public Server choose(Object key) {
nextServerIndex = incrementAndGetModulo(serverCount);
return allServers.get(nextServerIndex);
}
}
Netflix Ribbon
143
private int incrementAndGetModulo(int modulo) {
for (;;) {
int current = nextServerCyclicCounter.get();
int next = (current + 1) % modulo;
if (nextServerCyclicCounter.compareAndSet(current, next))
return next;
}
}
Netflix Ribbon
144
private int incrementAndGetModulo(int modulo) {
for (;;) {
int current = nextServerCyclicCounter.get();
int next = (current + 1) % modulo;
if (nextServerCyclicCounter.compareAndSet(current, next))
return next;
}
}
Netflix Ribbon
145
private int incrementAndGetModulo(int modulo) {
for (;;) {
int current = nextServerCyclicCounter.get();
int next = (current + 1) % modulo;
if (nextServerCyclicCounter.compareAndSet(current, next))
return next;
}
}
Spring cloud Netflix
146
app 1
eureka
server
app 2
app 3
app 4
Spring cloud Netflix
147
app 1
eureka
server
app 2
app 3
app 4
Eureka server
148
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaServer.class)
.web(true)
.run(args);
}
}
Eureka server
149
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaServer.class)
.web(true)
.run(args);
}
}
Eureka client
150
@SpringBootApplication
@RestController
@EnableEurekaClient
public class CardsApi {
public static void main(String... args) {
SpringApplication.run(CardsApi.class, args);
}
}
Eureka client
151
@SpringBootApplication
@RestController
@EnableEurekaClient
public class CardsApi {
public static void main(String... args) {
SpringApplication.run(CardsApi.class, args);
}
}
‣ Прямая коммуникация

‣ Нет точки отказа в виде 

прокси-сервера

‣ Можно задавать правила
per-app

‣ Дополнительная логика на
клиенте
152
Client-side Server-side
‣ Прозрачно для
приложений

‣ Можно задавать
глобальные правила



‣ Дополнительные точки
отказа
vs
Load balancing
‣ Прямая коммуникация

‣ Нет точки отказа в виде 

прокси-сервера

‣ Можно задавать правила
per-app

‣ Дополнительная логика на
клиенте
153
Client-side Server-side
‣ Прозрачно для
приложений

‣ Можно задавать
глобальные правила



‣ Дополнительные точки
отказа
vs
Load balancing
Выдохнули
‣ In-place обновление - самое простое. 

Но вызывает длинные окна недоступности.

‣ Недоступность можно обеспечить настройками прокси 

и оркестрацией с healthcheck’ами

‣ Для large-scale оркестрации можно использовать 

Mesos/Marathon + Marathon-LB

‣ Альтернатива проксям - Client-side Service Discovery
154
Выдохнули
‣ In-place обновление - самое простое. 

Но вызывает длинные окна недоступности.

‣ Недоступность можно обеспечить настройками прокси 

и оркестрацией с healthcheck’ами

‣ Для large-scale оркестрации можно использовать 

Mesos/Marathon + Marathon-LB

‣ Альтернатива проксям - Client-side Service Discovery
155
Выдохнули
‣ In-place обновление - самое простое. 

Но вызывает длинные окна недоступности.

‣ Недоступность можно обеспечить настройками прокси 

и оркестрацией с healthcheck’ами

‣ Для large-scale оркестрации можно использовать 

Mesos/Marathon + Marathon-LB

‣ Альтернатива проксям - Client-side Service Discovery
156
Выдохнули
‣ In-place обновление - самое простое. 

Но вызывает длинные окна недоступности.

‣ Недоступность можно обеспечить настройками прокси 

и оркестрацией с healthcheck’ами

‣ Для large-scale оркестрации можно использовать 

Mesos/Marathon + Marathon-LB

‣ Альтернатива проксям - Client-side Service Discovery
157
Спасибо за внимание!
stereohorse/jpoint2017
stereohorse

Más contenido relacionado

La actualidad más candente

HighLoad++ 2019: iptables + consul = :3
HighLoad++ 2019: iptables + consul = :3HighLoad++ 2019: iptables + consul = :3
HighLoad++ 2019: iptables + consul = :3Ivan Agarkov
 
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)Ontico
 
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)Ontico
 
Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...
Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...
Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...Anton Baranov
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Ontico
 
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)Ontico
 
Опыт разработки сервиса с асинхронным API на kafka
Опыт разработки сервиса с асинхронным API на kafkaОпыт разработки сервиса с асинхронным API на kafka
Опыт разработки сервиса с асинхронным API на kafkaSergey Zaika
 
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)Ontico
 
Истинный DevOps. Секрет 42.
Истинный DevOps. Секрет 42.Истинный DevOps. Секрет 42.
Истинный DevOps. Секрет 42.Nikita Borzykh
 
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)Ontico
 
Мой маленький уютный PaaS / Илья Беда (bro.agency)
Мой маленький уютный PaaS / Илья Беда (bro.agency)Мой маленький уютный PaaS / Илья Беда (bro.agency)
Мой маленький уютный PaaS / Илья Беда (bro.agency)Ontico
 
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»FDConf
 
Лучшие практики Continuous Delivery с Docker / Дмитрий Столяров (Флант)
Лучшие практики Continuous Delivery с Docker / Дмитрий Столяров (Флант)Лучшие практики Continuous Delivery с Docker / Дмитрий Столяров (Флант)
Лучшие практики Continuous Delivery с Docker / Дмитрий Столяров (Флант)Ontico
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорьdrupalconf
 
Виртуализированные сетевые сервисы на line rate в серверном окружении / Алекс...
Виртуализированные сетевые сервисы на line rate в серверном окружении / Алекс...Виртуализированные сетевые сервисы на line rate в серверном окружении / Алекс...
Виртуализированные сетевые сервисы на line rate в серверном окружении / Алекс...Ontico
 
Подводные камни в нагрузочном тестировании
Подводные камни в нагрузочном тестированииПодводные камни в нагрузочном тестировании
Подводные камни в нагрузочном тестированииVladimir Sitnikov
 
Трудовые будни инженера производительности
Трудовые будни инженера производительностиТрудовые будни инженера производительности
Трудовые будни инженера производительностиVladimir Sitnikov
 
DC/OS – больше чем PAAS, Никита Борзых (Express 42)
DC/OS – больше чем PAAS, Никита Борзых (Express 42)DC/OS – больше чем PAAS, Никита Борзых (Express 42)
DC/OS – больше чем PAAS, Никита Борзых (Express 42)Ontico
 

La actualidad más candente (19)

HighLoad++ 2019: iptables + consul = :3
HighLoad++ 2019: iptables + consul = :3HighLoad++ 2019: iptables + consul = :3
HighLoad++ 2019: iptables + consul = :3
 
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)
Неочевидные детали при запуске HTTPS в OK.Ru / Андрей Домась (Одноклассники)
 
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)
Переосмысливая подход к инфраструктурному коду / Евгений Пивень (IPONWEB)
 
Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...
Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...
Мониторинг в высоконагруженных (и не только) проектах: сравнительный анализ с...
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
 
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)
Кит на службе у человека microPaaS Deis / Алексей Медведчиков (2ГИС)
 
Опыт разработки сервиса с асинхронным API на kafka
Опыт разработки сервиса с асинхронным API на kafkaОпыт разработки сервиса с асинхронным API на kafka
Опыт разработки сервиса с асинхронным API на kafka
 
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)
 
Истинный DevOps. Секрет 42.
Истинный DevOps. Секрет 42.Истинный DevOps. Секрет 42.
Истинный DevOps. Секрет 42.
 
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
 
Мой маленький уютный PaaS / Илья Беда (bro.agency)
Мой маленький уютный PaaS / Илья Беда (bro.agency)Мой маленький уютный PaaS / Илья Беда (bro.agency)
Мой маленький уютный PaaS / Илья Беда (bro.agency)
 
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
 
Лучшие практики Continuous Delivery с Docker / Дмитрий Столяров (Флант)
Лучшие практики Continuous Delivery с Docker / Дмитрий Столяров (Флант)Лучшие практики Continuous Delivery с Docker / Дмитрий Столяров (Флант)
Лучшие практики Continuous Delivery с Docker / Дмитрий Столяров (Флант)
 
Offzone | Another waf bypass
Offzone | Another waf bypassOffzone | Another waf bypass
Offzone | Another waf bypass
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
 
Виртуализированные сетевые сервисы на line rate в серверном окружении / Алекс...
Виртуализированные сетевые сервисы на line rate в серверном окружении / Алекс...Виртуализированные сетевые сервисы на line rate в серверном окружении / Алекс...
Виртуализированные сетевые сервисы на line rate в серверном окружении / Алекс...
 
Подводные камни в нагрузочном тестировании
Подводные камни в нагрузочном тестированииПодводные камни в нагрузочном тестировании
Подводные камни в нагрузочном тестировании
 
Трудовые будни инженера производительности
Трудовые будни инженера производительностиТрудовые будни инженера производительности
Трудовые будни инженера производительности
 
DC/OS – больше чем PAAS, Никита Борзых (Express 42)
DC/OS – больше чем PAAS, Никита Борзых (Express 42)DC/OS – больше чем PAAS, Никита Борзых (Express 42)
DC/OS – больше чем PAAS, Никита Борзых (Express 42)
 

Similar a JPoint 2017 - Where is my service, dude?

Zero Downtime PHP Deployment with Envoyer And Forge
Zero Downtime PHP Deployment with Envoyer And ForgeZero Downtime PHP Deployment with Envoyer And Forge
Zero Downtime PHP Deployment with Envoyer And ForgeYehor Herasymchuk
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
Web осень 2013 лекция 5
Web осень 2013 лекция 5Web осень 2013 лекция 5
Web осень 2013 лекция 5Technopark
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPITimur Shemsedinov
 
Building deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayBuilding deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayAndrey Rebrov
 
Java black box profiling
Java black box profilingJava black box profiling
Java black box profilingaragozin
 
Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Ontico
 
Jiramania презентации @augspb
Jiramania презентации   @augspbJiramania презентации   @augspb
Jiramania презентации @augspbGonchik Tsymzhitov
 
Опыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервисаОпыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервисаIlya Chesnokov
 
Изоморфные React-приложения: производительность и масштабирование
Изоморфные React-приложения: производительность и масштабированиеИзоморфные React-приложения: производительность и масштабирование
Изоморфные React-приложения: производительность и масштабированиеDenis Izmaylov
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов ИгорьPVasili
 
Концепция QaAPI: взгляд на тестирование с другой стороны баррикад
Концепция QaAPI: взгляд на тестирование с другой стороны баррикадКонцепция QaAPI: взгляд на тестирование с другой стороны баррикад
Концепция QaAPI: взгляд на тестирование с другой стороны баррикадSQALab
 
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?Ivan Tsyganov
 
Cовременный станок верстальщика
Cовременный станок верстальщикаCовременный станок верстальщика
Cовременный станок верстальщикаmcslayer
 
Евгений Батовский, Николай Птущук "Современный станок верстальщика"
Евгений Батовский, Николай Птущук "Современный станок верстальщика"Евгений Батовский, Николай Птущук "Современный станок верстальщика"
Евгений Батовский, Николай Птущук "Современный станок верстальщика"Yandex
 
Как Vagrant и Chef ускорили разработку в несколько раз / Тимур Батыршин (Cina...
Как Vagrant и Chef ускорили разработку в несколько раз / Тимур Батыршин (Cina...Как Vagrant и Chef ускорили разработку в несколько раз / Тимур Батыршин (Cina...
Как Vagrant и Chef ускорили разработку в несколько раз / Тимур Батыршин (Cina...Ontico
 
еще один недостаток современных клиент серверных приложений
еще один недостаток современных клиент серверных приложенийеще один недостаток современных клиент серверных приложений
еще один недостаток современных клиент серверных приложенийsnowytoxa
 
DDоS: Практическое руководство к выживанию. (Часть 2: Работа над ошибками)
DDоS: Практическое руководство к выживанию. (Часть 2: Работа над ошибками)DDоS: Практическое руководство к выживанию. (Часть 2: Работа над ошибками)
DDоS: Практическое руководство к выживанию. (Часть 2: Работа над ошибками)HLL
 

Similar a JPoint 2017 - Where is my service, dude? (20)

Zero Downtime PHP Deployment with Envoyer And Forge
Zero Downtime PHP Deployment with Envoyer And ForgeZero Downtime PHP Deployment with Envoyer And Forge
Zero Downtime PHP Deployment with Envoyer And Forge
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
Breaking logs
Breaking logsBreaking logs
Breaking logs
 
Web осень 2013 лекция 5
Web осень 2013 лекция 5Web осень 2013 лекция 5
Web осень 2013 лекция 5
 
Erlang tasty & useful stuff
Erlang tasty & useful stuffErlang tasty & useful stuff
Erlang tasty & useful stuff
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPI
 
Building deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayBuilding deployment pipeline - DevOps way
Building deployment pipeline - DevOps way
 
Java black box profiling
Java black box profilingJava black box profiling
Java black box profiling
 
Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)
 
Jiramania презентации @augspb
Jiramania презентации   @augspbJiramania презентации   @augspb
Jiramania презентации @augspb
 
Опыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервисаОпыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервиса
 
Изоморфные React-приложения: производительность и масштабирование
Изоморфные React-приложения: производительность и масштабированиеИзоморфные React-приложения: производительность и масштабирование
Изоморфные React-приложения: производительность и масштабирование
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов Игорь
 
Концепция QaAPI: взгляд на тестирование с другой стороны баррикад
Концепция QaAPI: взгляд на тестирование с другой стороны баррикадКонцепция QaAPI: взгляд на тестирование с другой стороны баррикад
Концепция QaAPI: взгляд на тестирование с другой стороны баррикад
 
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
 
Cовременный станок верстальщика
Cовременный станок верстальщикаCовременный станок верстальщика
Cовременный станок верстальщика
 
Евгений Батовский, Николай Птущук "Современный станок верстальщика"
Евгений Батовский, Николай Птущук "Современный станок верстальщика"Евгений Батовский, Николай Птущук "Современный станок верстальщика"
Евгений Батовский, Николай Птущук "Современный станок верстальщика"
 
Как Vagrant и Chef ускорили разработку в несколько раз / Тимур Батыршин (Cina...
Как Vagrant и Chef ускорили разработку в несколько раз / Тимур Батыршин (Cina...Как Vagrant и Chef ускорили разработку в несколько раз / Тимур Батыршин (Cina...
Как Vagrant и Chef ускорили разработку в несколько раз / Тимур Батыршин (Cina...
 
еще один недостаток современных клиент серверных приложений
еще один недостаток современных клиент серверных приложенийеще один недостаток современных клиент серверных приложений
еще один недостаток современных клиент серверных приложений
 
DDоS: Практическое руководство к выживанию. (Часть 2: Работа над ошибками)
DDоS: Практическое руководство к выживанию. (Часть 2: Работа над ошибками)DDоS: Практическое руководство к выживанию. (Часть 2: Работа над ошибками)
DDоS: Практическое руководство к выживанию. (Часть 2: Работа над ошибками)
 

JPoint 2017 - Where is my service, dude?