SlideShare ist ein Scribd-Unternehmen logo
1 von 197
Downloaden Sie, um offline zu lesen
Everything as a Code
Непривычно о привычном
@aatarasoff
@aatarasoff
@aatarasoff
Everything as a Code
Непривычно о привычном
No warranty guarantee
You think you are creator
5
6
… but matrix has you
7
Выйти за пределы...
8
...поняв, что всё есть код
9
Как вы представляете себе код?
10
@Configuration
@EnableConfigurationProperties(OneServerProperties.class)
public class OneServerConfiguration implements ApplicationContextAware {
ApplicationContext applicationContext;
@Autowired
OneServerProperties properties;
@Bean
public HttpServer httpServer() throws IOException {
HttpServer httpServer = new RelativePathHttpServer();
for (String beanName : context.getBeans(HttpController.class)) {
httpServer.addRequestHandlers(context.getBean(beanName));
}
return httpServer;
}
}
11
Наверное как-то так
>>,[>>,]<<[
[<<]>>>>[
<<[>+<<+>-]
>>[>+<<<<[->]>[<]>>-]
<<<[[-]>>[>+<-]>>[<<<+>>>-]]
>>[[<+>-]>>]<
]<<[>>+<<-]<<
]>>>>[.>>]
12
...или может быть так?
Что такое код?
● Коллекция инструкций
● Человекочитаемый формат
○ plain text
● Может быть понят и “проигран”
○ после компиляции
○ интерпретатором
13
Да я тоже пишу код!
14
Вооружи себя
15
Настройка рабочего окружения
16
Install apps Code Checkout
Configure
workspace
First Blood
17
Install apps Code Checkout
Configure
workspace
First Blood
brew install
18
Install apps Code Checkout
Configure
workspace
First Blood
brew install
pip install
19
Install apps Code Checkout
Configure
workspace
First Blood
git
20
Install apps Code Checkout
Configure
workspace
First Blood
customize
*.properties
21
Install apps Code Checkout
Configure
workspace
First Blood
customize
*.propertiestemplate
.gradle
22
Install apps Code Checkout
Configure
workspace
First Blood
customize
*.properties
install
certificates
23
Install apps Code Checkout
Configure
workspace
First Blood
first build
24
Install apps Code Checkout
Configure
workspace
First Blood
mass build
first deploy
25
ansible-playbook -i local-inv setup.yml --tags configure
26
Интерпретатор
ansible-playbook -i local-inv setup.yml --tags configure
27
Конфигурация
ansible-playbook -i local-inv setup.yml --tags configure
28
Алгоритм
# checkout repositories from git
- include: checkout.yml
# configure your local environment
- include: configure.yml
# add useful mappings to your hosts file
- include: hosts.yml
# add gradle support
- include: gradle.yml
# clean and build all projects
- include: build.yml
# delpoy all services to dev
- include: deploy.yml
29
Алгоритм
ansible-playbook -i local-inv setup.yml --tags configure
30
Входные параметры
- name: checkout services
git:
repo: "{{ git.root }}/{{ item.name }}.git"
dest: "{{ work_dir }}/{{ item.name }}"
update: yes
with_items:
- "{{ services }}"
tags:
- services
31
Массовый checkout/pull
- name: checkout services
git:
repo: "{{ git.root }}/{{ item.name }}.git"
dest: "{{ work_dir }}/{{ item.name }}"
update: yes
with_items:
- "{{ services }}"
tags:
- services
Переменные
32
- name: checkout services
git:
//
with_items:
- "{{ services }}"
services:
- { name: one-instant-messenger , sourceDir: src }
- { name: one-discussions , sourceDir: src }
- { name: one-attachment , sourceDir: src, testDir: test, local: true }
Циклы
33
services:
- { name: one-instant-messenger, sourceDir: src }
- { name: one-discussions, sourceDir: src }
- { name: one-attachment, sourceDir: src, testDir: test }
Коллекции и структуры данных
34
- name: create gradle build file
template:
src: build.gradle.j2
dest: "{{ work_dir }}/build.gradle"
mode: 0644
- name: create gradle settings file
template:
src: settings.gradle.j2
dest: "{{ work_dir }}/settings.gradle"
mode: 0644
Шаблоны
35
{% if services is not none %}{% for service in services %}
if (project.name == '{{ service.name }}') {
{% if 'sourceDir' in service %}
main.java.srcDir '{{ service.sourceDir }}'
{% endif %}{% if 'testDir' in service %}
test.java.srcDir '{{ service.testDir }}'
{% endif %}
}
Условные операторы
36
{% if services is not none %}{% for service in services %}
if (project.name == '{{ service.name }}') {
{% if 'sourceDir' in service %}
main.java.srcDir '{{ service.sourceDir }}'
{% endif %}{% if 'testDir' in service %}
test.java.srcDir '{{ service.testDir }}'
{% endif %}
}
Опять циклы
37
{% if services is not none %}{% for service in services %}
if (project.name == '{{ service.name }}') {
{% if 'sourceDir' in service %}
main.java.srcDir '{{ service.sourceDir }}'
{% endif %}{% if 'testDir' in service %}
test.java.srcDir '{{ service.testDir }}'
{% endif %}
}
Переменные
38
- stat: path={{ username }}.key
register: certkey
- name: generate private key
shell: openssl genrsa -out {{ username }}.key -aes256 4096
when: not certkey.stat.exists
Идемпотентность
39
Install apps Code Checkout
Configure
workspace
Multiplie Use
40
Петля обратной связи
git
Что получили
● Автоконфигурация рабочего
пространства
○ повторяемая
○ немутабельная
● Можно дать скрипт новичку
● Можно и нужно пользоваться этим
каждый день
41
Код есть код
42
Искусство сборки
43
Compile code Unit tests Package Publishing
44
Compile code Unit tests Package
compiler
Publishing
45
Compile code Unit tests Package
javacresource
processing
Publishing
46
Compile code Unit tests Package
javacresources
copyingdependency
resolving
Publishing
47
Compile code Unit tests Package
junit
Publishing
48
Compile code Unit tests Package
jar
Publishing
49
Compile code Unit tests Package
jar
npm, deb, ...
Publishing
50
Compile code Unit tests Package
jar
npm, so, ...
docker image
Publishing
51
Compile code Unit tests Package
ivy
Publishing
52
Compile code Unit tests Package
maven, ivy
maven
Publishing
53
Compile code Unit tests Package Publishing
maven, ivylocal or dev
deploydocker registry
54
Системы сборки
● Ant + Ivy
● Maven
● Gradle
● Docker
● npm
● ...
55
FROM golang:1.7-alpine
MAINTAINER aatarasoff@gmail.com
VOLUME /data
WORKDIR /data
RUN apk update && 
apk upgrade && 
apk add git bash
RUN go get github.com/aatarasoff/apistress && 
go install github.com/aatarasoff/apistress
CMD [ "apistress" ]
Dockerfile. Наследование
56
FROM golang:1.7-alpine
MAINTAINER aatarasoff@gmail.com
VOLUME /data
WORKDIR /data
RUN apk update && 
apk upgrade && 
apk add git bash
RUN go get github.com/aatarasoff/apistress && 
go install github.com/aatarasoff/apistress
CMD [ "apistress" ]
Dockerfile. Инструкции
57
FROM golang:1.7-alpine
MAINTAINER aatarasoff@gmail.com
ARG maindir=/data
VOLUME $maindir
WORKDIR $maindir
RUN apk update && apk upgrade && apk add git bash
RUN go get github.com/aatarasoff/apistress && 
go install github.com/aatarasoff/apistress
CMD [ "apistress" ]
Dockerfile. Переменные
58
docker build … && docker push …
59
publishing {
publications {
mavenJava(MavenPublication) {
artifactId 'spring-one-nio-autoconfigure'
from components.java
artifact sourceJar {
classifier "sources"
}
}
}
}
Gradle. DSL
60
compile(ivyDependencies(projectDir, 'runtime'))
def ivyDependencies(ivyPath, conf) {
def dep = []
def ivyModule = new XmlParser().parse(file("${ivyPath}/ivy.xml"))
ivyModule.dependencies.dependency.each
dep.add([group: (null == it.@org ? 'ru.odnoklassniki' : it.@org),
name: it.@name,
version: it.@rev,
configuration: (it.@conf =~ /->(w+)/)[0][1]])
}
return dep
}
Gradle. Код как он есть
61
<macrodef name="docker-build-image" description="Build docker image">
<attribute name=" buildcommand"
default="build -t @{repo}/@{image}:@{tag} ."/>
<sequential>
<exec executable="docker">
<arg line=" @{buildcommand} "/>
</exec>
</sequential>
</macrodef>
И даже в Ant-е есть жизнь
62
./gradlew build test ant-docker-build-image publish
63
Фреймворки
для автоматизации
● Ant + Ivy
● Maven
● Gradle
● Docker
● npm
● ...
64
Что получили
● Сборка это код
○ XML
○ DSL
○ Groovy
○ etc
● Системы сборки не только для
сборки
65
Ликвидация багов
66
Unit tests API tests Stress tests UI tests
67
Unit tests API tests Stress tests UI tests
TDD
68
goss --vars vars.yaml validate
69
port:
tcp:5601:
listening: true
ip:
- 0.0.0.0
service:
mesosd:
enabled: true
running: true
goss.yml
70
port:
tcp:5601:
listening: true
ip:
- 0.0.0.0
service:
mesosd:
enabled: true
running: true
goss.yml
71
port:
tcp:5601:
listening: true
ip:
- 0.0.0.0
service:
mesosd:
enabled: true
running: true
goss.yml
72
Unit tests API tests Stress tests UI tests
BDD Specs
73
def "Return error code 400, if User-ID header is not presented"() {
given:
def request = post("/rent")
when:
def result = this.mvc.perform(request)
then:
result.andExpect(status().isBadRequest())
.andDo(document("rent-user-id-is-absent"))
}
Дружелюбный BDD
74
def "Return error code 400, if User-ID header is not presented"() {
given:
def request = post("/rent")
when:
def result = this.mvc.perform(request)
then:
result.andExpect( status().isBadRequest())
.andDo(document("rent-user-id-is-absent"))
}
Простые проверки
75
Unit tests API tests Stress tests UI tests
JMeter, wrk,
vegeta
76
Unit tests API tests Stress tests UI tests
JMeter
production
77
> config | run command
> echo $?
{0,1}
0 - success
1 - error
78
Экспресс-тест
{
"baseUrl": "http://host:9000/rent-service",
"tests": [
{
"rps": 10,
"duration": 5,
"target": {
"method": "GET",
"path": "/rent",
"headers": [
...
]
},
"sla": {
"latency": 1000,
"successRate": 99.999
}
},
... ]
}
config.json
79
{
"baseUrl": "http://host:9000/rent-service",
"tests": [
{
"rps": 10,
"duration": 5,
"target": {
"method": "GET",
"path": "/rent",
"headers": [
...
]
},
"sla": {
"latency": 1000,
"successRate": 99.999
}
},
... ]
}
config.json
80
{
"baseUrl": "http://host:9000/rent-service",
"tests": [
{
"rps": 10,
"duration": 5,
"target": {
"method": "GET",
"path": "/rent",
"headers": [
...
]
},
"sla": {
"latency": 1000,
"successRate": 99.999
}
},
... ]
}
config.json
81
cat config.json | docker run -i apistress -config=stdin
82
Где-то мы такое видели
https://github.com/aatarasoff/apistress
Requests [total, rate] 50, 10.20
Duration [total, attack, wait] 5.022872793s, 4.899943287s, 122.929506ms
Latencies [mean, 50, 95, 99, max] 143.772484ms, ..., 290.101831ms
Bytes In [total, mean] 4842, 96.84
Bytes Out [total, mean] 950, 19.00
Success [ratio] 100.00%
Status Codes [code:count] 200:50
Error Set:
Test#1
83
Requests [total, rate] 50, 10.20
Duration [total, attack, wait] 5.022872793s, 4.899943287s, 122.929506ms
Latencies [mean, 50, 95, 99, max] 143.772484ms, ..., 290.101831ms
Bytes In [total, mean] 4842, 96.84
Bytes Out [total, mean] 950, 19.00
Success [ratio] 100.00%
Status Codes [code:count] 200:50
Error Set:
Test#1
84
attacker := vegeta.NewAttacker()
var metrics vegeta.Metrics
for res := range attacker.Attack(targeter, rate, duration) {
metrics.Add(res)
}
metrics.Close()
if metrics.Success*100 < test.SLA.SuccessRate {
os.Exit(1)
}
if metrics.Latencies.P99() > SLA.Latency*time.Millisecond.Nanoseconds() {
os.Exit(1)
}
Немного go-кода
85
attacker := vegeta.NewAttacker()
var metrics vegeta.Metrics
for res := range attacker.Attack( targeter, rate, duration) {
metrics.Add(res)
}
metrics.Close()
if metrics.Success*100 < test.SLA.SuccessRate {
os.Exit(1)
}
if metrics.Latencies.P99() > SLA.Latency*time.Millisecond.Nanoseconds() {
os.Exit(1)
}
Майним метрики
86
attacker := vegeta.NewAttacker()
var metrics vegeta.Metrics
for res := range attacker.Attack(targeter, rate, duration) {
metrics.Add(res)
}
metrics.Close()
if metrics.Success*100 < test.SLA.SuccessRate {
os.Exit(1)
}
if metrics.Latencies.P99() > SLA.Latency*time.Millisecond.Nanoseconds() {
os.Exit(1)
}
Не слишком ли много ошибок?
87
attacker := vegeta.NewAttacker()
var metrics vegeta.Metrics
for res := range attacker.Attack(targeter, rate, duration) {
metrics.Add(res)
}
metrics.Close()
if metrics.Success*100 < test.SLA.SuccessRate {
os.Exit(1)
}
if metrics.Latencies.P99() > SLA.Latency*time.Millisecond.Nanoseconds() {
os.Exit(1)
}
Уложились ли по времени?
88
> cat config.json | docker run -i apistress -config=stdin
> echo $?
0
89
Код возврата
Requests [total, rate] 200, 10.05
Duration [total, attack, wait] 23.04784s, 19.899754743s, 3.148093811s
Latencies [mean, 50, 95, 99, max] 3.023677499s, ..., 11.832287083s
Bytes In [total, mean] 6874, 34.37
Bytes Out [total, mean] 1349, 6.75
Success [ratio] 35.50%
Status Codes [code:count] 0:129 200:71
Error Set:
Get http://host:9000/rent-service/rent: EOF
Get http://host:9000/rent-service/rent: http: server closed idle connection
...
Test#2
90
> cat config.json | docker run -i apistress -config=stdin
> echo $?
1
91
Код возврата
Unit tests API tests Stress tests UI tests
Selenium,
Selenide
92
Что получили
● Все тестовые сценарии в коде
● Можно встроить в процесс сборки
или доставки ПО
● Если хотите, то можно
генерировать отчёты для разбора
полётов
93
Эксперименты
94
Code Branches
95
if / switch
Code Branches
96
if / switch
DI
Code Branches
97
if / switch
DI
API v2
ISupplier<String, Ctx> srcsetSupplier = (ctx) -> {
if (configuration. isDoubleDensityAvatarsEnabled(user.getModel())) {
String link = imageSrc.getModel();
return linkBuilder.createSourceSetLink(link);
}
return "";
};
Очень простой эксперимент
98
Code Branches
One server or
partition
99
//by partition
app.photos.doubleDensityAvatarsEnabled: 0
Step#1
Code Branches
One server or
partition
Part of servers
or partitions
100
//by partition
app.photos.doubleDensityAvatarsEnabled: 0,4,7-9
Step#1 Step#2
Code Branches
One server or
partition
Part of servers
or partitions
All servers or
partitions
101
//by partition
app.photos.doubleDensityAvatarsEnabled: ALL
Step#1 Step#2 Step#3
//step#1
app.photos.doubleDensityAvatarsEnabled: 0
//step#2
app.photos.doubleDensityAvatarsEnabled: 0,4,7-9
//step#3
app.photos.doubleDensityAvatarsEnabled: ALL
102
Очень простой эксперимент
No one
One server or
partition
Part of servers
or partitions
All servers or
partitions
103
monitor
Step#1 Step#2 Step#3Step#0
104
Что хотим?
ansible-playbook -i {dev,test,prod}-env exp.yml --tags stepN
105
Абстракция
- name: update properties
uri:
url: "http://{{ pms_host }}/api/conf/update"
method: POST
user: "{{ username }}"
password: "{{ password }}"
force_basic_auth: yes
body:
applicationName: "{{ application_name }}"
propertyName: "{{ item.value.name }}"
propertyValue: "{{ item.value.value }}"
body_format: json
status_code: 200
headers:
Content-Type: "application/json"
with_dict: "{{ properties }}"
106
Координаты
- name: update properties
uri:
url: "http://{{ pms_host }}/api/conf/update"
method: POST
user: "{{ username }}"
password: "{{ password }}"
force_basic_auth: yes
body:
applicationName: "{{ application_name }}"
propertyName: "{{ item.value.name }}"
propertyValue: "{{ item.value.value }}"
body_format: json
status_code: 200
headers:
Content-Type: "application/json"
with_dict: "{{ properties }}"
107
Вкатываем настройки
- name: update properties
uri:
url: "http://{{ pms_host }}/api/conf/update"
method: POST
user: "{{ username }}"
password: "{{ password }}"
force_basic_auth: yes
body:
applicationName: "{{ application_name }}"
propertyName: "{{ item.value.name }}"
propertyValue: "{{ item.value.value }}"
body_format: json
status_code: 200
headers:
Content-Type: "application/json"
with_dict: "{{ properties }}"
108
Проверяем корректность
- name: update properties
uri:
url: "http://{{ pms_host }}/api/conf/update"
method: POST
user: "{{ username }}"
password: "{{ password }}"
force_basic_auth: yes
body:
applicationName: "{{ application_name }}"
propertyName: "{{ item.value.name }}"
propertyValue: "{{ item.value.value }}"
body_format: json
status_code: 200
headers:
Content-Type: "application/json"
with_dict: "{{ properties }}"
109
Step#0
- hosts: local
vars:
application_name: odnoklassniki-web
props:
doubleDensityAvatarsEnabled:
name: "app.photos.doubleDensityAvatarsEnabled"
value: ""
roles:
- { name: pms, properties: "{{ props }}" }
110
Step#0
- hosts: local
vars:
application_name: odnoklassniki-web
props:
doubleDensityAvatarsEnabled:
name: "app.photos.doubleDensityAvatarsEnabled"
value: ""
roles:
- { name: pms, properties: "{{ props }}" }
111
Step#1
- hosts: local
vars:
application_name: odnoklassniki-web
props:
doubleDensityAvatarsEnabled:
name: "app.photos.doubleDensityAvatarsEnabled"
value: "0"
roles:
- { name: pms, properties: "{{ props }}" }
112
Step#2
- hosts: local
vars:
application_name: odnoklassniki-web
props:
doubleDensityAvatarsEnabled:
name: "app.photos.doubleDensityAvatarsEnabled"
value: "0,4,7-9"
roles:
- { name: pms, properties: "{{ props }}" }
113
Step#3
- hosts: local
vars:
application_name: odnoklassniki-web
props:
doubleDensityAvatarsEnabled:
name: "app.photos.doubleDensityAvatarsEnabled"
value: "ALL"
roles:
- { name: pms, properties: "{{ props }}" }
114
exp.yml
---
- include: step0.yml
tags:
- step0
- cleanup
- include: step1.yml
tags: step1
- include: step2.yml
tags: step2
- include: step3.yml
tags:
- step3
- complete
Что получили
● Эксперименты хранятся в git-
репозитории
● Можно применить любой шаг в
любой момент времени на любой
среде
● Можно встроить в пайплайн
доставки
115
Кододокументация
116
Analyst, PM Developer Tester Docs
Word, PDF...
117
Analyst, PM Developer Tester Docs
Word, PDF... Code + Tests
118
Analyst, PM Developer Tester Docs
Word, PDF... Code + Tests Test cases
119
Analyst, PM Developer Tester Docs :(
Word, PDF... Code + Tests Test cases
120
Analyst, PM Developer Tester Docs :)
Markdown/Asciidoctor
Docs :)
121
= Hippo Rent Service
This is documentation for Open API of our hippo renting service
== Methods
=== Rent
==== Request specification
===== Headers
//тут опишем http-заголовки
===== Example
//а здесь будут примеры вызова
==== Response specification
===== Response fields
//здесь описание полей ответа
===== Example
//ну и пример того, что вообще ожидать в ответе
Вот такой документ
122
./gradlew ... asciidoc publishDocs
123
Компиляция документа
def "Rent a hippo"() {
given:
def request = post("/rent").header("User-ID", "aatarasoff")
when:
def result = this.mvc.perform(request)
then:
result.andExpect(status().isOk())
.andDo(document(
"rent-hippo",
preprocessResponse(prettyPrint()),
requestHeaders(
headerWithName("User-ID").description("User unique identifier")),
responseFields(
fieldWithPath("hippoRemain").description("Hippo remain count"),
fieldWithPath("parrot_fee").description("Fee in virtual parrots"),
fieldWithPath("ins").description("Insurance number. Yeah, we sell it"),
fieldWithPath("hash").description("Blockchain block hash"))
))
}
…и снова тесты
124
def "Rent a hippo"() {
given:
def request = post("/rent").header("User-ID", "aatarasoff")
when:
def result = this.mvc.perform(request)
then:
result.andExpect(status().isOk())
.andDo(document(
"rent-hippo",
preprocessResponse(prettyPrint()),
requestHeaders(
headerWithName("User-ID").description("User unique identifier")),
responseFields(
fieldWithPath("hippoRemain").description("Hippo remain count"),
fieldWithPath("parrot_fee").description("Fee in virtual parrots"),
fieldWithPath("ins").description("Insurance number. Yeah, we sell it"),
fieldWithPath("hash").description("Blockchain block hash"))
))
}
А не документация ли это?
125
document(
"rent-hippo",
preprocessResponse(prettyPrint()),
requestHeaders(
headerWithName("User-ID").description("User unique identifier")),
responseFields(
fieldWithPath("hippoRemain").description("Hippo remain count"),
fieldWithPath("parrot_fee").description("Fee in virtual parrots"),
fieldWithPath("ins").description("Insurance number. Yeah, we sell
it"),
fieldWithPath("hash").description("Blockchain block hash"))
)
Имя сниппета
126
document(
"rent-hippo",
preprocessResponse(prettyPrint()),
requestHeaders(
headerWithName("User-ID").description("User unique identifier")),
responseFields(
fieldWithPath("hippoRemain").description("Hippo remain count"),
fieldWithPath("parrot_fee").description("Fee in virtual parrots"),
fieldWithPath("ins").description("Insurance number. Yeah, we sell
it"),
fieldWithPath("hash").description("Blockchain block hash"))
)
Тестируем заголовки
127
document(
"rent-hippo",
preprocessResponse(prettyPrint()),
requestHeaders(
headerWithName("User-ID").description("User unique identifier")),
responseFields(
fieldWithPath("hippoRemain").description("Hippo remain count"),
fieldWithPath("parrot_fee").description("Fee in virtual parrots"),
fieldWithPath("ins").description("Insurance number. Yeah, we sell it"),
fieldWithPath("hash").description("Blockchain block hash"))
)
Тестируем поля ответа
128
generated-snippets
rent-hippo
curl-request.adoc
http-request.adoc
http-response.adoc
httpie-request.adoc
request-headers.adoc
response-fields.adoc
Получаем сниппеты
129
= Hippo Rent Service
This is documentation for Open API of our hippo renting service
== Methods
=== Rent
==== Request specification
===== Headers
include::{snippets}/rent-hippo/request-headers.adoc[]
===== Example
include::{snippets}/rent-hippo/http-request.adoc[]
==== Response specification
===== Response fields
include::{snippets}/rent-hippo/response-fields.adoc[]
===== Example
include::{snippets}/rent-hippo/http-response.adoc[]
Вставляем их в документ
130
= Hippo Rent Service
This is documentation for Open API of our hippo renting
service
== Methods
=== Rent
==== Request specification
===== Headers
include::{snippets}/rent-hippo/request-headers.adoc[]
===== Example
include::{snippets}/rent-hippo/http-request.adoc[]
==== Response specification
===== Response fields
include::{snippets}/rent-hippo/response-fields.adoc[]
===== Example
include::{snippets}/rent-hippo/http-response.adoc[]
131
132
Что получили?
● Документация как код
○ лежит в репозитории с кодом
○ встроена в цикл сборки
○ рендерится в html, pdf и т.д.
○ почти всегда актуальна
● Синергия с тестами
133
Инфракод
134
Hardware
Containers
Application
PaaS
Mesos/Kubernetes/Private cloud
135
Hardware + OS System Libs PaaS Application
136
Hardware + OS System Libs PaaS Application
Ansible
137
Hardware + OS System Libs PaaS Application
Ansible
Puppet/Chef
138
Ansible. Inventory
[datacenter]
api-server-1
api-server-2
api-server-3
[datacenter:vars]
magicvar = 42
139
Ansible. Playbook
- hosts: datacenter
roles:
- role: docker
- role: rsyslog
140
ansible-playbook -i dc1 bootstrap.yml
141
Без комментариев
Hardware + OS System Libs PaaS Application
Ansible
142
Hardware + OS System Libs PaaS Application
Ansible
Puppet/Chef
143
Hardware + OS System Libs PaaS Application
Manifest
144
Docker compose
services:
zk:
image: zookeeper
network_mode: bridge
ports:
- 2181:2181
environment:
ZK_CONFIG: tickTime=2000,initLimit=10,clientPort=2181
ZK_ID: 1
145
Docker compose
services:
zk:
image: zookeeper
network_mode: bridge
ports:
- 2181:2181
environment:
ZK_CONFIG: tickTime=2000,initLimit=10,clientPort=2181
ZK_ID: 1
146
Конфигурация сервиса
services:
zk:
image: zookeeper
network_mode: bridge
ports:
- 2181:2181
environment:
ZK_CONFIG: tickTime=2000,initLimit=10,clientPort=2181
ZK_ID: 1
147
Mesos/Marathon
{
"id": "/api/rent-service",
"cpus": 1,
"mem": 1024,
"instances": 3,
"container": {
"docker": {
"image": "rent-service:0.0.1",
"portMappings": [
{
"containerPort": 8080
}
]
}
}
}
148
curl -X POST ... http://marathon/v2/apps?force=true
149
Современный деплоймент
Конфигурация приложений
https://your_repo/rent-service-config/routes.yml
routes:
payment:
path: /payment-service/**
serviceId: payment-service
150
Ещё конфигурация
● Zookeeper
● Consul
● Vault
● configo
● ...
151
configo
152
docker run 
-e CONFIGO_SOURCE_0='{"type": "http", "format": "yaml", "url":
"https://my.server.com/common.yaml"}' 
rent-service
//внутри приложения
getEnvironmentVariable("MY_ENV_VAR")
https://github.com/bsideup/configo
configo
153
docker run 
-e CONFIGO_SOURCE_0='{"type": "http", "format": "yaml", "url":
"https://my.server.com/common.yaml"}' 
-e CONFIGO_SOURCE_1='{"type" : "consul",
"address": "consul.master:8500",
"prefix" : "common"}' 
rent-service
//внутри приложения
getEnvironmentVariable("MY_ENV_VAR")
https://github.com/bsideup/configo
Что получили?
● Инфрастуктура может быть легко
описана в виде кода
● Деплоймент и конфигурация
приложений в виде конфигов и
манифестов
154
Неубиваемый CI
155
156
Install Master
Configure
Slaves
157
Install Master
Configure
Slaves
Ansible
158
Install Master
Configure
Slaves
Ansible
Jenkins Docker Cloud plugin
<——— Хост с докером
<——— Сколько контейнеров можно запустить
159
Автоконфигурация
<clouds>
{% for group in ['build', 'test', 'production'] %}
{% for node in groups[group + '-slaves'] %}
<com.github.kostyasha.yad.DockerCloud plugin="yet-another-docker-plugin@0.1.0-rc31">
<name>{{ node }}</name>
...
<templates>
<com.github.kostyasha.yad.DockerSlaveTemplate>
<id>mycloud-template</id>
<dockerContainerLifecycle>
<image>{{ group }}-jenkins-slave</image>
...
</templates>
<connector>
<serverUrl>tcp://{{ node.hostname }}:2375</serverUrl>
<apiVersion>1.20</apiVersion>
</connector>
</com.github.kostyasha.yad.DockerCloud>
{% endfor %}
{% endfor %}
</clouds>
160
Код доставки
161
//checkout and definition stage
node('build') {
// Mark the code checkout 'stage'
stage 'Checkout'
git credentialsId: 'jenkins-git',
url: "${git_url}/${repo}.git"
// Mark build 'stage'
stage 'Build'
sh ('./gradlew clean build final')
}
//next steps
//checkout and definition stage
node('build') {
// Mark the code checkout 'stage'
stage 'Checkout'
git credentialsId: 'jenkins-git',
url: "${git_url}/${repo}.git"
// Mark build 'stage'
stage 'Build'
sh ('./gradlew clean build final')
}
//next steps
//checkout and definition stage
node('build') {
// Mark the code checkout 'stage'
stage 'Checkout'
git credentialsId: 'jenkins-git',
url: "${git_url}/${repo}.git"
// Mark build 'stage'
stage 'Build'
sh ('./gradlew clean build final')
}
//next steps
//checkout and definition stage
node('build') {
// Mark the code checkout 'stage'
stage 'Checkout'
git credentialsId: 'jenkins-git',
url: "${git_url}/${repo}.git"
// Mark build 'stage'
stage 'Build'
sh ('./gradlew clean build final')
}
//next steps
//checkout and definition stage
node('build') {
// Mark the code checkout 'stage'
stage 'Checkout'
git credentialsId: 'jenkins-git',
url: "${git_url}/${repo}.git"
// Mark build 'stage'
stage 'Build'
sh ('./gradlew clean build final')
}
//next steps
//checkout and definition stage
node('build') {
// Mark the code checkout 'stage'
stage 'Checkout'
git credentialsId: 'jenkins-git',
url: "${git_url}/${repo}.git"
// Mark build 'stage'
stage 'Build'
sh ('./gradlew clean build final')
}
//next steps
//deploy artifact to test
node('test') {
sh('ansible-galaxy install -r requirements.yml')
ansiblePlaybook(
credentialsId: 'ansible',
installation: 'ansible',
playbook: 'deploy.yml',
inventory: 'test'
)
}
//deploy artifact to test
node('test') {
sh('ansible-galaxy install -r requirements.yml')
ansiblePlaybook(
credentialsId: 'ansible',
installation: 'ansible',
playbook: 'deploy.yml',
inventory: 'test'
)
}
//deploy artifact to test
node('test') {
sh('ansible-galaxy install -r requirements.yml')
ansiblePlaybook(
credentialsId: 'ansible',
installation: 'ansible',
playbook: 'deploy.yml',
inventory: 'test'
)
}
//deploy artifact to test
node('test') {
sh('ansible-galaxy install -r requirements.yml')
ansiblePlaybook(
credentialsId: 'ansible',
installation: 'ansible',
playbook: 'deploy.yml',
inventory: 'test'
)
}
//deploy artifact to test
node('test') {
sh('ansible-galaxy install -r requirements.yml')
ansiblePlaybook(
credentialsId: 'ansible',
installation: 'ansible',
playbook: 'deploy.yml',
inventory: 'test'
)
}
jiraComment (
issueKey: issue_id,
body: "Artifact has been deployed"
)
node('build') {
def repos = fetchRepos(project)
for (repo in repos) {
build(repo)
}
}
def fetchRepos(String project) {
def url = new URL("https://repo/projects/${project}/repos?limit=1000")
def conn = url.openConnection()
conn.setRequestMethod("GET")
def responseCode = conn.getResponseCode()
final slurper = new groovy.json.JsonSlurper()
def repos = slurper.parse(conn.getInputStream()).values
for (repo in repos) {
if (repo.slug.contains('one-'))
result << repo.slug
}
return result
}
node('build') {
def repos = fetchRepos(project)
for (repo in repos) {
build(repo)
}
}
def fetchRepos(String project) {
def url = new URL("https://repo/projects/${project}/repos?limit=1000")
def conn = url.openConnection()
conn.setRequestMethod("GET")
def responseCode = conn.getResponseCode()
final slurper = new groovy.json.JsonSlurper()
def repos = slurper.parse(conn.getInputStream()).values
for (repo in repos) {
if (repo.slug.contains('one-'))
result << repo.slug
}
return result
}
node('build') {
def repos = fetchRepos(project)
for (repo in repos) {
build(repo)
}
}
def fetchRepos(String project) {
def url = new URL("https://repo/projects/${project}/repos?limit=1000")
def conn = url.openConnection()
conn.setRequestMethod("GET")
def responseCode = conn.getResponseCode()
final slurper = new groovy.json.JsonSlurper()
def repos = slurper.parse(conn.getInputStream()).values
for (repo in repos) {
if (repo.slug.contains('one-'))
result << repo.slug
}
return result
}
Микросервисы
178
179
Install Master
Configure
Slaves
Create
meta job
Ansible
180
Install Master
Configure
Slaves
Create
meta job
Ansible
cURL
181
Install Master
Configure
Slaves
Create
meta job
Create
pipelines
jobs.each { job ->
pipelineJob("${basePath}/${job}") {
//define SCM
definition {
cps {
script(readFileFromWorkspace('pipeline-template.groovy'))
sandbox()
}
}
}
}
JobDSL plugin
182
jobs.each { job ->
pipelineJob("${basePath}/${job}") {
//define SCM
definition {
cps {
script(readFileFromWorkspace('pipeline-template.groovy'))
sandbox()
}
}
}
}
JobDSL plugin
183
jobs.each { job ->
pipelineJob("${basePath}/${job}") {
//define SCM
definition {
cps {
script(readFileFromWorkspace('pipeline-template.groovy'))
sandbox()
}
}
}
}
JobDSL plugin
184
185
Install Master
Configure
Slaves
Create
meta job
Create
pipelines
git
ansible-playbook -i jenkins-for-my-team jenkins.yml
186
Это последний раз
Что получили?
● Пайплайн как код
● Неубиваемый CI
○ без бэкапов
○ всё хранится как код
○ разворачивается за X минут
187
Development Testing Deployment
Post
Deployment
188
> ./gradlew build test
Development Testing Deployment
Post
Deployment
189
> ./gradlew integrationTest publishDocs
Development Testing Deployment
Post
Deployment
190
> ansible-playbook -i env deploy.yml
Development Testing Deployment
Post
Deployment
191
> ansible-playbook -i prod exp.yml
Development Testing Deployment
Post
Deployment
192
Delivery Pipeline
193
Позитивные выводы
● Почти любой процесс можно
формализовать, представить в
виде кода и автоматизировать
● Мы все пишем код, хотя можем
думать, что это не так
● Рано или поздно всё превращается
в код
194
Trade-offs
● Необходимы как разовые
“капиталовложения”, так и
постоянные затраты ресурсов
● Могут потребоваться изменения в
архитектуре
● Требует дисциплины и более
высокой квалификации
специалистов
195
Спасибо, что выбрали красную
@aatarasoff
@aatarasoff
@aatarasoff
QA

Weitere ähnliche Inhalte

Was ist angesagt?

Zero Downtime Deployment with Ansible
Zero Downtime Deployment with AnsibleZero Downtime Deployment with Ansible
Zero Downtime Deployment with AnsibleStein Inge Morisbak
 
Continuous Integration: SaaS vs Jenkins in Cloud
Continuous Integration: SaaS vs Jenkins in CloudContinuous Integration: SaaS vs Jenkins in Cloud
Continuous Integration: SaaS vs Jenkins in CloudIdeato
 
Ansible not only for Dummies
Ansible not only for DummiesAnsible not only for Dummies
Ansible not only for DummiesŁukasz Proszek
 
Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Halil Kaya
 
Making environment for_infrastructure_as_code
Making environment for_infrastructure_as_codeMaking environment for_infrastructure_as_code
Making environment for_infrastructure_as_codeSoshi Nemoto
 
Docker orchestration v4
Docker orchestration v4Docker orchestration v4
Docker orchestration v4Hojin Kim
 
How to stay sane during your Vagrant journey
How to stay sane during your Vagrant journeyHow to stay sane during your Vagrant journey
How to stay sane during your Vagrant journeyJakub Wadolowski
 
Preparation study of_docker - (MOSG)
Preparation study of_docker  - (MOSG)Preparation study of_docker  - (MOSG)
Preparation study of_docker - (MOSG)Soshi Nemoto
 
What Have Syscalls Done for you Lately?
What Have Syscalls Done for you Lately?What Have Syscalls Done for you Lately?
What Have Syscalls Done for you Lately?Docker, Inc.
 
Into The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and dockerInto The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and dockerOrtus Solutions, Corp
 
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
파이썬 개발환경 구성하기의 끝판왕 - Docker Composeraccoony
 
開放運算&GPU技術研究班
開放運算&GPU技術研究班開放運算&GPU技術研究班
開放運算&GPU技術研究班Paul Chao
 
DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)Soshi Nemoto
 
How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...
How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...
How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...Docker, Inc.
 
Python virtualenv & pip in 90 minutes
Python virtualenv & pip in 90 minutesPython virtualenv & pip in 90 minutes
Python virtualenv & pip in 90 minutesLarry Cai
 
Testing Wi-Fi with OSS Tools
Testing Wi-Fi with OSS ToolsTesting Wi-Fi with OSS Tools
Testing Wi-Fi with OSS ToolsAll Things Open
 
[오픈소스컨설팅] Linux Network Troubleshooting
[오픈소스컨설팅] Linux Network Troubleshooting[오픈소스컨설팅] Linux Network Troubleshooting
[오픈소스컨설팅] Linux Network TroubleshootingOpen Source Consulting
 

Was ist angesagt? (20)

Zero Downtime Deployment with Ansible
Zero Downtime Deployment with AnsibleZero Downtime Deployment with Ansible
Zero Downtime Deployment with Ansible
 
Continuous Integration: SaaS vs Jenkins in Cloud
Continuous Integration: SaaS vs Jenkins in CloudContinuous Integration: SaaS vs Jenkins in Cloud
Continuous Integration: SaaS vs Jenkins in Cloud
 
Ansible not only for Dummies
Ansible not only for DummiesAnsible not only for Dummies
Ansible not only for Dummies
 
Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36
 
Making environment for_infrastructure_as_code
Making environment for_infrastructure_as_codeMaking environment for_infrastructure_as_code
Making environment for_infrastructure_as_code
 
Docker orchestration v4
Docker orchestration v4Docker orchestration v4
Docker orchestration v4
 
(Re)discover your AEM
(Re)discover your AEM(Re)discover your AEM
(Re)discover your AEM
 
How to stay sane during your Vagrant journey
How to stay sane during your Vagrant journeyHow to stay sane during your Vagrant journey
How to stay sane during your Vagrant journey
 
Preparation study of_docker - (MOSG)
Preparation study of_docker  - (MOSG)Preparation study of_docker  - (MOSG)
Preparation study of_docker - (MOSG)
 
What Have Syscalls Done for you Lately?
What Have Syscalls Done for you Lately?What Have Syscalls Done for you Lately?
What Have Syscalls Done for you Lately?
 
Into The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and dockerInto The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and docker
 
Statyczna analiza kodu PHP
Statyczna analiza kodu PHPStatyczna analiza kodu PHP
Statyczna analiza kodu PHP
 
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
 
開放運算&GPU技術研究班
開放運算&GPU技術研究班開放運算&GPU技術研究班
開放運算&GPU技術研究班
 
DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)DevOps(3) : Ansible - (MOSG)
DevOps(3) : Ansible - (MOSG)
 
How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...
How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...
How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...
 
Python virtualenv & pip in 90 minutes
Python virtualenv & pip in 90 minutesPython virtualenv & pip in 90 minutes
Python virtualenv & pip in 90 minutes
 
kubernetes practice
kubernetes practicekubernetes practice
kubernetes practice
 
Testing Wi-Fi with OSS Tools
Testing Wi-Fi with OSS ToolsTesting Wi-Fi with OSS Tools
Testing Wi-Fi with OSS Tools
 
[오픈소스컨설팅] Linux Network Troubleshooting
[오픈소스컨설팅] Linux Network Troubleshooting[오픈소스컨설팅] Linux Network Troubleshooting
[오픈소스컨설팅] Linux Network Troubleshooting
 

Ähnlich wie Everything as a Code / Александр Тарасов (Одноклассники)

Guide to Node.js: Basic to Advanced
Guide to Node.js: Basic to AdvancedGuide to Node.js: Basic to Advanced
Guide to Node.js: Basic to AdvancedEspeo Software
 
OWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA TestersOWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA TestersJavan Rasokat
 
Madrid JAM limitaciones - dificultades
Madrid JAM limitaciones - dificultadesMadrid JAM limitaciones - dificultades
Madrid JAM limitaciones - dificultadesJavier Delgado Garrido
 
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMPInria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMPStéphanie Roger
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Roberto Franchini
 
PuppetDB: A Single Source for Storing Your Puppet Data - PUG NY
PuppetDB: A Single Source for Storing Your Puppet Data - PUG NYPuppetDB: A Single Source for Storing Your Puppet Data - PUG NY
PuppetDB: A Single Source for Storing Your Puppet Data - PUG NYPuppet
 
Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)DECK36
 
Java EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJava EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJiayun Zhou
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleAnton Arhipov
 
Introduction to Codeigniter
Introduction to Codeigniter Introduction to Codeigniter
Introduction to Codeigniter Zero Huang
 
DevOps Workflow: A Tutorial on Linux Containers
DevOps Workflow: A Tutorial on Linux ContainersDevOps Workflow: A Tutorial on Linux Containers
DevOps Workflow: A Tutorial on Linux Containersinside-BigData.com
 
What to expect from Java 9
What to expect from Java 9What to expect from Java 9
What to expect from Java 9Ivan Krylov
 
[CB20] Vulnerabilities of Machine Learning Infrastructure by Sergey Gordeychik
[CB20] Vulnerabilities of Machine Learning Infrastructure by Sergey Gordeychik[CB20] Vulnerabilities of Machine Learning Infrastructure by Sergey Gordeychik
[CB20] Vulnerabilities of Machine Learning Infrastructure by Sergey GordeychikCODE BLUE
 
.gradle 파일 정독해보기
.gradle 파일 정독해보기.gradle 파일 정독해보기
.gradle 파일 정독해보기경주 전
 

Ähnlich wie Everything as a Code / Александр Тарасов (Одноклассники) (20)

Js tacktalk team dev js testing performance
Js tacktalk team dev js testing performanceJs tacktalk team dev js testing performance
Js tacktalk team dev js testing performance
 
Gradle
GradleGradle
Gradle
 
Guide to Node.js: Basic to Advanced
Guide to Node.js: Basic to AdvancedGuide to Node.js: Basic to Advanced
Guide to Node.js: Basic to Advanced
 
Excelian hyperledger walkthrough-feb17
Excelian hyperledger walkthrough-feb17Excelian hyperledger walkthrough-feb17
Excelian hyperledger walkthrough-feb17
 
OWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA TestersOWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA Testers
 
Madrid JAM limitaciones - dificultades
Madrid JAM limitaciones - dificultadesMadrid JAM limitaciones - dificultades
Madrid JAM limitaciones - dificultades
 
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMPInria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!
 
PuppetDB: A Single Source for Storing Your Puppet Data - PUG NY
PuppetDB: A Single Source for Storing Your Puppet Data - PUG NYPuppetDB: A Single Source for Storing Your Puppet Data - PUG NY
PuppetDB: A Single Source for Storing Your Puppet Data - PUG NY
 
Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)Our Puppet Story (GUUG FFG 2015)
Our Puppet Story (GUUG FFG 2015)
 
Java EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJava EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSF
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
 
Introduction to Codeigniter
Introduction to Codeigniter Introduction to Codeigniter
Introduction to Codeigniter
 
DevOps Workflow: A Tutorial on Linux Containers
DevOps Workflow: A Tutorial on Linux ContainersDevOps Workflow: A Tutorial on Linux Containers
DevOps Workflow: A Tutorial on Linux Containers
 
Living with garbage
Living with garbageLiving with garbage
Living with garbage
 
Living With Garbage
Living With GarbageLiving With Garbage
Living With Garbage
 
What to expect from Java 9
What to expect from Java 9What to expect from Java 9
What to expect from Java 9
 
[CB20] Vulnerabilities of Machine Learning Infrastructure by Sergey Gordeychik
[CB20] Vulnerabilities of Machine Learning Infrastructure by Sergey Gordeychik[CB20] Vulnerabilities of Machine Learning Infrastructure by Sergey Gordeychik
[CB20] Vulnerabilities of Machine Learning Infrastructure by Sergey Gordeychik
 
.gradle 파일 정독해보기
.gradle 파일 정독해보기.gradle 파일 정독해보기
.gradle 파일 정독해보기
 

Mehr von Ontico

One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...Ontico
 
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Ontico
 
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Ontico
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Ontico
 
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Ontico
 
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)Ontico
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Ontico
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Ontico
 
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)Ontico
 
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)Ontico
 
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Ontico
 
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Ontico
 
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Ontico
 
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Ontico
 
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)Ontico
 
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Ontico
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Ontico
 
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...Ontico
 
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Ontico
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Ontico
 

Mehr von Ontico (20)

One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
 
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
 
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
 
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
 
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
 
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
 
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
 
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
 
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
 
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
 
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
 
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
 
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
 
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
 
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
 

Kürzlich hochgeladen

UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performancesivaprakash250
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSISrknatarajan
 
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).pptssuser5c9d4b1
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)simmis5
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...roncy bisnoi
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Christo Ananth
 
SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )Tsuyoshi Horigome
 
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...Soham Mondal
 
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Serviceranjana rawat
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSSIVASHANKAR N
 
Porous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingPorous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingrakeshbaidya232001
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Dr.Costas Sachpazis
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escortsranjana rawat
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130Suhani Kapoor
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
UNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular ConduitsUNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular Conduitsrknatarajan
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSAPPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSKurinjimalarL3
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...ranjana rawat
 

Kürzlich hochgeladen (20)

UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSIS
 
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt
247267395-1-Symmetric-and-distributed-shared-memory-architectures-ppt (1).ppt
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
 
SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )
 
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
 
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
 
Porous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingPorous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writing
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
 
UNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular ConduitsUNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular Conduits
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
 
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINEDJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
 
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSAPPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
 

Everything as a Code / Александр Тарасов (Одноклассники)