Rumah  >  Artikel  >  pangkalan data  >  Sentinel Ketersediaan Tinggi Pembelajaran Lanjutan Redis (Perkongsian Ringkasan)

Sentinel Ketersediaan Tinggi Pembelajaran Lanjutan Redis (Perkongsian Ringkasan)

WBOY
WBOYke hadapan
2022-02-22 17:29:041935semak imbas

Artikel ini membawakan anda pengetahuan yang berkaitan tentang sentinel ketersediaan tinggi dalam Redis, termasuk isu yang berkaitan dengan seni bina fungsi, penggunaan dan konfigurasi saya harap ia akan membantu semua orang.

Sentinel Ketersediaan Tinggi Pembelajaran Lanjutan Redis (Perkongsian Ringkasan)

Pembelajaran yang disyorkan: Tutorial video Redis

1. Fungsi dan seni bina

1

Sebelum memperkenalkan Sentinel, mari kita semak dahulu teknologi yang berkaitan dengan ketersediaan tinggi Redis dari perspektif makro. Ia termasuk: ketekunan, replikasi, sentinel dan kelompok Fungsi utama dan masalah yang diselesaikan ialah:

    Kegigihan: Kegigihan ialah kaedah ketersediaan tinggi yang paling mudah (kadangkala tidak diklasifikasikan sebagai ketersediaan tinggi) cara yang tersedia. ), fungsi utamanya ialah sandaran data, iaitu menyimpan data pada cakera keras untuk memastikan data tidak akan hilang akibat proses keluar.
  • Replikasi: Replikasi ialah asas kepada Redis yang mempunyai ketersediaan tinggi Kedua-dua Sentinel dan Kluster mencapai ketersediaan tinggi berdasarkan replikasi. Replikasi terutamanya melaksanakan sandaran data berbilang mesin, serta pengimbangan beban dan pemulihan kerosakan mudah untuk operasi baca. Kecacatan: Pemulihan kegagalan tidak boleh diautomatikkan;
  • Sentinel: Berdasarkan replikasi, Sentinel melaksanakan pemulihan kegagalan automatik. Kelemahan: Operasi tulis tidak boleh seimbang beban kapasiti storan dihadkan oleh satu mesin.
  • Kluster: Melalui pengelompokan, Redis menyelesaikan masalah bahawa operasi tulis tidak boleh diseimbangkan beban dan kapasiti storan dihadkan oleh satu mesin, mencapai penyelesaian ketersediaan tinggi yang agak lengkap.
Sekarang mari kita bercakap tentang pengawal.

Redis Sentinel, juga dikenali sebagai Redis Sentinel, telah diperkenalkan dalam Redis versi 2.8.

Ciri teras Sentinel ialah failover automatik nod induk. Berikut ialah perihalan fungsi Sentinel dalam dokumen rasmi Redis:

    Pemantauan: Sentinel akan terus menyemak sama ada nod induk dan nod hamba beroperasi secara normal.
  • Failover automatik: Apabila nod induk gagal berfungsi dengan betul, Sentinel akan memulakan operasi failover automatik Ia akan menaik taraf salah satu nod hamba nod induk yang gagal kepada nod induk baharu dan membiarkan yang lain The slave. nod ditukar untuk meniru nod induk baharu.
  • Pembekal konfigurasi: Semasa pemula, klien memperoleh alamat nod induk perkhidmatan Redis semasa dengan menyambung kepada sentinel.
  • Pemberitahuan: Sentinel boleh menghantar keputusan failover kepada pelanggan.
Antaranya, fungsi pemantauan dan failover automatik membolehkan Sentinel mengesan kegagalan nod induk dalam masa dan menyelesaikan pemindahan manakala penyedia konfigurasi dan fungsi pemberitahuan perlu ditunjukkan dalam interaksi dengan pelanggan.

Berikut ialah penjelasan penggunaan perkataan "klien" dalam artikel: Dalam artikel sebelum ini, selagi pelayan redis diakses melalui API, ia akan dipanggil pelanggan, termasuk redis- cli dan klien Java Jedis, dsb.; untuk memudahkan perbezaan dan penjelasan, klien dalam artikel ini tidak termasuk redis-cli, tetapi lebih kompleks daripada redis-cli: redis-cli menggunakan antara muka asas yang disediakan oleh redis , manakala pelanggan menggunakan antara muka dan fungsi Encapsulated ini untuk memanfaatkan sepenuhnya pembekal konfigurasi dan keupayaan pemberitahuan Sentinel.

2. Seni bina

Rajah seni bina sentinel yang tipikal adalah seperti berikut:

Ia terdiri daripada dua bahagian, nod sentinel dan nod data :

    Nod sentinel: Sistem sentinel terdiri daripada satu atau lebih nod sentinel ialah nod redis khas yang tidak menyimpan data.
  • Nod data: Nod induk dan nod hamba ialah kedua-dua nod data.
2. Penerapan

Bahagian ini akan menggunakan sistem sentinel mudah, termasuk 1 nod induk, 2 nod hamba dan 3 nod sentinel. Untuk kemudahan: semua nod ini digunakan pada satu mesin (LAN IP: 192.168.92.128), dibezakan dengan nombor port konfigurasi nod dipermudahkan sebanyak mungkin.

1. Gunakan nod induk-hamba

Nod induk-hamba dalam sistem Sentinel adalah sama dengan konfigurasi nod induk-hamba biasa dan tidak memerlukan sebarang konfigurasi tambahan. Berikut ialah fail konfigurasi nod induk (port=6379) dan dua nod hamba (port=6380/6381).

#redis-6379.conf
port 6379
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
#redis-6380.conf
port 6380
daemonize yes
logfile "6380.log"
dbfilename "dump-6380.rdb"
slaveof 192.168.92.128 6379
#redis-6381.conf
port 6381
daemonize yes
logfile "6381.log"
dbfilename "dump-6381.rdb"
slaveof 192.168.92.128 6379
redis-server redis-6379.conf
redis-server redis-6380.conf
redis-server redis-6381.conf
Selepas nod bermula, sambungkan ke nod induk untuk menyemak sama ada status induk-hamba adalah normal. Selepas konfigurasi selesai, mulakan nod induk dan nod hamba mengikut urutan:

2. Gunakan nod sentinel

Nod sentinel pada asasnya ialah nod Redis khas.

Konfigurasi tiga nod sentinel hampir sama Perbezaan utama ialah nombor port (26379/26380/26381 yang berikut menggunakan nod 26379 sebagai contoh untuk memperkenalkan kaedah konfigurasi dan permulaan). daripada nod; bahagian konfigurasi adalah sejauh mungkin Dipermudahkan, lebih banyak konfigurasi akan diperkenalkan kemudian.

#sentinel-26379.conf
port 26379
daemonize yes
logfile "26379.log"
sentinel monitor mymaster 192.168.92.128 6379 2

哨兵节点的启动有两种方式,二者作用是完全相同的:其中,sentinel monitor mymaster 192.168.92.128 6379 2 配置的含义是:该哨兵节点监控192.168.92.128:6379这个主节点,该主节点的名称是mymaster,最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移。

redis-sentinel sentinel-26379.conf
redis-server sentinel-26379.conf --sentinel

3.  总结

按照上述方式配置和启动之后,整个哨兵系统就启动完毕了。可以通过redis-cli连接哨兵节点进行验证

哨兵系统的搭建过程,有几点需要注意:

(1)哨兵系统中的主从节点,与普通的主从节点并没有什么区别,故障发现和转移是由哨兵来控制和完成的。

(2)哨兵节点本质上是redis节点。

(3)每个哨兵节点,只需要配置监控主节点,便可以自动发现其他的哨兵节点和从节点。

(4)在哨兵节点启动和故障转移阶段,各个节点的配置文件会被重写(config rewrite)。

三、客户端访问哨兵系统

上一小节演示了哨兵的两大作用:监控和自动故障转移,本小节则结合客户端演示哨兵的另外两个作用:配置提供者和通知。

1.  代码示例

在介绍客户端的原理之前,先以Java客户端Jedis为例,演示一下使用方法:下面代码可以连接我们刚刚搭建的哨兵系统,并进行各种读写操作(代码中只演示如何连接哨兵,异常处理、资源关闭等未考虑)。

public static void testSentinel() throws Exception {
         String masterName = "mymaster";
         Set<String> sentinels = new HashSet<>();
         sentinels.add("192.168.92.128:26379");
         sentinels.add("192.168.92.128:26380");
         sentinels.add("192.168.92.128:26381");
         JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinels); //初始化过程做了很多工作
         Jedis jedis = pool.getResource();
         jedis.set("key1", "value1");
         pool.close();
}

Jedis客户端对哨兵提供了很好的支持。如上述代码所示,我们只需要向Jedis提供哨兵节点集合和masterName,构造JedisSentinelPool对象;然后便可以像使用普通redis连接池一样来使用了:通过pool.getResource()获取连接,执行具体的命令。2.  客户端原理

在整个过程中,我们的代码不需要显式的指定主节点的地址,就可以连接到主节点;代码中对故障转移没有任何体现,就可以在哨兵完成故障转移后自动的切换主节点。之所以可以做到这一点,是因为在JedisSentinelPool的构造器中,进行了相关的工作;主要包括以下两点:

(1)遍历哨兵节点,获取主节点信息:遍历哨兵节点,通过其中一个哨兵节点+masterName获得主节点的信息;该功能是通过调用哨兵节点的sentinel get-master-addr-by-name命令实现,该命令示例如下:

一旦获得主节点信息,停止遍历(因此一般来说遍历到第一个哨兵节点,循环就停止了)。

(2)增加对哨兵的监听:这样当发生故障转移时,客户端便可以收到哨兵的通知,从而完成主节点的切换。具体做法是:利用redis提供的发布订阅功能,为每一个哨兵节点开启一个单独的线程,订阅哨兵节点的+switch-master频道,当收到消息时,重新初始化连接池。

3.  总结

通过客户端原理的介绍,可以加深对哨兵功能的理解:

(1)配置提供者:客户端可以通过哨兵节点+masterName获取主节点信息,在这里哨兵起到的作用就是配置提供者。

需要注意的是,哨兵只是配置提供者,而不是代理。二者的区别在于:如果是配置提供者,客户端在通过哨兵获得主节点信息后,会直接建立到主节点的连接,后续的请求(如set/get)会直接发向主节点;如果是代理,客户端的每一次请求都会发向哨兵,哨兵再通过主节点处理请求。

举一个例子可以很好的理解哨兵的作用是配置提供者,而不是代理。在前面部署的哨兵系统中,将哨兵节点的配置文件进行如下修改:

sentinel monitor mymaster 192.168.92.128 6379 2
改为
sentinel monitor mymaster 127.0.0.1 6379 2

(2)通知:哨兵节点在故障转移完成后,会将新的主节点信息发送给客户端,以便客户端及时切换主节点。然后,将前述客户端代码在局域网的另外一台机器上运行,会发现客户端无法连接主节点;这是因为哨兵作为配置提供者,客户端通过它查询到主节点的地址为127.0.0.1:6379,客户端会向127.0.0.1:6379建立redis连接,自然无法连接。如果哨兵是代理,这个问题就不会出现了。

四、基本原理

前面介绍了哨兵部署、使用的基本方法,本部分介绍哨兵实现的基本原理。

1. Arahan disokong oleh nod sentinel

Sebagai nod redis berjalan dalam mod khas, nod sentinel menyokong perintah yang berbeza daripada nod redis biasa. Dalam operasi dan penyelenggaraan, kami boleh bertanya atau mengubah suai sistem Sentinel melalui arahan ini, tetapi yang lebih penting, agar sistem Sentinel melaksanakan pelbagai fungsi seperti penemuan kesalahan dan kegagalan, ia tidak dapat dipisahkan daripada komunikasi antara nod Sentinel, dan komunikasi adalah sangat Kebanyakan ini dicapai melalui arahan yang disokong oleh nod sentinel. Berikut menerangkan arahan utama yang disokong oleh nod sentinel.

(1) Pertanyaan asas: Melalui arahan ini, anda boleh menanyakan topologi, maklumat nod, maklumat konfigurasi, dll. sistem Sentinel.

  • maklumat sentinel: Dapatkan maklumat asas semua nod induk yang dipantau
  • induk sentinel: Dapatkan maklumat terperinci semua nod induk yang dipantau
  • induk sentinel mymaster: Dapatkan maklumat terperinci daripada nod induk mymaster yang dipantau
  • hamba sentinel mymaster: Dapatkan maklumat terperinci tentang nod hamba mymaster nod yang dipantau
  • sentinel sentinels mymaster: Dapatkan nod sentinel sentinel yang dipantau Nod sentinel mymaster Maklumat terperinci
  • sentinel get-master-addr-by-name mymaster: Dapatkan maklumat alamat mymaster nod induk yang dipantau, yang telah diperkenalkan sebelum ini
  • sentinel is-master-down-by-addr : Sentinel nodes boleh menggunakan arahan ini untuk bertanya sama ada nod induk berada di luar talian, untuk menilai sama ada ia berada di luar talian secara objektif

(2) Tambah/buang pemantauan nod induk

pantau sentinel mymaster2 192.168.92.128 16379 2: Fungsinya adalah sama seperti fungsi monitor sentinel dalam fail konfigurasi apabila menggunakan nod sentinel, dan tidak akan diterangkan secara terperinci

sentinel remove mymaster2: Batalkan pemantauan ke atas nod induk mymaster2 oleh nod sentinel semasa

(3) Failover paksa

failover sentinel mymaster: Perintah ini boleh memaksa failover tuan saya , Walaupun nod induk semasa berjalan dengan baik, contohnya, jika mesin di mana nod induk semasa berada hampir dihapuskan, anda boleh menggunakan perintah failover untuk melakukan failover terlebih dahulu.

2. Prinsip Asas

Mengenai prinsip pengawalan, kuncinya ialah memahami konsep berikut.

(1) Tugas berjadual: Setiap nod sentinel mengekalkan 3 tugas berjadual. Fungsi tugas berjadual adalah seperti berikut: dapatkan struktur induk-hamba terkini dengan menghantar arahan info ke nod induk-hamba mendapatkan maklumat nod sentinel lain melalui fungsi penerbitan dan langgan dengan menghantar ping; arahan kepada nod lain untuk menentukan sama ada ia berada di luar talian.

(2) Luar talian subjektif: Dalam tugas pengesanan degupan jantung yang dijadualkan, jika nod lain tidak membalas untuk tempoh masa tertentu, nod sentinel akan secara subjektif di luar talian. Seperti namanya, subjektif luar talian bermaksud bahawa nod sentinel "secara subjektif" menilai luar talian;

(3) Objektif luar talian: Selepas nod sentinel secara subjektif log keluar dari nod induk, ia akan bertanya nod sentinel lain tentang status nod induk melalui arahan sentinel is-master-down-by-addr; jika ia dinilai Apabila bilangan sentinel yang pergi ke luar talian pada nod induk mencapai nilai tertentu, nod induk akan secara objektif dibawa ke luar talian.

Adalah penting untuk ambil perhatian bahawa objektif luar talian adalah konsep hanya untuk nod induk jika nod hamba dan nod sentinel gagal, selepas berada di luar talian secara subjektif oleh sentinel, tidak akan ada objektif luar talian berikutnya; operasi talian dan failover.

(4) Pilih nod sentinel ketua: Apabila nod induk dinilai sebagai luar talian secara objektif, setiap nod sentinel akan berunding untuk memilih nod sentinel ketua, dan nod ketua akan Melakukan operasi failover.

Semua sentinel yang memantau nod induk boleh dipilih sebagai ketua Algoritma yang digunakan dalam pilihan raya ialah algoritma Raft adalah pertama datang, dilayan dahulu: iaitu, dalam satu pusingan pemilihan, Sentinel A Hantar permohonan untuk menjadi ketua kepada B. Jika B tidak bersetuju dengan sentinel lain, ia akan bersetuju untuk A menjadi ketua. Proses pemilihan khusus tidak akan diterangkan secara terperinci di sini Secara umumnya, proses pemilihan sentinel adalah sangat cepat Sesiapa yang menyelesaikan objektif secara luar talian secara amnya akan menjadi ketua.

(5) Failover: Sentinel ketua yang dipilih memulakan operasi failover, yang boleh dibahagikan secara kasar kepada 3 langkah:

  • Pilih nod hamba baharu Nod induk: Prinsip pemilihan ialah untuk menapis nod hamba yang tidak sihat dahulu; kemudian pilih nod hamba dengan keutamaan tertinggi (ditentukan oleh keutamaan hamba, pilih nod hamba dengan offset replikasi terbesar, jika ia masih tidak dapat dibezakan; nod hamba dengan runid terkecil.
  • Kemas kini status tuan-hamba: gunakan perintah slaveof no one untuk menjadikan nod hamba yang dipilih sebagai nod induk; dan gunakan perintah slaveof untuk menjadikan nod lain nod hambanya.
  • Tetapkan nod induk luar talian (iaitu 6379) sebagai nod hamba nod induk baharu. Apabila 6379 kembali dalam talian, ia akan menjadi nod hamba nod induk baharu.

5. Cadangan konfigurasi dan amalan

1.

(1) sentinel monitor {masterName} {masterIp} {masterPort} {quorum}

Monitor sentinel ialah konfigurasi teras sentinel Ia telah diterangkan sebelum ini semasa menggunakan nod sentinel Antaranya: masterName menentukan nama nod induk, masterIp dan masterPort menentukan alamat nod induk, dan kuorum ialah sentinel. menentukan objektif luar talian nod induk ambang kuantiti: Apabila bilangan sentinel yang menentukan bahawa nod induk berada di luar talian mencapai kuorum, nod induk akan berada di luar talian secara objektif. Nilai yang disyorkan ialah separuh daripada bilangan pengawal ditambah 1.

(2) sentinel turun-selepas-milisaat {masterName} {masa}

sentinel turun-selepas-milisaat berkaitan dengan pertimbangan subjektif luar talian: sentinel menggunakan perintah ping untuk melaksanakan degupan jantung pada Pengesanan nod lain, jika nod lain tidak membalas selepas masa yang dikonfigurasikan oleh turun-selepas-milisaat, Sentinel akan secara subjektif membawanya ke luar talian. Konfigurasi ini sah untuk penentuan luar talian subjektif nod induk, nod hamba dan nod sentinel.

Nilai lalai bagi turun-selepas-milisaat ialah 30000, iaitu 30s; ia boleh dilaraskan mengikut persekitaran rangkaian dan keperluan aplikasi yang berbeza: semakin besar nilainya, semakin longgar pertimbangan subjektif luar talian, kelebihannya; adalah salah pertimbangan Kemungkinan kecil, tetapi kelemahannya ialah masa untuk penemuan kesalahan dan failover akan menjadi lebih lama, dan masa menunggu pelanggan juga akan menjadi lebih lama. Sebagai contoh, jika aplikasi mempunyai keperluan ketersediaan yang tinggi, nilai boleh dikurangkan dengan sewajarnya untuk menyelesaikan pemindahan secepat mungkin apabila kegagalan berlaku jika persekitaran rangkaian agak lemah, ambang boleh ditingkatkan dengan sewajarnya untuk mengelakkan kesilapan yang kerap berlaku;

(3) sentinel parallel-syncs {masterName} {number}

sentinel parallel-syncs berkaitan dengan replikasi nod hamba selepas failover: ia menyatakan bahawa setiap kali ia dimulakan untuk nod induk baharu Bilangan nod hamba untuk operasi replikasi. Sebagai contoh, anggap bahawa selepas suis nod induk selesai, 3 nod hamba ingin memulakan replikasi ke nod induk baharu jika selari-segerak=1, nod hamba akan mula mereplikasi satu demi satu jika selari-segerak=3; kemudian 3 nod hamba Nod akan mula mereplikasi bersama.

Semakin besar nilai penyegerakan selari, semakin cepat nod hamba menyelesaikan replikasi, tetapi semakin besar tekanan pada beban rangkaian dan beban cakera keras nod induk ia harus ditetapkan mengikut kepada keadaan sebenar. Contohnya, jika beban pada nod induk adalah rendah dan nod hamba mempunyai keperluan ketersediaan perkhidmatan yang tinggi, anda boleh meningkatkan nilai penyegerakan selari dengan sewajarnya. Nilai lalai untuk penyegerakan selari ialah 1.

(4) sentinel failover-timeout {masterName} {time}

sentinel failover-timeout adalah berkaitan dengan penghakiman failover timeout, tetapi parameter ini tidak digunakan untuk menilai tamat masa keseluruhan fasa failover , tetapi tamat masa beberapa sub-peringkatnya, contohnya, jika masa untuk nod induk mempromosikan nod hamba melebihi masa, atau masa untuk nod hamba memulakan operasi replikasi kepada induk baharu. nod (tidak termasuk masa untuk menyalin data) melebihi tamat masa, ia akan menyebabkan tamat masa failover gagal.

Nilai lalai failover-timeout ialah 180000, iaitu 180s jika tamat masa, nilai akan menjadi dua kali ganda nilai asal pada masa akan datang.

(5) Selain parameter di atas, terdapat beberapa parameter lain, seperti parameter yang berkaitan dengan pengesahan keselamatan, yang tidak akan diperkenalkan di sini.

2. Cadangan praktikal

(1) Bilangan nod sentinel harus lebih daripada satu, ia meningkatkan redundansi nod sentinel dan mengelakkan sentinel itu sendiri menjadi tinggi. - kesesakan ketersediaan; sebaliknya, ia mengurangkan bilangan nod sentinel. Tambahan pula, nod sentinel yang berbeza ini harus digunakan pada mesin fizikal yang berbeza.

(2) Bilangan nod sentinel hendaklah nombor ganjil untuk memudahkan pengawal membuat "keputusan" melalui pengundian: keputusan mengenai pemilihan pemimpin, keputusan di luar talian objektif, dsb.

(3) Konfigurasi setiap nod sentinel harus konsisten, termasuk perkakasan, parameter, dsb. di samping itu, semua nod harus menggunakan ntp atau perkhidmatan yang serupa untuk memastikan masa yang tepat dan konsisten.

(4) Pembekal konfigurasi Sentinel dan fungsi klien pemberitahuan memerlukan sokongan pelanggan, seperti Jedis yang dinyatakan di atas jika perpustakaan yang digunakan oleh pembangun tidak memberikan sokongan yang sepadan, pembangun mungkin perlu Melaksanakannya sendiri.

(5) Apabila nod dalam sistem Sentinel digunakan dalam docker (atau perisian lain yang mungkin melakukan pemetaan port), perhatian khusus harus diberikan kepada fakta bahawa pemetaan port boleh menyebabkan sistem Sentinel tidak berfungsi dengan betul, kerana kerja Sentinel adalah berdasarkan Komunikasi dengan nod lain, dan pemetaan port docker boleh menyebabkan Sentinel tidak dapat menyambung ke nod lain. Sebagai contoh, penemuan antara satu sama lain oleh sentinel bergantung pada IP dan port yang mereka isytiharkan kepada dunia luar Jika sentinel A digunakan dalam docker dengan pemetaan port, sentinel lain tidak boleh menyambung ke A menggunakan port yang diisytiharkan oleh A.

6. Ringkasan

Artikel ini mula-mula memperkenalkan peranan Sentinel: pemantauan, failover, pembekal konfigurasi dan pemberitahuan, kemudian ia menerangkan kaedah penggunaan sistem Sentinel dan mengakses sistem Sentinel melalui kaedah klien; kemudian menerangkan secara ringkas prinsip asas pelaksanaan sentinel dan akhirnya memberikan beberapa cadangan tentang amalan sentinel.

Berdasarkan replikasi tuan-hamba, Sentinel memperkenalkan failover automatik nod induk, meningkatkan lagi ketersediaan Redis yang tinggi, bagaimanapun, kelemahan Sentinel juga jelas: Sentinel tidak boleh melakukan kegagalan automatik nod hamba senario pemisahan baca-tulis, kegagalan nod hamba akan menyebabkan perkhidmatan baca tidak tersedia, memerlukan kami melakukan operasi pemantauan dan penukaran tambahan pada nod hamba.

Selain itu, Sentinel masih belum menyelesaikan masalah bahawa operasi tulis tidak boleh diseimbangkan beban dan kapasiti storan dihadkan oleh satu mesin penyelesaian kepada masalah ini memerlukan penggunaan kluster, yang akan saya perkenalkan; artikel kemudian.

Pembelajaran yang disyorkan: "Tutorial video Redis", "Soalan dan jawapan temuduga redis terkini 2022"

Atas ialah kandungan terperinci Sentinel Ketersediaan Tinggi Pembelajaran Lanjutan Redis (Perkongsian Ringkasan). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:csdn.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam