1. Pendahuluan
Strategi pemisahan baca dan tulis dari basis data dalam lingkungan terdistribusi adalah solusi utama untuk menyelesaikan bottleneck database membaca dan menulis kinerja, dan juga memaksimalkan kecepatan dan konkurensi data membaca (baca) dalam aplikasi.
Saat memisahkan database membaca dan menulis, pertama -tama kita perlu mengonfigurasi master dan slave basis data. Yang paling sederhana adalah seorang master dan budak (untuk sistem situs web besar, tentu saja, itu akan sangat rumit. Di sini kita hanya menganalisis situasi paling sederhana). Melalui konfigurasi master-slave, database master-slave menyimpan data yang sama. Kami mengakses Slave Database Slave saat melakukan operasi baca dan master basis data master saat melakukan operasi penulisan. Ini akan mengurangi tekanan pada server.
Saat melakukan analisis kasus pemisahan baca dan tulis. Pertama, konfigurasikan replikasi master-slave dari database, dan berikan penjelasan terperinci tentang instalasi sinkron dan konfigurasi MySQL5.6 Basis Data Master-Slave (Master/Slave)
Tentu saja, ini hanya cara sederhana untuk melihat cara menggunakan kode untuk mencapai pemisahan database membaca dan menulis, dan tidak perlu mengkonfigurasi database master dan slave. Ini hanya membutuhkan dua mesin dengan database yang sama diinstal.
2. Dua cara untuk mencapai pemisahan membaca dan menulis
Secara khusus dalam pengembangan, ada dua cara umum untuk mencapai pemisahan membaca dan menulis:
1. Metode pertama adalah metode yang paling umum digunakan, yaitu untuk menentukan dua koneksi basis data, satu adalah MasterDataSource dan yang lainnya adalah SlavedataSource. Saat memperbarui data, kami membaca MasterDataSource, dan ketika menanyakan data, kami membaca SlaveDataSource. Metode ini sangat sederhana, jadi saya tidak akan membahas detailnya.
2. Metode kedua dari switching sumber data dinamis adalah untuk secara dinamis menenun sumber data ke dalam program saat program berjalan, sehingga dapat memilih untuk membaca perpustakaan master atau perpustakaan slave. Teknologi utama yang digunakan adalah: anotasi, pegas AOP, refleksi.
Metode implementasi akan dijelaskan secara rinci di bawah ini.
3. AOP mewujudkan kasus pemisahan baca dan tulis dari database master-slave
1. Alamat Kode Proyek
Alamat proyek saat ini dari demo ini: demo
2. Struktur Proyek
Pada gambar di atas, selain kode yang ditandai, yang lain terutama kode konfigurasi dan kode bisnis.
3. Analisis Khusus
Proyek ini adalah demo dari kerangka kerja SSM, Spring, Spring MVC dan Mybatis. File konfigurasi spesifik tidak terlalu banyak diperkenalkan.
(1) UserContoller mensimulasikan data membaca dan menulis
/*** Dibuat oleh Xuliugen pada 2016/5/4. */@Controller@requestMapping (value = "/user", menghasilkan = {"application/json; charset = utf-8"}) kelas publik usercontroller {@Inject private iuserservice UserserService; //http://localhost:8080/user/select.do @responseBody @RequestMapping (value = "/select.do", Method = requestMethod.get) string publik Select () {user user = Userservice.selectuserbyId (123); return user.toString (); } //http://localhost:8080/user/add.do @responseBody @RequestMapping (value = "/add.do", Method = requestMethod.get) Public String Add () {boolean isok = Userservice.adduser (pengguna baru ("333", "44" 44)))); return isok == true? "Shibai": "Chenggong"; }}Simulasi membaca dan menulis data dan hubungi iUserservice.
(2) spring-db.xml membaca dan menulis konfigurasi sumber data
<? XML Versi = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmls xmlns: aop = "http://www.springframework.org/schema/aop" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="statFilter" lazy-init="true"> <property name="logSlowSql" value="true"/> <property name="mergeSql" value="true"/> </bean> <!-- Database Connection--> <bean id="readDataSource" destroy-method="close" init-method="init" lazy-init="true"> <property name="driverClassName" value="${driver}"/> <property name="url" value="${url1}"/> <property name="username" value = "root"/> <name properti = "password" value = "$ {password}"/> <!-hilangkan beberapa konten-> </ bean> <bean id = "writedatasource" destroy-metod = "tutup" init-metod = "init" lazy-init = "true"> <nama properti = "driverclassname" value = "$" $ {"name"> <"Property =" "name" name = "value" $ "$" value="${url}"/> <property name="username" value="root"/> <property name="password" value="${password}"/> <!-- Omit some content --> </bean> <!-- Configure dynamically allocated read and write data sources --> <bean id="dataSource" lazy-init="true"> <property name="targetDataSources"> <map Key-Type = "java.lang.string" value-type = "javax.sql.datasource"> <!-write-> <entry key = "write" value-ref = "writedataSource"/> <!-baca-> <entri key = "baca" value-ref = "readDataSource"//</Map> </Map> </Peta> APROP besar = "Nilai-" DEFAURED "DEFAURED" DEFAUREC "//</MAP> </MAP> </PATAC> APROKUS =" NEVELY-REF = "ReadDataSource"//</MAP> </MAP> APROKUS = "NEVELY-" ref="writeDataSource"/> <property name="methodType"> <map key-type="java.lang.String"> <!-- read --> <entry key="read" value=",get,select,count,list,query"/> <!-- write --> <entry key="write" value=",add,create,update,delete,remove,"/> </map> </property> </tagel> </tobel>Dalam konfigurasi di atas, ReadDataSource dan WritedataSource dikonfigurasi, tetapi hanya sumber data yang diserahkan kepada SQLSessionFactoryBean untuk manajemen, dan penggunaan: com.xuliugen.choosedb.demo.aspect.choosedataSource Ini digunakan untuk pemilihan basis data.
<name properti = "MethodType"> <peta key-type = "java.lang.string"> <!-baca-> <entry key = "baca" value = ", get, count, list, query"/<!-write-> <entry key = "write" value = ", buat, perbarui, hapus, hapus,"/</peta> </peta "value ="
Kata kunci awalan spesifik basis data dikonfigurasi. Kode spesifik dari pilihan pilihan adalah sebagai berikut:
(3) Pilihan yang dipilih
/*** Dapatkan sumber data, yang digunakan untuk secara dinamis beralih sumber data*/kelas publik yang dipilih dari PublicAsource meluas abstractroutingDataSource {peta statis public <string, daftar <string>> method_type_map = hashmap <string, daftar <string> () (); / *** Menerapkan metode abstrak di kelas induk dan dapatkan nama sumber data* @return*/ Deteksi Objek ProtectedRentLookUpkey () {return DataSourceHandLer.GetDataSource (); } // Atur sumber data yang sesuai dengan nama metode prefix public void setMethodType (peta <string, string> peta) {for (tombol string: peta.keyset ()) {list <string> v = ArrayList baru <string> (); String [] type = map.get (key) .split (","); untuk (string type: type) {if (stringutils.isnotblank (type)) {v.add (type); }} Method_type_map.put (key, v); }}}(4) DataSourCeaspect melakukan intersep AOP untuk metode tertentu
/** * Beralih Sumber Data (Metode yang Berbeda Menyelubungi Sumber Data yang Berbeda) */@aspek@komponen@enableaspectjautoproxy (proxyTargetClass = true) kelas publik dataSourceaspect {logger yang dilindungi = loggerFactory.getLogger (this.getClass ()); @Pointcut ("Eksekusi (*com.xuliugen.choosedb.demo.mybatis.dao.*.*(..))") public void aspek () {} / ***Mengkonfigurasi pra-notifications, gunakan titik masuk yang terdaftar pada Metode Aspect ()* / @before ("aspect ()") point point point point ()* / @before ("aspect ()") point point point point ()* / @before ("aspect ()") public point point) point point ()* / @before ("aspect ()") public void point Point () () oPoint () {bubul POINT () {point point () {point () ("") point.getTarget (). getClass (). getName (); Metode String = point.getSignature (). GetName (); logger.info (classname + "." + Metode + "(" + stringutils.join (point.getArgs (), ",") + ")"); Coba {untuk (tombol string: choosedatasource.method_type_map.keyset ()) {for (type string: choosedatasource.method_type_map.get (key)) {if (method.startswith (type)) {dataSourceHandler.putDataSource (key); }}}} catch (Exception e) {E.PrintStackTrace (); }}}(5) DataSourceHandler, kelas penangan dari sumber data
Paket com.xuliugen.choosedb.demo.aspect;/*** Kelas pawang sumber data*/kelas publik DataSourceHandler {// nama sumber data Threadpool statis publik statis threadlocal <string> holder = new threadlocal <string> (); / *** Tambahkan sumber data baca dan tulis yang dikonfigurasi ke pemegang saat proyek dimulai*/ public static void putDataSource (String DataSource) {holder.set (DataSource); } / *** Dapatkan string sumber data dari holer* / string statis public getDataSource () {return holder.get (); }} Kode utama, seperti yang disebutkan di atas.
Kode dalam artikel ini: Demo
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.