PHP学习心得


核心模块-订单模块开发

<h2>整体流程</h2> <ul> <li>购物车-&gt;</li> <li>订单确认页面-&gt;</li> <li>提交订单-&gt; <ul> <li>分布式发号器(订单号)</li> <li>从购物车中获取数据</li> <li>组装数据</li> <li>订单信息入库</li> <li>删除购物车</li> <li>减库存操作</li> </ul></li> <li>订单生成-&gt;</li> <li>发起支付-&gt;</li> <li>支付系统 <ul> <li>独立服务做到服务化,也可以说是微服务</li> </ul></li> </ul> <h2>订单主表</h2> <ul> <li>订单id在分库分表时,就不能订单id处理了,请使用生成的订单号</li> <li>取消订单时间,也要记录一下</li> </ul> <h2>从分布式场景考虑</h2> <ul> <li>所有涉及id的表,都应该使用编号</li> </ul> <h2>订单号生成方法,保证唯一</h2> <ul> <li>订单表主键id <ul> <li>业务量不大场景,不去分库分表。</li> <li>表数据达到千万级别,就要分表。</li> </ul></li> <li>年月日 + 毫秒 + 固定位置随机数 <ul> <li>在高并发的场景下,会生成相同的订单号</li> </ul></li> <li>年月日 + 毫秒 + 固定位置随机数 + 用户id后三位 <ul> <li>在高并发的场景下,仍然会生成相同的订单号。</li> <li>不建议使用全部位数的用户id,这样会把用户id暴露给用户,不安全。建议在用户表中生成一个区别于用户id的数字的字段,只用于生成订单号使用</li> </ul></li> <li>-redis incr <ul> <li>订单id不建议使用redis,会增加网络请求,稳定性也会减小</li> <li>是incr字符串类型中使用,将 key 中储存的数字值增一</li> </ul></li> <li>雪花算法 php-snowflake <ul> <li><a href="https://github.com/52fhy/IDWork">https://github.com/52fhy/IDWork</a></li> <li>推荐使用此算法,在分布式中使用最广。</li> <li>在分布式中,部署多台服务器,在高并发场景下,支持生成唯一订单id。</li> <li>基本每秒可以产生400万的唯一性id</li> <li>php-snowflake就是一个类库文件,也可以通过提供C的源码版本,进行编译.so文件,成为php的扩展文件来使用</li> <li>在并发量特别大时,订单编号重复机率非常小,可以忽略不计</li> </ul></li> </ul> <h2>可变参数</h2> <ul> <li>可以使用数组作为可变参数</li> </ul> <h2>取消订单</h2> <ul> <li>使用redis有序集合 <ul> <li>将订单编号,过期时间戳存入到redis有序集合中</li> <li>使用thinkphp命令行-&gt;自定义指令,使用命令行形式对redis有序集合存放的数据进行消费</li> <li>注意:thinkphp命令行操作是有一定的bug,要注意</li> </ul></li> <li>不挂断地运行命令 <ul> <li>nohup php think 自定义命令 &gt; 日志文件路径 &amp;</li> <li>当这个进程挂了,要有一个监控机制</li> </ul></li> </ul> <h2>队列开多个服务跑脚本运行处理时</h2> <ul> <li>如果同一时间获取到同一个消息,该怎么去避免这种情况或者进行处理</li> <li>从redis中取出订单id之后,在mysql中查一下这行数据是否需要处理,并加一个乐观锁或悲观锁,如果是需要处理的那就处理,记得加mysql事务,</li> <li>另一个进程刚好也读到这个id,读数据库,因为上个进程有事务和锁,也不怕这个进程再次改动</li> <li>并且在此基础上还可以使用redis来实现锁,假如我第一个进程取出一个值,先判断下有没有这个id的锁存在,不存在就用redis的setex加一个锁,然后再处理逻辑,如果存在就跳过本次操作</li> </ul>

页面列表

ITEM_HTML