关于订单号保持唯一

关于订单号生成 

list做mq的总结

使用方法

1. 生产者可以 lpush 写入消息,消费者可以 rpop 读取消息,也就是pull模式

2. 消费者可以使用 brpop 阻塞性读取消息,约等于服务器端的实时推送

3. 如何保证消息读取但未处理时,消费者程序异常宕机造成的消息丢失,答案:rpoplpush 或 brpoplpush ,即先从原队列中移除一个消息并插入到一个新队列,消费者处理完该消息后再从新队列中删除,相当于ack机制,避免消费者异常时消息丢失

//获取订单号 //下单类型 V:VIP; M:普通 // 由年月日时分秒+赛事活动编号【2位数】+-【商户编号/编码】+自动递进的【序号】

public static function getOrderNo($time, $m_no, $shop_id='', $order_type='M')

{ if( !in_array($order_type, ['M', 'V']) ) return [10102, config('code.10102')];

$d = date('YmdHis', $time);

$redis = Redis::connection(); i

f( $order_type == 'M' ){

$serial_num = $redis->lpop(self::ORDER_NO_LIST_COMMON_KEY); //重点

$order_no = $d.$m_no.$shop_id.$serial_num;

}elseif( $order_type == 'V' ){

$order_no = $redis->lpop(self::ORDER_NO_LIST_VIP_KEY); //重点

}

if( empty($order_no) ){ return [10103, config('code.10103')]; } return [200, $order_no]; }

以下是产生自动递进的序列号

<?php

namespace App\Console\Commands;

use App\Models\Orders;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use SebastianBergmann\Timer\Timer;

class CreateTradeNoCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'gym:create:trade:no';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '创建订单号';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        Log::info($this->description.' start ');
        $redis = Redis::connection();
        $order_no_running_key = 'gym:order:no:create_running';

        //普通用户配置
        $order_common_num_key = 'gym:order:no:common:now_num';
        $order_no_list_common_key= Orders::ORDER_NO_LIST_COMMON_KEY;//'gym:order:no:common:list';
        $order_common_num = 0;
        $order_no_common_exists_max = env('GYM_ORDER_COMMON_NO_EXISTS_MAX', 10000);
        $order_no_common_min_need_run = env('GYM_ORDER_COMMON_NO_MIN_NEED_RUN', 5000);

        //VIP用户配置
        $order_vip_num_key = 'gym:order:no:vip:now_num';
        $order_no_list_vip_key= Orders::ORDER_NO_LIST_VIP_KEY;
        $order_vip_num = 10000;
        $order_no_vip_exists_max   = env('GYM_ORDER_VIP_NO_EXISTS_MAX', 1000);
        $order_no_vip_min_need_run = env('GYM_ORDER_VIP_NO_MIN_NEED_RUN', 500);

        $string = '';

        if( ! $redis->exists($order_no_running_key) ){
            $redis->setex($order_no_running_key, env('GYM_ORDER_NO_RUNNING_TIMES', 1200), 123);

            $common_len = $redis->llen($order_no_list_common_key);
            if( $common_len < $order_no_common_min_need_run ){
                if( $redis->exists($order_common_num_key) ) $order_common_num  = $redis->get($order_common_num_key);
                $common_diff = $order_no_common_exists_max - $common_len;

                $string .= ' run common no, start:'.$order_common_num.'; lens:'.$common_diff.';';
                $push_array = [];
                while ( $common_diff > 0 ){
                    $common_diff--;
                    $order_common_num++;
                    $push_array[] = $order_common_num;
                }
                $redis->rpush($order_no_list_common_key, $push_array);
                $redis->set($order_common_num_key, $order_common_num);
                $string .= ' common no end:'.$order_common_num.';';
            }






            $vip_len = $redis->llen($order_no_list_vip_key);
            if( $vip_len < $order_no_vip_min_need_run ){
                if( $redis->exists($order_vip_num_key) ) $order_vip_num  = $redis->get($order_vip_num_key);
                $vip_diff = $order_no_vip_exists_max - $vip_len;
                $string .= ' run vip no, start:'.$order_vip_num.'; lens:'.$vip_diff.';';

                $push_array = [];
                while ( $vip_diff > 0 ){
                    $vip_diff--;
                    $order_vip_num++;
                    $push_array[] = $order_vip_num;
                }
                $redis->rpush($order_no_list_vip_key, $push_array);
                $redis->set($order_vip_num_key, $order_vip_num);
                $string .= ' vip no end:'.$order_vip_num.';';
            }

            $redis->del($order_no_running_key);
        }
        if( empty($string) ) $string = ' not run';
        Log::info($this->description.' stop ', [$string]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值