消息队列
1.异步处理场景
用户在注册成功后,需要给用户发送注册短信和手机验证码进行告知。
问题:三个动作是并发执行的
解决方案:用户注册成功后直接写入数据库,发送短信和发送验证码写入消息队列
用户注册成功此方法做异步处理,当写入数据库后,消息队列执行另外两个动作(因为redis的写入和读取是非常快的,可以忽略这个时间)
2.解耦sku场景
最常见的就是订单和sku这块,订单和库存的解耦
问题:订单下单的同时,减少相应库存,库存改变不及时,导致超卖问题
解决:下单直接进数据库,因为订单是持久化的问题,订单记录只允许生成修改,下单就要入库。redis这边拉/推拿到订单那边的下单情况,库存这边进行相应的改变。下单库存这是一体的,我们分开的话,一环出问题不会导致另一环也出问题,再就是redis速度是非常快的,能及时的响应下单那边的商品数量,库存这边及时更改。
3.秒杀场景
问题:一瞬间订单数量特别大单靠mysql是吃不下的
解决:所有的订单先进redis,不管进的速度是什么样的,出的速度是一致的,因为redis是操作原子的。进来的都按照同样的速度一个一个出
最基本的代码:
1.php
<?php
$redis = new Redis();
//连接redis服务器
$redis->connect('127.0.0.1', 6379);
// echo "Connection to server sucessfully <br/>";
$msg = array('1','2','3','4','5','6');
//将数据一个一个写入
foreach ($msg as $key => $value)
{
# code...
$redis->rpush('mylist',$value);
}
2.php
<?php
$redis = new Redis();
//连接redis服务器
$redis->connect('127.0.0.1', 6379);
// echo "Connection to server sucessfully <br/>";
$value = $redis->lpop('mylist');
// var_dump($value);
// exit;
if($value)
{
echo "出队值".$value;
}
else
{
echo "出队完成";
}
可以借助 redis desktop manager工具,redis的安装https://blog.csdn.net/qq_31164125/article/details/103704180
redis desktop manager使用,下载安装就不说了
先进到redis的目录,找到
redis.windows.conf文件
requirepass foobared Sky!123
打开注释,后面写上密码,然后连接,name随便写,host:127.0.0.1,端口:6379,密码:自己设置的我这里是(Sky!123)
PHP+redis实现共同好友
1.php
<?php
$redis = new Redis();
//连接redis服务器
$redis->connect('127.0.0.1', 6379);
// echo "Connection to server sucessfully <br/>";
// 每执行一次,实现一个粉丝关注一个用户,执行多次录入数据
if(!empty($_GET['uid'])&&!empty($_GET['fansid']))
{
$key="user:{$_GET['uid']}:fansid";
$redis->sadd($key,$_GET['fansid']);
}
else
{
echo "关注不成功";
}
2.php
<?php
$redis = new Redis();
//连接redis服务器
$redis->connect('127.0.0.1', 6379);
// echo "Connection to server sucessfully <br/>";
// exit;
if(!empty($_GET['uid'])&&!empty($_GET['followsid']))
{
$key="user:{$_GET['uid']}:follows";
$redis->sadd($key,$_GET['followsid']);
}
else
{
echo "关注不成功";
}
3.php
<?php
$redis = new Redis();
//连接redis服务器
$redis->connect('127.0.0.1', 6379);
//通过sinter获取自己的粉丝和自己所有的关注用户交集
$userlist1 = $redis->sinter("user:{$_GET['uid']}:fansid","user:{$_GET['uid']}:follows");
if($userlist1)
{
echo "和用户{$_GET['uid']}互关的有";
print_r($userlist1);
}
else
{
echo "没有和用户{$_GET['uid']}互关的有";
}
echo "<br>";
$user1id=1;
$user2id=2;
$userlist2 = $redis->sinter("user:{$user1id}:follows","user:{$user2id}:follows");
if($userlist2)
{
echo "和用户{$user1id}和{user2id}共同关注的用户有";
print_r($userlist2);
}
else
{
echo "没有和用户{$user1id}和{user2id}共同关注的用户有";
}
PHP+REDIS实现排行榜功能
<?php
class Rank
{
private $redis = null;
//构造方法,创建redis对象,并连接
public function __construct($ip,$port)
{
$this->redis = new redis();
$this->redis->connect($ip,$port);
}
//像zsert类型集合添加元素,包括用户信息和排序用的分数
function set( $key, $score, $userinfo)
{
//增加一个或多个元素,如果该元素存在,更新他的score
if($this->redis->zadd($key,$score,json_encode($userinfo)))
{
print_r($userinfo);
echo "数据添加成功";
}
else
{
echo "数据存在只更新score或者添加失败";
}
}
//从zsert类型集合种获取全部排行好的用户信息和分数
function get( $key,$withscores=true)
{
//返回key对应的有序集合中指定区间的所有元素。这些元素按照score从高到低顺序排列
//0代表第一个元素,1第二个,-1代表最后一个,-2倒数第二个
return $this->redis->zrevrange($key,0,-1,$withscores);
}
}
$rank = new Rank('127.0.0.1',6379);
//设置A的score
$rank->set('Rank',100,array('img'=>'xx.jpg','username'=>'A','userid'=>1));
//设置B的score
$rank->set('Rank',250,array('img'=>'xx.jpg','username'=>'B','userid'=>3));
//设置C的score
$rank->set('Rank',50,array('img'=>'xx.jpg','username'=>'C','userid'=>2));
//设置C的score
$rank->set('Rank',600,array('img'=>'xx.jpg','username'=>'C','userid'=>2));
echo "<pre>";
print_r($rank->get('Rank'));
结果进行了自动排序和自动去重
PHP+REDIS实现购物车功能
<?php
session_start();
class Cart
{
private $redis=null;
public function __construct()
{
$this->redis = new Redis();
$this->redis->connect('127.0.0.1',6379);
}
//向购物车添加商品,修改已经有的商品数量
public function addCart($gid,$cartNum=1)
{
//根据商品ID查询调用内部方法,模拟从数据库获取商品数据信息
$goodDate = $this->goodsDta($gid);
//组合key,seeion_id关联用户,gid关联商品
$key = 'cart:'.session_id().':'.$gid;
//将当前用户放入购物车的所有商品ID放到集合种,组合集合key
$idskey = 'cart:ids:'.session_id();
//通过key获取对应的商品数量,如果获取到说明商品存在
$pnum = $this->redis->hget($key,'num');
//购物车有对应的商品,只需要添加对应商品的数量
$newNum= $pnum + $cartNum;
//判断购物车中是否存在商品,如果不存在
if(!$pnum)
{
//如果用户传入的数是负数,就证明用户在减少数量,传入的数和原购物车中的商品数量之和应该大于0
if($newNum>0)
{
//向购物车的商品添加数量
$goodsDta['num'] = $cartNum;
//将商品数据存放到redis的hash,使用Hmset一次添加多个字段
$this->redis->hmset($key,$goodsDta);
//将商品id存放集合是为了更好的将用户购物车的商品遍历出来
$this->redis->sadd($idskey,$gid);
}
else
{
//如果数量小于1,清除购物车商品
if($newNum<1)
{
$this->redis->del($key); //删除用户购物车的商品
$this->redis->srem($idskey,$gid);//在集合中去掉对应的商品id
}
else
{
$this->redis->hset($key,'num',$newNum);//原来的数量加上用户新传入的数量
}
}
}
}
//通过商品od删除购物车一条信息,如果没有传gid就清空购物车
public function delCart($gid = false)
{
//获取当前用户放入购物车中所有商品id集合key
$idskey = 'cart:ids:'.session_id();
//如果参数$gid没有传入商品id,清空购物车
if(!$gid)
{
//去集合拿到商品id
foreach ($this->redis->sMembers($idskey) as $key => $id)
{
//组合一个key,使用session_id和用户关联,使用gid和商品关联
$key = 'cart:'.session_id().':'.$id;
}
//删除按当前用户购买的商品id集合
$this->redis->del($idskey);
}
else
{
//组合一个key,使用session_id和用户关联,使用gid和商品关联
$key = 'cart:'.session_id().':'.$gid;
$this->redis->del($key);
$this->redis->srem($idskey,$gid);
}
}
//显示用户购物车的所有商品
public function showCartList()
{
$idskey = 'cart:ids'.session_id();
$idsArr = $this->redis->sMembers($idskey);
$list = null; //声明商品列表
$total = 0;//商品总加个变量
foreach ($idsArr as $key => $gid)
{
//获取当前用户放入购物车中所有商品
$good = $this->redis->hGetAll('cart:'.session_id().':'.$gid);
$list[] = $good;
//将所有商品的价格汇总
$total +=$good['price'] * $good['num'];
}
$list['total'] = $total; // 将总金额一并放到商品列表
return $list;
}
//临时模拟从mysql数据库中获取商品数据
private function goodsDta($gid)
{
$goodsDta = [
1 => ['id'=>1,'gname'=>'qwe','price'=>'21'],
2 => ['id'=>2,'gname'=>'22','price'=>'333'],
3 => ['id'=>3,'gname'=>'33','price'=>'444'],
4 => ['id'=>4,'gname'=>'44','price'=>'555']
];
return $goodsDta[$gid];
}
}
//简单测试向购物车增,删,改,查等商品的操作
$cart = new Cart();
$cart->addCart(1);
// $cart->addCart(2,2); //id为2的商品放入购物车,数量为2
// $cart->addCart(2,1); //修改id为2的商品,原数量加1
// $cart->addCart(3,3); //id为3的商品放入购物车,数量为3
// $cart->addCart(4,-4);// 商品为4的放入,数量-4
// $cart->addCart(3,-1);//id为3的放入,数量-1
echo "<pre>";
print_r($cart->showCartList());//打印购物车列表的金额
// $cart->delCart(2);
// print_r($cart->showCartList());//打印购物车列表的金额
// $cart->delCart(); //清空购物车