Mari kita ingat rencana pergerakan kita:
1 bagian . Kami memutuskan TOR dan arsitektur solusinya, menulis aplikasi di golang.
Bagian 2 (Anda di sini sekarang). Kami merilis aplikasi kami ke produksi, membuatnya dapat diskalakan dan menguji beban.
Bagian 3. Mari kita coba mencari tahu mengapa kita perlu menyimpan pesan dalam buffer, dan bukan dalam file, dan juga membandingkan layanan antrian kafka, rabbitmq, dan yandex di antara mereka sendiri.
Bagian 4. Kami akan menerapkan cluster Clickhouse, menulis streaming untuk mentransfer data dari buffer di sana, menyiapkan visualisasi di datalens.
Bagian 5.Mari kita letakkan seluruh infrastruktur dalam bentuk yang tepat - konfigurasikan ci / cd menggunakan gitlab ci, hubungkan pemantauan dan penemuan layanan menggunakan consul dan prometheus.
Baiklah, mari kita lanjutkan ke tugas kita.
Kami tuangkan ke dalam produksi
Pada bagian 1, kami merakit aplikasi, mengujinya, dan juga mengunggah gambar ke registri kontainer pribadi, siap untuk diterapkan.
Secara umum, langkah selanjutnya seharusnya hampir jelas - kami membuat mesin virtual, menyiapkan penyeimbang beban, dan mendaftarkan nama DNS dengan proxy ke cloudflare. Tetapi saya khawatir opsi ini tidak cocok dengan kerangka acuan kami. Kami ingin dapat menskalakan layanan kami jika terjadi peningkatan beban dan membuang node yang rusak darinya yang tidak dapat melayani permintaan.
Untuk penskalaan, kami akan menggunakan grup instance yang tersedia di komputasi awan. Mereka memungkinkan Anda membuat mesin virtual dari template, memantau ketersediaannya menggunakan health check, dan juga secara otomatis meningkatkan jumlah node jika terjadi peningkatan beban.Lebih lengkapnya di sini .
Hanya ada satu pertanyaan - template mana yang digunakan untuk mesin virtual? Tentu saja, Anda dapat menginstal linux, mengkonfigurasinya, membuat gambar dan mengunggahnya ke penyimpanan gambar di Yandex.Cloud. Tetapi bagi kami ini adalah perjalanan yang panjang dan sulit. Saat meninjau berbagai gambar yang tersedia saat membuat mesin virtual, kami menemukan contoh menarik - gambar yang dioptimalkan untuk wadah ( https://cloud.yandex.ru/docs/cos/concepts/ ). Ini memungkinkan Anda untuk menjalankan kontainer buruh pelabuhan tunggal dalam mode jaringan host. Artinya, saat membuat mesin virtual, kira-kira spesifikasi berikut diindikasikan untuk gambar yang dioptimalkan untuk container:
spec:
containers:
- name: api
image: vozerov/events-api:v1
command:
- /app/app
args:
- -kafka=kafka.ru-central1.internal:9092
securityContext:
privileged: false
tty: false
stdin: false
restartPolicy: Always
Dan setelah mesin virtual dimulai, penampung ini akan diunduh dan diluncurkan secara lokal.
Skemanya cukup menarik:
- Kami membuat grup instance dengan penskalaan otomatis saat penggunaan cpu melebihi 60%.
- Sebagai template, kami menentukan mesin virtual dengan gambar dan parameter yang dioptimalkan untuk container untuk menjalankan container Docker kami.
- Kami membuat penyeimbang beban, yang akan melihat grup instance kami dan memperbarui secara otomatis saat menambahkan atau menghapus mesin virtual.
- Aplikasi akan dipantau sebagai grup instance dan oleh penyeimbang itu sendiri, yang akan membuat mesin virtual yang tidak dapat diakses kehilangan keseimbangan.
Kedengaranya seperti sebuah rencana!
Mari kita coba membuat grup instance menggunakan terraform. Seluruh deskripsi ada di instance-group.tf, saya akan mengomentari poin utama:
- ID akun layanan akan digunakan untuk membuat dan menghapus mesin virtual. Ngomong-ngomong, kita harus membuatnya.
service_account_id = yandex_iam_service_account.instances.id
- spec.yml, , . registry , - β docker hub. , β
metadata = { docker-container-declaration = file("spec.yml") ssh-keys = "ubuntu:${file("~/.ssh/id_rsa.pub")}" }
- service account id, container optimized image, container registry . registry , :
service_account_id = yandex_iam_service_account.docker.id
- Scale policy. :
autoscale { initialsize = 3 measurementduration = 60 cpuutilizationtarget = 60 minzonesize = 1 maxsize = 6 warmupduration = 60 stabilizationduration = 180 }
. β fixed_scale , auth_scale.
:
initial size β ;
measurement_duration β ;
cpu_utilization_target β , ;
min_zone_size β β , ;
max_size β ;
warmup_duration β , , ;
stabilization_duration β β , .
. 3 (initial_size), (min_zone_size). cpu (measurement_duration). 60% (cpu_utilization_target), , (max_size). 60 (warmup_duration), cpu. 120 (stabilization_duration), 60% (cpu_utilization_target).
β https://cloud.yandex.ru/docs/compute/concepts/instance-groups/policies#auto-scale-policy - Allocation policy. , , β .
allocationpolicy { zones = ["ru-central1-a", "ru-central1-b", "ru-central1-c"] }
- :
deploy_policy { maxunavailable = 1 maxcreating = 1 maxexpansion = 1 maxdeleting = 1 }
max_creating β ;
max_deleting β ;
max_expansion β ;
max_unavailable β RUNNING, ;
β https://cloud.yandex.ru/docs/compute/concepts/instance-groups/policies#deploy-policy - :
load_balancer { target_group_name = "events-api-tg" }
Saat membuat grup instance, Anda juga dapat membuat grup target untuk penyeimbang beban. Ini akan menargetkan mesin virtual terkait. Jika dihapus, node akan dihapus dari penyeimbangan, dan setelah dibuat, node tersebut akan ditambahkan ke penyeimbangan setelah melewati pemeriksaan status.
Tampaknya semuanya dasar - mari buat akun layanan untuk grup instance dan, faktanya, grup itu sendiri.
vozerov@mba:~/events/terraform (master *) $ terraform apply -target yandex_iam_service_account.instances -target yandex_resourcemanager_folder_iam_binding.editor
... skipped ...
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
vozerov@mba:~/events/terraform (master *) $ terraform apply -target yandex_compute_instance_group.events_api_ig
... skipped ...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Grup telah dibuat - Anda dapat melihat dan memeriksa:
vozerov@mba:~/events/terraform (master *) $ yc compute instance-group list
+----------------------+---------------+------+
| ID | NAME | SIZE |
+----------------------+---------------+------+
| cl1s2tu8siei464pv1pn | events-api-ig | 3 |
+----------------------+---------------+------+
vozerov@mba:~/events/terraform (master *) $ yc compute instance list
+----------------------+---------------------------+---------------+---------+----------------+-------------+
| ID | NAME | ZONE ID | STATUS | EXTERNAL IP | INTERNAL IP |
+----------------------+---------------------------+---------------+---------+----------------+-------------+
| ef3huodj8g4gc6afl0jg | cl1s2tu8siei464pv1pn-ocih | ru-central1-c | RUNNING | 130.193.44.106 | 172.16.3.3 |
| epdli4s24on2ceel46sr | cl1s2tu8siei464pv1pn-ipym | ru-central1-b | RUNNING | 84.201.164.196 | 172.16.2.31 |
| fhmf37k03oobgu9jmd7p | kafka | ru-central1-a | RUNNING | 84.201.173.41 | 172.16.1.31 |
| fhmh4la5dj0m82ihoskd | cl1s2tu8siei464pv1pn-ahuj | ru-central1-a | RUNNING | 130.193.37.94 | 172.16.1.37 |
| fhmr401mknb8omfnlrc0 | monitoring | ru-central1-a | RUNNING | 84.201.159.71 | 172.16.1.14 |
| fhmt9pl1i8sf7ga6flgp | build | ru-central1-a | RUNNING | 84.201.132.3 | 172.16.1.26 |
+----------------------+---------------------------+---------------+---------+----------------+-------------+
vozerov@mba:~/events/terraform (master *) $
Tiga node dengan nama bengkok adalah grup kami. Kami memeriksa apakah aplikasi tersedia untuk mereka:
vozerov@mba:~/events/terraform (master *) $ curl -D - -s http://130.193.44.106:8080/status
HTTP/1.1 200 OK
Date: Mon, 13 Apr 2020 16:32:04 GMT
Content-Length: 3
Content-Type: text/plain; charset=utf-8
ok
vozerov@mba:~/events/terraform (master *) $ curl -D - -s http://84.201.164.196:8080/status
HTTP/1.1 200 OK
Date: Mon, 13 Apr 2020 16:32:09 GMT
Content-Length: 3
Content-Type: text/plain; charset=utf-8
ok
vozerov@mba:~/events/terraform (master *) $ curl -D - -s http://130.193.37.94:8080/status
HTTP/1.1 200 OK
Date: Mon, 13 Apr 2020 16:32:15 GMT
Content-Length: 3
Content-Type: text/plain; charset=utf-8
ok
vozerov@mba:~/events/terraform (master *) $
Ngomong-ngomong, Anda bisa pergi ke mesin virtual dengan login ubuntu dan melihat log penampung dan bagaimana itu dimulai.
Grup target juga telah dibuat untuk penyeimbang ke mana permintaan dapat dikirim:
vozerov@mba:~/events/terraform (master *) $ yc load-balancer target-group list
+----------------------+---------------+---------------------+-------------+--------------+
| ID | NAME | CREATED | REGION ID | TARGET COUNT |
+----------------------+---------------+---------------------+-------------+--------------+
| b7rhh6d4assoqrvqfr9g | events-api-tg | 2020-04-13 16:23:53 | ru-central1 | 3 |
+----------------------+---------------+---------------------+-------------+--------------+
vozerov@mba:~/events/terraform (master *) $
Mari kita sudah membuat penyeimbang dan mencoba mengirim lalu lintas ke sana! Proses ini dijelaskan di load-balancer.tf, poin-poin penting:
- Kami menunjukkan port eksternal mana yang akan didengarkan oleh penyeimbang dan port mana yang mengirim permintaan ke mesin virtual. Kami menunjukkan jenis alamat eksternal - ip v4. Saat ini, penyeimbang beban beroperasi pada tingkat pengangkutan, sehingga hanya dapat menyeimbangkan koneksi tcp / udp. Jadi Anda harus memasang ssl baik di mesin virtual Anda, atau pada layanan eksternal yang dapat menangani https, misalnya, cloudflare.
listener { name = "events-api-listener" port = 80 target_port = 8080 external_address_spec { ipversion = "ipv4" } }
healthcheck { name = "http" http_options { port = 8080 path = "/status" } }
Pemeriksaan kesehatan. Di sini kami menentukan parameter untuk memeriksa node kami - kami memeriksa dengan http url / status pada port 8080. Jika pemeriksaan gagal, mesin akan dikeluarkan dari penyeimbangan.
Informasi selengkapnya tentang penyeimbang beban - cloud.yandex.ru/docs/load-balancer/concepts . Menariknya, Anda dapat menghubungkan layanan perlindungan DDOS pada penyeimbang. Kemudian lalu lintas yang sudah dibersihkan akan datang ke server Anda.
Kami menciptakan:
vozerov@mba:~/events/terraform (master *) $ terraform apply -target yandex_lb_network_load_balancer.events_api_lb
... skipped ...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Kami mengambil ip penyeimbang yang dibuat dan menguji pekerjaan:
vozerov@mba:~/events/terraform (master *) $ yc load-balancer network-load-balancer get events-api-lb
id:
folder_id:
created_at: "2020-04-13T16:34:28Z"
name: events-api-lb
region_id: ru-central1
status: ACTIVE
type: EXTERNAL
listeners:
- name: events-api-listener
address: 130.193.37.103
port: "80"
protocol: TCP
target_port: "8080"
attached_target_groups:
- target_group_id:
health_checks:
- name: http
interval: 2s
timeout: 1s
unhealthy_threshold: "2"
healthy_threshold: "2"
http_options:
port: "8080"
path: /status
Sekarang kita bisa meninggalkan pesan di dalamnya:
vozerov@mba:~/events/terraform (master *) $ curl -D - -s -X POST -d '{"key1":"data1"}' http://130.193.37.103/post
HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 13 Apr 2020 16:42:57 GMT
Content-Length: 41
{"status":"ok","partition":0,"Offset":1}
vozerov@mba:~/events/terraform (master *) $ curl -D - -s -X POST -d '{"key1":"data1"}' http://130.193.37.103/post
HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 13 Apr 2020 16:42:58 GMT
Content-Length: 41
{"status":"ok","partition":0,"Offset":2}
vozerov@mba:~/events/terraform (master *) $ curl -D - -s -X POST -d '{"key1":"data1"}' http://130.193.37.103/post
HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 13 Apr 2020 16:43:00 GMT
Content-Length: 41
{"status":"ok","partition":0,"Offset":3}
vozerov@mba:~/events/terraform (master *) $
Bagus, semuanya bekerja. Ada sentuhan terakhir yang tersisa sehingga kami dapat diakses melalui https - kami akan menghubungkan cloudflare dengan proxying. Jika Anda memutuskan untuk melakukannya tanpa cloudflare, Anda dapat melewati langkah ini.
vozerov@mba:~/events/terraform (master *) $ terraform apply -target cloudflare_record.events
... skipped ...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Menguji melalui HTTPS:
vozerov@mba:~/events/terraform (master *) $ curl -D - -s -X POST -d '{"key1":"data1"}' https://events.kis.im/post
HTTP/2 200
date: Mon, 13 Apr 2020 16:45:01 GMT
content-type: application/json
content-length: 41
set-cookie: __cfduid=d7583eb5f791cd3c1bdd7ce2940c8a7981586796301; expires=Wed, 13-May-20 16:45:01 GMT; path=/; domain=.kis.im; HttpOnly; SameSite=Lax
cf-cache-status: DYNAMIC
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 5836a7b1bb037b2b-DME
{"status":"ok","partition":0,"Offset":5}
vozerov@mba:~/events/terraform (master *) $
Semuanya akhirnya bekerja.
Menguji beban
Kami hanya memiliki langkah yang paling menarik - untuk melakukan pengujian beban layanan kami dan mendapatkan beberapa angka - misalnya, persentil ke-95 dari waktu pemrosesan satu permintaan. Akan menyenangkan juga untuk menguji penskalaan otomatis nodegroup kami.
Sebelum memulai pengujian, ada baiknya melakukan satu hal sederhana - tambahkan node aplikasi kita ke prometheus untuk melacak jumlah permintaan dan waktu pemrosesan satu permintaan. Karena kami belum menambahkan penemuan layanan apa pun (kami akan melakukannya di artikel 5 dari seri ini), kami hanya akan menulis static_configs di server pemantauan kami. Anda dapat mengetahui ip-nya dengan cara standar melalui daftar contoh komputasi yc, dan kemudian menambahkan pengaturan berikut ke /etc/prometheus/prometheus.yml:
- job_name: api
metrics_path: /metrics
static_configs:
- targets:
- 172.16.3.3:8080
- 172.16.2.31:8080
- 172.16.1.37:8080
Alamat IP mesin kami juga dapat diambil dari daftar contoh komputasi yc. Mulai ulang prometheus melalui systemctl restart prometheus dan periksa apakah node berhasil disurvei dengan membuka antarmuka web yang tersedia di port 9090 (84.201.159.71:9090).
Mari tambahkan dasbor ke grafana dari folder grafana. Kami pergi ke Grafana di port 3000 (84.201.159.71:3000) dan dengan nama pengguna / kata sandi - admin / Kata sandi. Selanjutnya, tambahkan prometheus lokal dan impor dasbor. Sebenarnya, pada titik ini, persiapan sudah selesai - Anda dapat mengajukan permintaan di instalasi kami.
Untuk pengujian, kami akan menggunakan tangki yandex ( https://yandex.ru/dev/tank/ ) dengan plugin untuk overload.yandex.netyang akan memungkinkan kami untuk memvisualisasikan data yang diterima oleh tangki. Semua yang Anda butuhkan untuk bekerja ada di folder muat dari repositori git asli.
Sedikit tentang apa yang ada di sana:
- token.txt - file dengan kunci API dari overload.yandex.net - Anda bisa mendapatkannya dengan mendaftar di layanan.
- load.yml - file konfigurasi untuk tangki, ada domain untuk pengujian - events.kis.im, jenis beban rps dan jumlah permintaan 15.000 per detik selama 3 menit.
- data - file khusus untuk membuat konfigurasi dalam format ammo.txt. Di dalamnya kami menulis jenis permintaan, url, grup untuk menampilkan statistik dan data aktual yang perlu dikirim.
- makeammo.py - script untuk menghasilkan file ammo.txt dari file data. Lebih lanjut tentang script - yandextank.readthedocs.io/en/latest/ammo_generators.html
- ammo.txt - file amunisi yang dihasilkan yang akan digunakan untuk mengirim permintaan.
Untuk pengujian, saya mengambil mesin virtual di luar Yandex.Cloud (untuk menjaga semuanya tetap jujur) dan membuat catatan DNS untuk itu load.kis.im. Saya menggulung buruh pelabuhan di sana, karena kami akan memulai tangki menggunakan gambar https://hub.docker.com/r/direvius/yandex-tank/ .
Baiklah, mari kita mulai. Salin folder kami ke server, tambahkan token dan mulai tangki:
vozerov@mba:~/events (master *) $ rsync -av load/ cloud-user@load.kis.im:load/
... skipped ...
sent 2195 bytes received 136 bytes 1554.00 bytes/sec
total size is 1810 speedup is 0.78
vozerov@mba:~/events (master *) $ ssh load.kis.im -l cloud-user
cloud-user@load:~$ cd load/
cloud-user@load:~/load$ echo "TOKEN" > token.txt
cloud-user@load:~/load$ sudo docker run -v $(pwd):/var/loadtest --net host --rm -it direvius/yandex-tank -c load.yaml ammo.txt
No handlers could be found for logger "netort.resource"
17:25:25 [INFO] New test id 2020-04-13_17-25-25.355490
17:25:25 [INFO] Logging handler <logging.StreamHandler object at 0x7f209a266850> added
17:25:25 [INFO] Logging handler <logging.StreamHandler object at 0x7f209a20aa50> added
17:25:25 [INFO] Created a folder for the test. /var/loadtest/logs/2020-04-13_17-25-25.355490
17:25:25 [INFO] Configuring plugins...
17:25:25 [INFO] Loading plugins...
17:25:25 [INFO] Testing connection to resolved address 104.27.164.45 and port 80
17:25:25 [INFO] Resolved events.kis.im into 104.27.164.45:80
17:25:25 [INFO] Configuring StepperWrapper...
17:25:25 [INFO] Making stpd-file: /var/loadtest/ammo.stpd
17:25:25 [INFO] Default ammo type ('phantom') used, use 'phantom.ammo_type' option to override it
... skipped ...
Itu dia, prosesnya sedang berjalan. Di konsol, terlihat seperti ini:
Dan kami sedang menunggu penyelesaian proses dan mengamati waktu respons, jumlah permintaan, dan, tentu saja, penskalaan otomatis grup mesin virtual kami. Anda dapat memantau sekelompok mesin virtual melalui antarmuka web; dalam pengaturan sekelompok mesin virtual terdapat tab "Pemantauan".
Seperti yang Anda lihat, node kami tidak memuat bahkan hingga 50% dari CPU, jadi uji penskalaan otomatis harus diulang. Untuk saat ini, mari kita lihat waktu pemrosesan request di Grafana:
Jumlah permintaan - sekitar 3000 per node - tidak dimuat sedikit hingga 10.000. Waktu respons menyenangkan - sekitar 11 md per permintaan. Satu-satunya yang menonjol - 172.16.1.37 - memiliki separuh waktu untuk memproses permintaan. Tapi ini juga logis - ini berada di zona ketersediaan ru-central1-a yang sama dengan kafka, yang menyimpan pesan.
Omong-omong, laporan peluncuran pertama tersedia di tautan: https://overload.yandex.net/265967 .
Jadi, mari kita jalankan pengujian yang lebih menyenangkan - tambahkan parameter instance: 2000 untuk mendapatkan 15.000 permintaan per detik, dan tingkatkan waktu pengujian menjadi 10 menit. File yang dihasilkan akan terlihat seperti ini:
overload:
enabled: true
package: yandextank.plugins.DataUploader
token_file: "token.txt"
phantom:
address: 130.193.37.103
load_profile:
load_type: rps
schedule: const(15000, 10m)
instances: 2000
console:
enabled: true
telegraf:
enabled: false
Pembaca yang penuh perhatian akan melihat bahwa saya mengubah alamat ke IP penyeimbang - ini karena fakta bahwa cloudflare mulai memblokir saya untuk sejumlah besar permintaan dari satu ip. Saya harus mengatur tangki langsung di penyeimbang Yandex.Cloud. Setelah peluncuran, Anda dapat mengamati gambar berikut:
Penggunaan CPU telah berkembang, dan penjadwal memutuskan untuk meningkatkan jumlah node di zona B, yang dia lakukan. Ini dapat dilihat di log grup instance:
vozerov@mba:~/events/load (master *) $ yc compute instance-group list-logs events-api-ig
2020-04-13 18:26:47 cl1s2tu8siei464pv1pn-ejok.ru-central1.internal 1m AWAITING_WARMUP_DURATION -> RUNNING_ACTUAL
2020-04-13 18:25:47 cl1s2tu8siei464pv1pn-ejok.ru-central1.internal 37s OPENING_TRAFFIC -> AWAITING_WARMUP_DURATION
2020-04-13 18:25:09 cl1s2tu8siei464pv1pn-ejok.ru-central1.internal 43s CREATING_INSTANCE -> OPENING_TRAFFIC
2020-04-13 18:24:26 cl1s2tu8siei464pv1pn-ejok.ru-central1.internal 6s DELETED -> CREATING_INSTANCE
2020-04-13 18:24:19 cl1s2tu8siei464pv1pn-ozix.ru-central1.internal 0s PREPARING_RESOURCES -> DELETED
2020-04-13 18:24:19 cl1s2tu8siei464pv1pn-ejok.ru-central1.internal 0s PREPARING_RESOURCES -> DELETED
2020-04-13 18:24:15 Target allocation changed in accordance with auto scale policy in zone ru-central1-a: 1 -> 2
2020-04-13 18:24:15 Target allocation changed in accordance with auto scale policy in zone ru-central1-b: 1 -> 2
... skipped ...
2020-04-13 16:23:57 Balancer target group b7rhh6d4assoqrvqfr9g created
2020-04-13 16:23:43 Going to create balancer target group
Penjadwal juga memutuskan untuk meningkatkan jumlah server di zona lain, tetapi saya kehabisan batas pada alamat-ip eksternal :) Omong-omong, mereka dapat ditingkatkan melalui permintaan ke dukungan teknis, menentukan kuota dan nilai yang diinginkan.
Kesimpulan
Artikel itu tidak mudah - baik dalam volume maupun jumlah informasinya. Tetapi kami melewati tahap yang paling sulit dan melakukan hal berikut:
- Peningkatan pemantauan dan kafka.
- , .
- load balancerβ cloudflare ssl .
Lain kali, mari bandingkan dan uji layanan antrean rabbitmq / kafka / yandex.
Tetap disini!
* Materi ini ada dalam rekaman video lokakarya terbuka REBRAIN & Yandex.Cloud: Kami menerima 10.000 permintaan per detik di Yandex Cloud - https://youtu.be/cZLezUm0ekE
Jika Anda tertarik untuk menghadiri acara semacam itu secara online dan mengajukan pertanyaan secara real time, hubungi saluran DevOps oleh REBRAIN .
Kami ingin mengucapkan terima kasih khusus kepada Yandex.Cloud atas kesempatan untuk mengadakan acara seperti itu. Tautkan ke mereka
Jika Anda perlu pindah ke cloud atau memiliki pertanyaan tentang infrastruktur Anda, silakan tinggalkan permintaan .
PS Kami memiliki 2 audit gratis per bulan, mungkin proyek Anda termasuk di antaranya.