Meniru layanan web Amazon dalam proses JVM. Menghindari Roskomnadzor dan mempercepat pengembangan dan pengujian

Mengapa Anda perlu meniru infrastruktur layanan web Amazon?

Pertama-tama, ini menghemat - menghemat waktu untuk pengembangan dan debugging, dan yang sama pentingnya - menghemat uang dari anggaran proyek. Jelas bahwa emulator tidak akan 100% identik dengan lingkungan asli yang kami coba tiru. Tetapi untuk tujuan mempercepat pengembangan dan otomatisasi proses, kesamaan yang ada sudah cukup. Hal paling topikal yang terjadi pada tahun 2018 dengan AWS adalah pemblokiran oleh penyedia IP dari alamat IP dari subnet AWS di Federasi Rusia. Dan kunci ini memengaruhi infrastruktur kami yang terletak di cloud Amazon. Jika Anda berencana untuk menggunakan teknologi AWS dan menempatkan proyek di cloud ini, maka untuk pengembangan dan pengujian emulasi lebih dari terbayar.



Dalam publikasi ini saya akan memberi tahu Anda bagaimana kami berhasil menyelesaikan trik seperti itu dengan layanan S3, SQS, RDS PostgreSQL, dan Redshift ketika memigrasi gudang data yang ada ke AWS selama bertahun-tahun.

Ini hanya bagian dari pertemuan tahun lalu saya di peta , yang sesuai dengan tema AWS dan hub Java. Bagian kedua berkaitan dengan database PostgreSQL, Redshift dan kolom, dan versi teksnya dapat dipublikasikan di hub, video, dan slide yang sesuai ada di situs web konferensi .

Ketika mengembangkan aplikasi untuk AWS selama memblokir subnet AWS, tim praktis tidak memperhatikan mereka dalam proses harian mengembangkan fungsionalitas baru. Tes juga berhasil dan Anda dapat men-debug aplikasi. Dan hanya ketika mencoba untuk melihat log aplikasi di logentries, metrik di SignalFX atau analisis data di Redshift / PostgreSQL RDS kecewa - layanan tidak tersedia melalui jaringan penyedia Rusia. Emulasi AWS membantu kami tidak memperhatikan hal ini dan menghindari penundaan yang jauh lebih besar ketika bekerja dengan cloud Amazon melalui jaringan VPN.

Setiap penyedia cloud "di bawah tenda" memiliki banyak naga dan Anda tidak boleh menyerah pada iklan. Anda perlu memahami mengapa semua ini diperlukan untuk penyedia layanan. Tentu saja, infrastruktur Amazon, Microsoft dan Google yang ada memiliki kelebihan. Dan ketika mereka memberi tahu Anda bahwa semuanya dilakukan hanya untuk membuatnya nyaman bagi Anda untuk berkembang, mereka kemungkinan besar mencoba untuk menempatkan Anda pada jarum Anda dan memberikan dosis pertama secara gratis. Sehingga nantinya mereka tidak turun dari infrastruktur dan teknologi tertentu. Karena itu, kami akan mencoba untuk menghindari vendor lock-in. Jelas bahwa tidak selalu mungkin untuk sepenuhnya abstrak dari keputusan tertentu dan saya pikir cukup sering untuk abstrak hampir 90% dalam sebuah proyek. Tetapi 10% sisanya dari proyek, terkait dengan penyedia teknologi yang sangat penting, adalah mengoptimalkan kinerja aplikasi atau fitur unik yang tidak ada di tempat lain. Mereka harus selalu mengingat kelebihan dan kekurangan teknologi dan melindungi diri mereka sebanyak mungkin, bukan "duduk" di API tertentu dari penyedia infrastruktur cloud.

Amazon menulis tentang pemrosesan pesan di situs webnya. Esensi dan abstraksi teknologi pertukaran pesan adalah sama di mana-mana, meskipun ada nuansa - pesan yang melewati antrian atau melalui topik. Jadi, AWS merekomendasikan menggunakan Apache ActiveMQ yang disediakan dan dikelola untuk memigrasikan aplikasi dari broker perpesanan yang ada, dan untuk aplikasi Amazon SQS / SNS baru. Ini adalah contoh dari pengikatan ke API mereka sendiri, bukan JMS API standar dan protokol AMQP, MMQT, STOMP. Jelas bahwa penyedia ini dengan solusinya mungkin memiliki kinerja lebih tinggi, mendukung skalabilitas, dll. Dari sudut pandang saya, jika Anda menggunakan perpustakaan mereka, dan bukan API standar, maka akan ada lebih banyak masalah.

AWS memiliki database Redshift. Ini adalah database terdistribusi dengan arsitektur paralel masif. Anda dapat mengunggah sejumlah besar data Anda ke tabel di beberapa situs Redshft di Amazon dan melakukan kueri analitik pada set data besar. Ini bukan sistem OLTP di mana penting bagi Anda untuk melakukan permintaan kecil pada sejumlah kecil catatan yang cukup sering dengan jaminan ACID. Saat bekerja dengan Redshift, diasumsikan bahwa Anda tidak memiliki sejumlah besar kueri per unit waktu, tetapi mereka dapat membaca agregat pada sejumlah besar data. Sistem ini diposisikan oleh vendor untuk meningkatkan gudang data Anda (gudang) di AWS dan menjanjikan pemuatan data sederhana. Sama sekali tidak benar.

Kutipan dari dokumentasi tentang jenis apa yang didukung Amazon Redshift. Set yang agak sedikit, dan jika Anda perlu sesuatu untuk menyimpan dan memproses data yang tidak tercantum di sini, akan sulit bagi Anda untuk bekerja. Misalnya GUID.

Pertanyaan dari aula, “Dan JSON?”

- JSON hanya dapat ditulis sebagai VARCHAR dan ada beberapa fungsi untuk bekerja dengan JSON.
Komentar dari audiens: "Postgres memiliki dukungan JSON normal."

- Ya, ia memiliki dukungan untuk jenis data dan fungsi ini. Tetapi Redshift didasarkan pada PostgreSQL 8.0.2. Ada proyek ParAccel, jika saya tidak salah, teknologi 2005 ini adalah garpu postgres yang memiliki penjadwal untuk permintaan yang didistribusikan berdasarkan arsitektur paralel-besar. 5-6 tahun berlalu dan proyek ini dilisensikan untuk platform Amazon Web Servces dan diberi nama Redshift. Sesuatu telah dihapus dari Postgres asli, banyak yang telah ditambahkan. Mereka menambahkan bahwa terkait dengan otentikasi / otorisasi di AWS, dengan peran, keamanan di Amazon berfungsi dengan baik. Tetapi jika Anda perlu, misalnya, untuk terhubung dari Redshift ke database lain menggunakan Sumber Data Asing, maka Anda tidak akan menemukan ini. Tidak ada fungsi untuk bekerja dengan XML, fungsi untuk bekerja dengan JSON dua kali dan salah perhitungan.

Saat mengembangkan aplikasi, cobalah untuk tidak bergantung pada implementasi spesifik, dan kode aplikasi hanya bergantung pada abstraksi. Anda dapat membuat sendiri fasad dan abstraksi ini, tetapi dalam hal ini ada banyak perpustakaan siap pakai - fasad. Yang abstrak kode dari implementasi spesifik, dari kerangka kerja tertentu. Jelas bahwa mereka mungkin tidak mendukung semua fungsi, sebagai "common denominator" untuk teknologi. Lebih baik mengembangkan perangkat lunak yang mengandalkan abstraksi untuk menyederhanakan pengujian.

Untuk meniru AWS, saya akan menyebutkan dua opsi. Yang pertama lebih jujur ​​dan benar, tetapi bekerja lebih lambat. Yang kedua kotor dan cepat. Saya akan memberi tahu Anda tentang opsi peretasan - kami mencoba membuat seluruh infrastruktur dalam satu proses - pengujian dan opsi lintas platform akan bekerja lebih cepat dengan pekerjaan di Windows (di mana buruh pelabuhan tidak selalu dapat menghasilkan uang dari Anda).

Metode pertama sangat cocok jika Anda mengembangkan di linux / macos dan Anda memiliki buruh pelabuhan, akan lebih baik menggunakan atlassian localstack . Lebih mudah menggunakan testcontainers untuk mengintegrasikan localstack ke dalam JVM.

Saya dihentikan dari menggunakan lockalstack di buruh pelabuhan pada proyek yang pengembangannya berada di bawah Windows dan tidak ada yang menjamin versi alpha dari buruh pelabuhan ketika proyek ini dimulai ... Mungkin juga mereka tidak akan diizinkan untuk menginstal mesin virtual dengan linux dan buruh pelabuhan di perusahaan mana pun yang serius tentang untuk keamanan informasi. Saya tidak berbicara tentang bekerja di lingkungan yang aman di bank investasi dan melarang hampir semua firewall lalu lintas di sana.

Mari kita pertimbangkan opsi bagaimana meniru S3 penyimpanan sederhana. Ini bukan sistem file Amazon biasa, melainkan toko objek terdistribusi. Di mana Anda menempatkan data Anda sebagai Gumpalan, tanpa kemungkinan modifikasi dan penambahan data. Ada penyimpanan terdistribusi lengkap yang serupa dari produsen lain. Sebagai contoh, penyimpanan objek terdistribusi Ceph memungkinkan Anda untuk bekerja dengan fungsinya menggunakan protokol S3 REST dan klien yang ada dengan modifikasi minimal. Tapi ini adalah solusi yang agak berat untuk pengembangan dan pengujian aplikasi java.

Proyek yang lebih cepat dan lebih cocok adalah perpustakaan java s3proxy . Ini mengemulasi protokol S3 REST dan menerjemahkannya ke dalam panggilan API jcloud yang sesuai dan memungkinkan Anda untuk menggunakan banyak implementasi untuk pembacaan dan penyimpanan data yang nyata. Ini dapat menyiarkan panggilan ke Google App Engine API, Microsoft Azure API, tetapi untuk pengujian lebih mudah menggunakan penyimpanan sementara jcloud di RAM. Anda juga perlu mengkonfigurasi versi protokol otentikasi AWS S3 dan menentukan nilai kunci dan rahasia, juga mengkonfigurasi titik akhir - port dan antarmuka tempat Proxy S3 ini akan mendengarkan. Dengan demikian, kode Anda menggunakan klien AWS SDK harus terhubung dalam tes ke titik akhir S3 AWS, bukan wilayah AWS. Sekali lagi, ingat bahwa s3proxy tidak mendukung semua fitur API S3, tetapi semua skenario penggunaan kami meniru dengan sempurna! Bahkan pengunggahan Multipart untuk file besar didukung oleh s3proxy.



Layanan Antrian Sederhana Amazon adalah layanan antrian. Ada layanan antrian elasticmq yang ditulis dalam scala dan dapat disajikan ke aplikasi Anda menggunakan protokol Amazon SQS. Saya tidak menggunakannya dalam proyek, jadi saya akan memberikan kode inisialisasi, mempercayai informasi dari pengembangnya.



Dalam proyek ini, saya pergi ke arah lain dan kode tergantung pada abstraksi spring-jms dari JmsTemplate dan JmsListener dan dependensi proyek menentukan driver JMS untuk SQS com.amazonaws: amazon-sqs-java-messaging-lib. Inilah yang menyangkut kode aplikasi utama.



Dalam pengujian, kami menghubungkan Artemis-jms-server sebagai server JMS tertanam untuk pengujian, dan dalam konteks uji Spring, alih-alih pabrik koneksi SQS, kami menggunakan pabrik koneksi Artemis. Artemis adalah versi selanjutnya dari Apache ActiveMQ, sebuah Middleware Message Oriented Middleware modern yang lengkap - tidak hanya solusi pengujian. Mungkin kita akan beralih ke penggunaannya di masa depan, tidak hanya di autotests. Dengan demikian, menggunakan abstraksi JMS bersama dengan Spring, kami telah menyederhanakan kode aplikasi dan kemampuan untuk dengan mudah mengujinya. Anda hanya perlu menambahkan dependensi org.springframework.boot: spring-boot-starter-artemis dan org.apache.activemq: artemis-jms-server.



Dalam beberapa tes, PostgreSQL dapat ditiru dengan menggantinya dengan H2Database . Ini akan bekerja jika tes tidak diterima dan tidak menggunakan fungsi PG tertentu. Pada saat yang sama, H2 dapat meniru sebagian dari protokol kawat PostgreSQL tanpa dukungan untuk tipe dan fungsi data. Dalam proyek kami, kami menggunakan Pembungkus Data Foreing, jadi metode ini tidak berfungsi untuk kami.

Anda dapat menjalankan PostgreSQL nyata. postgresql-embedded mengunduh distribusi sebenarnya, atau lebih tepatnya arsip dengan file biner untuk platform yang kita jalankan, membukanya. Di linux pada tempfs di RAM, di windows di% TEMP%, proses server postgresql dimulai, mengkonfigurasi pengaturan server dan parameter database. Karena fitur distribusi distribusi, versi yang lebih tua dari PG 11 tidak berfungsi di Linux. Untuk saya sendiri, saya membuat perpustakaan pembungkus yang memungkinkan Anda untuk mendapatkan rakitan biner PostgreSQL tidak hanya dari server HTTP tetapi juga dari repositori maven. Yang bisa sangat berguna ketika bekerja di jaringan terisolasi dan membangun server CI tanpa akses Internet. Kenyamanan lain dalam bekerja dengan pembungkus saya adalah penjelasan komponen CDI, yang membuatnya mudah untuk menggunakan komponen dalam konteks Spring misalnya. Implementasi antarmuka server AutoClosable muncul lebih awal daripada di proyek asli. Tidak perlu ingat untuk menghentikan server, itu akan berhenti ketika konteks Spring ditutup secara otomatis.

Saat memulai, Anda dapat membuat database berdasarkan skrip, melengkapi konteks Spring dengan properti yang sesuai. Kami sekarang membuat skema database menggunakan skrip flyway untuk memigrasi skema database, yang diluncurkan setiap kali database dibuat dalam pengujian.

Untuk memverifikasi data setelah menjalankan tes, kami menggunakan pustaka uji-semi-dbunit. Dalam anotasi pada metode pengujian, kami mengindikasikan dengan unggahan mana yang membandingkan kondisi database. Ini menghilangkan kebutuhan untuk menulis kode untuk bekerja dengan dbunit, Anda hanya perlu menambahkan pendengar perpustakaan ke kode tes. Anda dapat menentukan urutan data dari tabel yang dihapus setelah metode pengujian selesai, jika konteks database digunakan kembali di antara tes. Pada 2019, ada pendekatan yang lebih modern diimplementasikan dalam database-rider yang bekerja dengan junit5. Anda dapat melihat contoh penggunaan, misalnya di sini .

Yang paling sulit adalah meniru Amazon Redshift. Ada proyek driver redshift-fake-palsu.Proyek ini berfokus pada meniru pemuatan data batch ke dalam database analitik dari AWS. Dalam jdbc: emulator protokol postgresqlredshift, perintah COPY, UNLOAD diimplementasikan, semua perintah lainnya didelegasikan ke driver JDBC PostgreSQL biasa.

Oleh karena itu, tes tidak akan bekerja dengan cara yang sama seperti di Redshift, operasi pembaruan, yang menggunakan tabel berbeda sebagai sumber data untuk memperbarui (sintaksnya berbeda dalam Redshift dan PostgreSQL 9+. Saya juga melihat interpretasi yang berbeda dari kutipan garis dalam perintah SQL di antara database ini.

Karena arsitektur database Redshift nyata, operasi memasukkan, memperbarui, dan menghapus data agak lambat dan "mahal" dalam hal I / O. Dimungkinkan untuk memasukkan data dengan kinerja yang dapat diterima hanya dalam "paket" besar dan perintah COPY hanya memungkinkan Anda untuk mengunduh data dari sistem file S3 terdistribusi. Perintah ini dalam database mendukung beberapa format data AVRO, CSV, JSON, Parket, ORC, dan TXT. Dan proyek emulator berfokus pada CSV, TXT, JSON.

Jadi, untuk meniru Redshift dalam tes, Anda perlu memulai database PostgreSQL seperti yang dijelaskan sebelumnya dan memulai emulasi repositori S3, dan ketika membuat koneksi ke postgres, Anda hanya perlu menambahkan driver redshift-palsu di classpath dan tentukan kelas driver jp.ne.opt.redshiftfake.postgres. FakePostgresqlDriver. Setelah itu, Anda dapat menggunakan jalur terbang yang sama untuk memigrasi skema database, dan dbunit sudah terbiasa untuk membandingkan data setelah menjalankan tes.



Saya bertanya-tanya berapa banyak pembaca yang menggunakan AWS dan Redshift dalam pekerjaan mereka? Tulis di komentar tentang pengalaman Anda.

Hanya menggunakan proyek Open Source, tim dapat mempercepat pengembangan di lingkungan AWS, menghemat uang dari anggaran proyek dan tidak menghentikan tim dari bekerja ketika subnet AWS diblokir oleh Roskomnadzor.

Source: https://habr.com/ru/post/id444472/


All Articles