海量数据处理商用短链接生成器平台 - 7

第十五章 短链服务-Murmur哈希算法封装组件

第1集 Guava框架里面的Murmur哈希算法测试

简介: Guava框架里面的Murmur哈希算法测试

  • Guava框里里面自带Murmur算法
  • 单元测试
@Test
    public void testMurmurHash() {
        for (int i = 0; i < 50; i++) {
            int num1 = random.nextInt(1000000);
            int num2 = random.nextInt(1000000);
            int num3 = random.nextInt(1000000);
            String originalUrl = num1 + "baidu+" + num2 + ".net" + num3;
            long murmur3_32 = Hashing.murmur3_32().hashUnencodedChars(originalUrl).padToLong();
            System.out.println("murmur3_32="+murmur3_32);


        }


    }
  • CommonUtil工具类
  /**
     * murmur hash算法
     * @param param
     * @return
     */
    public static long murmurHash32(String param){
        long murmur32 = Hashing.murmur3_32().hashUnencodedChars(param).padToLong();
        return murmur32;
    }
第2集 短链生成组件ShortLinkComponent封装

简介: 短链生成组件ShortLinkComponent封装

  • 创建短链组件类 ShortLinkComponent
    /**
     * 创建短链
     * @param originalUrl
     * @return db编码+6位短链编码
     */
    public String createShortLinkCode(String originalUrl){
        long murmur32 = CommonUtil.murmurHash32(originalUrl);
        //转62进制
        String shortLinkCode = encodeToBase62(murmur32);
        return code;
    }
  • 10进制转62进制
private static final String CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";


    /**
     * 10进制转62进制
     * @param num
     * @return
     */
    private static String encodeToBase62(long num) {
        //StringBuffer:线程安全;    StringBuilder:线程不安全
        StringBuffer sb = new StringBuffer();
        do {
            int i = (int) (num % 62);
            sb.append(CHARS.charAt(i));
            num /= 62;
            // num = num/ 62;
        } while (num > 0);


        String value = sb.reverse().toString();
        return value;
    }
第3集 组件ShortLinkComponent测试和疑惑解答

简介: 组件ShortLinkComponent测试和疑惑解答

  • 单元测试
    /**
     * 测试短链平台
     */
    @Test
    public void testCreateShortLink() {
        Random random = new Random();
        for (int i = 0; i < 100; i++) {
            int num1 = random.nextInt(10);
            int num2 = random.nextInt(1000000);
            int num3 = random.nextInt(1000000);
            String originalUrl = num1 + "baidu" + num2 + ".net" + num3;
            String shortLinkCode = shortLinkComponent.createShortLinkCode(originalUrl);
            log.info("originalUrl:" + originalUrl + ", shortLinkCode=" + shortLinkCode);
        }
    }
  • 为什么要用62进制转换,不是64进制?
    • 62进制转换是因为62进制转换后只含数字+小写+大写字母
    • 而64进制转换会含有/、+这样的符号(不符合正常URL的字符)
    • 10进制转62进制可以缩短字符,如果我们要6位字符的话,已经有560亿个组合了
  • 看业务情况有些短链也会加入其它特殊字符
    • 短链固定6位?肯定不是的,后续会进行分库分表改造

第十六章 短链服务-数据库表建立和业务代码开发

第1集 数据库表模型讲解-短链分组和短链

简介: 数据库表模型讲解-短链分组和短链

  • 关系

    • 一个账号有多个分组
    • 一个分组下有多个短链
      在这里插入图片描述
  • 短链-分组

CREATE TABLE `link_group` (
  `id` bigint unsigned NOT NULL,
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '组名',
  `account_no` bigint DEFAULT NULL COMMENT '账号唯一编号',
  `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP,
  `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
  • 短链
CREATE TABLE `short_link` (
  `id` bigint unsigned NOT NULL ,
  `group_id` bigint DEFAULT NULL COMMENT '组',
  `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '短链标题',
  `original_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '原始url地址',
  `domain` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '短链域名',
  `code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '短链压缩码',
  `sign` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '长链的md5码,方便查找',
  `expired` datetime DEFAULT NULL COMMENT '过期时间,长久就是-1',
  `account_no` bigint DEFAULT NULL COMMENT '账号唯一编号',
  `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  `del` int unsigned NOT NULL COMMENT '0是默认,1是删除',
  `state` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '状态,lock是锁定不可用,active是可用',
  `link_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '链接产品层级:FIRST 免费青铜、SECOND黄金、THIRD钻石',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
第2集 MybatisPlus逆向工具生成短链服务相关java对象

简介: MybatisPlus逆向工具生成短链服务相关java对象

  • 配置代码
public class MyBatisPlusGenerator {


    public static void main(String[] args) {
        //1. 全局配置
        GlobalConfig config = new GlobalConfig();
        // 是否支持AR模式
        config.setActiveRecord(true)
                // 作者
                .setAuthor("oop")
                // 生成路径,最好使用绝对路径,window路径是不一样的
                //TODO  TODO  TODO  TODO
                .setOutputDir("/Users/class/Desktop/demo/src/main/java")
                // 文件覆盖
                .setFileOverride(true)
                // 主键策略
                .setIdType(IdType.AUTO)


                .setDateType(DateType.ONLY_DATE)
                // 设置生成的service接口的名字的首字母是否为I,默认Service是以I开头的
                .setServiceName("%sService")


                //实体类结尾名称
                .setEntityName("%sDO")


                //生成基本的resultMap
                .setBaseResultMap(true)


                //不使用AR模式
                .setActiveRecord(false)


                //生成基本的SQL片段
                .setBaseColumnList(true);


        //2. 数据源配置
        DataSourceConfig dsConfig = new DataSourceConfig();
        // 设置数据库类型
        dsConfig.setDbType(DbType.MYSQL)
                .setDriverName("com.mysql.cj.jdbc.Driver")
                //TODO  TODO  TODO  TODO
                .setUrl("jdbc:mysql://120.79.150.146:3306/dcloud_link?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai")
                .setUsername("root")
                .setPassword("xdclass.net168");


        //3. 策略配置globalConfiguration中
        StrategyConfig stConfig = new StrategyConfig();


        //全局大写命名
        stConfig.setCapitalMode(true)
                // 数据库表映射到实体的命名策略
                .setNaming(NamingStrategy.underline_to_camel)


                //使用lombok
                .setEntityLombokModel(true)


                //使用restcontroller注解
                .setRestControllerStyle(true)


                // 生成的表, 支持多表一起生成,以数组形式填写
                //TODO  TODO  TODO  TODO
                .setInclude("link_group","short_link");


        //4. 包名策略配置
        PackageConfig pkConfig = new PackageConfig();
        pkConfig.setParent("net.class")
                .setMapper("mapper")
                .setService("service")
                .setController("controller")
                .setEntity("model")
                .setXml("mapper");


        //5. 整合配置
        AutoGenerator ag = new AutoGenerator();
        ag.setGlobalConfig(config)
                .setDataSource(dsConfig)
                .setStrategy(stConfig)
                .setPackageInfo(pkConfig);


        //6. 执行操作
        ag.execute();
        System.out.println("======= Done 相关代码生成完毕  ========");
    }
}
  • 导入生成好的代码
    • model (为啥不放common项目,如果是确定每个服务都用到的依赖或者类才放到common项目)
    • mapper 类接口拷贝
    • resource/mapper文件夹 xml脚本拷贝
    • controller
    • service 不拷贝
第3集 遇到的坑-配置文件修改-yml转properties

简介: 配置文件修改-yml转properties

  • SpringBoot的配置文件有两种
    • 一种是properties结尾的
    • 一种是yaml或者yml文件结尾的
    • 如果同时存在properties和yml, application.properties里面的属性就会覆盖里application.yml的属性
  • yml的注意点
    • yml中缩进一定不能使用TAB,否则会报很奇怪的错误
    • yml每个的冒号后面一定都要加一个空格
    • 第一个是yml是支持中文内容的,properties想使用中文需要unicode编码
  • 账号服务配置转换
    • 在线转换工具:https://www.toyaml.com
server.port=8001
spring.application.name=dcloud-account


#----------服务注册和发现--------------
spring.cloud.nacos.discovery.server-addr=120.79.150.146:8848
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos


#-------redis连接配置-------
spring.redis.client-type=jedis
spring.redis.host=120.79.150.146
spring.redis.password=class.net
spring.redis.port=6379
spring.redis.jedis.pool.max-active=100
spring.redis.jedis.pool.max-idle=100
spring.redis.jedis.pool.min-idle=100
spring.redis.jedis.pool.max-wait=60000


#-------分库分表数据源配置-------
spring.shardingsphere.datasource.names=ds0
spring.shardingsphere.datasource.ds0.connectionTimeoutMilliseconds=30000
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.idleTimeoutMilliseconds=60000
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://120.79.150.146:3306/dcloud_account?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.maintenanceIntervalMilliseconds=30000
spring.shardingsphere.datasource.ds0.maxLifetimeMilliseconds=1800000
spring.shardingsphere.datasource.ds0.maxPoolSize=50
spring.shardingsphere.datasource.ds0.minPoolSize=50
spring.shardingsphere.datasource.ds0.password=class.net168
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.props.sql.show=true


# 指定traffic表的数据分布情况,配置数据节点,行表达式标识符使用 ${...} 或 $->{...},但前者与 Spring 本身的文件占位符冲突,所以在 Spring 环境中建议使用 $->{...}
spring.shardingsphere.sharding.tables.traffic.actual-data-nodes=ds0.traffic_$->{0..1}
#水平分表策略+行表达式分片
spring.shardingsphere.sharding.tables.traffic.table-strategy.inline.algorithm-expression=traffic_$->{ account_no % 2 }
spring.shardingsphere.sharding.tables.traffic.table-strategy.inline.sharding-column=account_no


#id生成策略
spring.shardingsphere.sharding.tables.traffic.key-generator.column=id
spring.shardingsphere.sharding.tables.traffic.key-generator.props.worker.id=${workId}
spring.shardingsphere.sharding.tables.traffic.key-generator.type=SNOWFLAKE


#----------sms短信配置--------------
sms.app-code=6999d4df3e7d48028470bbe517169a8d
sms.template-id=M72CB42894


#----------阿里云OSS配置--------------
aliyun.oss.endpoint=oss-cn-guangzhou.aliyuncs.com
aliyun.oss.access-key-id=LTAI5tHVGvYw7twoVFyruB1H
aliyun.oss.access-key-secret=r4d0EudzSvPfVMb9Zp0TfmsE32RXmN
aliyun.oss.bucketname=dcloud-link


  • 短链服务相关配置文件(复制账号微服务配置修改)
第4集 短链分组管理-CURD接口开发实战《上》

简介: 短链分组管理-CURD接口开发实战《上》

  • 配置登录拦截器
  • 新增接口
  • 删除接口
第5集 短链分组管理-CURD接口开发实战《下》

简介: 短链分组管理-CURD接口开发实战《下》

  • 查询详情
  • 查询用户全部分组
  • 更新分组接口
第6集 短链分组管理-水平分库分表配置实战《青铜玩法》

简介: 短链分组管理-水平分库分表配置实战

  • 需求
    • 未来2年,短链平台累计5百万用户
      • 短链组:一个用户30个组,就是1.5亿个组
      • 单表不超过1千万数据,需要分15张表
      • 进一步延伸,进行水平分库分表,比如 2库、4库、8库、16库
      • 一个库一张表
    • 需要降低单表数据量,进行水平分库分表
    • 分库数量:线上分16库,本地分2库即可
    • 分片key: account_no,查询维度都是根据account_no进行查询
    • 分片策略:行表达式分片策略 InlineShardingStrategy
  • 配置
#----------短链组,策略:水平分库,不水平分表--------------
# 先进行水平分库, 水平分库策略,行表达式分片
spring.shardingsphere.sharding.tables.link_group.database-strategy.inline.sharding-column=account_no
spring.shardingsphere.sharding.tables.link_group.database-strategy.inline.algorithm-expression=ds$->{account_no % 2}


第十七章 短链服务分库分表-如何做到扩容免数据迁移《黄金玩法》

第1集 短链服务-ShortLink分库分表解决方案讲解《青铜》

简介: 短链服务-ShortLink分库分表解决方案讲解

    • 数据量预估

      • 首年日活用户: 10万
      • 首年日新增短链数据:10万*50 = 500万
      • 年新增短链数:500万 * 365天 = 18.2亿
      • 往高的算就是100亿,支撑3年
    • 分库分表策略

      • 分库分表

        • 16个库, 每个库64个表,总量就是 1024个表
      • 分片键:短链码 code

        • 比如 g1.fit/92AEva 的短链码 92AEva
      • 分库分表算法:短链码进行hash取模

        ID = 短链码hash值 % 库数量  
        表ID = 短链码hash值 / 库数量  % 表数量
        
  • 优点

    • 保证数据较均匀的分散落在不同的库、表中,可以有效的避免热点数据集中问题,
    • 分库分表方式清晰易懂
  • 问题

    • 扩容不是很方便,需要数据迁移
    • 需要一次性建立16个库, 每个库64个表,总量就是 1024个表,浪费资源
第2集 短链服务-分库分表扩容免数据迁移解决方案讲解《黄金玩法》

简介: 短链服务-分库分表免迁移扩容解决方案讲解《黄金玩法》

  • 需要解决的问题

    • 数据量增加,扩容避免迁移数据或者免迁移

    • 前期数据量不多,不浪费库表系统资源

      • 分库分表:16个库, 每个库64个表,总量就是 1024个表
  • 短链码

    • 比如 g1.fit/92AEva 的短链码 92AEva
  • 如何做?

    • 从短链码入手-增加库表位
    • 类似案例-阿里这边商品订单号-里面也包括了库表信息

在这里插入图片描述

第3集 短链服务-分库分表相关库表建立

简介: 短链服务-分库分表相关库表建立

  • 为啥能做到免迁移扩容?

    • A92AEva1
    • 由于短链码的前缀和后缀是是固定的,所以扩容也不影响旧的数据
    • 类似的免迁移扩容策略还有哪些?
      • 时间范围分库分表
      • id范围分库分表
  • 三个库

  • 一个库两个表

  • properties配置多库表

spring.shardingsphere.datasource.names=ds0,ds1,dsa


#ds0配置
spring.shardingsphere.datasource.ds0.connectionTimeoutMilliseconds=30000
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.idleTimeoutMilliseconds=60000
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://120.79.150.146:3306/dcloud_link_0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.maintenanceIntervalMilliseconds=30000
spring.shardingsphere.datasource.ds0.maxLifetimeMilliseconds=1800000
spring.shardingsphere.datasource.ds0.maxPoolSize=50
spring.shardingsphere.datasource.ds0.minPoolSize=50
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=class.net168


#ds1配置
spring.shardingsphere.datasource.ds1.connectionTimeoutMilliseconds=30000
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.idleTimeoutMilliseconds=60000
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://120.79.150.146:3306/dcloud_link_1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.maintenanceIntervalMilliseconds=30000
spring.shardingsphere.datasource.ds1.maxLifetimeMilliseconds=1800000
spring.shardingsphere.datasource.ds1.maxPoolSize=50
spring.shardingsphere.datasource.ds1.minPoolSize=50
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=class.net168




#dsa配置
spring.shardingsphere.datasource.dsa.connectionTimeoutMilliseconds=30000
spring.shardingsphere.datasource.dsa.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.dsa.idleTimeoutMilliseconds=60000
spring.shardingsphere.datasource.dsa.jdbc-url=jdbc:mysql://120.79.150.146:3306/dcloud_link_a?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.dsa.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.dsa.maintenanceIntervalMilliseconds=30000
spring.shardingsphere.datasource.dsa.maxLifetimeMilliseconds=1800000
spring.shardingsphere.datasource.dsa.maxPoolSize=50
spring.shardingsphere.datasource.dsa.minPoolSize=50
spring.shardingsphere.datasource.dsa.username=root
spring.shardingsphere.datasource.dsa.password=class.net168
第4集 短链服务水平分库分表实战-标准分片策略-精准分片算法《上》

简介: 短链服务分库分表实战-标准分片策略-精准分片算法

  • 水平分库-标准分片策略-精准分片算法 Ae23asa1
public class CustomDBPreciseShardingAlgorithm implements PreciseShardingAlgorithm<String> {


    /**
     * @param availableTargetNames 数据源集合
     *                             在分库时值为所有分片库的集合 databaseNames
     *                             分表时为对应分片库中所有分片表的集合 tablesNames
     * @param shardingValue        分片属性,包括
     *                             logicTableName 为逻辑表,
     *                             columnName 分片健(字段),
     *                             value 为从 SQL 中解析出的分片健的值
     * @return
     */


    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {


        //获取短链码第一位,即库位
        String codePrefix = shardingValue.getValue().substring(0, 1);


        for (String targetName : availableTargetNames) {
            //获取库名的最后一位,真实配置的ds
            String targetNameSuffix = targetName.substring(targetName.length() - 1);


            //如果一致则返回
            if (codePrefix.equals(targetNameSuffix)) {
                return targetName;
            }
        }


        //抛异常
        throw new BizException(BizCodeEnum.DB_ROUTE_NOT_FOUND);


    }
}
  • 配置
#----------短链,策略:分库+分表--------------
# 先进行水平分库,然后再水平分表
spring.shardingsphere.sharding.tables.short_link.database-strategy.standard.sharding-column=code
spring.shardingsphere.sharding.tables.short_link.database-strategy.standard.precise-algorithm-class-name=net.class.strategy.CustomDBPreciseShardingAlgorithm
第5集 短链服务水平分库分表实战-标准分片策略-精准分片算法《下》

简介: 短链服务分库分表实战-标准分片策略-精准分片算法

  • 水平分表-标准分片策略-精准分片算法
public class CustomTablePreciseShardingAlgorithm implements PreciseShardingAlgorithm<String> {


    /**
     * @param availableTargetNames 数据源集合
     *                             在分库时值为所有分片库的集合 databaseNames
     *                             分表时为对应分片库中所有分片表的集合 tablesNames
     * @param shardingValue        分片属性,包括
     *                             logicTableName 为逻辑表,
     *                             columnName 分片健(字段),
     *                             value 为从 SQL 中解析出的分片健的值
     * @return
     */
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {




        //获取逻辑表名
        String targetName = availableTargetNames.iterator().next();


        String value = shardingValue.getValue();
        //短链码最后一位
        String codePrefix = value.substring(value.length()-1);
        //拼装actual table
        return targetName + "_" + codePrefix;


    }
}
  • 配置文件
# 水平分表策略,自定义策略。   真实库.逻辑表
spring.shardingsphere.sharding.tables.short_link.actual-data-nodes=ds0.short_link,ds1.short_link,dsa.short_link
spring.shardingsphere.sharding.tables.short_link.table-strategy.standard.sharding-column=code
spring.shardingsphere.sharding.tables.short_link.table-strategy.standard.precise-algorithm-class-name=net.class.strategy.CustomTablePreciseShardingAlgorithm


#id生成策略
spring.shardingsphere.sharding.tables.short_link.key-generator.column=id
spring.shardingsphere.sharding.tables.short_link.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.short_link.key-generator.props.worker.id=${workerId}


第6集 短链服务-短链码配置生成库表位实战

简介: 短链服务-短链码配置生成库表位实战

  • 分库位
public class ShardingDBConfig {


    /**
     * 存储数据库位置编号
     */
    private static final List<String> dbPrefixList = new ArrayList<>();


    private static Random random = new Random();


    //配置启用那些库的前缀
    static {
        dbPrefixList.add("0");
        dbPrefixList.add("1");
        dbPrefixList.add("a");
    }




    /**
     * 获取随机的前缀
     * @return
     */
    public static String getRandomDBPrefix(){
        int index = random.nextInt(dbPrefixList.size());
        return dbPrefixList.get(index);
    }






}
  • 分表位
public class ShardingTableConfig {


    /**
     * 存储数据表位置编号
     */
    private static final List<String> tableSuffixList = new ArrayList<>();


    private static Random random = new Random();


    //配置启用那些表的后缀
    static {
        tableSuffixList.add("0");
        tableSuffixList.add("a");
    }




    /**
     * 获取随机的后缀
     * @return
     */
    public static String getRandomTableSuffix(){
        int index = random.nextInt(tableSuffixList.size());
        return tableSuffixList.get(index);
    }






}
  • 短链码配置
String code = ShardingDBConfig.getRandomDBPrefix() + shortLinkCode + ShardingTableConfig.getRandomTablePrefix();


第7集 短链服务-Manager层模块CRUD开发

简介: 短链服务-Manager层模块CRUD开发

  • 代码
public interface ShortLinkManager {




    /**
     * 新增域名
     *
     * @param shortLinkDO
     * @return
     */
    int addShortLink(ShortLinkDO shortLinkDO);




    /**
     * 根据短链码找内容
     *
     * @param shortLinkCode
     * @return
     */
    ShortLinkDO findByShortLinkCode(String shortLinkCode);




    /**
     * 根据短链码和accountNo删除
     *
     * @param shortLinkCode
     * @param accountNo
     * @return
     */
    int del(String shortLinkCode, Long accountNo);




}




@Component
@Slf4j
public class ShortLinkManagerImpl implements ShortLinkManager {


    @Autowired
    private ShortLinkMapper shortLinkMapper;


    @Override
    public int addShortLink(ShortLinkDO shortLinkDO) {
        return shortLinkMapper.insert(shortLinkDO);
    }


    @Override
    public ShortLinkDO findByShortLinkCode(String shortLinkCode) {
        ShortLinkDO shortLinkDO = shortLinkMapper.selectOne(new QueryWrapper<ShortLinkDO>().eq("code", shortLinkCode).eq("del", 0));
        return shortLinkDO;
    }


    /**
     * 逻辑删除
     *
     * @param shortLinkCode
     * @param accountNo
     * @return
     */
    @Override
    public int del(String shortLinkCode, Long accountNo) {
        ShortLinkDO shortLinkDO = new ShortLinkDO();
        shortLinkDO.setDel(1);
        int rows = shortLinkMapper.update(shortLinkDO, new QueryWrapper<ShortLinkDO>()
                .eq("code", shortLinkCode).eq("account_no", accountNo));


        return rows;
    }




}
第8集 短链服务-自定义分库分表策略单元测试实战

简介: 短链服务-自定义分库分表策略单元测试实战

  • 单元测试

    • 保存
     @Autowired
        private ShortLinkManager shortLinkManager;
        /**
         * 保存
         */
        @Test
        public void testSaveShortLink() {
    
    
            Random random = new Random();
            //for (int i = 0; i < 10; i++) {
                int num1 = random.nextInt(10);
                int num2 = random.nextInt(10000000);
                int num3 = random.nextInt(10000000);
                String originalUrl = num1 + "class" + num2 + ".net" + num3;
                String shortLinkCode = shortLinkComponent.createShortLinkCode(originalUrl);
                ShortLinkDO shortLinkDO = new ShortLinkDO();
                shortLinkDO.setCode(shortLinkCode);
                shortLinkDO.setAccountNo(Long.valueOf(num3));
                shortLinkDO.setSign(originalUrl);
                shortLinkDO.setDel(0);
                shortLinkManager.addShortLink(shortLinkDO);
            //}
    
    
        }
    
    • 查找
    @Test
    public void testFind() {
    
    
      ShortLinkDO shortLinkDO = shortLinkManager.findByShortLinkCode("03aAg0la");
      log.info(shortLinkDO.toString());
    
    
    }
    
第9集 加权负载均衡思想应用-数据库表扩容-数据不均匀问题解决方案

简介: 加权负载均衡思想应用-数据库表扩容-数据不均匀问题解决方案

  • 问题
    • 假如前期分三个库,一个库两个表,项目火爆,数据量激增,进行扩容
    • 增加了新的数据库表位,会导致旧的库表比新的库表数据量多,且容易出现超载情况

在这里插入图片描述

Nginx加权负载均衡的应用

  • 不同的库表位分配的概率不一样,类似的中间件应用场景有nginx

  • Nginx常见的负载均衡策略

    • 节点轮询(默认)

    • weight 权重配置

      • 简介:weight和访问比率成正比,数字越大,分配得到的流量越高
      • 场景:服务器性能差异大的情况使用
      upstream lbs {
              server 192.168.159.133:8080 weight=5;
              server 192.168.159.133:8081 weight=10;
      }
      

在这里插入图片描述

  • 加权解决方式(作业)

    • 库表位可以使用对象形式,配置权重,避免数据倾斜、数据集中
    • 编写算法,根据不同的,配置权重,不同的库表位配置不同的权重
    • 加权配置,list重复添加出现的高频的库表位
  • 是不是可以把这个亮点记录下

    • 你想到的解决方案,方便又清晰,还省服务器资源和避免了问题
      • 业务量超过评估量,分库分表-二次扩容的时候避免数据迁移
      • 不用一次性建立很多个库表,可以动态添加,节省服务器资源
      • 使用加权库表位算法,解决扩容后数据倾斜不均匀问题
        kDO = shortLinkManager.findByShortLinkCode(“03aAg0la”);
        log.info(shortLinkDO.toString());

    }

    
    
第9集 加权负载均衡思想应用-数据库表扩容-数据不均匀问题解决方案

简介: 加权负载均衡思想应用-数据库表扩容-数据不均匀问题解决方案

  • 问题
    • 假如前期分三个库,一个库两个表,项目火爆,数据量激增,进行扩容
    • 增加了新的数据库表位,会导致旧的库表比新的库表数据量多,且容易出现超载情况

[外链图片转存中…(img-rjjMnBdI-1722993581899)]

Nginx加权负载均衡的应用

  • 不同的库表位分配的概率不一样,类似的中间件应用场景有nginx

  • Nginx常见的负载均衡策略

    • 节点轮询(默认)

    • weight 权重配置

      • 简介:weight和访问比率成正比,数字越大,分配得到的流量越高
      • 场景:服务器性能差异大的情况使用
      upstream lbs {
              server 192.168.159.133:8080 weight=5;
              server 192.168.159.133:8081 weight=10;
      }
      

[外链图片转存中…(img-XmNbwxWe-1722993581899)]

  • 加权解决方式(作业)

    • 库表位可以使用对象形式,配置权重,避免数据倾斜、数据集中
    • 编写算法,根据不同的,配置权重,不同的库表位配置不同的权重
    • 加权配置,list重复添加出现的高频的库表位
  • 是不是可以把这个亮点记录下

    • 你想到的解决方案,方便又清晰,还省服务器资源和避免了问题
      • 业务量超过评估量,分库分表-二次扩容的时候避免数据迁移
      • 不用一次性建立很多个库表,可以动态添加,节省服务器资源
      • 使用加权库表位算法,解决扩容后数据倾斜不均匀问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从零开始学习人工智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值