Appearance
幂等性
一锁、二判、三更新
一锁:第一步,先加锁(请求一个唯一ID过来)。可以加分布式锁、或者悲观锁都可以。但是一定要是一个互斥锁!
二判:第二步,进行幂等性判断。可以基于状态机、流水表、唯一性索引等等进行重复操作的判断。
三更新:第三步,进行数据的更新,将数据进行持久化。
秒杀
- 静态缓存
- nginx 负载均衡
三种方式:DNS轮询、IP负债均衡、CDN - 限流机制 方式:ip限流、接口令牌限流、用户限流、header动态token(前端加密,后端解密)
- 分布式锁 方式: 1. setnx + expire (非原子性,redis2.6 之后set保证原子性) 2. 释放锁超时 (开启守护进程自动续时间) 3. 过期锁误删其他线程(requestId验证或者lua脚本保证查 + 删的原子性)
- 缓存数据 方式: 1. 缓存击穿:缓存数据预热 + 布隆过滤器/空缓存 2. 缓存雪崩:缓存设置随机过期时间,防止同一时间过期
- 库存及订单
- 扣库存
- redis 自减库存,并发场景下可能导致负数,影响库存回仓:使用lua脚本保证原子性
- redis预扣库存之后,然后使用异步消息创建订单并更新库存变动
- 数据库更新库存使用乐观锁:where stock_num - sell_num > 0
- 添加消息发送记录表及重试机制,防止异步消息丢失
- 创建订单
- 前端建立websocket连接或者轮询监听订单状态
- 消费验证记录状态,防止重复消费
- 回仓
- 创建订单之后发送延时消息,验证订单支付状态及库存是否需要回仓
- 扣库存
秒杀,需要支持 100W 以上 QPS
CDN边缘计算扛前端静态页面流量,设定概率,一部分用户请求直接被前端js脚本拒绝,不发请求直接显示秒杀结束。lvs keepalive nginx集群负载均衡流量到网关集群,网关鉴权,令牌桶限流,流量一致性哈希进入redis多副本分片集群,库存拆分给redis各个节点去抢,decr命令或lua脚本原子性扣减库存,抢了之后发送消息到RocketMQ集群,返回提示订单创建中,消费者集群异步写入订单到PolarDB集群,消费成功后告知用户成功
设计微博首页,需要拉取所有关注用户的最近 20 条微博
抢红包算法设计
php
<?php
/**
* @param $totalMoney float 总金额:元
* @param $num int 红包数量
* @return array 红包列表
*/
function createRedPack(float $totalMoney,int $num)
{
//剩余的 ,单位 分
$hasMoney = $totalMoney * 100;
//一分钱
$min = 1;
$res = [];
for ($i = 1;$i <= $num;$i++)
{
if ($i != $num)
{ //剩余的钱-($num-$i)
$max = $hasMoney - ($num - $i) * $min;
// 防止每个金额差距过大
if (intval($hasMoney/($num - $i)) > 0)
{
$max = min($max,intval($hasMoney/($num - $i)));
}
$money = random_int($min,$max);
}else
{
$money = $hasMoney;
}
$hasMoney -= $money;
$res[] = $money/100;
}
//打乱
shuffle($res);
return $res;
}
$arr = createRedPack(200,10);
echo '红包结果:'.json_encode($arr).PHP_EOL;
echo '共:'.count($arr).'个'.PHP_EOL;
echo '共:'.array_sum($arr).'元'.PHP_EOL;
"输出:
红包结果:[1.37,6.63,21.67,9.4,14.49,98.55,5.44,2.93,28.64,10.88]
共:10个
共:200元
";设计一个短链系统
插入数据库,或的id(或发号器?)然后对id进行加密,就的到 x.com/jiami(1) = x.com/aaaaa
接口设计
鉴权部分设计
防超卖
乐观锁
悲观锁
Redis分布式锁
Saas项目架构设计
每个表都要分配商户id?
单点,单用户
单点:SSO,输入账号密码,登录成功 ,重定向的url加上token和code等参数,新url对code和token判断并哪这两个参数去获取(curl发起请求)用户信息,获取后user保存在session里 单用户:保存一登陆的sid,另一个登录的话就将这个sid对应的session销毁
如何设计一个支持十几条业务线的短信发送服务,想到方面越多越好,幂等防重发,防超时,安全,权限验证,成功率,异步,等等情况
商城相关
购物车?
1.购物车只需要保存 sku_id ,数量和时间,查询的时候再反查; 2.未登录的用户,购物车数据就存储在客户端,cookie或localStorage,登录了再同步过去; 3.用redis的hash存储;
搜索?
订单号如何不重复?
1.Snowflake等唯一id算法; 2.订单号由多个参数组成,例如时间戳、商户编号、订单类型、商品类型等,通过组合不同的参数,生成不同的订单号。
支付幂等性?
如何通知用户付款成功
第三方支付回调失败,怎么办?
支付接口防刷和加密?
秒杀?
库存不超卖?
如何取消订单?
给一个文件,一行内容:uri、response_time、code 统计 qps 最大的 uri 使用 Linux 命令统计、后来改用PHP统计
awk '{if ($3 == 200) print $1}' your_file.log | sort | uniq -c | sort -nr | head -n 1
使用awk命令提取文件中的uri列和code列。
使用grep命令筛选出状态码为200的行。
使用sort命令按照uri进行排序。
使用uniq -c命令统计每个uri出现的次数。
使用sort -nr命令按照出现次数降序排序。
使用head命令获取出现次数最多的uri。
提取文件中状态码为200的uri列,按照uri进行排序并统计每个uri的出现次数,然后按照出现次数降序排序,并输出出现次数最多的uri及其出现次数。<?php
$file = 'your_file.log';
$uriCount = [];
$handle = fopen($file, "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
$parts = explode(" ", $line);
if (count($parts) >= 3 && $parts[2] == 200) {
$uri = $parts[0];
if (!isset($uriCount[$uri])) {
$uriCount[$uri] = 0;
}
$uriCount[$uri]++;
}
}
fclose($handle);
// Sort uriCount array by value in descending order
arsort($uriCount);
// Get the first element of the sorted array
$maxUri = key($uriCount);
$maxCount = current($uriCount);
echo "Max QPS URI: $maxUri, QPS: $maxCount\n";
} else {
echo "Failed to open file $file\n";
}
?>给你一个亿大小的文件,文件里包含 IP,设计能快速查询是否存在 IP
红包雨
40亿条个数字,限制1G内存,如何去重,如何找出来?
用bitmap,8bit=1byte;
40bit = 4000000000/8/1024/1024 = 479M;
思路都差不多;不够就用磁盘存来查找;
导出很多行EXCEL
excel2003最大行数65536;Excel 2007开始1048576;
前端导出,分页获取数据合并到excel表中;
注意excel的最大值,限制条件导出,或分成几个表 用扩展php-xlswrite;