Bagaimana cara menggunakan PHP untuk mengimplementasikan layanan microser?

Swoft


Mengapa harus bicara tata kelola layanan?


Dengan semakin populernya Internet, arsitektur MVC tradisional telah menjadi semakin membengkak dan sangat sulit untuk dipertahankan karena skala aplikasi terus berkembang.


Kita perlu mengambil tindakan untuk membagi sistem besar menjadi beberapa aplikasi sesuai dengan karakteristik bisnis. Sebagai contoh, sistem e-commerce yang besar dapat mencakup sistem pengguna, sistem produk, sistem pemesanan, sistem evaluasi, dll., Dan kami dapat memisahkannya menjadi beberapa aplikasi individual. Karakteristik arsitektur multi-aplikasi adalah aplikasi berjalan secara independen dan mereka tidak dapat saling memanggil.


Meskipun beberapa aplikasi menyelesaikan masalah aplikasi yang membengkak, aplikasi tersebut tidak tergantung satu sama lain dan layanan atau kode umum tidak dapat digunakan kembali.




Untuk sistem Internet yang besar, biasanya berisi beberapa aplikasi dengan layanan umum, dan masing-masing aplikasi memiliki hubungan panggilan satu sama lain. Selain itu, ada tantangan lain untuk sistem Internet skala besar, seperti bagaimana menangani pengguna yang tumbuh cepat, bagaimana mengelola tim R&D untuk dengan cepat mengubah pengembangan sistem, bagaimana menjaga peningkatan sistem dengan cara yang stabil, dan sebagainya.


Oleh karena itu, untuk menggunakan kembali layanan dengan baik dan memelihara modul agar mudah berkembang. Kami ingin layanan dipisahkan dari aplikasi. Layanan tidak lagi dalam aplikasi, tetapi dipertahankan sebagai layanan terpisah. Aplikasi itu sendiri bukan lagi tumpukan modul yang membengkak, tetapi komponen layanan modular.


Servitization


Fitur


Jadi apa fitur menggunakan "Servitization"?


  • Aplikasi terbagi menjadi beberapa layanan oleh bisnis
  • Layanan individual dapat digunakan secara mandiri
  • Layanan dapat dibagikan oleh banyak aplikasi
  • Layanan dapat berkomunikasi satu sama lain
  • Arsitektur sistem lebih jelas
  • Modul inti stabil, dan peningkatan komponen layanan dalam unit dapat menghindari risiko seringnya rilis baru
  • Mudah untuk pengembangan dan manajemen
  • Pemeliharaan dapat dilakukan oleh tim individu dengan alur kerja dan tanggung jawab yang jelas
  • Layanan digunakan kembali, kode digunakan kembali
  • Sangat mudah berkembang

Tantangan servisisasi


Setelah servis sistem, ketergantungan sistem menjadi rumit, dan jumlah interaksi di antara layanan meningkat. Dalam mode pengembangan fpm , karena memori penduduk tidak dapat disediakan, setiap permintaan harus dimulai dari nol dengan mulai memuat proses untuk keluar dari proses, menambahkan banyak overhead yang tidak berguna. Juga, koneksi basis data tidak dapat digunakan kembali dan tidak dapat dilindungi karena fpm adalah berbasis proses dan jumlah proses fpm juga menentukan jumlah bersamaan. Ini adalah masalah yang diberikan kepada kita oleh sederhana pengembangan fpm . Jadi, ini adalah alasan mengapa Java lebih populer sekarang di platform Internet dibandingkan dengan .NET dan PHP . Terlepas dari PHP non-memory resident , ada banyak masalah lain yang perlu diatasi.


  • Lebih banyak layanan, lebih banyak kompleksitas manajemen konfigurasi
  • Ketergantungan layanan yang kompleks
  • Load balancing antar layanan
  • Perluasan layanan
  • Pemantauan layanan
  • Downgrade layanan
  • Otentikasi layanan
  • Layanan online dan offline
  • Dokumentasi layanan
    ......

Anda dapat membayangkan manfaat yang dibawa oleh memori penduduk kepada kami.


  • Hanya mulai inisialisasi kerangka kerja setelah kita dapat berkonsentrasi pada pemrosesan permintaan karena kerangka kerja hanya dapat diinisialisasi dalam memori saat startup sekaligus untuk memori penduduk


  • Koneksi multiplexing , beberapa insinyur tidak dapat mengerti jika tidak menggunakan koneksi pool, apa konsekuensi dari membuat koneksi untuk setiap permintaan? Ini menyebabkan sumber daya backend terlalu banyak dalam koneksi. Untuk beberapa layanan dasar, seperti Redis, database, koneksi adalah saluran yang mahal.



Jadi, adakah solusi yang bagus? Jawabannya adalah ya, dan banyak orang menggunakan kerangka kerja yang disebut Swoft . Swoft adalah kerangka kerja RPC dengan fitur Service Governance . Swoft adalah kerangka kerja penuh stack penuh memori residen PHP, berdasarkan konsep inti Spring Boot , konvensi lebih besar daripada konfigurasi.


Swoft menyediakan cara yang lebih elegan untuk menggunakan layanan RPC seperti Dubbo dan Swoft memiliki kinerja hebat mirip dengan kinerja Golang . Ini adalah hasil stress test dari kinerja Swoft terjadi di PC saya.

Swoft


Kecepatan pemrosesan sangat luar biasa dalam tes stres ab . Dengan CPU i7 generation 8 dan memori 16GB , 100000 permintaan hanya menggunakan 5s . Waktu pada dasarnya tidak mungkin dicapai dalam mode pengembangan fpm . Tes ini juga cukup untuk menunjukkan kinerja tinggi dan stabilitas Swoft .


Tata kelola layanan yang elegan


Pendaftaran dan Penemuan Layanan


Dalam proses tata kelola layanan-layanan mikro, pendaftaran layanan yang diprakarsai ke kluster pihak ketiga, seperti konsul / etcd, sering dilibatkan. Bab ini menggunakan komponen konsul swoft dalam kerangka kerja Swoft untuk mengimplementasikan pendaftaran dan penemuan layanan.
Swoft
Logika implementasi


 <?php declare(strict_types=1); namespace App\Common; use ReflectionException; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Bean\Annotation\Mapping\Inject; use Swoft\Bean\Exception\ContainerException; use Swoft\Consul\Agent; use Swoft\Consul\Exception\ClientException; use Swoft\Consul\Exception\ServerException; use Swoft\Rpc\Client\Client; use Swoft\Rpc\Client\Contract\ProviderInterface; /** * Class RpcProvider * * @since 2.0 * * @Bean() */ class RpcProvider implements ProviderInterface { /** * @Inject() * * @var Agent */ private $agent; /** * @param Client $client * * @return array * @throws ReflectionException * @throws ContainerException * @throws ClientException * @throws ServerException * @example * [ * 'host:port', * 'host:port', * 'host:port', * ] */ public function getList(Client $client): array { // Get health service from consul $services = $this->agent->services(); $services = [ ]; return $services; } } 

Pemutus Sirkuit Layanan


Dalam lingkungan terdistribusi, terutama sistem arsitektur microservice terdistribusi, sangat umum bagi satu sistem perangkat lunak untuk memanggil sistem jarak jauh lain. Callee panggilan jarak jauh semacam itu mungkin merupakan proses lain, atau host lain di seluruh jaringan. Perbedaan terbesar antara panggilan jarak jauh ini dan panggilan internal proses adalah bahwa panggilan jarak jauh mungkin gagal atau hang. Tidak ada respons hingga batas waktu. Lebih buruk lagi, jika ada banyak penelepon yang memanggil layanan yang ditangguhkan yang sama, sangat mungkin bahwa batas waktu layanan menunggu dengan cepat menyebar ke seluruh sistem terdistribusi, menyebabkan reaksi berantai yang menghabiskan seluruh sumber daya dalam sistem terdistribusi. Akhirnya, itu dapat menyebabkan kelumpuhan sistem.


Mode Circuit Breaker dirancang untuk mencegah bencana yang disebabkan oleh reaksi berantai seperti air terjun dalam sistem terdistribusi.



Dalam mode pemutus sirkuit dasar, untuk memastikan pemasok tidak dipanggil saat pemutus sirkuit dalam keadaan terbuka, tetapi kami juga memerlukan metode tambahan untuk mengatur ulang pemutus sirkuit setelah pemasok melanjutkan layanan. Salah satu solusi yang mungkin adalah pemutus sirkuit secara berkala mendeteksi apakah layanan pemasok dilanjutkan. Setelah dilanjutkan, status ditetapkan untuk ditutup. Keadaan ini adalah kondisi setengah terbuka ketika pemutus sirkuit mencoba lagi.


Penggunaan sekeringnya sederhana dan kuat. Ini dapat dijelaskan dengan @Breaker . Sekering Swoft dapat digunakan dalam skenario apa pun, seperti layanan yang dipanggil. Itu dapat diturunkan atau tidak dipanggil saat meminta layanan pihak ketiga.


 <?php declare(strict_types=1); namespace App\Model\Logic; use Exception; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Breaker\Annotation\Mapping\Breaker; /** * Class BreakerLogic * * @since 2.0 * * @Bean() */ class BreakerLogic { /** * @Breaker(fallback="loopFallback") * * @return string * @throws Exception */ public function loop(): string { // Do something throw new Exception('Breaker exception'); } /** * @return string * @throws Exception */ public function loopFallback(): string { // Do something } } 

Pembatasan layanan


Pembatasan Aliran, Pemutus Arus Listrik, Downgrade Layanan Ini dapat ditekankan berulang kali karena sangat penting. Ketika layanan tidak berfungsi, itu harus rusak. Pembatasan aliran adalah alat untuk melindungi dirinya sendiri. Jika tidak ada mekanisme perlindungan diri dan koneksi diterima tidak peduli berapa banyak mereka, front-end pasti akan hang ketika lalu lintas sangat besar sedangkan back-end tidak dapat menangani semua koneksi.


Pembatasan aliran adalah untuk membatasi jumlah permintaan bersamaan dan jumlah ketika mengakses sumber daya yang langka, seperti barang penjualan kilat, sehingga secara efektif memotong puncak dan memperlancar kurva aliran. Tujuan dari pembatasan aliran adalah untuk membatasi laju akses bersamaan dan permintaan bersamaan, atau untuk membatasi kecepatan permintaan dalam rentang waktu untuk melindungi sistem. Setelah batas nilai tercapai atau dilampaui, permintaan dapat ditolak, atau diantrekan.


Lapisan bawah dari pembatasan aliran Swoft menggunakan algoritma token bucket, dan lapisan yang mendasarinya bergantung pada Redis untuk menerapkan pembatasan aliran yang didistribusikan.


Pembatasan aliran Swoft tidak hanya membatasi pengontrol, tetapi juga membatasi metode dalam kacang apa pun dan mengontrol laju akses metode. Contoh berikut adalah penjelasan secara rinci.


 <?php declare(strict_types=1); namespace App\Model\Logic; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Limiter\Annotation\Mapping\RateLimiter; /** * Class LimiterLogic * * @since 2.0 * * @Bean() */ class LimiterLogic { /** * @RequestMapping() * @RateLimiter(rate=20, fallback="limiterFallback") * * @param Request $request * * @return array */ public function requestLimiter2(Request $request): array { $uri = $request->getUriPath(); return ['requestLimiter2', $uri]; } /** * @param Request $request * * @return array */ public function limiterFallback(Request $request): array { $uri = $request->getUriPath(); return ['limiterFallback', $uri]; } } 

Ini mendukung symfony/expression-language . Jika kecepatan terbatas, metode limiterFallback yang didefinisikan dalam fallback akan dipanggil.


Pusat konfigurasi


Sebelum kita berbicara tentang pusat konfigurasi, mari kita bicara tentang file konfigurasi. Kami tidak asing dengan itu. Ini memberi kami kemampuan untuk memodifikasi program secara dinamis. Kutipan dari seseorang adalah:


Penyesuaian dinamis dari sikap penerbangan dari runtime sistem!

Saya dapat memanggil pekerjaan kami untuk memperbaiki suku cadang di pesawat terbang cepat. Kita manusia selalu tidak mampu mengendalikan dan memprediksi segalanya. Untuk sistem kami, kami selalu perlu mencadangkan beberapa garis kontrol untuk membuat penyesuaian ketika kami membutuhkannya, untuk mengendalikan arah sistem (seperti kontrol abu-abu, penyesuaian pembatasan aliran), yang sangat penting bagi industri Internet yang mencakup perubahan.


Untuk versi yang berdiri sendiri, kami menyebutnya konfigurasi (file); untuk sistem cluster terdistribusi, kami menyebutnya pusat konfigurasi (sistem);


Apa sebenarnya pusat konfigurasi terdistribusi?


Dengan perkembangan bisnis dan peningkatan arsitektur layanan mikro, jumlah layanan dan konfigurasi program meningkat (berbagai layanan mikro, berbagai alamat server, berbagai parameter), dan metode file konfigurasi tradisional, serta metode database tidak dapat memenuhi kebutuhan pengembang dalam manajemen konfigurasi:


  • Keamanan: Konfigurasi mengikuti kode sumber yang disimpan dalam basis kode, yang mudah menyebabkan kebocoran konfigurasi;
  • Ketepatan waktu: Memodifikasi konfigurasi dan memulai kembali layanan agar berlaku.
  • Keterbatasan: Penyesuaian dinamis tidak dapat didukung: misalnya, sakelar log, sakelar fungsi;

Karena itu, kita perlu mengonfigurasi pusat untuk mengelola konfigurasi! Membebaskan pengembang bisnis dari konfigurasi yang rumit dan rumit, mereka hanya perlu fokus pada kode bisnis itu sendiri, yang secara signifikan dapat meningkatkan pengembangan dan efisiensi operasional. Pada saat yang sama, konfigurasi dan rilis paket akan semakin meningkatkan tingkat keberhasilan rilis, dan memberikan dukungan kuat untuk kontrol fine tune dan penanganan darurat operasi dan pemeliharaan.


Tentang pusat konfigurasi terdistribusi, ada banyak solusi open source di web, seperti:


Apollo adalah pusat konfigurasi terdistribusi yang dikembangkan oleh departemen kerangka Ctrip. Ini dapat secara terpusat mengelola konfigurasi berbagai lingkungan dan kelompok aplikasi yang berbeda. Itu dapat didorong ke akhir aplikasi secara real time setelah modifikasi konfigurasi. Ini memiliki fitur otoritas standar dan manajemen proses, dan cocok untuk skenario mengkonfigurasi dan mengelola layanan microser.


Bab ini menggunakan Apollo sebagai contoh untuk menarik konfigurasi dan mengamankan layanan restart dari pusat konfigurasi jarak jauh. Jika Anda tidak terbiasa dengan Apollo , pertama-tama Anda dapat melihat komponen Apollo ekstensi Swoft dan membaca dokumentasi Resmi Apollo .


Bab ini menggunakan Apollo di Swoft sebagai contoh. Ketika konfigurasi Apollo berubah, restart layanan (http-server / rpc-server / ws-server). Berikut ini adalah contoh agen:


 <?php declare(strict_types=1); namespace App\Model\Logic; use Swoft\Apollo\Config; use Swoft\Apollo\Exception\ApolloException; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Bean\Annotation\Mapping\Inject; /** * Class ApolloLogic * * @since 2.0 * * @Bean() */ class ApolloLogic { /** * @Inject() * * @var Config */ private $config; /** * @throws ApolloException */ public function pull(): void { $data = $this->config->pull('application'); // Print data var_dump($data); } } 

Di atas adalah tarikan konfigurasi Apollo yang sederhana, selain metode ini, Swoft-Apollo menyediakan lebih banyak cara untuk digunakan.



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


All Articles