So implementieren Sie das Flash-Sale-System in Redis
1. Design-Ideen
Das Flash-Kill-System zeichnet sich durch eine große Menge an Parallelität aus. Wenn einige Maßnahmen nicht ergriffen werden, bricht das System zusammen. Lassen Sie uns besprechen, wie man ein Flash-Kill-System entwirft, das gespielt werden kann.
1. Aktuelle Einschränkung:
Zuallererst, unabhängig von der Geschäftslogik, wenn es die folgende einfachste Schnittstelle gibt:
@GetMapping("/test") public String test() { return "success"; }
Obwohl diese Schnittstelle sehr einfach ist und keine Logik hat, wenn Tausende von Anfragen auf die zugreifen Server gleichzeitig, der Server Es wird auch abstürzen. Daher sollte ein System mit hoher Parallelität zunächst den Stromfluss begrenzen. Springcloud-Projekte können Hystrix zur Strombegrenzung verwenden, und Springcloud Alibaba kann Sentinel zur Strombegrenzung verwenden. Was ist mit Nicht-Springcloud-Projekten? Guava stellt uns eine RateLimiter-Toolklasse zur Verfügung, die den Strom begrenzen kann. Es umfasst hauptsächlich den Leaky-Bucket-Algorithmus und den Token-Bucket-Algorithmus.
-
Leckiger Eimer-Algorithmus: Ein Eimer mit Löchern wird unter dem Wasserhahn mit Wasser gefüllt. Wenn das Wasser im Wasserhahn jedoch sehr groß ist, läuft das Wasser im Eimer früher oder später über. und der Überlauf ist begrenzt. Dies eignet sich zur Begrenzung der Upload- und Downloadraten.
-
Token-Bucket-Algorithmus: Jedes Mal, wenn eine Anfrage eingeht, muss das Token aus dem Bucket entnommen werden, wird die Anfrage blockiert. Dies eignet sich zur Strombegrenzung, also zur Begrenzung von QPS.
Der Token-Bucket-Algorithmus sollte hier verwendet werden, um den Fluss zu begrenzen. Wenn der Token nicht erhalten wird, wird direkt die Meldung „Zu viele Leute können sich nicht hineinquetschen“ zurückgegeben.
2. Überprüfen Sie, ob der Benutzer angemeldet ist:
Nach dem ersten Schritt der Flussbegrenzung sollten eingehende Anfragen prüfen, ob der Benutzer angemeldet ist. Dieses Projekt verwendet JWT, das heißt, es fordert zuerst die Anmeldeschnittstelle an und gibt das Token zurück Nachdem Sie sich angemeldet haben, können Sie alle anderen Schnittstellen anfordern, indem Sie das Token in den Anforderungsheader einfügen. Anschließend können Sie die Benutzerinformationen über das Token abrufen. Wenn die Benutzerinformationen nicht abgerufen werden, wird der Benutzer aufgefordert, sich erneut anzumelden: ungültiges Token.
3. Überprüfen Sie, ob das Produkt ausverkauft ist:
Wenn die ersten beiden Schritte der Überprüfung bestanden sind, müssen Sie überprüfen, ob das Produkt ausverkauft ist „ausverkauft“ wird zurückgegeben. Beachten Sie, dass Sie die Datenbank nicht überprüfen können, um zu überprüfen, ob das Produkt ausverkauft ist, da es sonst sehr langsam ist. Sie können ein Wörterbuch zum Speichern von Produkt-IDs verwenden und dabei die Produkt-ID als Schlüssel verwenden. Wenn der Artikel ausverkauft ist, setzen Sie seinen Wert auf True, andernfalls auf False.
4. Fügen Sie die am Flash-Sale teilnehmenden Produkte zu Redis hinzu:
Setzen Sie zunächst den Wert von ISINREDIS
的key,表示商品是否已经加到redis中了,避免每个请求进来都重复此操作。如果ISINREDIS
值为false,表示redis中还没有秒杀商品。那么就查询出所有参加秒杀的商品,商品id作为key,商品库存作为value,存到redis中,同时将商品id作为key,false作为value,放到第三步的map中,表示该商品没有售完。最后将ISINREDIS
auf true, was bedeutet, dass alle am Flash-Sale teilnehmenden Produkte zu Redis hinzugefügt wurden.
5. Lagerbestand einbehalten:
Verwenden Sie die Decr-Funktion von Redis, um die Warenmenge zu reduzieren und den reduzierten Wert zu beurteilen. Wenn das Ergebnis nach der Selbstabnahme kleiner als 0 ist, bedeutet dies, dass das Produkt ausverkauft ist. Dann wird der Wert der entsprechenden Produkt-ID in der Karte auf „true“ gesetzt und die Meldung „Es ist spät, das Produkt war schon“ wird angezeigt ausverkauft“ wird zurückgegeben.
6. Bestimmen Sie, ob der Flash-Sale wiederholt wird:
Wenn der Flash-Sale des Benutzers erfolgreich ist, werden nach dem Speichern des Flash-Sale-Auftrags in der Datenbank die Benutzer-ID und die Produkt-ID als Schlüssel verwendet und „true“ gespeichert in Redis, was darauf hinweist, dass der Benutzer das Produkt bereits geflasht hat. Hier gehen wir also zu Redis, basierend auf der Benutzer-ID und der Produkt-ID, um festzustellen, ob der Flash-Sale wiederholt wird. Wenn ja, wird die Aufforderung „Flash-Sale nicht wiederholen“ zurückgegeben.
7. Asynchrone Verarbeitung:
Wenn die oben genannten Überprüfungen bestanden werden, kann der Flash-Sale verarbeitet werden. Wenn Sie für jede Flash-Sale-Anfrage Lagerbestände abziehen und Bestellungen erstellen, ist nicht nur die Geschwindigkeit sehr langsam, sondern es kann auch zum Absturz der Datenbank führen. So können wir es asynchron verarbeiten, das heißt, nach bestandener Überprüfung werden die Benutzer-ID und die Produkt-ID als Nachrichten an MQ gesendet und anschließend wird sofort eine „Warteschlangen“-Eingabeaufforderung an den Benutzer zurückgegeben. Konsumieren Sie dann die Nachricht auf der Verbraucherseite von MQ, rufen Sie die Benutzer-ID und die Produkt-ID ab und fragen Sie den Lagerbestand anhand der Produkt-ID ab, um erneut einen ausreichenden Lagerbestand sicherzustellen. Anschließend können Sie auch bestimmen, ob der Flash-Verkauf wiederholt werden soll. Nachdem Sie das Urteil gefällt haben, betreiben Sie die Datenbank, ziehen den Lagerbestand ab und erstellen einen Flash-Sale-Auftrag. Beachten Sie, dass das Abziehen des Lagerbestands und das Erstellen von Flash-Sale-Bestellungen in derselben Transaktion erfolgen müssen.
8. Überverkaufsproblem:
Das Überverkaufsproblem ist ein negativer Warenbestand. Wenn der Lagerbestand beispielsweise 1 beträgt, verkaufen 10 Benutzer sofort gleichzeitig. Bei der Beurteilung des Lagerbestands sind alle 1, sodass 10 Personen erfolgreich Bestellungen aufgeben können, und der endgültige Lagerbestand beträgt -9. Wie kann man es lösen? Tatsächlich wird ein solches Problem in diesem System überhaupt nicht auftreten, da Redis zu Beginn zur Vorabreduzierung des Lagerbestands verwendet wird und das Redis-Befehlskernmodul Single-Threaded ist, sodass garantiert werden kann, dass es nicht überverkauft wird. Wenn Redis nicht verwendet wird, können Sie dem Produkt auch ein Versionsfeld hinzufügen, bevor Sie den Bestand jedes Mal abziehen. Fügen Sie der SQL eine Bedingung für den Abzug des Bestands hinzu, dh die Version muss mit der gerade gefundenen Version übereinstimmen.
二、核心代码
@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>
三、压测
用jmeter模拟并发请求,测试高并发情况下系统能否扛得住。由于只有一个id为1的商品,所以商品id固定写死1。但是每个用户都要先请求登录接口获取到token才能进行秒杀请求,有点儿麻烦,所以可以先把jwt模块注释掉,把userId当成参数传进去。jmeter配置如下图:


Das obige ist der detaillierte Inhalt vonSo implementieren Sie das Flash-Sale-System in Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

1. Starten Sie das Menü [Start], geben Sie [cmd] ein, klicken Sie mit der rechten Maustaste auf [Eingabeaufforderung] und wählen Sie Als [Administrator] ausführen. 2. Geben Sie nacheinander die folgenden Befehle ein (kopieren und fügen Sie sie sorgfältig ein): SCconfigwuauservstart=auto, drücken Sie die Eingabetaste. SCconfigbitsstart=auto, drücken Sie die Eingabetaste. SCconfigcryptsvcstart=auto, drücken Sie die Eingabetaste. SCconfigtrustedinstallerstart=auto, drücken Sie die Eingabetaste. SCconfigwuauservtype=share, drücken Sie die Eingabetaste. netstopwuauserv, drücken Sie die Eingabetaste für netstopcryptS

Engpässe bei PHP-Funktionen führen zu geringer Leistung, was durch die folgenden Schritte behoben werden kann: Suchen Sie die Engpassfunktion und verwenden Sie Tools zur Leistungsanalyse. Ergebnisse zwischenspeichern, um Neuberechnungen zu reduzieren. Verarbeiten Sie Aufgaben parallel, um die Ausführungseffizienz zu verbessern. Optimieren Sie die Zeichenfolgenverkettung und verwenden Sie stattdessen integrierte Funktionen. Verwenden Sie integrierte Funktionen anstelle benutzerdefinierter Funktionen.

Die Caching-Strategie in GolangAPI kann die Leistung verbessern und die Serverlast reduzieren. Häufig verwendete Strategien sind: LRU, LFU, FIFO und TTL. Zu den Optimierungstechniken gehören die Auswahl geeigneter Cache-Speicher, hierarchisches Caching, Invalidierungsmanagement sowie Überwachung und Optimierung. Im praktischen Fall wird der LRU-Cache verwendet, um die API zum Abrufen von Benutzerinformationen aus der Datenbank zu optimieren. Andernfalls kann der Cache nach dem Abrufen aus der Datenbank aktualisiert werden.

Es gibt Leistungsunterschiede zwischen Erlang und Go. Erlang zeichnet sich durch Parallelität aus, während Go einen höheren Durchsatz und eine schnellere Netzwerkleistung bietet. Erlang eignet sich für Systeme, die eine hohe Parallelität erfordern, während Go für Systeme geeignet ist, die einen hohen Durchsatz und eine geringe Latenz erfordern.

In der PHP-Entwicklung verbessert der Caching-Mechanismus die Leistung, indem er häufig aufgerufene Daten vorübergehend im Speicher oder auf der Festplatte speichert und so die Anzahl der Datenbankzugriffe reduziert. Zu den Cache-Typen gehören hauptsächlich Speicher-, Datei- und Datenbank-Cache. In PHP können Sie integrierte Funktionen oder Bibliotheken von Drittanbietern verwenden, um Caching zu implementieren, wie zum Beispiel Cache_get() und Memcache. Zu den gängigen praktischen Anwendungen gehören das Zwischenspeichern von Datenbankabfrageergebnissen zur Optimierung der Abfrageleistung und das Zwischenspeichern von Seitenausgaben zur Beschleunigung des Renderings. Der Caching-Mechanismus verbessert effektiv die Reaktionsgeschwindigkeit der Website, verbessert das Benutzererlebnis und reduziert die Serverlast.

Durch die Verwendung des Redis-Cache kann die Leistung des PHP-Array-Pagings erheblich optimiert werden. Dies kann durch die folgenden Schritte erreicht werden: Installieren Sie den Redis-Client. Stellen Sie eine Verbindung zum Redis-Server her. Erstellen Sie Cache-Daten und speichern Sie jede Datenseite in einem Redis-Hash mit dem Schlüssel „page:{page_number}“. Rufen Sie Daten aus dem Cache ab und vermeiden Sie teure Vorgänge auf großen Arrays.

Zuerst müssen Sie die Systemsprache auf die Anzeige in vereinfachtem Chinesisch einstellen und neu starten. Wenn Sie die Anzeigesprache zuvor auf vereinfachtes Chinesisch geändert haben, können Sie diesen Schritt natürlich einfach überspringen. Beginnen Sie als Nächstes mit dem Betrieb der Registrierung regedit.exe, navigieren Sie direkt zu HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlNlsLanguage in der linken Navigationsleiste oder der oberen Adressleiste und ändern Sie dann den InstallLanguage-Schlüsselwert und den Standardschlüsselwert auf 0804 (wenn Sie ihn in Englisch ändern möchten). us, Sie müssen zunächst die Anzeigesprache des Systems auf en-us einstellen, das System neu starten und dann alles auf 0409 ändern) Sie müssen das System an dieser Stelle neu starten.

Ja, Navicat kann eine Verbindung zu Redis herstellen, wodurch Benutzer Schlüssel verwalten, Werte anzeigen, Befehle ausführen, Aktivitäten überwachen und Probleme diagnostizieren können. Um eine Verbindung zu Redis herzustellen, wählen Sie in Navicat den Verbindungstyp „Redis“ und geben Sie die Serverdetails ein.
