定制设计拥抱新技术?你需要考虑的方面

前言

大家好,定制设计本文是博主在负责对企定制设计业项目新技术引入时,定制设计考虑不周的点,定制设计文中以第一视角对整个定制设计过程进行复盘以及事后分析。以 Mycat 为例。定制设计希望对大家有所帮助~

目录

一、背景

定制设计在一次会议内容提到一定制设计个新的技术,定制设计是我没有涉及到的领域—定制设计分库分表技术预研,定制设计当时会议提到该领域其定制设计中一个技术点 Mycat 技术点,定制设计该技术是我没有涉及到,定制设计而在此次会议被安排负定制设计责该项技术的预研。

二、需求

接下来,定制设计我就花时间去了解 Mycat这个东西,定制设计网上各种找资料,说实话,定制设计资料还是非常的多的,定制设计当时的想法就是满足现有的需求。当时 Leader 定制设计给我的任务是针对部分定制设计数据量大的表,定制设计进行单库分表。定制设计将这些需要分表的表按定制设计照月份进行分表。

定制设计比如订单表,定制设计将订单表分成:m_order_202201, m_order_202202, m_order_202203…

定制设计我就针对这个需求,去学习 Mycat 定制设计如何去实现按月分表。

三、Demo 环境搭建

定制设计每学习一个新的技术点,定制设计亦或是引入一个新的技术,定制设计需要将该知识点最简化。定制设计先搭建一个 Demo 出来,定制设计然后在基于 Demo 进行扩展。定制设计我觉得这样是可以充分定制设计的降低出现预期外的问题,定制设计使我们的学习、定制设计引入或集成更加的轻便。

很快,定制设计我在网上下载好了 Mycat 的程序,定制设计进行按月分表的实操。

一切从简,我首先是创建了一个测试表,表里总共两个字段,在 Mycat 中配置使用很简单的针对日期分表的规则。此时是很成功的,内心是无比的喜悦,觉得这个东西也没啥,非常简单。当天就快快乐乐的下班啦~

3.1、初遇问题

然而,第二天上班的时候,我发现一个问题,就是原有 Mycat 程序提供的按月分表,仅支持 datedatetime 字段类型的分表。我们的订单表(m_order)的创建时间(created_time),是bigint类型的,也就是我们插入的创建时间是一个时间戳,而 Mycat 对时间戳方式的分表是不支持的,此时我上网找了半天,也没有针对时间戳进行分表的方案。

3.2、解决问题

突然想到 Mycat 是开源的,我是不是能增加一个按时间戳分表的方式呢?

说干就干,马上在 GitHub 上找到 Mycat 的源码,Fork 后拉取到本地。找到官方写的按月分表的类后,我也照着原有的代码,写了一个按时间戳分表的类,将其编译后,放入中间件源码包内,并配置分表规则。具体可以看我之前写的博客。

Mycat实现单库水平分表、按月分表:

https://micromaple.blog.csdn.net/article/details/125395498
  • 1

四、方案制定

此时按时间戳分表方式我们也解决了。但是面临一个问题,就是 Leader 是否允许咱们这样做?

临时做了几个方案,将其汇报给了 Leader ,看是否开会讨论一下方案。方案如下:

  • 方案一:

    在需要分表的表中增加一个字段,例如插入时间(insertDate)类型为datetime或者date,根据该插入字段进行分表。

    优点:满足现有分表规则,不需要修改中间件源码。
    缺点:需要修改代码,插入的时候,需要增加插入时间字段。

  • 方案二:

    修改源码,增加适配时间戳分表方式。

    优点:最大程度降低了代码和中间件的耦合度,代码几乎不需要进行更改。
    缺点:由于是自己写的分库(或分表)规则,对于以后中间件的升级不友好。

  • 方案三:

    按范围分表,提前规划好分表字段某个范围属于哪个分表。

    优点:满足现有分表规则。
    缺点:根据时间戳配置麻烦。

  • 方案四:

    选择其他分表方式,根据其他字段及规则进行分表。例如:取模。

    优点:易于配置。
    缺点:所有的表都会用起来,数据散列分布。

将这四个方案提给 Leader 后,跟 Leader 讨论后。 Leader 觉得不更改中间件源码,采用方案一,增加字段来进行分表。

原因就是觉得更改源码后,后续升级会比较麻烦。但是我觉得增加字段有点麻烦,此时这个分表的事情也不紧急,我就去问了一下Mycat的官方开发人员。如下图:

五、实战-项目集成

突然有一天下午,我们有一个地方项目爆出 MySQL 突然挂了,怎么也启动不起来,后面我们排查后发现是表损坏了。第二天上午,我们 Leader 就跟我们开了一个会,说单表数据量太大了,Mycat分表这个得提上日程了,刚好最近有一个地方项目要进行升级,顺便就把这个Mycat分表的推上去用。接下来我就拉取了一个 Mycat 的分支版本,并搭建配置 Mycat 版本的环境。

5.1、再遇问题

我们将其配置好后,发现项目启动后疯狂报错,各种 SQL 不兼容的问题,当时我人都懵了。

经过排查,发现我们原先引入的 Activity 工作流完全没办法用了,里面一些内置的 SQL 是不支持的。这块我是考虑不周的,没有对 SQL 进行充分的兼容测试。当天下班,我都在自责。

然后我马不停蹄的去总结了一些SQL不兼容的地方。如下:

  • 增加(insert)
    • insert插入的时候必须要带字段名,必须带分表字段
    • insert into x select from y 的sql语句不被支持
  • 删除(delete)
    • 支持子查询删除方式delete from a where a.id in (select id from b), 但表不能起别名
  • 修改(update)
    • 不支持多表更新
    • 分表字段不能被更新
  • 查询(select)
    • select中DISTINCT不支持对a.*的查询
    • distinct 和 select 查询列中用子查询的会冲突,二者选其一
    • 子查询where条件中不支持使用or
    • 查询最好能够按照分表字段,否则查询效率不是太好
    • 关于order by排序,Order by 后的排序字段必须是select的一部分,查询全局表的时候除外

然后我马不停蹄的将其汇报给 Leader ,并说明了我在这块考虑不周全,没有做好。

5.2、总结问题

此时我的问题已经很明显了。对新技术没有进行充分的了解和熟悉,没有对此项技术进行充分的测试,没有考虑到新技术引入进来所带来的耦合度的提升。各种各样的原因吧,没有考虑清楚。

六、持续引入集成

到这里了,大家可能会很好奇,为啥有这么多不支持的点了,还要继续引入呢?

结合当时的项目和业务使用场景,以及 Leader 对 Mycat 技术栈的信任,工作流模块是可以直接干掉的(因为这个东西没有什么人用)。我们就开会讨论,后续如何的集成 Mycat 分表;此时我们已经消耗了大半个月的时间了。紧接着我们就评估集成后的改动工作量。我和另一位后端同学评估出来的工作量大概是10个工作日,随后 Leader 就协调了一位后端同学跟我一起改,协调了另外一位测试同学帮助我们测试。

6.1、项目改动

集成Mycat后,项目SQL改动进行的如火如荼。发现了很多改动都是差不多的,大部分都是在子查询中加了 OR 的条件查询,改动起来也很快。

遇到一些查询结果不一致的,还需要在代码中调整。例如,连表查询统计数量的时候,我要统计近七天的数据,Mycat会将每一个分表后的表的这个日期都统计一遍。假设我统计2022-01-01到2022-01-07的数据,此时我的订单表(m_order)分成了12个表,那么2022-01-01会有12条数据,加起来就一共有 7*12 = 84 条数据。接着我们还要通过代码进行分组(还好这块 JDK1.8 的 stream 流操作丝滑)。在这之中,也将之前一些同事写的bug优化了~

6.2、致命问题

我和另一位后端同学正改的起劲的时,突然发现一个致命的问题,就是有一个地方进行新增操作的时候,增加了Spring 的注解 @Transactional 导致业务层代码一直挂起,无法响应。这里分享出来,感兴趣的同学可以看一下。代码如下:

Controller层

@RestController@RequestMapping("/order")@Slf4jpublic class OrderController {    @Autowired    private OrderService orderService;    @PostMapping("/save")    public Object save(Order order) {        int save = orderService.save(order);        log.info("保存完成==>" + save);        if(save > 0) {            return "success";        }        return "fail";    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Service层

public interface OrderService {    public int save(Order order);    }
  • 1
  • 2
  • 3
  • 4
  • 5

Service实现

@Service@Slf4jpublic class OrderServiceImpl implements OrderService {    @Autowired    private OrderMapper orderMapper;    @Override    public int save(Order order) {        log.info("开始保存数据");        int insert = orderMapper.insert(order);        log.info("插入数据==>" + insert);        return insert;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Mapper层

@Mapperpublic interface OrderMapper extends BaseMapper<Order> {}
  • 1
  • 2
  • 3
  • 4

日志输出

开始保存数据插入数据==>1
  • 1
  • 2

Controller层的日志一直没有输出,也就是进入到Service层执行完业务代码后,一直没有出来。此时我也不知道啥问题,应该也有人遇到这个问题吧,我就打开了 GitHub,在 Issues 检索,发现了这个。如下图:

当时想,不妨试试,反正要不了多少时间。结果,还真的可以了,数据也进入到数据库了,此时有些人可能觉得已经解决了这个问题,但是并没有。事务是何等的重要,没有事务,无法保证程序数据的一致性和完整性,这将是致命的大问题。

6.3、寻找解决方案

我在找了一周的解决方案后,没有找到一个合适的解决方案。例如:XA事务,虽然可以回滚,但是经过测试,是非隔离的,会出现更多的问题。

之后,我跟一位朋友聊天时,问了问他以前是否使用过Mycat?如下是我跟朋友的聊天,大家可以感受一下。

我:你们以前用过 Mycat 吗?

朋友:用过,是好几年前的事情了,但是几年前 Mycat 停更过后,也就再也没有使用过 Mycat 了。

我:之前公司使用过 ShardingSphere-JDBC,但是觉得跟代码耦合度太高了。

朋友:ShardingSphere 有好几种模式,一种叫 ShardingSphere-JDBC,属于 SDK 形式嵌入的,还有跟 Mycat 对标的 ShardingSphere-Proxy,这个才是独立的部署服务器的,就看咱们怎么用。

虽然短短几句,我意识到自己有很多的不足。技术广度不够,没有仔细的去比对各项同类技术,导致技术选型的时候出现了许多的问题。其次是对技术的关注度不够,Mycat已经停更过,咱都不知道。

后续就是朋友建议我把 Spring 的 DEBUG 日志和 Mycat 的 DEBUG 日志打出来,分析看看。我到现在也没分析出来啥问题(手动难过)。

第二种就是同事建议我是否可以手动的去打开、提交或者回滚事务,也是行不通的,根本不回滚。

这个问题困扰了我很久,迟迟无法解决(手动头痛)。

GitHub上也有很多类似的问题,一直没有得到解决

6.4、最终方案

后来实在是解决不了了,就跟 Leader 说明了情况,从各个方面演示这个问题,以及我针对这个问题找的解决方案。他也暂时没有好的解决方法。

当时项目有新需求需要紧急开发了,也不消耗时间去考虑其他分表方案了。最终决定后续可能采用数据归档的方式来处理。

七、总结

经历了这件事情,从开始到后面不完美的闭环,意识到了自己很多的不足:

  • 学习一个新技术,只关注眼前,只听别人说有多好用,自己怀着猜想的方式去学习,别人说可以这样,殊不知还有很多坑等着自己去踩。
  • 在引入一个新的技术点,尤其是针对数据源的这类技术,考虑不全面,没有对整个项目的使用场景进行一个充分的测试。
  • 对技术的关注度不够,技术点是否有巨大变动,完全不知。
  • 技术广度不够,对于自己学习的技术,没有形成一个知识网络,导致技术选型的时候,没有方案可选。

读到这里,想必你也学习到了博主的一些经验,不管是之后学习或是工作或是其他方面有帮助的话,别忘了三连支持博主呀~
我是微枫Micromaple,期待你的关注~💪💪💪

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发