SpringCloud生态框架(四)-分布式事务管理中心

背景:对于cloud分布式架构,最难避免的就是多服务调用问题,然而在某些难以避免的情况下会发生一次请求会协调多个服务调用去完成这一个事件的任务,正式这种情况的存在,才会造成先调用的服务已经对数据库操作完成了,后面的对于数据库操作却失败了,在这种情况下就会存在数据库的一次操作数据处理残缺,所以才引入了今天我们要说的分布式事务。

官方解释:事务是由一组操作构成的可靠的独立的工作单元,事务具备ACID的特性,即原子性、一致性、隔离性和持久性。但是lcntx不生产事务,只是事务的协调者!

     在一个分布式系统下存在多个模块协调来完成一次业务。那么就存在一次业务事务下可能横跨多种数据源节点的可能。TX-LCN将可以解决这样的问题。

例如存在服务模块A 、B、 C。A模块是mysql作为数据源的服务,B模块是基于redis作为数据源的服务,C模块是基于mongo作为数据源的服务。若需要解决他们的事务一致性就需要针对不同的节点采用不同的方案,并且统一协调完成分布式事务的处理。接下来进入正题

一.新建一个module,作为分布式事务服务(前面文章已经讲述如何创建,不再重复阐述),引入jar包

<!-- lcnTx start -->
<dependency>
    <groupId>com.codingapi.txlcn</groupId>
    <artifactId>txlcn-tm</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<!-- lcnTx end -->

建表:

/*
Navicat Premium Data Transfer
Source Server : local
Source Server Type : MySQL
Source Server Version : 100309
Source Host : localhost:3306
Source Schema : tx-manager
Target Server Type : MySQL
Target Server Version : 100309
File Encoding : 65001
Date: 29/12/2018 18:35:59
*/
CREATE DATABASE IF NOT EXISTS
`tx-manager` DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

/*

tx-manager修改成为自己的数据库名

*/
USE `tx-manager`;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_tx_exception
-- ----------------------------
DROP TABLE IF EXISTS `t_tx_exception`;
CREATE TABLE `t_tx_exception` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`group_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`unit_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`mod_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`transaction_state` tinyint(4) NULL DEFAULT NULL,
`registrar` tinyint(4) NULL DEFAULT NULL,
`ex_state` tinyint(4) NULL DEFAULT NULL COMMENT '0 待处理 1已处理',
`remark` varchar(10240) NULL DEFAULT NULL COMMENT '备注',
`create_time` datetime(0) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT
= 967 CHARACTER SET = utf8mb4 COLLATE =
utf8mb4_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1

二.配置文件有两种方案,第一种采用properties,这种是官方给出的配置文件格式

spring.application.name=TransactionManager
server.port=7970
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://{hostname}:{port}/internethsp?characterEncoding=UTF-8&useUnicode=true&useSSL=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=none
#redis配置
spring.redis.host=10.10.10.242
spring.redis.password=
spring.redis.port=6379
spring.redis.database=0
spring.redis.timeout=60000
#事物日志配置
tx-lcn.logger.enabled=true
tx-lcn.logger.driver-class-name=${spring.datasource.driver-class-name}
tx-lcn.logger.jdbc-url=${spring.datasource.url}
tx-lcn.logger.username=${spring.datasource.username}
tx-lcn.logger.password=${spring.datasource.password}

第二种:因为我们已经搭建了统一配置管理中心,所以我们这次采用yml的配置文件格式,但是有一个问题就是如果只留下yml配置文件,将会启动失败,这或许是个bug,也或许是笔者技术太菜,不太清楚怎么处理这个,所以我用了一个另类的解决方案,

用了两个配置文件,但是properties的这个配置文件里面所有的东西都注释掉了,然后在用yml来配置,配置如下

spring:
  application:
    name: serviceConfig
  profiles:
    active: git
  cloud:
    config:
      label: master
#这里的profile和远程的配置文件名字一致
      profile: consult-master
      uri: http://localhost:9527/serviceConfig
      discovery:
        enabled: true
        service-id: fool-cloud-config
eureka:
  instance:
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://admin:admin@127.0.0.1:9526/eureka/eureka
    enabled: true

三.远程配置文件,第二篇文章说到我们的配置文件都将上远程配置,所以我们的远程库里面的配置文件为

server:
  #端口号
  port: 9529
spring:
  application:
    name: fool-cloud-lcn
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://{hostname}:{name}/internethsp?characterEncoding=UTF-8&useUnicode=true&useSSL=true&serverTimezone=UTC
    username: root
    password:
  jpa:
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    hibernate.ddl-auto: none
  #redis host名字
  redis:
    host:  {hostname}
    #redis端口号
    port: 6379
    #redis 密码
    password:
  # 心跳检测时间(ms). 默认为 30000
tx-lcn:
  manager:
    heart-time: 30000
    # 分布式事务执行总时间(ms). 默认为36000
    dtx-time: 8000

    # 事务处理并发等级. 默认为机器逻辑核心数5倍
    concurrent-level: 160
    # 分布式事务锁超时时间 默认为-1,当-1时会用tx-lcn.manager.dtx-time的时间
    dtx-lock-time: ${tx-lcn.manager.dtx-time}

    # 雪花算法的sequence位长度,默认为12位.
    seq-len: 12

    # 异常回调开关。开启时请制定ex-url
    ex-url-enabled: false

    # TM后台登陆密码,默认值为123456
    admin-key: 123456
    #注册中心配置
    #邮箱配置
    #tx-lcn.manager.ex-url=/provider/email-to/18628960476@163.com
    #TM监听IP. 默认为 127.0.0.1
    host: 127.0.0.1
    #TM监听
    port: 8070

  # 开启日志,默认为false
  logger:
    enabled: true
    driver-class-name: ${spring.datasource.driver-class-name}
    jdbc-url: ${spring.datasource.url}
    username: ${spring.datasource.username}
    password: ${spring.datasource.password}
logging:
  level:
    com:
      codingapi:
        txlcn: DEBUG
eureka:
  instance:
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://admin:admin@127.0.0.1:9526/eureka/eureka/
    enabled: true


#spring.mail.host=smtp.163.com
#spring.mail.port=587
#spring.mail.username=18628960476@163.com
#spring.mail.password=334353

 

当然这里为了支持datasource还需要引入jar

<properties>
    <lcn.version>5.0.2.RELEASE</lcn.version>
    <config.version>2.1.1.RELEASE</config.version>
    <jdbc.version>5.2.2.RELEASE</jdbc.version>
    <mysql.version>5.1.6</mysql.version>
</properties>
<!-- lcnTx end -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.version}</version>
    <scope>runtime</scope>
</dependency>
<!-- jdbc start -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${jdbc.version}</version>
</dependency>
<!-- jdbc end -->

<!-- jdbc start -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-client</artifactId>
    <version>${config.version}</version>
</dependency>
<!-- jdbc end -->

四.接下来启动我们的统一配置中心,并且访问hostname+port会发现

配置成功了,再输入我们刚刚配置的初始密码登录就会进入到事务的后台管理了,这样统一事务管理中心就搭建完成了,然后我们原来的example服务上增加配置,来模拟事务客户端。

五.需要引入的jar,因为需要用到持久层,所以这里选用的mysql和jdbc链接

<properties>
    <config.version>2.1.1.RELEASE</config.version>
    <tc.version>5.0.2.RELEASE</tc.version>
    <tc.netty.version>5.0.2.RELEASE</tc.netty.version>
    <jdbc.version>5.2.2.RELEASE</jdbc.version>
    <mysql.version>5.1.6</mysql.version>
</properties>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.version}</version>
    <scope>runtime</scope>
</dependency>
<!--事务管理 start-->
<dependency>
    <groupId>com.codingapi.txlcn</groupId>
    <artifactId>txlcn-tc</artifactId>
    <version>${tc.version}</version>
</dependency>

<dependency>
    <groupId>com.codingapi.txlcn</groupId>
    <artifactId>txlcn-txmsg-netty</artifactId>
    <version>${tc.netty.version}</version>
</dependency>
<!--事务管理 end-->
<!-- jdbc start -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${jdbc.version}</version>
</dependency>
<!-- jdbc end -->

然后在启动类增加@EnableDistributedTransaction注解! 你以为这样就完了么?兄弟莫慌,快成功了,我们客户端肯定要配置注册到哪个事务管理中心撒,在example的远程配置文件增加如下配置

tx-lcn:
  client:
    manager-address: 127.0.0.1:8070
  ribbon:
    loadbalancer:
      dtx:
        enabled: true
  logger:
    enabled: true
    driver-class-name: ${spring.datasource.driver-class-name}
    jdbc-url: ${spring.datasource.url}
    username: ${spring.datasource.username}
    password: ${spring.datasource.password}

接下来可以启动了,有没有发现启动成功了,然后我们再来看第四步的登录事务管理后台,登录进去会发现有一个事务客户端注册进来,证明我们的搭建成功了。如果想试试分布式事务的效果,可以多搭建几个服务相互调用来测试,之前笔者采用的是cloud完整架构请求来测试的。

 

今天我们的搭建分布式事务管理就搭建成功了,下期将开始搭建gateway负载均衡式转发了,敬请期待!

                                                                                                                         更多技术问题请加入QQ群:260292706交流

                                                                                                                                                                     Owen

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Alibaba是一个基于Spring Cloud的开源框架,提供了丰富的微服务开发工具包,包括服务注册与发现、配置管理、消息总线、负载均衡、熔断降级、分布式事务、流量控制、安全控制、分布式追踪等功能。 Spring Cloud Alibaba与Nacos、Dubbo、Sentinel等组件协同工作,Nacos作为注册中心和配置中心,Dubbo作为RPC框架,Sentinel作为流量控制和熔断降级组件,共同构建起完整的微服务生态体系。 使用Spring Cloud Alibaba进行服务注册和发现,可以通过注解@EnableDiscoveryClient开启服务注册与发现功能,并通过@FeignClient或@LoadBalanced注解实现服务调用和负载均衡。 使用Spring Cloud Alibaba进行服务治理,可以通过注解@EnableCircuitBreaker开启熔断降级功能,并通过@SentinelResource注解配置熔断降级规则。 使用Spring Cloud Alibaba进行熔断降级,可以通过Sentinel Dashboard进行实时监控和管理,同时通过注解@SentinelRestTemplate实现对RestTemplate的熔断降级。 使用Spring Cloud Alibaba进行服务配置管理,可以通过注解@EnableConfigNacosConfig和@Value注解实现动态配置管理。 使用Spring Cloud Alibaba进行分布式事务管理,可以通过注解@EnableDistributedTransaction开启分布式事务管理功能,并通过@GlobalTransactional注解实现分布式事务的统一管理和控制。 使用Spring Cloud Alibaba进行链路追踪,可以通过注解@EnableZipkinServer和@EnableZipkinClient开启链路追踪功能,并通过Sleuth和Zipkin实现对微服务调用链的追踪和分析。 使用Spring Cloud Alibaba进行服务限流,可以通过Sentinel进行实时流控和熔断降级,同时通过注解@SentinelResource实现对服务的限流控制。 Spring Cloud Alibaba支持微服务的服务网关管理,可以通过注解@EnableZuulProxy或@EnableGateway开启服务网关功能,并通过Zuul或Gateway实现微服务的API网关管理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值