1. Prefacio
La estrategia de separación de lectura y escritura de las bases de datos en un entorno distribuido es una solución clave para resolver el cuello de botella del rendimiento de lectura y escritura de la base de datos, y también maximiza la velocidad y la concurrencia de los datos de lectura (lectura) en las aplicaciones.
Al separar la base de datos Leer y escribir, primero debemos configurar el maestro y el esclavo de la base de datos. El más simple es un maestro y un esclavo (para grandes sistemas de sitios web, por supuesto, será muy complicado. Aquí solo analizamos la situación más simple). A través de la configuración del esclavo maestro, la base de datos maestro-esclavo mantiene los mismos datos. Accedemos al esclavo de la base de datos de esclavos cuando realizamos operaciones de lectura y el maestro de la base de datos maestro cuando realizamos operaciones de escritura. Esto reducirá la presión en un servidor.
Al realizar análisis de casos de separación de lectura y escritura. Primero, configure la replicación del esclavo maestro de la base de datos y proporcione una explicación detallada de la instalación y configuración sincrónicas del esclavo maestro de la base de datos MySQL5.6 (maestro/esclavo)
Por supuesto, es solo una forma simple de ver cómo usar el código para lograr la separación de la base de datos Leer y escribir, y no hay necesidad de configurar la base de datos maestro y esclavo. Solo requiere dos máquinas con la misma base de datos instalada.
2. Dos formas de lograr la separación de lectura y escritura
Específicamente en el desarrollo, hay dos formas comunes de lograr la separación de lectura y escritura:
1. El primer método es el método más utilizado, que es definir dos conexiones de bases de datos, una es MasterDataSource y el otro es SlavedataSource. Al actualizar los datos, leemos el MasterDataSource y al consultar los datos, leemos el SlavedataSource. Este método es muy simple, por lo que no entraré en detalles.
2. El segundo método de conmutación de fuente de datos dinámico es tejer dinámicamente la fuente de datos en el programa cuando el programa se está ejecutando, para elegir leer la biblioteca maestra o la biblioteca de esclavos. Las principales tecnologías utilizadas son: anotación, AOP de primavera, reflexión.
El método de implementación se describirá en detalle a continuación.
3. AOP se da cuenta del caso de separación de lectura y escritura de la base de datos maestro-esclavo
1. Dirección del código de proyecto
La dirección del proyecto actual de esta demostración: demostración
2. Estructura del proyecto
En la figura anterior, además del código marcado, los otros son principalmente código de configuración y código de negocio.
3. Análisis específico
Este proyecto es una demostración de SSM Framework, Spring, Spring MVC y MyBatis. Los archivos de configuración específicos no se introducen demasiado.
(1) UserConToller simula datos de lectura y escritura
/*** Creado por Xuliugen el 2016/5/4. */@Controlador@requestmapping (valor = "/user", produce = {"aplicación/json; charset = utf-8"}) clase pública UserController {@Inject Private IUSERService UserService; //http://localhost:8080/user/select.do @ResponseBody @RequestMapping (valor = "/select.do", método = requestmethod.get) public String select () {user User = Userservice.selectUserById (123); return user.ToString (); } //http://localhost:8080/user/add.do @ResponseBody @RequestMapping (valor = "/add.do", método = requestmethod.get) public string add () {boolean isok = userserservice.adduser (nuevo usuario ("333", "444")); return isok == verdadero? "Shibai": "Chenggong"; }}Simule la lectura y la escritura de datos y llame a IUSERService.
(2) Configuración de la fuente de datos de lectura y escritura de lectura y escritura
<? xml versión = "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.springframework.org/schema/speans/spring-beans-4. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <bean id =" statfilter "lazy-init =" true "> <name de propiedad =" logSlowsql "value =" true "//" name = "Merges" Merges " value = "true"/> </bean> <!-Conexión de la base de datos-> <bean id = "readDataSource" destruye-method = "cerrar" init-method = "init" lazyinit = "true"> <Property name = "conductorClassName" value = "$ {controlador}"/> <name de propiedad = "url" valor = "$ {url1}"/> <name de propiedad name = "oval" <propiedad name = "contraseña" valor = "$ {contraseña}"/> <!-omitir algo de contenido-> </bean> <bean id = "writedataSource" destruye-method = "cerrar" init-method = "init" lazy-init = "true"> <Property name = "controlador name = "username" value = "root"/> <propiedad name = "contraseña" value = "$ {contraseña}"/> <!-omitir algo de contenido-> </bean> <!-Configurar las fuentes de lectura y escritura de lectura asignadas dinámicamente value-type = "javax.sql.dataSource"> <!-Write-> <Entry Key = "Write" Value-REF = "WritedataSource"/> <!-Read-> <Entrada Key = "Read-Ref =" ReadDataSource "/> </Map> </propiedad> <nombre de propiedad =" DefaultTargetDataSource "Ref =" Ref = "Ref =" Ref = "" " name = "MethodType"> <map key-type = "java.lang.string"> <!-Read-> <Entrada Key = "Read" Valor = ", Get, Select, Count, List, List, Query"/> <!-Write-> <Entry Key = "Write" Value = ", agregue, cree, actualice, elimine, elimine,"/> </propiedad> </propiedad> </bean> </beans>En la configuración anterior, ReadDataSource y WritedataSource están configurados, pero solo se entrega a SQLSessionFactoryBean para la administración, y el uso de: com.xuliugen.hoosedb.demo.spect.ChoosedAsource Esto se usa para la selección de datos.
<Property name = "MethodType"> <map key-type = "java.lang.string"> <!-read-> <entry key = "read" value = ", get, seleccione, contar, lista, consulta"/> <!-Write-> <Entry Key = "Write" Value = ", Agregar, crear, actualizar, eliminar, eliminar,"/> </map> </propers>
Las palabras clave de prefijo específicas de la base de datos están configuradas. El código específico de ChoosedAtAsource es el siguiente:
(3) ElegirataSource
/*** Obtenga la fuente de datos, se usa para cambiar dinámicamente las fuentes de datos*/public Class ChooseSeedAsource extiende AbstracTroutingDataSource {public static map <string, list <string>> método_type_map = new Hashmap <String, List <String> (); / *** Implemente el método abstracto en la clase principal y obtenga el nombre de la fuente de datos* @return*/ Protected Object DetermineCurrentOplowUpkey () {return dataSourceHandler.getDataSource (); } // Establezca la fuente de datos correspondiente al nombre del método prefijo public void setmethodype (map <string, string> map) {for (string key: map.keySet ()) {list <string> v = new ArrayList <String> (); Cadena [] tipos = map.get (key) .split (","); for (type de cadena: tipos) {if (stringUtils.isnotblank (type)) {V.add (type); }} Método_type_map.put (clave, v); }}}(4) DataSourCeSpect realiza una intersección de AOP para métodos específicos
/** * Switch Data Fuente (diferentes métodos llaman a diferentes fuentes de datos) */@aspecto@componente@enableaspectjaUtoProxy (proxyTargetClass = true) public class dataSourCeAspect {proteged logger = loggerFactory.getLogger (this.getCass ()); @PointCut ("Ejecution (*com.xuliugen.choosedb.demo.mybatis.dao.*.*(..))") public void aspecto () {} / ***Configure las pre-notificaciones, use el punto de entrada registrado en el aspecto del método ()* / @before ("Aspecto ()") Public Void antes (Punto de unión) {String ClassName = Point.getTarget (). getClass (). getName (); Method de cadena = Point.getSignature (). GetName (); logger.info (className + "." + Method + "(" + StringUtils.Join (Point.GetArgs (), ",") + ")"); Pruebe {for (tecla de cadena: choosedataSource.method_type_map.keyset ()) {for (type de cadena: eleccióneAsource.method_type_map.get (key)) {if (método.startswith (type)) {dataSourceHandler.putDataSource (key); }}}} Catch (Exception e) {E.PrintStackTrace (); }}}(5) DataSourceHandler, la clase de controlador de la fuente de datos
paquete com.xuliugen.hoosedb.demo.aspect;/*** clase de controlador de la fuente de datos*/clase public dataSourceHandler {// Nombre de fuente de datos ThreadPoL Public Static Final ThreadLocal <String> Holder = New ThreadLocal <string> (); / *** Agregue las fuentes de datos de lectura y escritura configuradas al titular cuando el proyecto inicia*/ public static void putDataSource (string dataSource) {holder.set (dataSource); } / *** Obtenga la cadena de origen de datos de Holer* / public static String getDataSource () {return Holder.get (); }} El código principal, como se mencionó anteriormente.
Código en este artículo: demostración
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.