Jadual Kandungan
1. Idea Reka Bentuk
二、核心代码
三、压测
Rumah pangkalan data Redis Bagaimana untuk melaksanakan sistem jualan kilat dalam redis

Bagaimana untuk melaksanakan sistem jualan kilat dalam redis

May 31, 2023 pm 03:11 PM
redis

1. Idea Reka Bentuk

Sistem pembunuh kilat dicirikan oleh sejumlah besar permintaan boleh masuk dalam satu saat , sistem akan Ia runtuh dalam beberapa minit. Mari kita bincangkan cara mereka bentuk sistem bunuh kilat yang boleh dimainkan.

1. Had semasa:

Pertama sekali, tanpa mengira logik perniagaan, jika terdapat antara muka paling mudah berikut:

@GetMapping("/test")
public String test() {
 return "success";
}
Salin selepas log masuk

Walaupun antara muka ini sangat mudah dan tidak mempunyai sebarang logik, Pelayan juga boleh ranap jika terdapat beribu-ribu permintaan mengaksesnya secara serentak. Oleh itu, perkara pertama yang perlu dilakukan oleh sistem konkurensi tinggi ialah mengehadkan aliran semasa. Projek Springcloud boleh menggunakan hystrix untuk mengehadkan semasa, dan springcloud alibaba boleh menggunakan sentinel untuk mengehadkan semasa. Bagaimana pula dengan projek bukan springcloud? Jambu batu memberikan kami kelas alat RateLimiter yang boleh mengehadkan arus. Ia terutamanya termasuk algoritma baldi bocor dan algoritma baldi token.

  • Algoritma Baldi Bocor: Baldi berlubang diisi dengan air di bawah paip Ia akan bocor sedikit apabila ia diisi sangat besar, baldi akan bocor Lambat laun, air akan melimpah, dan aliran akan terhad apabila ia melimpah. Ini sesuai untuk mengehadkan kadar muat naik dan muat turun.

  • Algoritma baldi token: masukkan token ke dalam baldi pada kadar tetap Setiap kali permintaan masuk, token mesti diambil dari baldi terlebih dahulu Jika token tidak diperoleh, permintaan akan disekat. Ini sesuai untuk pengehadan semasa, iaitu mengehadkan QPS.

Algoritma baldi token harus digunakan di sini untuk mengehadkan aliran Jika token tidak diperoleh, gesaan "terlalu ramai orang tidak boleh masuk". kembali secara langsung.

2. Semak sama ada pengguna telah log masuk:

Selepas langkah pertama pengehadan semasa, permintaan masuk harus menyemak sama ada pengguna telah log masuk. Projek ini menggunakan JWT, iaitu, pertama meminta antara muka log masuk dan kembali selepas log masuk. Token, minta semua antara muka lain untuk membawa token dalam pengepala permintaan, dan kemudian anda boleh mendapatkan maklumat pengguna melalui token. Apabila maklumat pengguna tidak diperoleh, pengguna digesa untuk log masuk semula: token tidak sah.

3. Semak sama ada produk habis dijual:

Jika dua langkah pengesahan pertama diluluskan, anda perlu menyemak sama ada produk itu habis dijual, a mesej segera "Maaf" akan dikembalikan , produk telah habis dijual dengan serta-merta. Ambil perhatian bahawa anda tidak boleh menyemak pangkalan data untuk menyemak sama ada produk itu habis dijual, jika tidak, ia akan menjadi sangat perlahan. Anda boleh menggunakan kamus untuk menyimpan ID produk, menggunakan ID produk sebagai kunci. Jika item itu habis dijual, tetapkan nilainya kepada Benar, jika tidak kepada Palsu.

4. Tambahkan produk yang menyertai jualan kilat ke redis:

Pertama dapatkan kunci ISINREDIS untuk menunjukkan sama ada produk telah ditambahkan ke redis untuk mengelakkan pertindihan bagi setiap permintaan. Operasi ini. Jika nilai ISINREDIS palsu, ini bermakna tiada produk jualan kilat dalam redis. Kemudian tanya semua produk yang mengambil bahagian dalam jualan kilat, gunakan id produk sebagai kunci, dan inventori produk sebagai nilai, dan simpannya dalam redis Pada masa yang sama, gunakan id produk sebagai kunci dan palsu sebagai nilai dan letakkannya dalam peta langkah ketiga, menunjukkan bahawa produk itu belum dijual. Akhir sekali, tetapkan nilai ISINREDIS kepada benar, yang bermaksud bahawa semua produk yang menyertai jualan kilat telah ditambahkan pada redis.

5. Menahan inventori:

Gunakan fungsi decr redis untuk mengurangkan kuantiti barang dan menilai nilai yang dikurangkan. Jika keputusan selepas pengurangan diri kurang daripada 0, ini bermakna produk telah habis dijual, maka nilai ID produk yang sepadan dalam peta ditetapkan kepada benar dan gesaan "Sudah lewat, produk telah habis dijual" dikembalikan.

6. Tentukan sama ada jualan kilat diulang:

Jika jualan kilat pengguna berjaya, selepas pesanan jualan kilat disimpan dalam pangkalan data, id pengguna dan id produk akan digunakan sebagai kunci, dan benar akan disimpan dalam redis sebagai nilai, menunjukkan Pengguna ini telah menjual produk ini serta-merta. Jadi di sini kita pergi ke redis berdasarkan ID pengguna dan ID produk untuk menentukan sama ada jualan kilat diulang. Jika ya, gesaan "Jangan ulangi jualan kilat" dikembalikan.

7. Pemprosesan tak segerak:

Jika pengesahan di atas diluluskan, maka jualan kilat boleh diproses. Jika anda memotong inventori dan membuat pesanan untuk setiap permintaan jualan kilat, bukan sahaja kelajuannya akan menjadi sangat perlahan, tetapi ia juga boleh menyebabkan pangkalan data ranap. Jadi kami boleh memprosesnya secara tidak segerak, iaitu, selepas lulus pengesahan di atas, ID pengguna dan ID produk akan dihantar ke MQ sebagai mesej, dan kemudian gesaan "beratur" akan dikembalikan kepada pengguna dengan serta-merta. Kemudian gunakan mesej di bahagian pengguna MQ, dapatkan ID pengguna dan ID produk, dan tanya inventori berdasarkan ID produk untuk memastikan inventori yang mencukupi sekali lagi, kemudian anda juga boleh menentukan sama ada untuk mengulangi jualan kilat. Selepas meluluskan penghakiman, kendalikan pangkalan data, tolak inventori dan buat pesanan jualan kilat. Ambil perhatian bahawa menolak inventori dan membuat pesanan jualan kilat perlu dalam transaksi yang sama.

8. Masalah terlebih jual:

Masalah terlebih jual ialah inventori negatif barang. Sebagai contoh, jika inventori adalah 1, maka 10 pengguna menjual serta-merta pada masa yang sama Apabila menilai inventori, mereka semua adalah 1, jadi 10 orang boleh membuat pesanan dengan jayanya, dan inventori akhir ialah -9. Bagaimana untuk menyelesaikannya? Malah, masalah sedemikian tidak akan berlaku dalam sistem ini sama sekali, kerana redis digunakan untuk pra-pengurangan inventori pada mulanya, dan modul teras arahan redis adalah satu-benang, jadi ia boleh dijamin tidak terlebih jual. Jika redis tidak digunakan, anda juga boleh menambah medan versi pada produk Semak versi sebelum menolak inventori setiap kali Tambah syarat pada sql untuk menolak inventori, iaitu versi mestilah sama dengan versi yang baru ditemui.

 

二、核心代码

@RestController
@RequestMapping("/seckill")
public class SeckillController {
 
 @Autowired
 private UserService userService;
 @Autowired
 private SeckillService seckillService;
 @Autowired
 private RabbitMqSender mqSender;
 
 // 用来标记商品是否已经加入到redis中的key
 private static final String ISINREDIS = "isInRedis";
 
 // 用goodsId作为key,标记该商品是否已经卖完
 private Map<integer> seckillOver = new HashMap<integer>();
 
 // 用RateLimiter做限流,create(10),可以理解为QPS阈值为10
 private RateLimiter rateLimiter = RateLimiter.create(10);
 
 @PostMapping("/{sgId}")
 public JsonResult> seckillGoods(@PathVariable("sgId") Integer sgId, HttpServletRequest httpServletRequest){
  
  // 1. 如果QPS阈值超过10,即1秒钟内没有拿到令牌,就返回“人太多了,挤不进去”的提示
  if (!rateLimiter.tryAcquire(1, TimeUnit.SECONDS)) {
   return new JsonResult(SeckillGoodsEnum.TRY_AGAIN.getCode(), SeckillGoodsEnum.TRY_AGAIN.getMessage());
  }
  
  // 2. 检查用户是否登录(用户登录后,访问每个接口都应该在请求头带上token,根据token再去拿user)
  String token = httpServletRequest.getHeader("token");
  String userId = JWT.decode(token).getAudience().get(0);
  User user = userService.findUserById(Integer.valueOf(userId));
  if (user == null) {
   return new JsonResult(SeckillGoodsEnum.INVALID_TOKEN.getCode(), SeckillGoodsEnum.INVALID_TOKEN.getMessage());
  }
  
  // 3. 如果商品已经秒杀完了,就不执行下面的逻辑,直接返回商品已秒杀完的提示
  if (!seckillOver.isEmpty() && seckillOver.get(sgId)) {
   return new JsonResult(SeckillGoodsEnum.SECKILL_OVER.getCode(), SeckillGoodsEnum.SECKILL_OVER.getMessage());
  }
  
  // 4. 将所有参加秒杀的商品信息加入到redis中
  if (!RedisUtil.isExist(ISINREDIS)) {
   List<seckillgoods> goods = seckillService.getAllSeckillGoods();
   for (SeckillGoods seckillGoods : goods) {
    RedisUtil.set(String.valueOf(seckillGoods.getSgId()), seckillGoods.getSgSeckillNum());
    seckillOver.put(seckillGoods.getSgId(), false);
   }
   RedisUtil.set(ISINREDIS, true);
  }
  
  // 5. 先自减,预扣库存,判断预扣后库存是否小于0,如果是,表示秒杀完了
  Long stock = RedisUtil.decr(String.valueOf(sgId));
  if (stock (SeckillGoodsEnum.SECKILL_OVER.getCode(), SeckillGoodsEnum.SECKILL_OVER.getMessage());
  }
  
  // 6. 判断是否重复秒杀(成功秒杀并创建订单后,会将userId和goodsId作为key放到redis中)
  if (RedisUtil.isExist(userId + sgId)) {
   return new JsonResult(SeckillGoodsEnum.REPEAT_SECKILL.getCode(), SeckillGoodsEnum.REPEAT_SECKILL.getMessage());
  }
  
  // 7. 以上校验都通过了,就将当前请求加入到MQ中,然后返回“排队中”的提示
  String msg = userId + "," + sgId;
  mqSender.send(msg);
  return new JsonResult(SeckillGoodsEnum.LINE_UP.getCode(), SeckillGoodsEnum.LINE_UP.getMessage());
 }

}
</seckillgoods></integer></integer>
Salin selepas log masuk
     

三、压测

用jmeter模拟并发请求,测试高并发情况下系统能否扛得住。由于只有一个id为1的商品,所以商品id固定写死1。但是每个用户都要先请求登录接口获取到token才能进行秒杀请求,有点儿麻烦,所以可以先把jwt模块注释掉,把userId当成参数传进去。jmeter配置如下图:

Bagaimana untuk melaksanakan sistem jualan kilat dalam redis
jmeter压测配置
Bagaimana untuk melaksanakan sistem jualan kilat dalam redis
jmeter压测配置

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan sistem jualan kilat dalam redis. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

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

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial Java
1659
14
Tutorial PHP
1258
29
Tutorial C#
1232
24
Cara Membina Mod Kluster Redis Cara Membina Mod Kluster Redis Apr 10, 2025 pm 10:15 PM

Mod Redis cluster menyebarkan contoh Redis ke pelbagai pelayan melalui sharding, meningkatkan skalabilitas dan ketersediaan. Langkah -langkah pembinaan adalah seperti berikut: Buat contoh Redis ganjil dengan pelabuhan yang berbeza; Buat 3 contoh sentinel, memantau contoh redis dan failover; Konfigurasi fail konfigurasi sentinel, tambahkan pemantauan maklumat contoh dan tetapan failover; Konfigurasi fail konfigurasi contoh Redis, aktifkan mod kluster dan tentukan laluan fail maklumat kluster; Buat fail nodes.conf, yang mengandungi maklumat setiap contoh Redis; Mulakan kluster, laksanakan perintah Buat untuk membuat kluster dan tentukan bilangan replika; Log masuk ke kluster untuk melaksanakan perintah maklumat kluster untuk mengesahkan status kluster; buat

Cara membersihkan data redis Cara membersihkan data redis Apr 10, 2025 pm 10:06 PM

Cara Mengosongkan Data Redis: Gunakan perintah Flushall untuk membersihkan semua nilai utama. Gunakan perintah flushdb untuk membersihkan nilai utama pangkalan data yang dipilih sekarang. Gunakan Pilih untuk menukar pangkalan data, dan kemudian gunakan FlushDB untuk membersihkan pelbagai pangkalan data. Gunakan perintah DEL untuk memadam kunci tertentu. Gunakan alat REDIS-CLI untuk membersihkan data.

Cara Membaca Gilir Redis Cara Membaca Gilir Redis Apr 10, 2025 pm 10:12 PM

Untuk membaca giliran dari Redis, anda perlu mendapatkan nama giliran, membaca unsur -unsur menggunakan arahan LPOP, dan memproses barisan kosong. Langkah-langkah khusus adalah seperti berikut: Dapatkan nama giliran: Namakannya dengan awalan "giliran:" seperti "giliran: my-queue". Gunakan arahan LPOP: Keluarkan elemen dari kepala barisan dan kembalikan nilainya, seperti LPOP Queue: My-Queue. Memproses Baris kosong: Jika barisan kosong, LPOP mengembalikan nihil, dan anda boleh menyemak sama ada barisan wujud sebelum membaca elemen.

Cara Mengkonfigurasi Masa Pelaksanaan Skrip Lua di Centos Redis Cara Mengkonfigurasi Masa Pelaksanaan Skrip Lua di Centos Redis Apr 14, 2025 pm 02:12 PM

Pada sistem CentOS, anda boleh mengehadkan masa pelaksanaan skrip LUA dengan mengubah fail konfigurasi REDIS atau menggunakan arahan REDIS untuk mengelakkan skrip jahat daripada memakan terlalu banyak sumber. Kaedah 1: Ubah suai fail konfigurasi Redis dan cari fail konfigurasi Redis: Fail konfigurasi Redis biasanya terletak di /etc/redis/redis.conf. Edit Fail Konfigurasi: Buka fail konfigurasi menggunakan editor teks (seperti Vi atau nano): sudovi/etc/redis/redis.conf Tetapkan had masa pelaksanaan skrip lua: Tambah atau ubah suai baris berikut dalam fail konfigurasi untuk menetapkan masa pelaksanaan maksimum skrip lua (unit: milidor)

Cara menggunakan baris arahan redis Cara menggunakan baris arahan redis Apr 10, 2025 pm 10:18 PM

Gunakan alat baris perintah redis (redis-cli) untuk mengurus dan mengendalikan redis melalui langkah-langkah berikut: Sambungkan ke pelayan, tentukan alamat dan port. Hantar arahan ke pelayan menggunakan nama arahan dan parameter. Gunakan arahan bantuan untuk melihat maklumat bantuan untuk arahan tertentu. Gunakan perintah berhenti untuk keluar dari alat baris arahan.

Cara Melaksanakan Kaunter Redis Cara Melaksanakan Kaunter Redis Apr 10, 2025 pm 10:21 PM

Kaunter Redis adalah satu mekanisme yang menggunakan penyimpanan pasangan nilai utama REDIS untuk melaksanakan operasi pengiraan, termasuk langkah-langkah berikut: mewujudkan kekunci kaunter, meningkatkan tuduhan, mengurangkan tuduhan, menetapkan semula, dan mendapatkan tuduhan. Kelebihan kaunter Redis termasuk kelajuan cepat, konkurensi tinggi, ketahanan dan kesederhanaan dan kemudahan penggunaan. Ia boleh digunakan dalam senario seperti pengiraan akses pengguna, penjejakan metrik masa nyata, skor permainan dan kedudukan, dan pengiraan pemprosesan pesanan.

Cara Menetapkan Dasar Tamat Redis Cara Menetapkan Dasar Tamat Redis Apr 10, 2025 pm 10:03 PM

Terdapat dua jenis strategi tamat tempoh data REDIS: Penghapusan berkala: Imbasan berkala untuk memadamkan kunci yang telah tamat tempoh, yang boleh ditetapkan melalui parameter-cap-cap-rempah yang telah tamat tempoh dan parameter kelewatan-cap-remove-time-time. Penghapusan Lazy: Periksa kekunci yang telah tamat tempoh hanya apabila kunci dibaca atau ditulis. Mereka boleh ditetapkan melalui parameter lazon-lazy-expire-expire-expire, lazy-lazy-user-del parameter.

Cara Mengoptimumkan Prestasi Debian Readdir Cara Mengoptimumkan Prestasi Debian Readdir Apr 13, 2025 am 08:48 AM

Dalam sistem Debian, panggilan sistem Readdir digunakan untuk membaca kandungan direktori. Jika prestasinya tidak baik, cuba strategi pengoptimuman berikut: Memudahkan bilangan fail direktori: Split direktori besar ke dalam pelbagai direktori kecil sebanyak mungkin, mengurangkan bilangan item yang diproses setiap panggilan readdir. Dayakan Caching Kandungan Direktori: Bina mekanisme cache, kemas kini cache secara teratur atau apabila kandungan direktori berubah, dan mengurangkan panggilan kerap ke Readdir. Cafh memori (seperti memcached atau redis) atau cache tempatan (seperti fail atau pangkalan data) boleh dipertimbangkan. Mengamalkan struktur data yang cekap: Sekiranya anda melaksanakan traversal direktori sendiri, pilih struktur data yang lebih cekap (seperti jadual hash dan bukannya carian linear) untuk menyimpan dan mengakses maklumat direktori

See all articles