Heim >häufiges Problem >So stellen Sie die Idempotenz von Schnittstellen bei hoher Parallelität sicher
In unserem tatsächlichen System gibt es viele Vorgänge, die unabhängig von der Häufigkeit ihrer Ausführung denselben Effekt haben oder dasselbe Ergebnis liefern sollten.
Zum Beispiel:
Wenn das Front-End die ausgewählten Daten wiederholt übermittelt, sollte der Hintergrund nur ein Antwortergebnis generieren, das diesen Daten entspricht.
Wenn wir eine Zahlungsanforderung einleiten, sollte das Benutzerkonto nur einmal abgebucht werden. Wenn ein erneutes Senden des Netzwerks oder ein Systemfehler auftritt, sollte das Geld nur einmal abgebucht werden , die gleiche Textnachricht wird an den Benutzer gesendet und der Benutzer wird weinen:
Eine Geschäftsanfrage erstellen Es kann immer nur eine einzige Geschäftsanfrage erstellt werden.
und viele andere wichtige Situationen erfordern zur Unterstützung dieser Logiken idempotente Funktionen.
Idempotenz (Idempotenz, Idempotenz) ist ein mathematisches und informatisches Konzept, das häufig in der abstrakten Algebra vorkommt.
Diese Funktionen wirken sich nicht auf den Systemstatus aus und Sie müssen sich keine Sorgen über Änderungen am System machen, die durch wiederholte Ausführung verursacht werden. Beispielsweise sind die Funktionen „getUsername() und setTrue()“ idempotente Funktionen.
Komplexere Operationen sind durch die Verwendung einer eindeutigen Transaktionsnummer (Seriennummer) garantiert idempotent.
Mein Verständnis: Egal wie oft sie ausgeführt wird, der Effekt und das zurückgegebene Ergebnis sind gleich.
1. Abfragevorgang Wenn Sie einmal oder mehrmals abfragen, sind die Abfrageergebnisse dieselben, wenn die Daten unverändert bleiben. Select ist eine natürliche idempotente Operation
2. Löschoperationen sind ebenfalls idempotent. (Beachten Sie, dass die zurückgegebenen Ergebnisse unterschiedlich sein können. Die gelöschten Daten sind nicht vorhanden, daher wird 0 zurückgegeben. Wenn mehrere gelöschte Daten vorhanden sind, werden mehrere Ergebnisse zurückgegeben.)
3. Eindeutiger Index, um neue schmutzige Daten zu verhindern Beispiel: Alipay-Fondskonto, Alipay Es gibt auch Benutzerkonten. Wie kann verhindert werden, dass für einen Benutzer mehrere Fondskonten erstellt werden? damit ein Benutzer erfolgreich einen Fondskontodatensatz hinzufügen kann
Wichtige Punkte:Eindeutiger Index oder eindeutiger kombinierter Index, um schmutzige Daten in neuen Daten zu verhindern (wenn die Tabelle einen eindeutigen Index hat und beim Hinzufügen neuer Daten während der Parallelität ein Fehler gemeldet wird, Fragen Sie es einfach erneut ab. Die Daten sollten bereits vorhanden sein. Geben Sie einfach das Ergebnis zurück.
4Geschäftsanforderungen:
Die Daten auf der Seite können nur einmal angeklickt und übermittelt werden
Ursache: Aufgrund wiederholter Klicks, Netzwerk-Erneutsendungen oder Nginx-Erneutsendungen usw. werden die Daten wiederholt übermittelt
Lösung: Cluster Umgebung: Token verwenden Redis hinzufügen (Redis ist Single-Threaded, die Verarbeitung muss in die Warteschlange gestellt werden) Einzelne JVM-Umgebung: Token plus Redis oder Token plus JVM-Speicher verwenden
Verarbeitungsprozess:
Bevor Sie Daten übermitteln, müssen Sie eine beantragen Token vom Dienst, und das Token wird in Redis oder JVM abgelegt. Speicher, Token-Gültigkeitszeit
Nach der Übermittlung überprüft der Hintergrund das Token, löscht gleichzeitig das Token und generiert ein neues Token für die Rückgabe
Token-Funktionen:
Zur Anwendung ist es einmal gültig und die aktuelle Gültigkeit kann begrenzt werden.
Hinweis: Verwenden Sie den Löschvorgang, um das Token zu beurteilen. Wenn Sie select+ verwenden, ist das Löschen erfolgreich Wenn Sie das Token löschen, treten Parallelitätsprobleme auf und es wird nicht empfohlen, es zu verwenden.
5. Sperren Sie die Erfassung beim Erfassen der Daten select * from table_xxx where id='xxx' for update; Hinweis: Das ID-Feld muss der Primärschlüssel oder der einzige Index sein, sonst wird die Tabelle gesperrt, was zum Tod von Personen führt Pessimistische Sperren werden im Allgemeinen zusammen verwendet mit Transaktionen und der Datensperrzeit Es kann sehr lang sein, wählen Sie bitte entsprechend der tatsächlichen Situation 6. Optimistische Sperre sperrt die Tabelle nur zum Zeitpunkt der Datenaktualisierung und nicht zu anderen Zeiten, daher ist es effizienter als pessimistisches Sperren. update table_xxx set name=#name#,version=version+1 where version=#version#
update tablexxx set avaiamount=avaiamount-#subAmount# where avaiamount-#subAmount# >= 0Anforderungen:quality-#subQuality# >=, dieses Szenario ist für keine Versionsnummer geeignet, nur Aktualisierung dient der Überprüfung der Datensicherheit, geeignet für Inventarmodell, Anteilsabzug und Rollback-Anteil, höhere Leistung
注意:乐观锁的更新操作,最好用主键或者唯一索引来更新,这样是行锁,否则更新时会锁表,上面两个sql改成下面的两个更好
update tablexxx set name=#name#,version=version+1 where id=#id# and version=#version#update tablexxx set avaiamount=avaiamount-#subAmount# where id=#id# and avai_amount-#subAmount# >= 0
7. 分布式锁 还是拿插入数据的例子,如果是分布是系统,构建全局唯一索引比较困难,例如唯一性的字段没法确定
这时候可以引入分布式锁,通过第三方的系统(redis或zookeeper),在业务系统插入数据或者更新数据,获取分布式锁,然后做操作,之后释放锁
这样其实是把多线程并发的锁的思路,引入多多个系统,也就是分布式系统中得解决思路。
要点:某个长流程处理过程要求不能并发执行,可以在流程执行之前根据某个标志(用户ID+后缀等)获取分布式锁,其他流程执行时获取锁就会失败,也就是同一时间该流程只能有一个能执行成功,执行完成后,释放分布式锁(分布式锁要第三方系统提供)
8. select + insert 并发不高的后台系统,或者一些任务JOB,为了支持幂等,支持重复执行,简单的处理方法是,先查询下一些关键数据,判断是否已经执行过,在进行业务处理,就可以了
注意:核心高并发流程不要用这种方法
9. 状态机幂等 在设计单据相关的业务,或者是任务相关的业务,肯定会涉及到状态机(状态变更图),就是业务单据上面有个状态,状态在不同的情况下会发生变更,一般情况下存在有限状态机
Wenn sich der Zustandsautomat bereits im nächsten Zustand befindet und zu diesem Zeitpunkt ein Wechsel zum vorherigen Zustand erfolgt, kann der Wechsel theoretisch nicht durchgeführt werden. In diesem Fall ist die Idempotenz des endlichen Zustandsautomaten garantiert.
Hinweis: Aufträge und andere dokumentartige Geschäfte haben einen langen Zustandsfluss. Sie müssen über ein tiefes Verständnis der Zustandsmaschinen verfügen, was erheblich dazu beitragen wird, die Designfähigkeiten Ihres Geschäftssystems zu verbessern. 10 So stellen Sie die Idempotenz für bereitgestellte APIs sicher externe Schnittstellen
Zum Beispiel die von UnionPay bereitgestellte Zahlungsschnittstelle: Wenn Sie auf den Händler zugreifen müssen, um eine Zahlungsanforderung einzureichen, enthält diese Folgendes: Quelle Quelle, seq Seriennummer
Quelle+seq erstellt einen eindeutigen Index in der Datenbank um mehrere Zahlungen zu verhindern (bei gleichzeitiger Verarbeitung kann nur eine Anfrage verarbeitet werden)Wichtiger Punkt
Um eine externe Schnittstelle zur Unterstützung idempotenter Aufrufe bereitzustellen, muss die Schnittstelle zwei Felder übergeben, eines ist die Quelle und das other ist die Quellsequenznummer seq. Diese beiden Felder werden als gemeinsamer eindeutiger Index im Anbietersystem verwendetAuf diese Weise wird bei einem Anruf eines Dritten zunächst im eigenen System überprüft, ob es verarbeitet wurde, und das zurückgegeben werden entsprechendes Verarbeitungsergebnis; wenn es nicht verarbeitet wurde, führen Sie die entsprechende Verarbeitung durch und geben Sie das Ergebnis zurück.
Beachten Sie, dass Sie, um idempotent und freundlich zu sein, zunächst prüfen müssen, ob das Geschäft verarbeitet wurde. Wenn Sie es ohne Abfrage direkt in das Geschäftssystem einfügen, wird ein Fehler gemeldet, es wurde jedoch tatsächlich verarbeitet.Idempotenz sollte ein Gen für qualifizierte Programmierer sein, insbesondere bei Systemen wie Alipay, Banken, Internet-Finanzunternehmen usw. Es muss effizient sein Außerdem müssen die Daten korrekt sein, damit es nicht zu Problemen wie übermäßigen Abzügen und Überzahlungen kommen kann. Dies wird schwierig zu bewältigen sein und die Benutzererfahrung wird nicht gut sein.
Das obige ist der detaillierte Inhalt vonSo stellen Sie die Idempotenz von Schnittstellen bei hoher Parallelität sicher. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!