DDD in real project 2

Wed, Mar 1, 2023 One-minute read

DDD in real project

State Pattern vs. Strategy Pattern

we use State Pattern in activity, but Strategy Pattern in ID generation, what’s the difference between them?

The State controls the entire object’s behavior, and it’s reasonable to think that the state will be changed at some point, either by the Context or by the States themselves.

The Strategy helps us to provide a custom behavior to some actions, which might or might not require being changed during the object’s lifetime.

ID generate

  • ids
    • IdContext, provide the service
    • IIDGenerator, interface for id generate
      • long nextId();
    • policy
      • @Component
      • RandomNumberic
        • implements IIdGenerator
        • org.apache.commons.lang3.RandomStringUtils
        • //生成随机数字字符串 11
        • return Long.parseLong(RandomStringUtils.randsomNumeric(11))
      • ShortCode
        • “02d”, 十进制,不足补 0
        • sb.append(String.format("%02d", week));
      • SnowFlake
        • synchronized long nextId() -> return snowflake.nextId();
        • @PostConstruct
        • init()

database router

为什么分库分表

减少数据库压力,提高效率,缩短查询时间

通常数据存量200万-300万,增量再单表50万就考虑拆表,拆分库大部分都是虚拟机上,不会造成服务器资源浪费,后续数量增多再迁移物理机

为什么分库

在这里,用户参与活动记录次数,是否中奖等等属于高频操作,如果业务量剧增,会造成数据库瓶颈。

磁盘存储: 业务量剧增,mysql单机磁盘容量会撑爆,拆成多个数据库,磁盘使用率大大提升

并发连接支持: 数据库连接是有限的,高并发下,大量请求访问数据库,mysql单机无法承受,因为本项目采用微服务,通过将订单,用户,商品拆成不同domain,将单个数据库拆成多个相同或不同功能的数据库,放在多个库里,同时采用缓存来降低访问。

为什么分表

数据太大,sql查询效率变慢,如果一个查询sql没有命中索引,前百万数据量的表会拖累一个库; 命中了索引,千万级别的表 B+ TREE 树高度会增高,。所以一般单表50万采用分表。

B+ tree高度计算: InnoDB存储最小单位是页,一页16kb,叶子节点储存的是索引和数据,内部节点是键值和指针。

分库分表问题

  • 事务问题, 相关的表在不同数据库中,本地事务不能保证原子性,需要分布式事务
  • 跨库关联, FEDERATED引擎,数据库分库后跨库join解决方案两次查询
  • 排序问题, 跨界点的count, order by, groud by以及聚合函数等问题,可以分表在各个节点上得到结果后在应用程序端进行合并
  • 分页问题, 在个节点查到对于结果后,在代码端汇聚再分页;或者把分页分到前端,然后在各个数据库节点执行分页,再汇聚总数量前端,但是这样容易造成空查
  • 解决方法: 分布式ID, 数据库划分后,不再依赖数据库自身的主键生成机制,最简单的可以用UUID,或者雪花算法生成分布式ID. uuid = uId + "_" + activityId + "_" + userTakeActivity.getTackCount();