Lihat arsitekturnya? Dan saya tidak melihat, tetapi dia

Dalam perkembangan hh.ru hari ini sekitar 150 orang. Kami memiliki banyak tim yang menarik, dan masing-masing memberikan kontribusi yang signifikan. Tetapi dalam artikel ini saya hanya akan menceritakan tentang salah satunya.


Karena saya adalah pemimpin timnya, dan ada beberapa alasan untuk ini:

  • seringkali para kandidat tidak mengerti apa yang kita lakukan;
  • kadang-kadang bahkan karyawan di dalam perusahaan tidak mengetahui hal ini, karena tim kami tidak memiliki manajer produk, area fungsional bisnisnya sendiri dan daftar layanan yang didukung oleh kami ...;
  • kebajikan kita paling sering tetap berada di tempat teduh;
  • pada akhirnya, "jika Anda ingin mencari tahu, cobalah untuk menjelaskannya kepada seseorang" :)

Oleh karena itu, saya akan mencoba memahami dengan contoh-contoh yang dapat dimengerti tentang apa sebenarnya pekerjaan kita.

Mari kita mulai dengan yang paling umum, yaitu, dengan prioritas, ada dua di antaranya:

  • dukungan sistem untuk keandalan dan ketahanan platform kami. Di sini perlu diperhatikan kata "sistem" - artinya kita tidak akan memperbaiki cacat kinerja tertentu, tetapi mengembangkan aturan dan pola umum, memperbaikinya dalam kerangka kerja, pemeriksaan otomatis, dll. Sehingga berfungsi untuk semua orang.
  • fokus pengembangan pada logika bisnis. Artinya, semakin sedikit pengembang berpikir tentang mendukung keandalan, arsitektur, dll. - lebih baik. Jelas bahwa membersihkan pikiran dari rekan semacam itu agak berbahaya, tetapi menjaga keseimbangan yang masuk akal masuk akal.

Dari prioritas ini, arahan utama pekerjaan kami mengikuti:

0. Dukungan dan pengembangan arsitektur


hh.ru adalah 5-6k rps dari pengguna, pada puncaknya mencapai 10k, yang tumbuh dengan urutan besarnya, mencapai backend. Ini lebih dari 1.500 contoh, memutar sekitar 150 layanan dalam 3 DC. Jadi ya, pertama-tama, ini adalah skema yang sangat bercabang dengan kotak, bank, dan panah: siapa yang pergi ke mana, di mana yang seharusnya. Tentu saja, kami tidak menggambar skema - kami menutupi kebutuhan dengan otomatisasi, penebangan, dan pemantauan, tetapi kami membuat siswa kami takut, misalnya, dengan hal-hal seperti itu:



Kami benar-benar bertanggung jawab untuk menemukan dan menghilangkan hambatan dan solusi yang tidak fleksibel dalam arsitektur dan mengembangkannya sesuai dengan kebutuhan.

Saya akan memberi contoh:

hh.ru telah bekerja jauh dari tahun pertama, dan sekali sepertinya ide yang bagus untuk memiliki mesin terpisah untuk melakukan tugas-tugas latar belakang pada suatu jadwal - Anda dapat mengalokasikan lebih banyak sumber daya untuk itu dan tidak akan ada balapan di atasnya. Tapi apa yang kita miliki pada akhirnya:

  • titik kegagalan untuk semua tugas
  • konfigurasi unik hanya direproduksi dalam prod
  • tugas-tugas yang logikanya dirancang untuk peluncuran khusus pada mesin tebal yang terpisah dan tidak skala secara horizontal

Ketika kami memahami ini, kami memastikan bahwa kami memiliki semua cara untuk mentransfer tugas mahkota ke mesin virtual umum, dan memulai tugas besar dalam kategori utang teknis - sekarang saatnya untuk melunasi utang, rekan kerja secara bertahap menghilangkan masalah ini.

1. Standarisasi kruk


Pertama-tama, ini adalah kerangka kerja dan alat kami untuk pengembangan layanan yang cepat: mur dan baut dan frontik . Bagaimanapun, jclient dan banyak perpustakaan lain yang dibuka di github kami muncul dari gagasan bahwa masuk akal untuk menggabungkan pengalaman mengoperasikan berbagai teknologi. Ini memungkinkan kita untuk menumbuhkan keterbatasan, pola desain dan perilaku yang kita kerjakan dalam pertempuran, dan kita menganggapnya sebagai yang paling cocok, dapat dimengerti, dan dapat diandalkan.

Selain contoh-contoh standardisasi yang jelas, ada beberapa contoh yang masuk akal untuk menggeneralisasi solusi tertentu.

Sebagai contoh, di beberapa titik, kami mulai secara berkala memiliki kebutuhan untuk mengirim pesan ke rabbitmq (setidaknya sekali). Tugas-tugas itu berulang kali diselesaikan oleh antrian yang ditulis sendiri di pangkalan, dan dba mengatakan berulang-ulang berapa banyak antrian di pangkalan yang SANGAT dicintai, terutama yang dimuat. Pada akhirnya, menjadi jelas bahwa solusi standar diperlukan di sini yang akan dapat diterima untuk dba, memastikan pengiriman yang andal dan nyaman untuk pengembangan - ini adalah bagaimana kami menulis perpustakaan kami untuk mengintegrasikan pgq dan rabbitmq. Sekarang ada kemungkinan besar bahwa kita akan menggunakan pgq juga dalam hubungannya dengan kafka.

1.0. Bug


Bug juga bersifat global. Sebagai contoh, di beberapa titik, kami menemukan bahwa kerangka python kami terdaftar di konsul di setiap proses pekerja, dan bahkan melakukan ini sebelum aplikasi siap menerima permintaan. Setelah memperbaiki dalam kerangka kerja, perubahan secara bertahap akan mencapai semua layanan saat mereka diperbarui.

Saya berbicara tentang bug umum lain yang terkait dengan pengaturan jvm pada jpoint panggung demo 2019 .

Dan apa, misalnya, yang harus dilakukan dengan bug yang direproduksi seminggu sekali di salah satu instance, diperlakukan dengan restart, tetapi tidak memuat atau sintetis mereproduksi itu?
, java- . nuts-and-bolts:

"qtp1778300121-22" #22 prio=5 os_prio=0 cpu=797.67ms elapsed=11737.06s tid=0x00007f5890139000 nid=0x26 waiting for monitor entry [0x00007f58922c7000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ch.qos.logback.core.AppenderBase.doAppend(AppenderBase.java:63)
- waiting to lock <0x00000000e86acad0> (a ru.hh.nab.logging.HhSyslogAppender)
at ru.hh.nab.logging.HhMultiAppender.doAppend(HhMultiAppender.java:47)
at ru.hh.nab.logging.HhMultiAppender.doAppend(HhMultiAppender.java:21)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)


:

"qtp1778300121-22" #22 prio=5 os_prio=0 cpu=5718.81ms elapsed=7767.14s tid=0x00007f1537dba000 nid=0x24 waiting for monitor entry [0x00007f153d2b9000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(java.base@11.0.4/ConcurrentHashMap.java:1723)
- waiting to lock <0x00000000e976a668> (a java.util.concurrent.ConcurrentHashMap$Node)
at org.springframework.beans.factory.BeanFactoryUtils.transformedBeanName(BeanFactoryUtils.java:86)


jackson:

"qtp1778300121-23" #23 prio=5 os_prio=0 cpu=494.19ms elapsed=7234.32s tid=0x00007f6c01218800 nid=0x25 waiting for monitor entry [0x00007f6c07cfa000]
java.lang.Thread.State: BLOCKED (on object monitor)
at org.glassfish.jersey.jackson.internal.jackson.jaxrs.base.ProviderBase._endpointForWriting(ProviderBase.java:711)
- waiting to lock <0x00000000e9f94c38> (a org.glassfish.jersey.jackson.internal.jackson.jaxrs.util.LRUMap)
at org.glassfish.jersey.jackson.internal.jackson.jaxrs.base.ProviderBase.writeTo(ProviderBase.java:588)


Code Cache:



java . java, , - . , .

1.1. Solusi umum


Terkadang mungkin untuk menghasilkan solusi standar sebelum ini menjadi masalah serius. Sebagai contoh, kita dapat mengutip tugas pemrosesan log yang dibicarakan Vlad Senin pada titik yang sama 2019 , atau tugas manajemen batas waktu di klien http kami.

Artinya adalah berguna untuk menentukan batas waktu yang wajar bukan pada sisi klien, tetapi pada sisi server. Untuk server, kami memiliki data tentang seberapa cepat server merespons ke titik akhir. Sekarang klien kami mendukung satu batas waktu untuk layanan ini. Tetapi jelas bahwa tidak semua titik akhir layanan merespons dengan cara yang sama - beberapa lebih lama, beberapa lebih cepat. Saya ingin dapat menggunakan batas waktu yang berbeda. Kalau tidak, situasi yang mirip dengan ini muncul:



Sejauh ini, situasi seperti itu hanya muncul di bawah pengujian stres, tetapi saya ingin menyelesaikannya sebelum ini menjadi masalah.

1.2. Masalah terbuka


Tetapi tidak semua masalah dijelaskan oleh beberapa tempat penting dan proses manual yang rumit. Lebih lanjut, saya akan memberikan beberapa contoh masalah yang juga masuk ke dalam prioritas kami, tetapi pada saat yang sama jauh kurang deterministik. Oleh karena itu, saya hanya akan menjelaskan data awal, dan kita dapat mendiskusikan solusinya jika diinginkan dalam komentar.

Jadi, contoh pertama: sekarang menjadi jelas bahwa ada masalah dalam mengintegrasikan layanan kami di antara mereka sendiri. Integrasi, katakanlah, pegangan situs dalam API mungkin membutuhkan waktu lebih lama daripada pengembangan awalnya.

Lain, mungkin akrab bagi banyak orang, contoh masalah yang sama adalah menggergaji satu. Semua orang mengerti bahwa monolit, yang ditumbuhi banyak warisan, mempersulit pengembangan dan operasi. Tapi siapa yang tahu berapa banyak? Apakah layak mengorbankan tugas-tugas lain dari hutang teknis demi menggergaji, yang masing-masing secara individual memiliki nilai yang semakin kecil?

Skala masalah-masalah ini dan masalah-masalah serupa sedemikian rupa sehingga untuk menyelesaikannya kadang-kadang seseorang harus jauh melampaui kerangka teknis dan terjun ke bidang yang benar-benar baru dalam proses kerja. Ini menakutkan di satu sisi, tetapi di sisi lain memberikan kebebasan luar biasa dalam memilih keputusan.

2. Bagaimana kami bekerja


Kisah tentang arah pekerjaan kita tidak akan lengkap tanpa deskripsi BAGAIMANA kita bekerja dengan semua ini.

Untuk mulai dengan, apa yang membuat saya tertarik untuk bekerja di "Arsitektur" dan apa yang memotivasi kita semua: kita benar-benar bekerja untuk kualitas.

Dan sebelum batu-batu itu terbang ke arah saya, saya akan mencoba menjelaskan apa yang saya maksud. Saya percaya bahwa tidak ada pengembang yang sengaja menilai kualitas. Intinya ada dalam utang teknis: jika kita berbicara tentang bagian dari logika bisnis yang tidak direncanakan untuk digunakan kembali, maka kemungkinan besar jumlah utang dari solusi yang tidak terlalu ideal akan tumbuh perlahan seiring waktu, jika sama sekali.

Ini memungkinkan Anda untuk sedikit meredam kesempurnaan Anda - mulailah tugas untuk hutang dan lanjutkan ke iterasi berikutnya. Tetapi jika kita berbicara tentang kerangka kerja atau alat persiapan konfigurasi global yang digunakan dalam ratusan aplikasi dan mengkonsolidasikan desain atau pola penamaan tertentu, maka tingkat pertumbuhan utang dari keputusannya yang tidak berhasil dapat menghalangi keuntungan sama sekali. Jelas bahwa ada situasi di mana bahkan solusi terbaik mengungkapkan kelemahan seperti yang digunakan, tetapi ini tidak sering terjadi ...

Menjelang akhir, saya ingin berbicara tentang hambatan yang masih timbul dalam cara kita. Tanpa ini, cerita tentang pekerjaan kita akan menjadi tidak jujur. Begitu.

2.0. Tugas penilaian kesulitan


Seperti yang saya katakan di atas, kita tidak dapat mengevaluasi efek menguntungkan untuk semua tugas. Berapa banyak waktu pelepasan tugas akan berkurang ketika solusi "kotak" keluar untuk beberapa fungsi? Manakah dari dua bagian kode yang bermasalah yang harus di refactored terlebih dahulu? Untuk mengembangkan sistem yang memadai untuk menilai tugas, kami bertemu beberapa kali seminggu selama beberapa bulan, tetapi ini adalah topik untuk pos terpisah.

2.1. Tidak sadar kolektif


Mengkoordinasikan sesuatu untuk 150 orang bukanlah tugas yang mudah. Struktur organisasi kami yang sangat terdesentralisasi paling sering memanifestasikan dirinya dengan sisi-sisi terbaiknya, tetapi untuk "Arsitektur" kadang-kadang merupakan kendala serius. Ada sangat sedikit perjanjian yang memungkinkan untuk mencapai kesepakatan, bahkan lebih sedikit lagi yang kepatuhannya dapat dipantau.

Dan semua perubahan harus digulirkan dengan lancar. Layanan mungkin tidak diperbarui selama berbulan-bulan, tetapi masih ada monolit ... Yah, cukup menyedihkan.

Jadi kami berbicara


Saya berharap setelah cerita saya, saya telah mengklarifikasi sedikit apa yang β€œArsitektur” lakukan di hh.ru. Dan jika saya berhasil membangkitkan minat Anda pada pekerjaan kami, itu umumnya fantastis. Selain itu, baru-baru ini lowongan terbuka di tim kami . Kami akan sangat senang dengan ide-ide segar yang akan membantu kami mencapai yang tersembunyi dari pandangan sekilas, tetapi kemenangan yang sangat penting.

ps KDPV yang asli ternyata merupakan ilustrasi dari pria ini . Saya harap dia tidak menentang penggunaan gambarnya sebagai KDPV

All Articles