仅供自学回顾使用,请支持javaGuide原版。
1.一码付(微信/支付宝二维码付款)
二维码的本质是一个字符串。
实现原理是当客户用 APP 扫码后,网站后台就会判断客户的扫码环境。(微信、支付宝、QQ 钱包、京东支付、云闪付等)。
判断扫码环境的原理就是根据打开链接浏览器的 HTTP header。任何浏览器打开 http 链接时,请求的 header 都会有 User-Agent(UA、用户代理)信息。
UA 是一个特殊字符串头,服务器依次可以识别出客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等很多信息。
各渠道对应支付产品的名称不一。
- 微信支付:JSAPI 支付支付
- 支付宝:手机网站支付
- QQ 钱包:公众号支付
其本质均为在 APP 内置浏览器中实现 HTML5 支付。
2.订单号
从技术角度看,除了 ID 服务必要的特性之外,在订单号的设计上需要体现几个特性:
-
信息安全
- 不能透露公司的运营情况,比如日销、公司流水号等信息。
- 不能透露用户手机号,身份证等隐私信息。
- 不能有明显的整体规律(可以有局部规律),任意修改一个字符就能查询到另一个订单信息,这也是不允许的。
类比于我们高考时候的考生编号的生成规则,一定不能是连号的,否则只需要根据顺序往下查询就能搜索到别的考生的成绩,这是绝对不可允许。
-
部分可读
- 过长的订单号或易读性差的订单号会导致输入困难且易错率较高。
- 因此订单号的设计通常都会适当携带一些允许公开的对使用场景有帮助的信息,如时间,星期,类型等等。
-
查询效率
- 常见的电商平台订单号大多是纯数字组成,兼具可读性的同时,int 类型相对 varchar 类型的查询效率更高,对在线业务更加友好。
3.优惠券/兑换券
优惠券/兑换券一般分为两种场景。
- 一种是临时的生成,譬如比如电商平台购物领取的优惠券,只需要在用户领取时分配优惠券信息即可。
- 一种是预先生成,譬如在活动正式开始前提供出来进行活动预热。
对于预先生成的优惠券,一般存在以下特性:
- 优惠券体量大,以万为单位,通常在 10 万级别以上;
- 不可破解、仿制券码;
- 支持用后核销;
- 优惠券、兑换券属于广撒网的策略,所以利用率低,也就不适合使用数据库进行存储 (占空间,有效的数据又少)。
所以一般优惠券的生成策略如下:
活动场次 ID + 兑换码序列号 i + 校验码
深耕业务还会有区分通用券和单独券的情况,分别具备以下特点,技术实现需要因地制宜地思考。
- 通用券:多个玩家都可以输入兑换,然后有总量限制,期限限制。
- 单独券:运营同学可以在后台设置兑换码的奖励物品、期限、个数,然后由后台生成兑换码的列表,兑换之后核销。
4.日志跟踪(分布式链路跟踪)
处理一个 Web 请求要调用的多个服务,为了能更方便的查询哪个环节的服务出现了问题,现在常用的解决方案是为整个系统引入分布式链路跟踪。
在分布式链路跟踪中有两个重要的概念:跟踪(trace)和 跨度( span)。
trace 是请求在分布式系统中的整个链路视图,span 则代表整个链路中不同服务内部的视图,span 组合在一起就是整个 trace 的视图。
在整个请求的调用链中,请求会一直携带 traceid 往下游服务传递,每个服务内部也会生成自己的 spanid 用于生成自己的内部调用视图,并和 traceid 一起传递给下游服务。
这种场景下,生成的 ID 除了要求唯一之外,还要求生成的效率高、吞吐量大。需要接入层的服务器实例最好可以自行计算 tracid,spanid,避免依赖外部服务。
假设一个 服务器实例 A 接收了一次用户请求,代表是整个调用的根节点,那么 A 层处理这次请求产生的非服务调用日志记录 spanid 的值都是 0。
A 层需要通过 RPC 依次调用 B、C、D 三个服务器实例,那么在 A 的日志中,SpanId 分别是 0.1,0.2 和 0.3,在 B、C、D 中,SpanId 也分别是 0.1,0.2 和 0.3;
如果 C 系统在处理请求的时候又调用了 E,F 两个服务器实例,那么 C 系统中对应的 spanid 是 0.2.1 和 0.2.2,E、F 两个系统对应的日志也是 0.2.1 和 0.2.2。
以上都属于一次完整的调用链路,所以每个节点(无论是A还是B还是F)的traceId都是相同的oa1234
4.1.traceId生成规则
产生规则:服务器 IP + ID 产生的时间 + 自增序列 + 当前进程号 。
比如:0ad1348f1403169275002100356696
前 8 位 0ad1348f
即产生 TraceId 的机器的 IP,这是一个十六进制的数字,每两位代表 IP 中的一段,我们把这个数字,按每两位转成 10 进制即可得到常见的 IP 地址表示方式 10.209.52.143
后面的 13 位 1403169275002
是产生 TraceId 的时间。
之后的 4 位 1003
是一个自增的序列,从 1000 涨到 9000,到达 9000 后回到 1000 再开始往上涨。
最后的 5 位 56696
是当前的进程 ID,为了防止单机多进程出现 TraceId 冲突的情况,所以在 TraceId 末尾添加了当前的进程 ID。
4.2.spanId生成规则
span 是层的意思,比如在第一个实例算是第一层, 请求代理或者分流到下一个实例处理,就是第二层,以此类推。通过层,SpanId 代表本次调用在整个调用链路树中的位置。
如果把一次调用中所有的 SpanId 收集起来,可以组成一棵完整的链路树。
spanid 的生成本质:在跨层传递透传的同时,控制大小版本号的自增来实现的。