Mengurus Kekacauan: Menyusun sesuatu dengan bantuan peta teknologi

Mengurus Kekacauan: Menyusun sesuatu dengan bantuan peta teknologi

:Ображение: Unsplash

Hai semua! Kami adalah jurutera automasi daripada syarikat Teknologi Positif dan kami menyokong pembangunan produk syarikat: kami menyokong keseluruhan saluran pemasangan daripada komit barisan kod oleh pembangun kepada penerbitan produk siap dan lesen pada pelayan kemas kini. Secara tidak rasmi, kami dipanggil jurutera DevOps. Dalam artikel ini, kami ingin bercakap tentang peringkat teknologi proses pengeluaran perisian, cara kami melihatnya dan cara kami mengklasifikasikannya.

Daripada bahan tersebut anda akan belajar tentang kerumitan penyelarasan pembangunan berbilang produk, tentang apa itu peta teknologi dan cara ia membantu menyelaraskan dan mereplikasi penyelesaian, apakah peringkat dan langkah utama proses pembangunan, bagaimana bidang tanggungjawab antara DevOps dan pasukan dalam syarikat kami.

Mengenai Chaos dan DevOps

Secara ringkas, konsep DevOps merangkumi alatan dan perkhidmatan pembangunan, serta metodologi dan amalan terbaik untuk kegunaannya. Mari kita pilih yang global tujuannya daripada pelaksanaan idea DevOps dalam syarikat kami: ini ialah pengurangan konsisten dalam kos pengeluaran dan penyelenggaraan produk dari segi kuantitatif (jam kerja atau waktu mesin, CPU, RAM, Cakera, dll.). Cara paling mudah dan paling jelas untuk mengurangkan kos keseluruhan pembangunan di peringkat keseluruhan syarikat ialah meminimumkan kos melaksanakan tugas bersiri biasa pada semua peringkat pengeluaran. Tetapi apakah peringkat ini, bagaimana untuk memisahkannya daripada proses umum, apakah langkah-langkah yang terdiri daripada mereka?

Apabila syarikat membangunkan satu produk, semuanya lebih atau kurang jelas: biasanya terdapat pelan hala tuju dan skim pembangunan yang sama. Tetapi apa yang perlu dilakukan apabila barisan produk berkembang dan terdapat lebih banyak produk? Pada pandangan pertama, mereka mempunyai proses dan baris pemasangan yang serupa, dan permainan "cari perbezaan X" dalam log dan skrip bermula. Tetapi bagaimana jika sudah ada 5+ projek dalam pembangunan aktif dan sokongan untuk beberapa versi yang dibangunkan selama beberapa tahun diperlukan? Adakah kita mahu menggunakan semula bilangan maksimum penyelesaian yang mungkin dalam saluran paip produk atau adakah kita bersedia membelanjakan wang untuk pembangunan unik untuk setiap satu?

Bagaimana untuk mencari keseimbangan antara keunikan dan penyelesaian bersiri?

Soalan-soalan ini mula timbul di hadapan kita lebih dan lebih kerap sejak 2015. Bilangan produk bertambah, dan kami cuba mengembangkan jabatan automasi kami (DevOps), yang menyokong barisan pemasangan produk ini, kepada tahap minimum. Pada masa yang sama, kami ingin meniru sebanyak mungkin penyelesaian antara produk. Lagipun, mengapa melakukan perkara yang sama dalam sepuluh produk dengan cara yang berbeza?

Pengarah Pembangunan: "Kawan-kawan, bolehkah kita menilai apa yang DevOps lakukan untuk produk?"

Kami: "Kami tidak tahu, kami tidak bertanya soalan sedemikian, tetapi apakah petunjuk yang perlu dipertimbangkan?"

Pengarah Pembangunan: "Siapa tahu! Fikir…”

Seperti dalam filem terkenal itu: "Saya di hotel! .." - "Uh ... Bolehkah anda tunjukkan saya jalan?" Pada refleksi, kami sampai pada kesimpulan bahawa kami perlu membuat keputusan mengenai keadaan akhir produk; ini menjadi matlamat pertama kami.

Jadi, bagaimana anda menganalisis sedozen produk dengan pasukan yang agak besar daripada 10 hingga 200 orang dan menentukan metrik yang boleh diukur apabila mereplikasi penyelesaian?

1:0 memihak kepada Chaos, atau DevOps pada bilah bahu

Kami bermula dengan percubaan untuk menggunakan rajah IDEF0 dan pelbagai rajah proses perniagaan daripada siri BPwin. Kekeliruan bermula selepas petak kelima peringkat seterusnya projek seterusnya, dan petak ini untuk setiap projek boleh dilukis dalam ekor ular sawa panjang di bawah 50+ langkah. Saya berasa sedih dan ingin meraung pada bulan - ia tidak sesuai secara umum.

Tugas pengeluaran biasa

Memodelkan proses pengeluaran ialah kerja yang sangat kompleks dan teliti: anda perlu mengumpul, memproses dan menganalisis banyak data daripada pelbagai jabatan dan rantaian pengeluaran. Anda boleh membaca lebih lanjut mengenai ini dalam artikel "Pemodelan proses pengeluaran dalam syarikat IT'.

Apabila kami mula memodelkan proses pengeluaran kami, kami mempunyai matlamat khusus - untuk menyampaikan kepada setiap pekerja yang terlibat dalam pembangunan produk syarikat kami, dan kepada pengurus projek:

  • bagaimana produk dan komponennya, bermula dari komit baris kod, menjangkau pelanggan dalam bentuk pemasang dan kemas kini,
  • apakah sumber yang disediakan untuk setiap peringkat pengeluaran produk,
  • perkhidmatan apa yang terlibat pada setiap peringkat,
  • bagaimana bidang tanggungjawab bagi setiap peringkat dihadkan,
  • apakah kontrak yang wujud di pintu masuk dan keluar setiap peringkat.

Mengurus Kekacauan: Menyusun sesuatu dengan bantuan peta teknologi

Mengklik pada imej akan membukanya dalam saiz penuh

Kerja kami dalam syarikat dibahagikan kepada beberapa bidang berfungsi. Arah infrastruktur terlibat dalam pengoptimuman operasi semua sumber "besi" jabatan, serta automasi penggunaan mesin maya dan persekitaran pada mereka. Arah pemantauan menyediakan kawalan prestasi perkhidmatan 24/7; kami juga menyediakan pemantauan sebagai perkhidmatan untuk pembangun. Arah aliran kerja menyediakan pasukan dengan alatan untuk mengurus proses pembangunan dan ujian, menganalisis keadaan kod dan mendapatkan analitis pada projek. Dan akhirnya, arah webdev menyediakan penerbitan keluaran pada pelayan kemas kini GUS dan FLUS, serta pelesenan produk menggunakan perkhidmatan LicenseLab. Untuk menyokong saluran pengeluaran, kami menyediakan dan mengekalkan banyak perkhidmatan sokongan yang berbeza untuk pembangun (anda boleh mendengar cerita tentang beberapa daripada mereka pada pertemuan lama: Op!DevOps! 2016 и Op!DevOps! 2017). Kami juga membangunkan alat automasi dalaman, termasuk penyelesaian sumber terbuka.

Sepanjang lima tahun yang lalu, kerja kami telah mengumpulkan banyak jenis dan operasi rutin yang sama, dan pemaju kami dari jabatan lain kebanyakannya datang daripada apa yang dipanggil tugas biasa, penyelesaian yang sepenuhnya atau sebahagiannya diautomatikkan, tidak menyebabkan kesukaran kepada penghibur dan tidak memerlukan banyak kerja. Bersama-sama dengan bidang utama, kami menganalisis tugasan tersebut dan dapat mengenal pasti kategori kerja individu, atau langkah pengeluaran, peringkat dibahagikan kepada langkah-langkah yang tidak boleh dibahagikan, dan beberapa peringkat ditambah rantaian proses pengeluaran.

Mengurus Kekacauan: Menyusun sesuatu dengan bantuan peta teknologi

Contoh paling mudah bagi rantaian teknologi ialah peringkat pemasangan, penggunaan dan ujian setiap produk kami dalam syarikat. Sebaliknya, sebagai contoh, peringkat binaan terdiri daripada banyak langkah tipikal yang berasingan: memuat turun sumber daripada GitLab, menyediakan kebergantungan dan perpustakaan pihak ketiga, ujian unit dan analisis kod statik, melaksanakan skrip binaan pada GitLab CI, menerbitkan artifak dalam repositori pada Artifactory dan penjanaan nota keluaran melalui alat ChangelogBuilder dalaman kami.

Anda boleh membaca tentang tugas DevOps biasa dalam artikel kami yang lain tentang Habré: "Pengalaman peribadi: rupa sistem Integrasi Berterusan kami"Dan"Automasi proses pembangunan: cara kami melaksanakan idea DevOps di Positive Technologies'.

Banyak rantaian pengeluaran biasa terbentuk proses pembuatan. Pendekatan standard untuk menerangkan proses adalah dengan menggunakan model IDEF0 berfungsi.

Contoh pemodelan proses CI pembuatan

Kami memberi perhatian khusus kepada pembangunan projek standard untuk sistem integrasi berterusan. Ini memungkinkan untuk mencapai penyatuan projek, menonjolkan apa yang dipanggil keluarkan skim binaan dengan promosi.

Mengurus Kekacauan: Menyusun sesuatu dengan bantuan peta teknologi

Begini cara ia berfungsi. Semua projek kelihatan biasa: ia termasuk konfigurasi pemasangan yang termasuk dalam repositori syot kilat di Artifactory, selepas itu ia digunakan dan diuji pada bangku ujian, dan kemudian dinaikkan pangkat ke repositori keluaran. Perkhidmatan Artifactory ialah satu titik pengedaran untuk semua binaan artifak antara pasukan dan perkhidmatan lain.

Jika kami sangat memudahkan dan menyamaratakan skim keluaran kami, maka ia termasuk langkah-langkah berikut:

  • pemasangan produk merentas platform,
  • penempatan ke bangku ujian,
  • menjalankan ujian fungsional dan lain-lain,
  • mempromosikan binaan yang diuji untuk mengeluarkan repositori di Artifactory,
  • penerbitan keluaran dibina pada pelayan kemas kini,
  • penghantaran perhimpunan dan kemas kini kepada pengeluaran,
  • melancarkan pemasangan dan pengemaskinian produk.

Sebagai contoh, pertimbangkan model teknologi skim keluaran biasa ini (selepas ini hanya Model) dalam bentuk model IDEF0 berfungsi. Ia mencerminkan peringkat utama proses CI kami. Model IDEF0 menggunakan apa yang dipanggil tatatanda ICOM (Input-Control-Output-Mechanism) untuk menerangkan sumber yang digunakan pada setiap peringkat, berdasarkan peraturan dan keperluan kerja yang dilakukan, apakah output, dan mekanisme, perkhidmatan atau orang yang melaksanakan peringkat tertentu.

Mengurus Kekacauan: Menyusun sesuatu dengan bantuan peta teknologi

Mengklik pada imej akan membukanya dalam saiz penuh

Sebagai peraturan, lebih mudah untuk mengurai dan memperincikan perihalan proses dalam model berfungsi. Tetapi apabila bilangan elemen bertambah, ia menjadi semakin sukar untuk memahami sesuatu di dalamnya. Tetapi dalam pembangunan sebenar terdapat juga peringkat tambahan: pemantauan, pensijilan produk, automasi proses kerja, dan lain-lain. Kerana masalah penskalaan kami meninggalkan penerangan ini.

Kelahiran Harapan

Dalam satu buku, kami menemui peta lama Soviet yang menerangkan proses teknologi (yang, dengan cara itu, masih digunakan hari ini di banyak perusahaan dan universiti milik kerajaan). Tunggu, tunggu, kerana kami juga mempunyai aliran kerja!.. Terdapat peringkat, keputusan, metrik, keperluan, penunjuk, dan sebagainya dan sebagainya... Mengapa tidak cuba menggunakan lembaran alir pada saluran paip produk kami juga? Ada perasaan: “Ini dia! Kami telah menemui benang yang betul, sudah tiba masanya untuk menariknya dengan baik!

Dalam jadual ringkas, kami memutuskan untuk merekodkan produk mengikut lajur, dan peringkat teknologi serta langkah saluran paip produk mengikut baris. Pencapaian adalah sesuatu yang besar, seperti langkah membina produk. Dan langkah adalah sesuatu yang lebih kecil dan lebih terperinci, seperti langkah memuat turun kod sumber ke pelayan binaan atau langkah menyusun kod.

Di persimpangan baris dan lajur peta, kami meletakkan status untuk peringkat dan produk tertentu. Untuk status, satu set keadaan telah ditakrifkan:

  1. Tiada maklumat - atau tidak sesuai. Ia adalah perlu untuk menganalisis permintaan untuk peringkat dalam produk. Sama ada analisis telah dijalankan, tetapi peringkat itu pada masa ini tidak diperlukan atau tidak wajar dari segi ekonomi.
  2. Ditangguh - atau tidak relevan pada masa ini. Satu peringkat dalam perancangan diperlukan, tetapi tiada kuasa untuk pelaksanaan tahun ini.
  3. Terancang. Peringkat tersebut dirancang untuk dilaksanakan pada tahun ini.
  4. Dilaksanakan. Peringkat dalam saluran paip dilaksanakan dalam jumlah yang diperlukan.

Pengisian jadual dimulakan projek demi projek. Pertama, peringkat dan langkah satu projek diklasifikasikan dan statusnya direkodkan. Kemudian mereka mengambil projek seterusnya, membetulkan status di dalamnya dan menambah peringkat dan langkah yang hilang dalam projek sebelumnya. Hasilnya, kami mendapat peringkat dan langkah keseluruhan saluran pengeluaran kami dan statusnya dalam projek tertentu. Ternyata sesuatu yang serupa dengan matriks kecekapan saluran paip produk. Kami memanggil matriks sedemikian sebagai peta teknologi.

Dengan bantuan peta teknologi, kami secara metrologi secara munasabah menyelaraskan dengan pasukan rancangan kerja untuk tahun ini dan sasaran yang ingin kami capai bersama: peringkat mana yang kami tambahkan pada projek tahun ini, dan peringkat mana yang kami tinggalkan kemudian. Selain itu, semasa menjalankan kerja, kami mungkin mempunyai peningkatan dalam peringkat yang telah kami selesaikan untuk satu produk sahaja. Kemudian kami mengembangkan peta kami dan memperkenalkan penambahbaikan ini sebagai peringkat atau langkah baharu, kemudian kami menganalisis untuk setiap produk dan mengetahui kemungkinan untuk mereplikasi penambahbaikan.

Mereka mungkin membantah kami: "Ini semua, sudah tentu, bagus, hanya dengan masa bilangan langkah dan peringkat akan menjadi sangat besar. Bagaimana untuk menjadi?

Kami telah memperkenalkan huraian standard dan agak lengkap tentang keperluan untuk setiap peringkat dan langkah, supaya ia difahami oleh semua orang dalam syarikat dengan cara yang sama. Dari masa ke masa, apabila penambahbaikan diperkenalkan, satu langkah mungkin diserap ke peringkat atau langkah lain, dan kemudian mereka akan "runtuh". Pada masa yang sama, semua keperluan dan nuansa teknologi sesuai dengan keperluan peringkat atau langkah generalisasi.

Bagaimana untuk menilai kesan penyelesaian replikasi? Kami menggunakan pendekatan yang sangat mudah: kami mengaitkan kos modal permulaan untuk pelaksanaan peringkat baharu kepada kos produk am tahunan, dan kemudian membahagikan kepada semua apabila mereplikasi.

Sebahagian daripada pembangunan telah ditunjukkan sebagai tonggak dan langkah pada peta. Kita boleh mempengaruhi pengurangan kos produk melalui pengenalan automasi untuk peringkat biasa. Selepas itu, kami mempertimbangkan perubahan dalam ciri kualitatif, metrik kuantitatif dan keuntungan yang diterima oleh pasukan (dalam jam kerja atau jam mesin simpanan).

Peta teknologi proses pengeluaran

Jika kita mengambil semua peringkat dan langkah kita, mengekodnya dengan tag dan mengembangkannya menjadi satu rantai, maka ia akan menjadi sangat panjang dan tidak dapat difahami (hanya "ekor ular sawa" yang sama yang kita bincangkan pada permulaan artikel) :

[Production] — [InfMonitoring] — [SourceCodeControl] — [Prepare] — [PrepareLinuxDocker] — [PrepareWinDocker] — [Build] — [PullSourceCode] — [PrepareDep] — [UnitTest] — [CodeCoverage] — [StaticAnalyze] — [BuildScenario] — [PushToSnapshot] — [ChangelogBuilder] — [Deploy] — [PrepareTestStand] — [PullTestCode] — [PrepareTestEnv] — [PullArtifact] — [DeployArtifact] — [Test] — [BVTTest] — [SmokeTest] — [FuncTest] — [LoadTest] — [IntegrityTest] — [DeliveryTest] — [MonitoringStands] — [TestManagement] — [Promote] — [QualityTag] — [MoveToRelease] — [License] — [Publish] — [PublishGUSFLUS] — [ControlVisibility] — [Install] — [LicenseActivation] — [RequestUpdates] — [PullUpdates] — [InitUpdates] — [PrepareEnv] — [InstallUpdates] — [Telemetry] — [Workflow] — [Communication] — [Certification] — [CISelfSufficiency]

Ini adalah peringkat membina produk [Bina], menggunakan mereka untuk menguji pelayan [Deploy], menguji [Test], mempromosikan binaan untuk mengeluarkan repositori berdasarkan hasil ujian [Promote], menjana dan menerbitkan lesen [Licence], menerbitkan [ Terbitkan] pada pelayan kemas kini GUS dan penghantaran ke pelayan kemas kini FLUS, pemasangan dan pengemaskinian komponen produk pada infrastruktur pelanggan menggunakan Pengurusan Konfigurasi Produk [Pasang], serta pengumpulan telemetri [Telemetri] daripada produk yang dipasang.

Sebagai tambahan kepada mereka, peringkat berasingan boleh dibezakan: pemantauan keadaan infrastruktur [InfMonitoring], versi kod sumber [SourceCodeControl], penyediaan persekitaran bina [Sediakan], pengurusan projek [Aliran Kerja], menyediakan pasukan dengan alat komunikasi [Komunikasi], pensijilan produk [ Pensijilan] dan memastikan kemandirian proses CI [CISelfSufficiency] (contohnya, kebebasan perhimpunan daripada Internet). Berpuluh-puluh langkah dalam proses kami tidak akan dipertimbangkan, kerana ia sangat khusus.

Ia akan menjadi lebih mudah untuk memahami dan melihat keseluruhan proses pengeluaran jika ia dibentangkan dalam bentuk peta teknologi; ini ialah jadual di mana peringkat pengeluaran individu dan langkah terurai Model ditulis dalam baris, dan dalam lajur penerangan tentang perkara yang dilakukan pada setiap peringkat atau langkah. Penekanan utama diberikan kepada sumber yang menyediakan setiap peringkat, dan persempadanan bidang tanggungjawab.

Peta untuk kami adalah sejenis pengelas. Ia mencerminkan bahagian teknologi besar pengeluaran produk. Berkat itu, menjadi lebih mudah bagi pasukan automasi kami untuk berinteraksi dengan pembangun dan bersama-sama merancang pelaksanaan peringkat automasi, serta memahami kos dan sumber buruh (manusia dan perkakasan) yang diperlukan untuk ini.

Di dalam syarikat kami, peta dijana secara automatik daripada templat jinja sebagai fail HTML biasa, dan kemudian dimuat naik ke pelayan Halaman GitLab. Tangkapan skrin dengan contoh peta yang dijana sepenuhnya boleh dilihat по ссылке.

Mengurus Kekacauan: Menyusun sesuatu dengan bantuan peta teknologi

Mengklik pada imej akan membukanya dalam saiz penuh

Ringkasnya, peta teknologi ialah gambaran umum proses pengeluaran, yang mencerminkan blok terperingkat dengan jelas dengan fungsi biasa.

Struktur peta jalan kami

Peta terdiri daripada beberapa bahagian:

  1. Kawasan tajuk - di sini adalah penerangan umum peta, konsep asas diperkenalkan, sumber utama dan hasil proses pengeluaran ditentukan.
  2. Papan pemuka - di sini anda boleh mengawal paparan data untuk produk individu, ringkasan peringkat yang dilaksanakan dan langkah secara umum untuk semua produk disediakan.
  3. Peta teknologi - penerangan jadual proses teknologi. Pada peta:
    • semua peringkat, langkah dan kod mereka diberikan;
    • penerangan ringkas dan lengkap tentang peringkat diberikan;
    • sumber input dan perkhidmatan yang digunakan pada setiap peringkat ditunjukkan;
    • keputusan setiap peringkat dan langkah berasingan ditunjukkan;
    • bidang tanggungjawab untuk setiap peringkat dan langkah ditunjukkan;
    • sumber teknikal, seperti HDD (SSD), RAM, vCPU, dan waktu kerja yang diperlukan untuk menyokong kerja pada peringkat ini, kedua-duanya pada masa semasa - fakta, dan pada masa hadapan - rancangan, telah ditentukan;
    • bagi setiap produk, ia ditunjukkan peringkat atau langkah teknologi mana yang telah dilaksanakan, dirancang untuk pelaksanaan, tidak relevan atau tidak dilaksanakan.

Membuat keputusan berdasarkan peta teknologi

Selepas memeriksa peta, adalah mungkin untuk mengambil beberapa tindakan - bergantung pada peranan pekerja dalam syarikat (pengurus pembangunan, pengurus produk, pembangun atau penguji):

  • memahami apakah peringkat yang tiada dalam produk atau projek sebenar, dan menilai keperluan untuk pelaksanaannya;
  • mengehadkan bidang tanggungjawab antara beberapa jabatan jika mereka bekerja pada peringkat yang berbeza;
  • bersetuju dengan kontrak di pintu masuk dan keluar peringkat;
  • integrasikan peringkat kerja anda ke dalam keseluruhan proses pembangunan;
  • menilai dengan lebih tepat keperluan sumber yang menyediakan setiap peringkat.

Merumuskan semua perkara di atas

Penghalaan adalah serba boleh, boleh dipanjangkan dan mudah diselenggara. Lebih mudah untuk membangunkan dan mengekalkan perihalan proses dalam bentuk ini berbanding model IDEF0 akademik yang ketat. Di samping itu, penerangan jadual adalah lebih mudah, lebih biasa dan berstruktur lebih baik daripada model berfungsi.

Untuk pelaksanaan teknikal langkah-langkah, kami mempunyai alat dalaman khas CrossBuilder - alat lapisan antara sistem, perkhidmatan dan infrastruktur CI. Pembangun tidak perlu memotong basikalnya: dalam sistem CI kami, sudah cukup untuk menjalankan salah satu skrip (yang dipanggil tugas) alat CrossBuilder, yang akan melaksanakannya dengan betul, dengan mengambil kira ciri infrastruktur kami .

Keputusan

Artikel itu ternyata agak panjang, tetapi ini tidak dapat dielakkan apabila menerangkan pemodelan proses yang kompleks. Pada akhirnya, saya ingin membetulkan secara ringkas idea utama kami:

  • Matlamat melaksanakan idea DevOps dalam syarikat kami adalah untuk mengurangkan kos pengeluaran dan penyelenggaraan produk syarikat secara konsisten dari segi kuantitatif (jam kerja atau waktu mesin, vCPU, RAM, Cakera).
  • Cara untuk mengurangkan kos keseluruhan pembangunan adalah dengan meminimumkan kos melaksanakan tugas bersiri biasa: peringkat dan langkah proses teknologi.
  • Tugas biasa ialah tugas yang penyelesaiannya automatik sepenuhnya atau sebahagiannya, tidak menyusahkan pelaksana dan tidak memerlukan kos buruh yang ketara.
  • Proses pengeluaran terdiri daripada peringkat, peringkat dibahagikan kepada langkah-langkah yang tidak boleh dibahagikan, yang merupakan tugas tipikal dengan skala dan skop yang berbeza.
  • Daripada tugas tipikal yang berbeza, kami telah sampai ke rantaian teknologi yang kompleks dan model pelbagai peringkat proses pengeluaran, yang boleh diterangkan oleh model IDEF0 berfungsi atau peta teknologi yang lebih ringkas.
  • Peta teknologi ialah perwakilan jadual peringkat dan langkah proses pengeluaran. Perkara yang paling penting: peta membolehkan anda melihat keseluruhan proses secara keseluruhan, dalam kepingan besar dengan kemungkinan memperincikannya.
  • Berdasarkan peta teknologi, adalah mungkin untuk menilai keperluan untuk memperkenalkan peringkat dalam produk tertentu, menggariskan bidang tanggungjawab, bersetuju dengan kontrak pada input dan output peringkat, dan menilai dengan lebih tepat keperluan sumber.

Dalam artikel berikut, kami akan menerangkan dengan lebih terperinci alat teknikal yang digunakan untuk melaksanakan peringkat teknologi tertentu pada peta kami.

Penulis artikel:

Sumber: www.habr.com

Tambah komen