Rumah > Java > javaTutorial > Bagaimana untuk menggunakan Java untuk membatalkan pesanan yang tidak dibayar secara automatik?

Bagaimana untuk menggunakan Java untuk membatalkan pesanan yang tidak dibayar secara automatik?

WBOY
Lepaskan: 2023-05-10 10:07:07
ke hadapan
1207 orang telah melayarinya

Tinjauan berjadual

Kaedah tinjauan berjadual pangkalan data, idea pelaksanaannya agak mudah. Mulakan tugas yang dijadualkan, imbas jadual pesanan pada masa tertentu dan batalkan pesanan tamat masa selepas menanyakannya.

Kelebihan: Mudah dilaksanakan.

Kelemahan: Selang pengundian sukar ditentukan, menduduki sumber pelayan dan menjejaskan prestasi pangkalan data.

Pembatalan Malas

Apabila menanyakan maklumat pesanan, mula-mula tentukan sama ada pesanan telah tamat masa, dan jika tamat masa, batalkannya dahulu.

Kelebihan: Mudah dilaksanakan.

Kelemahan: Ia mempengaruhi perniagaan selain pertanyaan (seperti statistik, inventori) dan menjejaskan kecekapan pertanyaan.

Baris Gilir Kelewatan JDK

Baris Gilir Kelewatan JDK DelayQueue ialah baris gilir sekatan tanpa sempadan, yang hanya boleh mendapatkan elemen daripadanya apabila kelewatan tamat tempoh.

Demo kod pelaksanaan yang mudah adalah seperti berikut Dalam proses pengeluaran sebenar, akan ada urutan khusus yang bertanggungjawab untuk queuing dan penggunaan mesej.

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
 
/**
 * @author 向振华
 * @date 2022/08/16 15:55
 */
public class OrderDelayed implements Delayed {
 
    /**
     * 延迟时间
     */
    private final Long time;
    /**
     * 订单编号
     */
    public String orderNo;
 
    public OrderDelayed(String orderNo, long time, TimeUnit unit) {
        this.orderNo = orderNo;
        this.time = System.currentTimeMillis() + (time > 0 ? unit.toMillis(time) : 0);
    }
 
    @Override
    public long getDelay(TimeUnit unit) {
        return time - System.currentTimeMillis();
    }
 
    @Override
    public int compareTo(Delayed o) {
        OrderDelayed orderDelayed = (OrderDelayed) o;
        long diff = this.time - orderDelayed.time;
        if (diff <= 0) {
            return -1;
        } else {
            return 1;
        }
    }
}
Salin selepas log masuk
rrree

Kelebihan: kecekapan tinggi, kelewatan masa pencetus tugas yang rendah.

Kelemahan: Kesukaran dalam pemulihan pengecualian, pengembangan kluster yang menyusahkan, penggunaan memori.

Roda Masa

Algoritma roda masa adalah serupa dengan jam dan akan berputar ke arah tertentu pada frekuensi tetap. Anda boleh menggunakan HashedWheelTimer Netty untuk melaksanakan kaedah roda masa.

import java.util.concurrent.DelayQueue;
import java.util.concurrent.TimeUnit;
 
/**
 * @author 向振华
 * @date 2022/08/16 16:02
 */
public class Test {
 
    public static void main(String[] args) {
 
        DelayQueue<OrderDelayed> delayQueue = new DelayQueue<>();
 
        delayQueue.put(new OrderDelayed("220101001", 8, TimeUnit.SECONDS));
        delayQueue.put(new OrderDelayed("220101002", 4, TimeUnit.SECONDS));
 
        System.out.println("订单延迟队列开始执行");
 
        while (true) {
            // 取队列头部元素是否过期
            OrderDelayed task = delayQueue.poll();
            if (task != null) {
                // 取消订单业务逻辑
                System.out.println("订单 ---> " + task.orderNo + " 已过期准备取消");
            }
        }
    }
}
Salin selepas log masuk
rrree

Kelebihan: kecekapan tinggi, kelewatan masa pencetus tugas yang lebih rendah.

Kelemahan: Kesukaran dalam pemulihan pengecualian, pengembangan kluster yang menyusahkan, penggunaan memori.

Panggil balik tamat tempoh Redis

Acara panggil balik tamat tempoh kekunci Redis juga boleh mencapai kesan melambatkan baris gilir.

Tambahkan konfigurasi dalam redis.conf:

notify-keyspace-events Ex

Konfigurasi mendengar

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.78.Final</version>
</dependency>
Salin selepas log masuk

Panggil balik tamat tempoh Redis Kaedah pemantauan

import io.netty.util.HashedWheelTimer;
import io.netty.util.Timeout;
import io.netty.util.Timer;
import io.netty.util.TimerTask;
 
import java.util.concurrent.TimeUnit;
 
/**
 * @author 向振华
 * @date 2022/08/16 16:02
 */
public class Test {
 
    public static void main(String[] args) {
 
        // 初始化时间轮
        Timer timer = new HashedWheelTimer();
 
        // 定时任务
        TimerTask task1 = new TimerTask() {
            public void run(Timeout timeout) throws Exception {
                // 取消订单业务逻辑
                System.out.println("订单1已过期准备取消");
            }
        };
        // 注册此定时任务(延迟时间为5秒,也就是说5秒后订单过期)
        timer.newTimeout(task1, 5, TimeUnit.SECONDS);
 
        // 定时任务
        TimerTask task2 = new TimerTask() {
            public void run(Timeout timeout) throws Exception {
                // 取消订单业务逻辑
                System.out.println("订单2已过期准备取消");
            }
        };
        // 注册此定时任务(延迟时间为3秒,也就是说3秒后订单过期)
        timer.newTimeout(task2, 3, TimeUnit.SECONDS);
    }
}
Salin selepas log masuk

Kelebihan: Data tidak mudah hilang dan pengembangan kluster mudah.

Kelemahan: Penyelenggaraan tambahan redis diperlukan.

Set pesanan Redis

Struktur data Redis Zset juga boleh mencapai kesan baris gilir tertunda, terutamanya menggunakan atribut skornya Redis menggunakan skor untuk meletakkan ahli dalam set daripada kecil kepada besar. menyusun. Tambahkan elemen pada baris gilir kelewatan melalui perintah zadd, dan tetapkan nilai skor untuk menunjukkan masa tamat tempoh elemen.

Pengguna meninjau delayqueue, mengisih elemen dan membandingkan masa minimum dengan masa semasa Jika kurang daripada masa semasa, ini bermakna kunci telah tamat tempoh dan dialih keluar.

@Configuration
public class RedisListenerConfig {
 
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}
Salin selepas log masuk

Kelebihan: Data tidak mudah hilang dan pengembangan kluster mudah.

Kelemahan: Kunci yang sama boleh digunakan berulang kali.

Penjadualan tugas

Gunakan middleware penjadualan tugas xxl-job, ScheduleX, Elastic-Job, dsb. untuk melaksanakannya apabila masa penjadualan tamat tempoh pesanan , pembatalan pelaksanaan tugas dicetuskan.

Contohnya, menggunakan pelaksanaan xxl-job, apabila pesanan dibuat, tugasan yang telah tamat tempoh diserahkan kepada pelayan xxl-job Berikut ialah kaedah pelaksana:

@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
 
    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }
 
    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 过期key,可以设置成订单号
        String expiredKey = message.toString();
        // 取消订单业务逻辑
        System.out.println("订单 ---> " + expiredKey + " 已过期准备取消");
    }
}
Salin selepas log masuk

Kelebihan: kuat. ketepatan masa dan sokongan untuk pengedaran.

Kelemahan: Pelaksanaan yang kompleks dan kos penyelenggaraan yang tinggi.

Baris Gilir Mesej

Menggunakan mesej tertunda daripada RocketMQ, RabbitMQ dan Kafka Selepas mesej dihantar ke pelayan baris gilir mesej, ia tidak akan dihantar serta-merta, tetapi akan ditangguhkan untuk tetap. masa berdasarkan atribut dalam mesej dan kemudian dihantar kepada pengguna.

Kod sampel untuk RocketMQ menghantar mesej tertunda adalah seperti berikut:

public void pollOrderQueue() {
 
    while (true) {
        Set<Tuple> set = jedis.zrangeWithScores(delayqueue, 0, 0);
 
        String value = ((Tuple) set.toArray()[0]).getElement();
        int score = (int) ((Tuple) set.toArray()[0]).getScore();
 
        int nowSecond = System.currentTimeMillis() / 1000);
        if (nowSecond >= score) {
            jedis.zrem(delayqueue, value);
            System.out.println(sdf.format(new Date()) + " removed key:" + value);
        }
 
        if (jedis.zcard(delayqueue) <= 0) {
            System.out.println(sdf.format(new Date()) + " zset empty ");
            return;
        }
        Thread.sleep(1000);
    }
}
Salin selepas log masuk

Langganan mesej tertunda RocketMQ adalah sama seperti langganan mesej biasa.

Kelebihan: cekap, mudah dikembangkan, menyokong pengedaran.

Kelemahan: Pelaksanaan yang kompleks dan kos penyelenggaraan yang tinggi.

Atas ialah kandungan terperinci Bagaimana untuk menggunakan Java untuk membatalkan pesanan yang tidak dibayar secara automatik?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:yisu.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan