从零开始搭建一套微服务框架(六)集成fescar

关于fescar的介绍,请移步

阿里开源分布式事务框架fescar

一、安装fescar服务

从https://github.com/alibaba/fescar/releases下载服务器包,解压缩。

 sh fescar-server.sh $ LISTEN_PORT  $ PATH_FOR_PERSISTENT_DATA
例如
sh fescar-server.sh 8091 / home / admin / fescar / data /

二、添加依赖

这里使用fescar最新的版本0.3.0

三、添加配置文件

registry.conf 

registry {
  # file nacos
  type = "file"

  nacos {
    serverAddr = "localhost"
    namespace = "public"
    cluster = "default"
  }
  file {
    name = "file.conf"
  }
}

file.conf

transport {
  # tcp udt unix-domain-socket
  type = "TCP"
  #NIO NATIVE
  server = "NIO"
  #enable heartbeat
  heartbeat = true
  #thread factory for netty
  thread-factory {
    boss-thread-prefix = "NettyBoss"
    worker-thread-prefix = "NettyServerNIOWorker"
    server-executor-thread-prefix = "NettyServerBizHandler"
    share-boss-worker = false
    client-selector-thread-prefix = "NettyClientSelector"
    client-selector-thread-size = 1
    client-worker-thread-prefix = "NettyClientWorkerThread"
    # netty boss thread size,will not be used for UDT
    boss-thread-size = 1
    #auto default pin or 8
    worker-thread-size = 8
  }
}
service {
  #vgroup->rgroup
  vgroup_mapping.my_test_tx_group = "localRgroup"
  #only support single node
  localRgroup.grouplist = "10.8.80.222:9999"
  #degrade current not support
  enableDegrade = false
  #disable
  disable = false
}

client {
  async.commit.buffer.limit = 10000
  lock {
    retry.internal = 10
    retry.times = 30
  }
}

fescar规划是可以使用各种注册中心和配置中心的,但是目前版本还没有支持,配置文件多数为预留项目,主要配置信息在file.conf中的srvice,主要配置项为

localRgroup.grouplist = "10.8.80.222:9999"设置fescar-server的地址

vgroup_mapping.my_test_tx_group = "localRgroup"中的my_test_tx_group为设置的事务组名称

四、与Spring集成

在TM和RM项目中分别创建Spring自动配置文件FescarConfig.java

package cn.ktp.demo.config;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import com.alibaba.fescar.rm.datasource.DataSourceProxy;
import com.alibaba.fescar.spring.annotation.GlobalTransactionScanner;

/**
 * @Author: kris
 * @Description  fescar全局设置,对数据源进行增强
 * @Date Created in 2019/3/14 10:28
 */
@Configuration
@Import(DruidDataSourceAutoConfigure.class)
public class FescarConfig {

    /**
     * 包装数据源代理,用于在执行SQL之前生成回退日志
     * @Param: druidDataSource  datasource bean instance
     * @Return: DataSourceProxy  datasource proxy
     */
    @Bean
    public DataSourceProxy dataSourceProxy(DataSource druidDataSource){
        return new DataSourceProxy((DruidDataSource)druidDataSource);
    }

    /**
     * 替换 mybatis 的sqlSessionFactory,用数据源代理替换自动装配的数据源
     * @Param: dataSourceProxy  fescar数据源代理
     * @Return: SqlSessionFactory  mybatic使用的数据源
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSourceProxy);
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:/mapper/*.xml"));
        factoryBean.setTransactionFactory(new JdbcTransactionFactory());
        return factoryBean.getObject();
    }


    /**
     * 初始化全局事务扫描器
     *
     * @Return: GlobalTransactionScanner
     */
    @Bean
    public GlobalTransactionScanner globalTransactionScanner(){
        return new GlobalTransactionScanner("demo_service", "my_test_tx_group");
    }
}

这里,我的数据库使用的是mysql,持久层使用mybatis,我需要对数据源进行包装以支持fescar分布式事务管理,因此在这里对数据源进行扩展。如果TM项目不需要访问数据库,可以去除数据源代理和SqlSeeionFactory的定义,记得连上面的Import一起去掉。

GlobalTransactionScanner向fescar服务注册TM和RM的id和分支事务组

五、启用开始使用分布式事务

我这里提供了一个例子,authApi的addUser调用了authService的addUser方法和demoService的demo方法,这是一个分布式服务调用,而我要做的仅仅是在方法上给一个标签@GlobalTransactional

之后,我们就可以开始测试了,调用这个服务,抛出异常,然后去数据库查询,发现已经demo方法已经回滚,在DemoService的控制台可以得到以下内容

2019-03-14 16:14:24.139  INFO 29117 --- [atch_RMROLE_1_8] c.a.f.core.rpc.netty.RmMessageListener   : onMessage:xid=10.8.80.222:9999:2005758210,branchId=2005758211,branchType=AT,resourceId=jdbc:mysql://10.8.80.222:3306/kris?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true,applicationData=null

2019-03-14 16:14:24.139  INFO 29117 --- [atch_RMROLE_1_8] com.alibaba.fescar.rm.RMHandlerAT        : AT Branch rolling back: 10.8.80.222:9999:2005758210 2005758211 jdbc:mysql://10.8.80.222:3306/kris?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true

2019-03-14 16:14:24.167  INFO 29117 --- [atch_RMROLE_1_8] com.alibaba.fescar.rm.RMHandlerAT        : AT Branch rollback result: PhaseTwo_Rollbacked

2019-03-14 16:14:24.167  INFO 29117 --- [atch_RMROLE_1_8] c.a.fescar.core.rpc.netty.RmRpcClient    : RmRpcClient sendResponse branchStatus=PhaseTwo_Rollbacked,result code =Success,getMsg =null

DemoService中的RM收到回滚消息,进行了事务回滚。

分布式事务变得如此简单,期待fescar的生产版本上线! 

代码已上传至https://gitee.com/krisdevhome/ktp-main ,如果觉得好就点个赞把

猜你喜欢

转载自blog.csdn.net/kris1122/article/details/88554452