- 浏览: 342120 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (212)
- spring (21)
- design pattern(java) (12)
- linux-shell (28)
- java-thread (20)
- java-collection (6)
- java-reflect (9)
- mysql (11)
- java-io (7)
- java-util&lang&io (3)
- algorithm (3)
- interview (2)
- tools-eclipse (2)
- tools-maven (1)
- web-script (1)
- java组建 (13)
- 博客收藏 (1)
- 架构设计与实践 (10)
- active-mq (6)
- java-jvm&性能&原理 (27)
- tomcat (2)
- flume (1)
- serialization (2)
- git (1)
- cache&redis (8)
- guava (1)
- zookeeper (3)
- socket&tcp&udp&http (6)
- test (1)
最新评论
-
bbls:
有用有用有用
java-jvm-jstack-(监视器和锁的概念) -
王新春:
小侠有点帅哦 写道此流怎么关闭新春这个实现 可以不关闭的,哈哈 ...
源码剖析之java.io.ByteArrayOutputStream -
小侠有点帅哦:
此流怎么关闭新春
源码剖析之java.io.ByteArrayOutputStream -
cumt168:
写的很好为什么初始化参数,年轻代-Xmn10M def new ...
jvm之内存申请过程分析 -
ronin47:
应该是跟共享域名思路差不多,根据cookie的key作判断
跨域:一种通过服务端解决跨域的实现
互联网的web项目,都有个特点:请求的并发量高,其中请求最耗时的db操作,又是系统优化的重中之重。
为此,往往搭建 db的 一主多从库的 数据库架构。作为web的DAO层,要保证针对主库进行写操作,对多个从库进行读操作。当然在一些请求中,为了避免主从复制的延迟导致的数据不一致性,部分的读操作也要到主库上。(这种需求一般通过业务垂直分开,比如下单业务的代码所部署的机器,读去应该也要从主库读取数据,这块需要定制化)
结合自己在实际项目中的使用的,我分享下一个简单的DAO进行一主多从库的读(取模型负载均衡)写操作的案例:
1、实际项目中的db架构(当然这块的配置交给dba即可)
master库:
server1:common库 以及多个customer库
server2:多个customer库
slave库:
server1机器上的库对于的从库在server3,server4,server5
server2机器上的库对于的从库在server6,server7,server8
2、关于数据库连接和数据源(Connection和DataSource)
Connection :是和服务器上的一个mysql实例的连接,可以指定库,也可以不指定。 如果不指定库,那么在db操作之前,需要先 执行:use dbname; 或者在在表的名字之前加上dbName.dbTable。
DataSource:是一个数据源,允许其实现进行数据库连接的管理和复用,考虑db连接的建立是一个相当耗时的过程,数据源能提升非常大的性能。
确定一个数据源只需要:ip+port,务必清楚这一点。
3、dao的分析和设计。
功能要求:支持一主多从,灵活配置,支持多种数据源提供商
实现思路:根据dbname->ip+port->DataSource->Connection
其中:
主库:dbname->ip+port
从库为:dbname->List<ip+port>,然后负载均衡选择其中一个ip+port
数据源配置的代码:
4、数据源初始化的代码。
数据初始化的一个具体实现:
5、spring 关于数据的配置。
6、数据源的使用。
通过数据源获取数据库连接
你说的这个是多数据源,而不是主从库。
为此,往往搭建 db的 一主多从库的 数据库架构。作为web的DAO层,要保证针对主库进行写操作,对多个从库进行读操作。当然在一些请求中,为了避免主从复制的延迟导致的数据不一致性,部分的读操作也要到主库上。(这种需求一般通过业务垂直分开,比如下单业务的代码所部署的机器,读去应该也要从主库读取数据,这块需要定制化)
结合自己在实际项目中的使用的,我分享下一个简单的DAO进行一主多从库的读(取模型负载均衡)写操作的案例:
1、实际项目中的db架构(当然这块的配置交给dba即可)
master库:
server1:common库 以及多个customer库
server2:多个customer库
slave库:
server1机器上的库对于的从库在server3,server4,server5
server2机器上的库对于的从库在server6,server7,server8
2、关于数据库连接和数据源(Connection和DataSource)
Connection :是和服务器上的一个mysql实例的连接,可以指定库,也可以不指定。 如果不指定库,那么在db操作之前,需要先 执行:use dbname; 或者在在表的名字之前加上dbName.dbTable。
DataSource:是一个数据源,允许其实现进行数据库连接的管理和复用,考虑db连接的建立是一个相当耗时的过程,数据源能提升非常大的性能。
确定一个数据源只需要:ip+port,务必清楚这一点。
3、dao的分析和设计。
功能要求:支持一主多从,灵活配置,支持多种数据源提供商
实现思路:根据dbname->ip+port->DataSource->Connection
其中:
主库:dbname->ip+port
从库为:dbname->List<ip+port>,然后负载均衡选择其中一个ip+port
数据源配置的代码:
package com.job.db.dataservice.datasource; import java.util.List; import javax.sql.DataSource; /** * 一主多从的配置包装类 * @author wangxinchun1988@163.com */ public class MasterSlaveDataSourceMapping { private List<MasterSlaveDataSourceMappingItem> list; public List<MasterSlaveDataSourceMappingItem> getList() { return list; } public void setList(List<MasterSlaveDataSourceMappingItem> list) { this.list = list; } /** 主从库配置项 */ public static class MasterSlaveDataSourceMappingItem{ /** 主库数据源*/ private DataSource master; /** 从库数据源列表*/ private List<DataSource> slaveList; public DataSource getMaster() { return master; } public void setMaster(DataSource master) { this.master = master; } public List<DataSource> getSlaveList() { return slaveList; } public void setSlaveList(List<DataSource> slaveList) { this.slaveList = slaveList; } } }
4、数据源初始化的代码。
package com.job.db.dataservice.datasource; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.job.db.dataservice.datasource.MasterSlaveDataSourceMapping.MasterSlaveDataSourceMappingItem; /** * 数据源上下文 * @author wangxinchun1988@163.com * @date 2014-7-14下午5:02:14 */ public abstract class DataSourceContext { private static final Logger logger = LoggerFactory.getLogger(DataSourceContext.class); /** * 主库数据源 (ip+port->IDataSourceProvider)*/ protected static final Map<String, IDataSourceProvider> masterMap = new HashMap<String, IDataSourceProvider>(); /** 主库数据库名称到ip+port的映射 (dbNmae->ip+port)*/ protected static final Map<String,String> masterDb2IpPortMapping = new HashMap<String,String>(); /** 从库数据源 (ip+port->IDataSourceProvider)*/ protected static final Map<String, IDataSourceProvider> slaveMap = new HashMap<String, IDataSourceProvider>(); /** 从库数据库名称到ip+port的映射*/ protected static final Map<String,List<String>> slaveDb2IpPortListMapping = new HashMap<String,List<String>>(); /** 主从数据源列表配置*/ private MasterSlaveDataSourceMapping masterSlaveDataSourceMapping; /** * 初始化资源 */ public void init(){ logger.info("DataSourceContext init begin"); List<MasterSlaveDataSourceMappingItem> masterSlaveList = masterSlaveDataSourceMapping.getList(); for(MasterSlaveDataSourceMappingItem item : masterSlaveList){ DataSource masterConfigList = item.getMaster(); masterInit(masterConfigList); List<DataSource> slaveConfigList = item.getSlaveList(); slaveInit(slaveConfigList); } logger.info("DataSourceContext init end"); } /** 初始化主库资源*/ private final void masterInit(DataSource dataSource) { doMasterInit(dataSource); } /** 初始化从库资源*/ private final void slaveInit(List<DataSource> dataSourceList) { for(DataSource dataSource : dataSourceList){ doSlaveInit(dataSource); } } protected abstract void doMasterInit(DataSource dataSource); protected abstract void doSlaveInit(DataSource dataSource); /** * 关闭资源 */ public void shutDown() { logger.info("DataSourceContext shutDown begin "); for (IDataSourceProvider provider : masterMap.values()) { provider.shutdown(); } Collection<IDataSourceProvider> listCollection = slaveMap.values(); for (IDataSourceProvider provider: listCollection) { provider.shutdown(); } logger.info("DataSourceContext shutDown end "); } /** 根据dbname获取主库数据源*/ public static IDataSourceProvider getMasterDataSourceProvider(String dbName){ String ipPortKey = masterDb2IpPortMapping.get(dbName); if(ipPortKey == null){ return null; } else { return masterMap.get(ipPortKey); } } /** 根据数据库的名字获取多个从库数据源列表*/ public static List<IDataSourceProvider> getSlaveDataSourceProvider(String dbName){ List<String> ipPortKeyList = slaveDb2IpPortListMapping.get(dbName); if(ipPortKeyList == null){ return null; } else { List<IDataSourceProvider> retList = new ArrayList<IDataSourceProvider>(); for(String item : ipPortKeyList){ IDataSourceProvider provider = slaveMap.get(item); retList.add(provider); } return retList; } } public void setMasterSlaveDataSourceMapping( MasterSlaveDataSourceMapping masterSlaveDataSourceMapping) { this.masterSlaveDataSourceMapping = masterSlaveDataSourceMapping; } }
数据初始化的一个具体实现:
package com.job.db.dataservice.datasource.impl; import java.util.ArrayList; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.lang.StringUtils; import com.job.db.dataservice.datasource.DataSourceContext; /** * 简单实现(TODO BasicDataSource 很粗糙的哈) * @author wangxinchun */ public class DefaultDataSourceContext extends DataSourceContext { protected void doMasterInit(DataSource dataSource) { URLInfo urlInfo = getDataSourceURLInfo(dataSource); String key = urlInfo.getDataSourceKey(); if(StringUtils.isNotEmpty(urlInfo.getDb())){ masterDb2IpPortMapping.put(urlInfo.getDb(), key); } if(masterMap.get(key) != null){ return; } masterMap.put(key, new DefaultDatasourceProvider(dataSource)); } protected void doSlaveInit(DataSource dataSource) { URLInfo urlInfo = getDataSourceURLInfo(dataSource); String key = urlInfo.getDataSourceKey(); if(StringUtils.isNotEmpty(urlInfo.getDb())) { if(slaveDb2IpPortListMapping.get(urlInfo.getDb()) == null){ slaveDb2IpPortListMapping.put(urlInfo.getDb(), new ArrayList<String>()); } slaveDb2IpPortListMapping.get(urlInfo.getDb()).add(key); } if(slaveMap.get(key) != null){ return; } slaveMap.put(key, new DefaultDatasourceProvider(dataSource)); } private URLInfo getDataSourceURLInfo(DataSource dataSource) { URLInfo urlInfo = new URLInfo(); if (dataSource instanceof BasicDataSource) { // jdbc:mysql://192.168.229.37:3309/tts?useUnicode=true&characterEncoding=utf8 BasicDataSource basicDataSource = (BasicDataSource) dataSource; String url = basicDataSource.getUrl(); String temp = url.substring(url.indexOf("//")+2); if(temp.indexOf("?") >0 ){ temp = temp.substring(0,temp.indexOf("?")); } String[] tempArr = temp.split(":|/"); urlInfo.setIp(tempArr[0]); urlInfo.setPort(tempArr[1]); urlInfo.setDb(tempArr[2]); } return urlInfo; } private class URLInfo{ private String ip; private String port; private String db; public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public String getPort() { return port; } public void setPort(String port) { this.port = port; } public String getDb() { return db; } public void setDb(String db) { this.db = db; } public String getDataSourceKey(){ return ip+":"+port; } } } package com.job.db.dataservice.datasource.impl; import javax.sql.DataSource; import org.apache.log4j.Logger; import com.job.db.dataservice.datasource.IDataSourceProvider; /** * Proxool 连接池包装类 * @author wangxinchun1988@163.com * @date 2014-7-15下午2:14:08 */ public class DefaultDatasourceProvider implements IDataSourceProvider { private static Logger log = Logger.getLogger(DefaultDatasourceProvider.class); private DataSource dataSource; public DefaultDatasourceProvider( DataSource dataSource){ this.dataSource = dataSource; } public DataSource getDataSource() { return dataSource; } public void shutdown() { log.info("shutdown"); } }
5、spring 关于数据的配置。
<bean id="parentDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" abstract="true"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="timeBetweenEvictionRunsMillis" value="60000"/> <!-- 每隔毫秒秒检查一次连接池中空闲的连接 --> <property name="minEvictableIdleTimeMillis" value="600000" /> <!-- 连接池中连接可空闲的时间,毫秒 --> <property name="removeAbandoned" value="true" /> <!-- 是否清理removeAbandonedTimeout秒没有使用的活动连接,清理后并没有放回连接池 --> <property name="removeAbandonedTimeout" value="60" /> <!-- 活动连接的最大空闲时间 --> <property name="minIdle" value="10" /> <!-- 最小空闲连接数 --> <property name="maxWait" value="60000" /> <!-- 最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间 --> </bean> <!-- ******************* ******************* 公共库 (主从配置) ******************* ******************* --> <bean id="commonMaster" parent="parentDataSource"> <property name="url" value="${jdbc.commonMaster.url}" /> <property name="username" value="${jdbc.commonMaster.username}" /> <property name="password" value="${jdbc.commonMaster.password}" /> </bean> <bean id="commonSlaveA" parent="parentDataSource"> <property name="url" value="${jdbc.commonSlaveA.url}" /> <property name="username" value="${jdbc.commonSlaveA.username}" /> <property name="password" value="${jdbc.commonSlaveA.password}" /> </bean> <bean id="commonSlaveB" parent="parentDataSource"> <property name="url" value="${jdbc.commonSlaveB.url}" /> <property name="username" value="${jdbc.commonSlaveB.username}" /> <property name="password" value="${jdbc.commonSlaveB.password}" /> </bean> <bean id="commonMasterSlaveMapping" class="com.job.db.dataservice.datasource.MasterSlaveDataSourceMapping.MasterSlaveDataSourceMappingItem"> <property name="master"> <ref bean="commonMaster"/> </property> <property name="slaveList"> <list> <ref bean="commonSlaveA"/> <ref bean="commonSlaveB"/> </list> </property> </bean> <!-- *************************************** 代理商库 A 组*************************************** --> <bean id="customerMasterA" parent="parentDataSource"> <property name="url" value="${jdbc.customerMasterA.url}" /> <property name="username" value="${jdbc.customerMasterA.username}" /> <property name="password" value="${jdbc.customerMasterA.password}" /> </bean> <bean id="customerSlaveAA" parent="parentDataSource"> <property name="url" value="${jdbc.customerSlaveAA.url}" /> <property name="username" value="${jdbc.customerSlaveAA.username}" /> <property name="password" value="${jdbc.customerSlaveAA.password}" /> </bean> <bean id="customerSlaveAB" parent="parentDataSource"> <property name="url" value="${jdbc.customerSlaveAB.url}" /> <property name="username" value="${jdbc.customerSlaveAB.username}" /> <property name="password" value="${jdbc.customerSlaveAB.password}" /> </bean> <bean id="customerMasterSlaveMappingA" class="com.job.db.dataservice.datasource.MasterSlaveDataSourceMapping.MasterSlaveDataSourceMappingItem"> <property name="master"> <ref bean="customerMasterA"/> </property> <property name="slaveList"> <list> <ref bean="customerSlaveAA"/> <ref bean="customerSlaveAB"/> </list> </property> </bean> <!-- ***************************************代理商库 B组 *************************************** --> <bean id="customerMasterB" parent="parentDataSource"> <property name="url" value="${jdbc.customerMasterB.url}" /> <property name="username" value="${jdbc.customerMasterB.username}" /> <property name="password" value="${jdbc.customerMasterB.password}" /> </bean> <bean id="customerSlaveBA" parent="parentDataSource"> <property name="url" value="${jdbc.customerSlaveBA.url}" /> <property name="username" value="${jdbc.customerSlaveBA.username}" /> <property name="password" value="${jdbc.customerSlaveBA.password}" /> </bean> <bean id="customerSlaveBB" parent="parentDataSource"> <property name="url" value="${jdbc.customerSlaveBB.url}" /> <property name="username" value="${jdbc.customerSlaveBB.username}" /> <property name="password" value="${jdbc.customerSlaveBB.password}" /> </bean> <bean id="customerMasterSlaveMappingB" class="com.job.db.dataservice.datasource.MasterSlaveDataSourceMapping.MasterSlaveDataSourceMappingItem"> <property name="master"> <ref bean="customerMasterB"/> </property> <property name="slaveList"> <list> <ref bean="customerSlaveBA"/> <ref bean="customerSlaveBB"/> </list> </property> </bean> <!-- **************************************主从关系总配置***************************************** --> <bean id="masterSlaveDataSourceMapping" class=" com.job.db.dataservice.datasource.MasterSlaveDataSourceMapping"> <property name="list"> <list> <ref bean="commonMasterSlaveMapping"/> <ref bean="customerMasterSlaveMappingA"/> <ref bean="customerMasterSlaveMappingB"/> </list> </property> </bean> <bean id="dataSourceContext" class="com.job.db.dataservice.datasource.impl.DefaultDataSourceContext" init-method="init" destroy-method="shutDown"> <property name="masterSlaveDataSourceMapping" ref="masterSlaveDataSourceMapping"/> </bean>
6、数据源的使用。
package com.job.db.dataservice.connection; import java.sql.Connection; /** * 提供Connection连接 * @author wangxinchun */ public interface ConnectionGetter { /** * 根据dbName获取数据库连接 * @param dbName 数据库的名字 */ public Connection getConnection(String dbName); }
通过数据源获取数据库连接
package com.job.db.dataservice.connection.impl; import java.sql.Connection; import java.sql.SQLException; import java.util.List; import com.job.db.dao.AppDBContext; import com.job.db.dataservice.connection.ConnectionGetter; import com.job.db.dataservice.datasource.DataSourceContext; import com.job.db.dataservice.datasource.IDataSourceProvider; import com.job.db.dataservice.exception.DaoException; /** * 提供根据dbName 获取读或写连接 * @author wangxinchun1988@163.com * @date 2014-7-15下午2:26:27 */ public abstract class AbstractConnectionGetter implements ConnectionGetter { private static Integer concount =Integer.MIN_VALUE; public Connection getDefaultConnection(String dbName, boolean isWrite) throws SQLException { if (dbName == null) { throw new DaoException("get connection error cause dbName id null"); } Integer id = AppDBContext.getLastReadWriteFlag(); // 写操作直接获得connection ,如果上一次操作是写连接,那么优先返回写连接 if ( isWrite || (id != null && id < 0)) { AppDBContext.setLastReadWriteFlag(-1); IDataSourceProvider provider = DataSourceContext.getMasterDataSourceProvider(dbName); if (provider == null) { throw new DaoException("no write database dbName is " + dbName); } return provider.getDataSource().getConnection(); } else { // 读操作取模做balance 负载均衡 List<IDataSourceProvider> providers = DataSourceContext.getSlaveDataSourceProvider(dbName); if (providers == null || providers.size() == 0) { throw new DaoException("no slave database for clientId " + dbName); } int psize = providers.size(); if (id == null) { id = Math.abs(concount++ % psize); AppDBContext.setLastReadWriteFlag(id); } IDataSourceProvider sdp = providers.get(id % psize); return sdp.getDataSource().getConnection(); } } }
- master-slave-commondao-trunk.rar (1.7 MB)
- 下载次数: 24
评论
2 楼
王新春
2014-10-16
james_lover 写道
如果只是主从库的话,
我想:Spring: AbstractRoutingDataSource
这个能解决问题。
我想:Spring: AbstractRoutingDataSource
这个能解决问题。
你说的这个是多数据源,而不是主从库。
1 楼
james_lover
2014-07-19
如果只是主从库的话,
我想:Spring: AbstractRoutingDataSource
这个能解决问题。
我想:Spring: AbstractRoutingDataSource
这个能解决问题。
发表评论
-
mvc-HandlerMapping
2017-06-03 23:13 841HandlerMapping:定义了web请求映射和处 ... -
spring-transaction-basic
2016-12-26 19:18 409Spring的事务本身是基于AOP的 AOP代理自 ... -
spring-transaction-propagation
2016-11-25 21:00 852Spring 事务:是spring 通过 aop实现的一套 ... -
spring bean & id
2016-11-25 17:57 459首先澄清一个概念: 同名bean:多个bean ... -
spring 父子容器
2016-11-25 17:11 3650特殊说明: ContextLoaderListe ... -
spring-mvc-基础
2016-09-26 15:03 390核心入口功能定位: HttpServletBean:完成的是& ... -
spring-mvc 学习资料
2016-09-20 15:42 358http://docs.spring.io/spring-fr ... -
spring-aop-DefaultAdvisorAutoProxyCreator
2016-08-16 19:50 469ProxyFactory:手工编程实现AOP,编程式 添加ad ... -
spring-aop基本概念
2016-07-26 16:37 826AOP词汇: Joinpoint:在程序执行过程中某个特定的 ... -
spring-扩展点-BeanFactoryPostProcessor
2016-06-15 18:15 6010BeanFactoryPostProcessor:允许自定 ... -
spring-扩展点-BeanPostProcessor
2016-06-14 15:02 1559理解spring中一个bean的初始化过程非常重要,很多基础功 ... -
spring-扩展点-namespacehandler(Spring自定义标签)
2016-05-27 11:31 2213在很多情况下,我们需要为系统提供可配置化支持,简单的做法可以直 ... -
spring 资源文件
2015-04-03 00:07 148【转载】 非原创 SpringMVC访问静态资源的三种方式 ... -
spring-jdbc-RoutingDataSource
2014-07-11 17:33 5465spring jdbc 提供了抽象类AbstractRouti ... -
spring-aop-ProxyFactoryBean 源码分析
2014-06-13 19:10 2033在阅读本篇之前,请先阅读http://wangxinchun. ... -
spring-aop-ProxyFactory 源码分析
2014-06-13 02:22 4778spring 提供的编程式aop实现,即通过 ProxyFac ... -
spring-aop-aspectj(Schema)-case
2014-05-31 15:50 1090基于Schema 配置切面: 1、切点定义的语言依然是Aspe ... -
spring-aop-aspectj-case
2014-05-31 14:51 1371AOP概念:面向切面编程。 spring 集成AOP: 1、 ... -
spring-rpc-case
2014-05-17 23:34 1096spring 提供了基本的基于http协议的rpc,同时提供了 ... -
spring-mvc-case
2014-05-10 23:50 1195spring mvc 是当前java比较流行的一种mvc架构, ...
相关推荐
标题中的"Modbus-Master-Slave-for-Arduino-master.zip_Master/Slave_arduino"指出这是一个关于Arduino平台的Modbus主从通信库。Modbus是一种广泛使用的工业通信协议,允许不同设备之间交换数据,尤其在自动化系统中...
《FreeModbus_Slave-Master-RTT-STM32-master_stm32mastermodbus_stm32:深入理解MODBUS通信在STM32中的应用》 MODBUS通信协议,作为工业自动化领域的标准通信协议,因其简单、开放、易实现的特点,在嵌入式系统...
在`sharding-master-slave`项目中,我们将看到如何将`Sharding-JDBC`与`SpringBoot`相结合,以实现数据的高效管理和访问。 1. **分库分表策略** `Sharding-JDBC`支持自定义分片策略,这在`描述`中提到。通常,分片...
在本项目“tvip-axi-master_Master/Slave_axivip_tvip_vip_AMBA”中,我们主要探讨的是与AXI协议相关的VIP(Verification Intellectual Property)组件,包括Master和Slave端。 VIP是验证IP的核心组件,用于在系统...
在分布式系统中,为了确保数据的高可用性和容错性,MongoDB提供了两种复制模式:master-slave(主从模式)和master-master(主主模式)。本实验将深入探讨这两种模式的工作原理、设置方法以及它们在实际应用中的优...
《FreeModbus库在RTU模式下的应用及STM32F407移植实践》 在工业自动化领域,Modbus协议因其简单易用和广泛支持而被广泛应用。FreeModbus库是一个开源的Modbus协议实现,它为开发者提供了在各种嵌入式系统上实现...
采用modbusslave进行测试,并行设置多种功能类型 F01:线圈 F02:输入状态 F03:保持寄存器 F04:输入寄存器 项目采用springboot2.4.6+mybatis-plus3.4.3+jlibmodbus+websocket实现Modbus中的数据监控
《FreeModbus_Slave-Master-RTT-STM32-master:STM32上的Modbus主从通信实现详解》 在嵌入式系统开发中,Modbus协议因其简单、可靠而广泛应用于工业自动化领域。本项目“FreeModbus_Slave-Master-RTT-STM32-master...
在本项目"Lung-Nodule-Detection-master_ofdm_slave554_"中,主要涉及的是肺结节检测技术,尤其结合了OFDM(正交频分复用)技术的一个子项目"slave554"。OFDM是一种广泛应用于无线通信领域的多载波调制技术,而在这...
标题中的“Raspberry-Pi-SPI-slave-master.7z”指示了这是一个关于树莓派(Raspberry Pi)的项目,特别关注SPI(Serial Peripheral Interface)通信协议,它包含了一个从机(slave)和主机(master)的角色设置。...
FreeModbus是一款开源的Modbus协议栈,但是只有从机开源,主机源码是需要收费的。同时网上也没有发现比较好的开源的Modbus主机协议栈,所以才开发这款支持主机模式的FreeModbus协议栈。本版FreeModbus版本号更改为V...
Sharding-JDBC教程:Spring Boot2.0以上整合Sharding-JDBC实现分库分表+读写分离,Mysql数据库主从搭建:https://blog.csdn.net/forezp/article/details/94173427
总的来说,FreeModbus--RTU--Master+Slave--uCOSIII--STM32F407这个软件包提供了一套完整的解决方案,涵盖了从协议栈到硬件平台的集成,对于基于STM32F407和uC/OSIII的嵌入式系统开发者来说,是一个宝贵的资源。
此资源为shardingsphere 调研...内容:一个master mysql docker实例,一个slave docker实例 内置3个库,mydb,mydb0,mydb1。仅开启了这三个库的主从。如果三个库主从不够用,自行配置。 使用:1.解压 2.执行build.sh
本篇文章将深入探讨如何在Arduino平台上实现Modbus主从通信,基于"Modbus-Master-Slave-for-Arduino-master"库,帮助开发者更好地理解和应用这一强大的工具。 一、Modbus协议简介 Modbus是一种公开的通信协议,由...
总结来说,"FreeModbus--RTU--Master+Slave--uCOSIII--STM32F407"项目展示了如何将开源的FreeModbus库与嵌入式实时操作系统uC/OSIII以及STM32F407微控制器相结合,实现MODBUS RTU通信功能。这个方案不仅为开发者提供...
Hadoop-2.2.0版本,虚拟机下建的三个centos系统:master,slave1,slave2.里边的配置文件都已经配好,只需要简单改下id,即可使用。不需要在进行解析。
在给定的压缩包"FreeModbus_Slave-Master-RTT-STM32.zip"中,包含的代码是针对STM32微控制器的,利用Real-Time-Thread (RTT)技术,这是一种轻量级实时操作系统,适合资源有限的嵌入式系统。 FreeModbus库分为两个...
MySQL的主主复制(Master-Master Replication)是一种高可用性解决方案,它允许两个或多个数据库服务器互相复制数据,形成一个集群。在这种模式下,每个节点既是主节点,也是从节点,可以接受读写操作。当一个节点...