1. Предисловие
Стратегия разделения чтения и записи баз данных в распределенной среде является ключевым решением для решения узкого места для чтения и записи базы данных, а также максимизирует скорость и параллелизм данных чтения (чтения) в приложениях.
При разделении чтения и записи базы данных нам сначала необходимо настроить мастер базы данных и рабов. Самый простой - это мастер и раб (для больших систем веб -сайтов, конечно, это будет очень сложно. Здесь мы просто анализируем самую простую ситуацию). Благодаря конфигурации мастер-солевой, база данных мастер-солевой поддерживает те же данные. Мы получаем доступ к подчиненной базе данных при выполнении операций чтения и мастер -мастер базы данных при выполнении операций записи. Это снизит давление на сервер.
При проведении анализа случая разделения чтения и записи. Во-первых, настроить репликацию базы данных в мастер-рав и предоставить подробное объяснение синхронной установки и конфигурации базы данных MySQL5.6 Master-Slave (Master/Slave)
Конечно, это просто простой способ увидеть, как использовать код для достижения разделения чтения и записи базы данных, и нет необходимости настраивать базу данных Master и Slave. Это требует только двух машин с одной и той же установленной базой данных.
2. Два способа достижения чтения и письма разделения
В частности, в разработке, существует два общих способа достижения чтения и разлуки с письмом:
1. Первым методом является наиболее часто используемый метод, который заключается в определении двух соединений базы данных, одним из них является MasterDataSource, а другой - Slavedatasource. При обновлении данных мы читаем MasterDataSource и при запросе данных мы читаем Slavedatasource. Этот метод очень прост, поэтому я не буду вдаваться в подробности.
2. Второй метод динамического переключения источника данных - динамически включить источник данных в программу при запуске программы, чтобы выбрать прочитать главную библиотеку или библиотеку рабов. Основные технологии используются: аннотация, пружина AOP, отражение.
Метод реализации будет подробно описан ниже.
3. AOP реализует случай разлуки чтения и записи базы данных мастер-раба
1. Адрес кода проекта
Текущий адрес проекта этой демонстрации: демонстрация
2. Структура проекта
На приведенном выше рисунке, в дополнение к отмеченному коду, остальные в основном являются кодом конфигурации и бизнес -кодом.
3. Конкретный анализ
Этот проект является демонстрацией платформы SSM, Spring, Spring MVC и Mybatis. Конкретные файлы конфигурации не вводятся слишком много.
(1) UserContoller имитирует данные чтения и написания
/*** Создано Xuliugen на 2016/5/4. */@Controller@requestmapping (value = "/user", производители = {"application/json; charset = utf-8"}) открытый класс usercontroller {@inject private iuserservice userservice; //http://localhost:8080/user/select.do @responsebody @requestmapping (value = "/select.do", method = requestmethod.get) public String select () {user user = userervice.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 (новый пользователь ("333", "444"); вернуть isok == true? «Шибай»: «Ченггонг»; }}Моделируйте чтение и написание данных и вызовите iUserservice.
(2) Настройка Spring-DB.xml Читать и записать
<? xml version = "1.0" Encoding = "UTF-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: aop = "http://www.springframework.org/schema/aop" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.spramework.orgemabema/spers.4.0.s.5.0.spring-xpring-xpring-xpring-4. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <bean id =" statfilter "lazy-init =" true "> name =" logslowsql "=" true "/valy"/"vallter"/"/> <lazy init =" true "> <свойство =" logslowsql "="/"/" valy "=" vallter "/" vallter "/"/"valy"/"value"/"value"/"vallter"/"valy"/"valy"/"valy"/"vallter"/"vAlice"/". value = "true"/> </bean> <!-Соединение базы данных-> <bean id = "readdatasource" drest-method = "close" init-method = "init" lazy-init = "true"> <name = "driverclassname" value = "$ {Driver}"/> name = "url" value = "$ {url1}"/"/"/> <property = "url" value = "$ {url1}"/"/"/""/"/"/"/"/"url" value = "root"/> <name = "password" value = "$ {пароль}"/> <!-Опубликайте какой-то контент-> </bean> <bean id = "writedatasource" drest method = "close" init-method = "init" lazy-init = "true"> <property name = "DriverClassname" value = "$ {river}"/> <prop-ry uR-yeport "vAlty" wAlt "/>" ur-name = "ur-name =" hrapt "vame". Value = "$ {url}"/> <name = "username" value = "root"/> <name = "password" value = "$ {пароль}"/> <!-Опустите какой-то контент-> </bean> <!-Настройка динамически распределенного чтения и записи данных-> <bean id = "dataSource" lazy-init = "true"> <> "ytemys =" ytemys = ">" key-type = "java.lang.string" value-type = "javax.sql.datasource"> <!-write-> <intpirt key = "write" value-ref = "writedatasource"/> <!-Read-> <write-ref = "readdatas name = "defaultTargetDataSource" ref = "writedAtasource"/> <name = "methodType"> <map key-type = "java.lang.string"> <!-read-> <intry key = "value =", get, select, count, list, Query "/> <! </map> </property> </bean> </beans>В вышеупомянутой конфигурации настраиваются ReadDataSource и writedAtasource, но только DataSource передается SQLSessionFactorybean для управления, и использование: com.xuliugen.chosedb.demo.aspect.choasedatasource Это используется для выбора базы базы.
<name = "methodType"> <map key-type = "java.lang.string"> <!-read-> <inpit key = "read" value = ", get, select, count, list, Query"/> <!-write-> <inpit key = "value", ", добавить, создать, обновить, удалить, удалить"/> </map> </map> </map> </map> </map
Ключевые слова, специфичные для базы данных, настроены. Конкретный кодекс выпокрированного атакуса заключается в следующем:
(3) Выполученные
/*** Получить источник данных, используемый для динамического переключения источников данных*/public Class whosedAtasource extraCtroutingDatasource {public Static Map <String, list <string >> method_type_map = new hashmap <string, list <string >> (); / *** Реализовать метод абстрактного в родительском классе и получить имя источника данных* @return*/ Защищенный объект DegineCurrentLookupkey () {return dataSourceHandler.getDatasource (); } // Установите источник данных, соответствующий имени метода Prefix public void setMethodType (map <string, string> map) {for (string key: map.keyset ()) {list <string> v = new ArrayList <string> (); String [] types = map.get (key) .split (","); for (string type: types) {if (stringutils.isnotblank (type)) {v.add (type); }} Method_type_map.put (key, v); }}}(4) DataSourCeaspect выполняет AOP -перехват для конкретных методов
/** * Переключение источника данных (разные методы вызывает различные источники данных) */@asmover@component@enableeSpectjautoproxy (proxyTargetClass = true) открытый класс DataSourceAsepect {Protected logger = loggerFactory.getLogger (this.getClass ()); @Pointcut ("execution (*com.xuliugen.choosedb.demo.mybatis.dao.*.*(..))") public void Aspize () {} / ***Настройте предварительные предварительные документы, используйте точку входа, зарегистрированную в методе ()* / @before ("amess ()") public vublic vublic ved vorefore ved vorefore void void void void void void void (intrpoint). point.getTarget (). getClass (). getName (); String method = point.getSignature (). GetName (); logger.info (classname + "." + method + "(" + stringutils.join (point.getargs (), ",") + ")"); try {for (String key: chocedatasource.method_type_map.keyset ()) {for (строка типа: choedatasource.method_type_map.get (key)) {if (method.startswith (type)) {dataSourcehandler.putDatasource (key); }}}} catch (Exception e) {e.printstacktrace (); }}}(5) DataSourceHandler, класс обработчика источника данных
Package com.xuliugen.choisedb.demo.aspect;/*** Класс обработчика источника данных*/public class dataSourceHandler {// Имя источника данных ThreadPool public static final Threadlocal <string> holder = new Threadlocal <string> (); / *** Добавить настроенные источники данных чтения и записи в держатель, когда проект запускается*/ public void putdataSource (String DataSource) {holder.set (dataSource); } / *** Получить строку источника данных из Holer* / public Static String getDataSource () {return holder.get (); }} Основной код, как упомянуто выше.
Код в этой статье: демонстрация
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.