首页 > 其他分享 >短链微服务

短链微服务

时间:2023-01-15 15:11:33浏览次数:61  
标签:分库 服务 62 分表 短链 id 冗余

短链应用场景

  • 业务背景:为啥需要短链
    • 公司电商产品推广、业务活动页、广告落地页 缺少实时【数据反馈和渠道效果分析】
    • 老项目业务推广【没人维护,无法做埋点】需要统计效果
    • APP和营销活动发送营销短信链接过长,【浪费短信发送费用】
    • 国内【反垄断后】微信、抖音、淘宝 流量互通,很多知识付费公司需要做 私域流量、社群运营
    • 可以对外做产品输出,实现商业化能力增加公司营收
    • 积累终端数据和人群数据,为公司未来产品人群做策略助力
  • 短链组成

    • 协议://短链域名/短链码
  • 最简单的方式

    • 一个短链编码,去数据库select * from table where code =XXX,返回给用户就行

微服务功能

生命周期

image-20230115133810171

接口

创建者(UI图大体类似哈)

  • 流量包管理
    • 免费流量包
    • 付费流量包

image-20230115133844487

分组管理

  • 新增分组
  • 删除分组
  • 修改分组
  • 查看分组下的短链

分组作用,例如:同一个链接需要生成多端的短链,抖音、快手、B站三个平台作为分组,后期埋点数据可以用来分析引流收益

image-20230115133856480

短链管理

  • 创建短链

    • 目标地址
    • 短链标题
    • 短链域名
    • 所属分组
    • 有效期

image-20230115133917672

  • 删除短链

  • 修改短链

  • 查看短链

    • 访问PV、UV
    • 地域分布
    • 时间分布
    • 来源分布

访问者

  • 访问短链
  • 跳转目标站点

短链服务问题解决方案

长链的关系和短链的关系是一对一还是一对多?

  • 一个长链,在不同情况下,生成的短网址应该不一样,才不会造成冲突
  • 多渠道推广下,也可以区分统计不同渠道的效果质量
  • 所以是 一个短链接只能对应一个长链接,当然一个长链接可以对应多个短链接

前端访问短链是如何跳转到对应的页面的?

  • 服务端转发

    • 由服务器端进行的页面跳转,刚学Servlet时, 从OneServlet中转发到TwoServlet
    • 地址栏不发生变化,显示的是上一个页面的地址
    • 请求次数:只有1次请求
    • 转发只能在同一个应用的组件之间进行,不可以转发给其他应用的地址
     request.getRequestDispatcher("/two").forward(request, response); 
    

    image-20211203113753524

  • 页面的跳转-重定向

    • 由浏览器端进行的页面跳转

    image-20211203114328117

    • 重定向涉及到3xx状态码,访问跳转是301还是302,301和302代表啥意思?
      • 301 是永久重定向
        • 会被浏览器硬缓存,第一次会经过短链服务,后续再访问直接从浏览器缓存中获取目标地址
      • 302 是临时重定向
        • 不会被浏览器硬缓存,每次都是会访问短链服务
      • 短地址一经生成就不会变化,所以用 301 是同时对服务器压力也会有一定减少
      • 但是如果使用了 301,无法统计到短地址被点击的次数
      • 所以选择302虽然会增加服务器压力,但是有很多数据可以获取进行分析
      • 选择使用302,这个也可以对违规推广的链接进行实时封禁

短链码如何是如何生成的

  • 短链码特点
    • 生成性能强劲
    • 碰撞概率低
      • 避免重复
      • 恶意猜测
    • 业务规则安全

image-20211203145018603

  • 方式

    • 自增ID

      • 利用插入数据库,利用数据库自增id
      • 把自增id转成62进制作为短链码
      • 短链码的长度不固定,随着 id 变大,短链码长度也增长
      • 可以指定从某个长度开始增长,到百亿、千亿数量
      • 转换工具:https://tool.lu/hexconvert/
      • 是否存在重复: 不重复
      • 但短链码是有序的递增,存在【业务数据安全】问题
    • MD5内容压缩

      • 长链接做md5加密
      43E08496,9E5CF455,E6D2D2B3,3407A6D2
      
      • 加密串查询是否已经生成过短链接
        • 如果已经存在,则拼接时间戳再MD5加密,插入数据库
        • 如果不存在则把长链接、长链接加密串插入数据库
      • 取MD5后 最后1 个 8 位字符串作为短链码
      • 是否存在重复: 存在碰撞(重复)可能
      • 是有损压缩算法,数据量超大情况碰撞概念越大
        • 比如 【小滴课堂-老王的女友】有300多个,每再多1个,再同一天生日的概率越大,就更加复杂

数据脱敏解决方案

  • 什么是数据脱敏
    • 也叫数据的去隐私化,在给定脱敏规则和策略的情况下,对敏感数据比如 手机号身份证 等信息,进行转换或者修改的一种技术手段,防止敏感数据直接在不可靠的环境下使用和泄露、撞库等

    • 技术分两类

      • 静态数据脱敏
        • 将生产数据导出,进行对外发送或者给开发、测试人员等
      • 动态数据脱敏
        • 程序直接连接生产数据的场景,如运维人员在运维的工作中直接连接生产数据库进行运维
        • 客服人员在生产中通过后台查询的个人信息

MurMurHash

Murmur哈希是一种非加密散列函数,适用于一般的基于散列的查找。
它在2008年由Austin Appleby创建,在Github上托管,名为“SMHasher” 的测试套件。 
它也存在许多变种,所有这些变种都已经被公开。 
该名称来自两个基本操作,乘法(MU)和旋转(R)--来自百科
  • 是一种【非加密型】哈希函数且【随机分布】特征表现更良好

  • 由于是非加密的哈希函数,性能会比MD5强

  • 再很多地方都用到比如Guava、Jedis、HBase、Lucence等

  • 存在两个版本

    • MurmurHash2(产生32位或64位值)
    • MurmurHash3(产生32位或128位值)
  • 数据量

    • MurmurHash的 32 bit 能表示的最大值近 43 亿的10进制

      • 满足多数业务,如果接近43亿则冲突概率大
    • 产品目标【超理想情况】

    首年日活用户: 10万
    
    首年日新增短链数据:10万*50 = 500万
    
    年新增短链数:500万 * 365天 = 18.2亿 
    
    年新增用户数:50万/1年
    
    年营收目标: 10万付费用户 * 客单价200元 = 2千万
    
    新增短链:50条/用户每日
    
    • MurMurHash得到的数值是10进制,一般会转化为62进制进行缩短

    • 常规短链码是6~8位数字+大小写字母组合

    0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
    
    6 位 62 进制数可表示 568 亿个短链(62的6次方,每位都有62个可能,如果扩大位数到7位,则可以支持3万5200亿)
    
    • MurmurHash的 32 bit 满足多数业务 43亿
      • 拼接上库-表位则可以表示更多数据(后续会讲分库分表的,库表位)
      • 7位则可以到到 43亿 * 62 = 2666亿
      • 8位则可以到到 2666亿 * 62 = 1.65万亿条数据
      • 结合短链过期数据归档,理论上满足未来全部需求了
    • 数据库存储
      • 单表1千万 * 62个库 * 62表 = 384亿数据

分库分表配置

分组管理-水平分库分表配置

  • 需求

    • 未来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}

分库分表免迁移扩容方案-库码编码

  • 需要解决的问题

    • 数据量增加,扩容避免迁移数据或者免迁移
    • 前期数据量不多,不浪费库表系统资源
      • 分库分表:16个库, 每个库64个表,总量就是 1024个表
  • 短链码

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

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

image-20211210155218497

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

分片策略加权负载均衡

冗余双写架构

问题:商家怎么看自己的全部短链

* 普通用户根据短链码可以路由到对应的库表
* 但是商家创建的短链码都是没规律,分布再不同的库表上
  • 不同维度查看数据,场景是不一样的,

    • 主要是分:有PartitionKey,没PartitionKey两个场景

      • 电商订单案例一:
        • 订单表 的partionKey是user_id,用户查看自己的订 单列表方便
        • 但商家查看自己店铺的订单列表就麻烦,分布在不同数据节点

      image-20211212152029514

      • 短链访问案例
        • 普通用户访问短链,根据短链码code可以解析到对应的库表
        • 但短链商家,查看自己全部的短链就麻烦了,分布再不同的库下面
image-20211212170650207
  • 这个是【 通用的业务场景痛点 】
    • 除了上面的电商业务、短链业务,还有更多
    • 招聘网站业务
      • 企业查看自己某个岗位的面试记录
      • 应聘者查看自己的全部面试记录
      • 痛点:
        • 根据user_id进行hash分库分表
        • 但是企业的岗位存在不同user_id进行面试

分库分表多维度查询解决方案

方案一【字段解析配置】

  • 分库分表后的查询问题

    • 有PartitionKey,没PartitionKey两个场景
    • 不同维度查询是不一样的,怎么解决?
    • 解决方案

      • 字段解析配置

      • NOSQL冗余

      • 本身库表冗余双写方案

        • 部分字段冗余
        • 全量内容冗余
  • 解决方式一(字段解析配置):

    • 建一个表,存储account_no对应的库表位,商家生成的【短链码】固定前缀或者后缀
    • 即【短链码】里面包括了商家的信息

image-20211212174022539

方案二【NOSQL方案】

  • 分库分表后的查询问题

    • 有PartitionKey,没PartitionKey两个场景
    • 不同维度查询是不一样的,怎么解决?
    • 解决方案
      • 字段解析配置
      • NOSQL冗余
      • 本身库表冗余双写方案
        • 部分字段冗余
        • 全量内容冗余
  • 解决方式二:

    • 电商订单案例
      • 订单表 的partionKey是user_id,用户查看自己的订单列表方便
      • 但商家查看自己店铺的订单列表就麻烦,分布在不同数据节点
        • 订单冗余存储在es上一份
        • 业务架构流程

    image-20211212175450861

    • 短链平台案例
      • 短链表的partionKey是短链码,用户访问短码方便解析
      • 但商家查看自己某个分组下全部短链列表就麻烦,分布在不同数据节点
        • 短链码冗余存储在es上一份
        • 业务架构流程

image-20211212180211424

方案三【冗余双写方案】

  • 分库分表后的查询问题

    • 有PartitionKey,没PartitionKey两个场景
    • 不同维度查询是不一样的,怎么解决?
  • 解决方式三:

    • 电商场景
      • b2b平台,比如淘宝、京东,买家和卖家都要能够看到自己的订单列表
      • 无论是按照买家id切分订单表,还是按照卖家id切分订单表都没法满足要求
      • 拆分买家库和卖家库
        • 买家库,按照用户的id来分库分表
        • 卖家库,按照卖家的id来分库分表
      • 数据冗余
        • 下订单的时候写两份数据
        • 在买家库和卖家库各写一份

    image-20211213131242530

    • 短链场景

    image-20211213130611913

冗余双写分布式事务问题解决

  • 方案一
    • 直接RPC调用+Seata分布式事务框架
    • 优点:强一致性,代码逻辑简单,业务侵入性小
    • 缺点:性能下降,seata本身存在一定的性能损耗
      • Seata支持AT、TCC、Saga 三种模式
        • AT:隔离性好和低改造成本, 但性能低
        • TCC:性能和隔离性,但改造成本大
        • Saga:性能和低改造成本,但隔离性不好

image-20211213133145677

  • 方案二(选用)
    • 使用MQ, 生产者确认消息发送成功后,不同的消费者订阅消息消费
      • 同时保证消息处理的幂等性
      • 保证Broker的高可用
    • 优点
      • 实现简单,改造成本小
      • 性能高,没有全局锁
    • 缺点
      • 弱一致性,需要强一致性的场景不适用
      • 消费者消费失败,需要额外写接口回滚生产者业务逻辑

image-20211213161903711

标签:分库,服务,62,分表,短链,id,冗余
From: https://www.cnblogs.com/youngleesin/p/17053515.html

相关文章

  • 服务调用OpenFeign
    1、介绍①什么是OpenFeignOpenFeign是在Feign的基础上进行了加强使用在Client-Consuemr(消费者客户端)Fiegn是一个声明式的Web服务客户端,让编写Web服务客户端非常容易,只......
  • 【oracle】ORA-12541: TNS: 无监听程序——监听日志太大/任务管理器服务里停监听删日
    可能性1:原因:监听日志的达到4g解决办法: 停监听,删日志,重启监听 ......
  • 48、商品服务---品牌管理---JSON格式化工具
    https://www.bejson.com/可以直接将我们的json数据生成对应的Java实体类,不用我们手写了......
  • 服务器租用价格抉择哪些合适免备案
    服务器租用的费用,一般是由以下几个不同的方面决定的:1.服务器的配置,服务器的配置是决定租用价格的主要因素。品牌不同、配置不一样的服务器的性能差距是非常大的,所以价......
  • (11)go-micro微服务雪花算法
    目录一雪花算法介绍二雪花算法优缺点三雪花算法实现四最后一雪花算法介绍雪花算法是推特开源的分布式ID生成算法,用于在不同的机器上生成唯一的ID的算法。该算法生......
  • 用Jersey构建RESTful服务5--Jersey+MySQL5.6+Hibernate4.3
    一、总体说明本例运行演示了用Jersey构建RESTful服务中,如何同过Hibernate将数据持久化进MySQL的过程二、环境1.上文的项目RestDemo2.MySQL5.6下载​​http://dev.mysql.com/......
  • Ribbon服务调用+负载均衡(入门)
    1、RibbonRibbon中文:(用于捆绑或装饰的)带子;丝带;带状物;主要功能是提供客户端的软件负载均衡算法和服务调用Ribbon已经进入了维护模式了,但是Ribbon仍然被广泛使用中......
  • Feign服务调用
    Feign服务调用☞​​博客导航​​,​​带你有序的阅读和学习!​​文章目录​​Feign服务调用​​​​服务提供方​​​​Controller​​​​服务消费方​​​​依赖​​​​......
  • Redis 高可用: twemproxy实现缓存服务器分片集群
    Twemproxy又称nutcracker,是一个memcache、redis协议的轻量级代理,一个用于sharding的中间件。有了Twemproxy,客户端不直接访问Redis服务器,而是通过twemproxy代理中间件......
  • 在Linxu云服务器中创建Java版MC服务器
    前言因为学校的课程里有华为云的Linux课程,课程发放有2佰代金券用于开启云服务器,现在课程基本结束了,代金券还剩一百五十多,之前已经试过和舍友开过MC服务器,那趁现在结课的时......