Spring+Mybatis+Mysql搭建分布式数据库访问框架

一、前言

用Java开发企业应用软件, 经常会采用Spring+MyBatis+Mysql搭建数据库框架。如果数据量很大,一个MYSQL库存储数据访问效率很低,往往会采用分库存储管理的方式。本文讲述如何通过Spring+Mybatis构建多数据库访问的架构,并采用多线程提升数据库的访问效率。

需要说明一下,这种方式只适合数据库数量、名称固定,且不是特别多的情况。针对数据库数量不固定的情况,后面再写一篇处理方案。

二、整体方案

这里写图片描述

三、开发环境准备

3.1 下载Spring、Mybatis、Mysql组件。

3.2 Eclipse:Java开发IDE。引入如下jar包:

这里写图片描述

代码结构如下:

这里写图片描述

四、构建数据库集群

在MYSQL中创建11个数据库(test1/2/3/4/5/6/7/8/9/10/11)创建一个简单的表:

这里写图片描述

在test1的tbl_Demo表中插入5千万条数据,其它10个数据库的tbl_Demo表中分别插入5百万条数据(用函数)。

在test1的tbl_Demo表中插入5千万条数据,其它10个数据库的tbl_Demo表中分别插入5百万条数据(用函数)。

五、创建Mybatis数据库映射接口

/**
 * Mybatis 映射接口
 * 
 *
 * @author elon
 * @version 1.0, 2015年10月23日
 */
public interface IDemo 
{   
    public void insertDemo(DemoDAO demo);
    public List<Integer> selectGroup();
}

/**
 * 
 * Mybatis 映射服务接口
 *
 * @author elon
 * @version 1.0, 2015年10月23日
 */
public interface IDemoService
{   
    public void insertDemo(DemoDAO demo);
    public List<Integer> selectGroup();
}

/**
 * 
 * Mybatis 映射服务实现
 *
 * @author elon
 * @version 1.0, 2015年10月23日
 */
public class DemoServiceImpl implements IDemoService
{
    private IDemo idemo = null;

    public void setIdemo(IDemo idemo) {
        this.idemo = idemo;
    }

    @Override
    public void insertDemo(DemoDAO demo)
    {
        idemo.insertDemo(demo);
    }

    @Override
    public List<Integer> selectGroup()
    {   
        return idemo.selectGroup();
    }
}

六、创建数据库标识管理和动态数据源

/**
 * 
 * 保存数据库标识。每个线程由独立的对象存储
 *
 * @author elon
 * @version 1.0, 2015年10月23日
 */
public class DBIndetifier
{   
    private static ThreadLocal<String> dbKey = new ThreadLocal<String>();

    public static void setDBKey(final String dbKeyPara)
    {   
        dbKey.set(dbKeyPara);
    }

    public static String getDBKey()
    {
        return dbKey.get();
    }
}

/**
 * 
 * 动态数据源。可根据不同的数据索引连接不同的数据库
 *
 * @author elon
 * @version 1.0, 2015年10月23日
 */
public class DynamicDataSource extends AbstractRoutingDataSource
{
    @Override
    public Object determineCurrentLookupKey()
    {
        return DBIndetifier.getDBKey();
    }
}

七、创建数据库访问对象

/**
 * 
 * 数据库访问对象。用于插入数据。
 *
 * @author elon
 * @version 1.0, 2015年10月23日
 */
public class DemoDAO
{
    private int a;
    private String b;
    private int c;

    public int getA()
    {
        return a;
    }
    public void setA(int a)
    {
        this.a = a;
    }
    public String getB()
    {
        return b;
    }
    public void setB(String b)
    {
        this.b = b;
    }
    public int getC()
    {
        return c;
    }
    public void setC(int c)
    {
        this.c = c;
    }
}

/**
 * 
 * 映射结果定义
 *
 * @author elon
 * @version 1.0, 2015年10月23日
 */
public class DemoResult implements Serializable
{
    /**
     * Comment for <code>serialVersionUID</code><br>
     * 
     */
    private static final long serialVersionUID = -413001138792531448L;
    private long sum;

    public long getSum()
    {
        return sum;
    }

    public void setSum(long sum)
    {
        this.sum = sum;
    }

    @Override
    public String toString()
    {
        return String.valueOf(sum);
    }
}

八、创建数据库访问任务

/**
 * 数据库访问任务定义。将每一个对数据库访问的请求包装为一个任务对象,放到任务管理中,
 * 然后等待任务执行完成,取出执行结果。
 *
 * @author elon
 * @version 1.0, 2015年10月23日
 */
public class DBTask implements Runnable
{   
    // 操作数据库标识,用于指定访问的数据库。与spring配置文件中的数据动态数据源定义一致。
    private final String dbKey;

    // mybatis数据库访问对象
    private final Object dbAccessObject;

    // mysbatis数据库访问方法名称,用于反射调用
    private final String methodName;

    // 存储可变参数的值
    private final Object[] paraArray;

    // 存储可变参数类型
    @SuppressWarnings("rawtypes")
    private final Class[] paraClassArray;

    // 数据库操作结果。查询操作返回查询结果; 插入、删除、修改操作返回null。
    private Object operateResult;

    // 操作数据库抛出的异常信息
    private Exception exception;

    // 标识任务是否已经执行
    private boolean finish;

    /**
     * 构造函数
     * @param dbKey 数据库标识
     * @param dbAccessObject 数据库访问对象
     * @param methodName 数据库访问方法名称
     * @param paraArray 参数列表
     */
    public DBTask(final String dbKey, final Object dbAccessObject, final String methodName, 
                  final Object... paraArray)
    {
        this.dbKey = dbKey;
        this.dbAccessObject = dbAccessObject;
        this.methodName = methodName;
        this.paraArray = paraArray;
        finish = false;
        exception = null;

        paraClassArray = new Class[paraArray.length];
        for (int index = 0; index < paraArray.length; ++index)
        {
            paraClassArray[index] = paraArray[index].getClass();
        }

        operateResult = null;
    }

    /**
     * 
     * 任务执行函数
     *
     */
    @Override
    public void run()
    {
        try
        {   
            DBIndetifier.setDBKey(dbKey);
            Method method = dbAccessObject.getClass().getMethod(methodName, paraClassArray);

            // 查询操作返回查询结果; 插入、删除、修改操作返回null
            operateResult = method.invoke(dbAccessObject, paraArray);
        }
        catch (Exception e)
        {
            exception = e;
            e.printStackTrace();
        }

        finish = true;
    }

    /**
     * 
     * 返回操作结果。查询操作返回查询结果; 插入、删除、修改操作返回null
     *
     * @return 操作结果
     */
    public Object getRetValue()
    {
        return operateResult;
    }

    /**
     * 抛出数据库操作异常
     * 
     * @return 异常
     */
    public Exception getException()
    {
        return exception;
    }

    /**
     * 
     * 返回任务是否已执行
     *
     * @return 标记
     */
    public boolean isFinish()
    {
        return finish;
    }
}

九、创建数据库任务管理器

/**
 * 数据库访问任务管理。将数据库访问任务放到线程池中执行。
 * 
 *
 * @author elon
 * @version 1.0, 2015年10月23日
 */
public class DBTaskMgr
{
    private static class DBTaskMgrInstance
    {
        public static final DBTaskMgr instance = new DBTaskMgr();
    }

    public static DBTaskMgr instance()
    {
        return DBTaskMgrInstance.instance;
    }

    private ThreadPoolExecutor pool;

    public DBTaskMgr()
    {
        pool = new ThreadPoolExecutor(10, 50, 60, TimeUnit.SECONDS,                                            
                                      new ArrayBlockingQueue<Runnable>(10000),
                                      new ThreadPoolExecutor.CallerRunsPolicy());
    }

    public void excute(Runnable task)
    {
        pool.execute(task);
    }
}

十、创建MyBatis配置文件

10.1 mybatis.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <mappers>
        <mapper resource="cfg/demoMapper.xml"/>
    </mappers>
</configuration>

10.2 demoMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="com.elon.IDemo">    
    <insert id="insertDemo" parameterType="com.elon.DemoDAO">
        insert into tbl_demo(a, b, c) values(#{a}, #{b}, #{c});
    </insert>

    <resultMap id="demoResult" type="com.elon.DemoResult">
        <id property="sum" column="sumColum"/>
    </resultMap>

    <select id="selectGroup" resultMap="demoResult">
        select sum(a) as sumColum from tbl_demo group by c;
    </select>
</mapper>

十一、创建Spring配置文件

11.1 spring.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="dataSource_1" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://10.70.69.69:3306/test1"></property>
        <property name="username" value="user123"></property>
        <property name="password" value="user123"></property>
        <property name="maxActive" value="100"></property>
        <property name="maxIdle" value="30"></property>
        <property name="maxWait" value="500"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>

    <bean id="dataSource_2" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://10.70.69.69:3306/test2"></property>
        <property name="username" value="user123"></property>
        <property name="password" value="user123"></property>
        <property name="maxActive" value="100"></property>
        <property name="maxIdle" value="30"></property>
        <property name="maxWait" value="500"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>

    <bean id="dataSource_3" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://10.70.69.69:3306/test3"></property>
        <property name="username" value="user123"></property>
        <property name="password" value="user123"></property>
        <property name="maxActive" value="100"></property>
        <property name="maxIdle" value="30"></property>
        <property name="maxWait" value="500"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>

    <bean id="dataSource_4" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://10.70.69.69:3306/test4"></property>
        <property name="username" value="user123"></property>
        <property name="password" value="user123"></property>
        <property name="maxActive" value="100"></property>
        <property name="maxIdle" value="30"></property>
        <property name="maxWait" value="500"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>

    <bean id="dataSource_5" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://10.70.69.69:3306/test5"></property>
        <property name="username" value="user123"></property>
        <property name="password" value="user123"></property>
        <property name="maxActive" value="100"></property>
        <property name="maxIdle" value="30"></property>
        <property name="maxWait" value="500"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>

    <bean id="dataSource_6" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://10.70.69.69:3306/test6"></property>
        <property name="username" value="user123"></property>
        <property name="password" value="user123"></property>
        <property name="maxActive" value="100"></property>
        <property name="maxIdle" value="30"></property>
        <property name="maxWait" value="500"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>


    <bean id="dataSource_7" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://10.61.67.246:3306/test7"></property>
        <property name="username" value="user123"></property>
        <property name="password" value="user123"></property>
        <property name="maxActive" value="100"></property>
        <property name="maxIdle" value="30"></property>
        <property name="maxWait" value="500"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>

    <bean id="dataSource_8" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://10.61.67.246:3306/test8"></property>
        <property name="username" value="user123"></property>
        <property name="password" value="user123"></property>
        <property name="maxActive" value="100"></property>
        <property name="maxIdle" value="30"></property>
        <property name="maxWait" value="500"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>

    <bean id="dataSource_9" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://10.61.67.246:3306/test9"></property>
        <property name="username" value="user123"></property>
        <property name="password" value="user123"></property>
        <property name="maxActive" value="100"></property>
        <property name="maxIdle" value="30"></property>
        <property name="maxWait" value="500"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>

    <bean id="dataSource_10" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://10.61.67.246:3306/test10"></property>
        <property name="username" value="user123"></property>
        <property name="password" value="user123"></property>
        <property name="maxActive" value="100"></property>
        <property name="maxIdle" value="30"></property>
        <property name="maxWait" value="500"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>

    <bean id="dataSource_11" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://10.61.67.246:3306/test11"></property>
        <property name="username" value="user123"></property>
        <property name="password" value="user123"></property>
        <property name="maxActive" value="100"></property>
        <property name="maxIdle" value="30"></property>
        <property name="maxWait" value="500"></property>
        <property name="defaultAutoCommit" value="true"></property>
    </bean>

    <bean id="dataSource" class="com.elon.DynamicDataSource">
        <property name="targetDataSources">
            <map>
                <entry key="test1" value-ref="dataSource_1"/>
                <entry key="test2" value-ref="dataSource_2"/>
                <entry key="test3" value-ref="dataSource_3"/>
                <entry key="test4" value-ref="dataSource_4"/>
                <entry key="test5" value-ref="dataSource_5"/>
                <entry key="test6" value-ref="dataSource_6"/>
                <entry key="test7" value-ref="dataSource_7"/>
                <entry key="test8" value-ref="dataSource_8"/>
                <entry key="test9" value-ref="dataSource_9"/>
                <entry key="test10" value-ref="dataSource_10"/>
                <entry key="test11" value-ref="dataSource_11"/>
            </map>
        </property>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation" value="classpath:cfg/mybatis.xml"></property>
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="iDemo" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.elon.IDemo"></property>
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
    </bean>

    <bean id="iDemoService" class="com.elon.DemoServiceImpl">
        <property name="idemo" ref="iDemo"></property>
    </bean>

</beans>

十二、测试代码

public class TestMain
{
    /**
     * 测试代码
     * 
     *
     * @param args
     */
    public static void main(String[] args)
    {
        @SuppressWarnings("resource")
        ApplicationContext context = new ClassPathXmlApplicationContext("cfg/spring.xml");
        IDemoService service1 = (IDemoService)context.getBean("iDemoService");

        // 创建任务对象
        DBTask task1 = new DBTask("test1", service1, "selectGroup");
        DBTask task2 = new DBTask("test2", service1, "selectGroup");
        DBTask task3 = new DBTask("test3", service1, "selectGroup");
        DBTask task4 = new DBTask("test4", service1, "selectGroup");
        DBTask task5 = new DBTask("test5", service1, "selectGroup");
        DBTask task6 = new DBTask("test6", service1, "selectGroup");
        DBTask task7 = new DBTask("test7", service1, "selectGroup");
        DBTask task8 = new DBTask("test8", service1, "selectGroup");
        DBTask task9 = new DBTask("test9", service1, "selectGroup");
        DBTask task10 = new DBTask("test10", service1, "selectGroup");
        DBTask task11 = new DBTask("test11", service1, "selectGroup");

        DemoDAO demo = new DemoDAO();
        demo.setA(10000000);
        demo.setB("12121212");
        demo.setC(100);
        DBTask taskInsert = new DBTask("test2", service1, "insertDemo", demo);

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        System.out.println("开始插入数据:" + format.format(new Date()));
        DBTaskMgr.instance().excute(taskInsert);

        while (true)
        {
            if (!taskInsert.isFinish())
            {
                try
                {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
            else
            {
                break;
            }
        }

        System.out.println("插入数据结束:" + format.format(new Date()));

        System.out.println("开始查询5千万数据表:" + format.format(new Date()));
        DBTaskMgr.instance().excute(task1);

        while (true)
        {
            if (!task1.isFinish())
            {
                try
                {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
            else
            {
                break;
            }
        }

        System.out.println(task1.getRetValue());
        System.out.println("查询5千万数据表结束:" + format.format(new Date()));

        List<DBTask> taskList = new ArrayList<DBTask>();
        taskList.add(task2);
        taskList.add(task3);
        taskList.add(task4);
        taskList.add(task5);
        taskList.add(task6);
        taskList.add(task7);
        taskList.add(task8);
        taskList.add(task9);
        taskList.add(task10);
        taskList.add(task11);

        System.out.println("开始查询10个5百万数据表:" + format.format(new Date()));
        for (DBTask task : taskList)
        {
            DBTaskMgr.instance().excute(task);
        }

        while (true)
        {
            int success  = 0;
            for (DBTask task : taskList)
            {
                if (!task.isFinish())
                {   
                    try
                    {
                        Thread.sleep(1000);
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
                else
                {
                    ++success;
                }
            }

            if (success == 10)
            {
                break;
            }
        }

        for (DBTask task : taskList)
        {
            System.out.println(task.getRetValue());;
        }

        System.out.println("10个5百万数据表查询结束:" +format.format(new Date()));
    }
}

十三、测试结果

这里写图片描述

直接查询一个5千万条数据的数据库用时:45s。
多线程同步查询10个5百万数据的数据库用时: 22s。

由于10个数据库放在两台服务器上,一个服务器5个数据库。如果将10个数据分别部署到10个服务器,效率将更高。

  • 6
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
好的,以下是基于 Spring Cloud+Spring Boot+Nacos+Dubbo+mybatis plus+RocketMQ+Sentinel+Seata+mysql 搭建一个项目的步骤: 1. 首先,你需要安装并启动 Nacos 作为服务注册中心和配置中心。可以去官网下载最新版本的 Nacos,然后解压并启动即可。 2. 接下来,使用 Spring Initializr 创建一个基于 Spring Boot 的项目,并添加以下依赖: ``` <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-seata</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-sentinel</artifactId> </dependency> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> ``` 3. 配置 Nacos 作为服务注册中心和配置中心: ``` spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 spring.cloud.nacos.config.server-addr=127.0.0.1:8848 spring.cloud.nacos.config.prefix=/config spring.cloud.nacos.config.file-extension=properties ``` 4. 配置 Dubbo: ``` spring.application.name=provider-service spring.dubbo.application.name=provider-service spring.dubbo.registry.address=nacos://127.0.0.1:8848 spring.dubbo.protocol.name=dubbo spring.dubbo.protocol.port=20880 ``` 5. 配置 RocketMQ: ``` spring.rocketmq.name-server=127.0.0.1:9876 spring.rocketmq.producer.group=producer-group spring.rocketmq.consumer.group=consumer-group ``` 6. 配置 Sentinel: ``` spring.cloud.sentinel.transport.dashboard=127.0.0.1:8080 ``` 7. 配置 Seata: ``` spring.cloud.alibaba.seata.tx-service-group=my_seata_tx_group spring.cloud.alibaba.seata.tx-service-mode=AT spring.cloud.alibaba.seata.config.type=nacos spring.cloud.alibaba.seata.config.nacos.server-addr=127.0.0.1:8848 spring.cloud.alibaba.seata.config.nacos.namespace=seata-dev ``` 8. 配置 MySQL 数据源: ``` spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver ``` 9. 编写 Dubbo 服务接口和实现类: ``` public interface UserService { User getUserById(Long id); } @Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public User getUserById(Long id) { return userDao.selectById(id); } } ``` 10. 配置 Dubbo 服务提供者: ``` @Configuration public class DubboConfig { @Reference private UserService userService; @Bean public ApplicationRunner runner() { return args -> { User user = userService.getUserById(1L); System.out.println(user); }; } } ``` 11. 编写 RocketMQ 生产者和消费者: ``` @Component public class MessageProducer { @Autowired private RocketMQTemplate rocketMQTemplate; public void send(String message) { rocketMQTemplate.convertAndSend("test-topic", message); } } @Component @RocketMQMessageListener(topic = "test-topic", consumerGroup = "test-consumer-group") public class MessageConsumer implements RocketMQListener<String> { @Override public void onMessage(String message) { System.out.println("Received message: " + message); } } ``` 12. 编写 MySQL 数据访问层: ``` @Mapper public interface UserDao extends BaseMapper<User> { } ``` 13. 使用 Seata 进行分布式事务控制: ``` @Service public class OrderServiceImpl implements OrderService { @Autowired private OrderDao orderDao; @GlobalTransactional @Override public void createOrder(Order order) { orderDao.insert(order); // 调用其他服务,可能会涉及到分布式事务操作 // ... } } ``` 14. 使用 Sentinel 进行服务限流和熔断: ``` @GetMapping("/hello") @SentinelResource(value = "hello", blockHandler = "helloBlockHandler") public String hello() { return "Hello World!"; } public String helloBlockHandler(BlockException ex) { return "Blocked by Sentinel: " + ex.getClass().getSimpleName(); } ``` 15. 最后,启动项目并测试各个功能是否正常运行。 以上就是基于 Spring Cloud+Spring Boot+Nacos+Dubbo+mybatis plus+RocketMQ+Sentinel+Seata+mysql 搭建一个项目的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值