Der Unterschied zwischen RPC und RESTful

RPC

Sowohl RPC als auch RESTful sind Remote-Aufrufschnittstellen. Was ist also der Unterschied zwischen ihnen? Früher war ich dumm und unklar. Erst als ich „Phoenix Architecture: Building a Reliable Large-Scale Distributed System“ von Herrn Zhou Zhiming las, erkannte ich den Unterschied zwischen ihnen. Ich hatte Angst, dass ich es vergessen würde es, also machte ich mir Notizen.

RPC (Remote Procedure Call, RPC), also Remote Procedure Call, wurde in den letzten Jahren häufig in verschiedenen Foren, Artikeln und Kursen erwähnt. Auf den ersten Blick dachte ich, es sei eine leistungsstarke neue Technologie. Tatsächlich gibt es sie Seit mehr als vierzig Jahren ist es eine durch und durch „alte Antiquität“.

Der ursprüngliche Zweck von RPC besteht darin, Computern den Aufruf von Remote-Methoden auf die gleiche Weise wie lokale Methoden zu ermöglichen.

Schauen wir uns zunächst an, wie der Computer den lokalen Ort aufruft. Ich habe das Beispiel im Buch kopiert:
// Caller: caller, main() im Code
// Callee: callee, println() im Code
// Call Site : Aufrufpunkt, also die Position des Befehlsflusses, an der der Methodenaufruf erfolgt
// Parameter: Parameter, die vom Aufrufer an Callee übergebenen Daten, also „Hallo Welt“
// Retval: Rückgabewert, die vom Callee an übergebenen Daten Aufrufer: Wenn die Methode normal enden kann, ist sie ungültig. Wenn die Methode abnormal abgeschlossen wird, handelt es sich um die entsprechende Ausnahme

public static void main(String[] args) {
    
        
System.out.println("hello world");
}

Ohne Berücksichtigung der Compiler-Optimierung muss der Computer (physische Maschine oder virtuelle Maschine) die folgenden Aufgaben ausführen, wenn das Programm ausgeführt wird, um die Methode println () aufzurufen und die Zeile „Hallo Welt“ auszugeben.

  1. Übergeben Sie Methodenparameter:
    Schieben Sie die Referenzadresse der Zeichenfolge „Hallo Welt“ auf den Stapel.
  2. Bestimmen Sie die Methodenversion:
    Bestimmen Sie anhand der Signatur der println()-Methode deren Ausführungsversion. Dies ist eigentlich kein einfacher Prozess. Unabhängig davon, ob es sich um eine statische Analyse zur Kompilierungszeit oder eine dynamische Zuordnung zur Laufzeit handelt, müssen Sie einen klaren Callee gemäß den in einigen Sprachspezifikationen klar definierten Prinzipien finden. „Definitiv“ bezieht sich auf den einzigen Callee. Oder mehrere Aufgerufene mit strengen Prioritäten, z. B. verschiedene überladene Versionen.
  3. Führen Sie die aufgerufene Methode aus:
    Nehmen Sie den Wert oder die Referenz von Parameter aus dem Stapel und verwenden Sie ihn als Eingabe, um die Logik in Callee auszuführen. Hier geht es uns nur darum, wie die Methode aufgerufen wird, nicht darum, wie die Methode darin ausgeführt wird.
  4. Ausführungsergebnis zurückgeben:
    Schieben Sie das Ausführungsergebnis von Callee auf den Stapel, stellen Sie den Befehlsfluss des Programms zur nächsten Anweisung von Call Site wieder her und fahren Sie mit der Ausführung nach unten fort.

Betrachten wir, was passiert, wenn sich die println()-Methode nicht im Speicheradressraum des aktuellen Prozesses befindet. Es ist nicht schwer, sich vorzustellen, dass dies auf mindestens zwei unmittelbare Hindernisse stoßen würde.

Zunächst hängen die im ersten und vierten Schritt übergebenen Parameter und zurückgegebenen Ergebnisse alle vom Stapelspeicher ab. Wenn der Aufrufer und der Angerufene zu unterschiedlichen Prozessen gehören, verfügen sie nicht über denselben Stapelspeicher. Zu diesem Zeitpunkt sind die Parameter vorhanden im Caller-Prozess gespeichert. Das Verschieben des Stapels in den Speicher ist für die Ausführung des Callee-Prozesses bedeutungslos.

Zweitens hängt die Auswahl der Methodenversion im zweiten Schritt von den Sprachregeln ab. Wenn Caller und Callee nicht in derselben Sprache implementierte Programme sind, ist die Auswahl der Methodenversion ein unscharfes und nicht erkennbares Verhalten.

Lassen Sie uns die zweite Frage vorerst ignorieren und davon ausgehen, dass Caller und Callee in derselben Sprache implementiert sind. Wie tauscht man also Daten zwischen zwei Prozessen aus? Dieses Problem soll durch „Inter-Process Communication“ (Inter-Process Communication, IPC) gelöst werden.

Mehrere Lösungen für die Interprozesskommunikation:

Pipe (Pipe) oder Named Pipe (Named Pipe)

Eine Pipe ähnelt einer Brücke zwischen zwei Prozessen. Über die Pipe kann eine kleine Menge an Zeichen- oder Byteströmen zwischen Prozessen übertragen werden. Gewöhnliche Pipes werden nur für die Kommunikation zwischen verwandten Prozessen verwendet (ein anderer Prozess wird von einem Prozess gestartet). Benannte Pipes beseitigen die Einschränkung gewöhnlicher Pipes ohne Namen. Zusätzlich zu allen Funktionen von Pipes ermöglichen sie auch unabhängige Kommunikation zwischen Prozessen.

Die typische Anwendung der Pipeline ist der Operator „|“ in der Befehlszeile,
zum Beispiel: ps -ef | grep java Sowohl
ps als auch grep haben unabhängige Prozesse. Der obige Befehl verwendet den Pipeline-Operator „|“, um die Standardausgabe von zu verbinden den ps-Befehl auf die Standardeingabe des grep-Befehls übertragen.

Signal

Signale werden verwendet, um den Zielprozess darüber zu informieren, dass ein Ereignis aufgetreten ist. Neben der Kommunikation zwischen Prozessen kann ein Prozess auch Signale an den Prozess selbst senden. Die typische Anwendung des Signals ist der Kill-Befehl,
zum Beispiel: Der obige Befehl kill -9 pid
bedeutet, dass der Shell-Prozess das SIGKILL-Signal an den Prozess mit der angegebenen PID sendet.

Semaphor

Das Semaphor wird zur Synchronisierung und Zusammenarbeit zwischen zwei Prozessen verwendet. Es entspricht einer speziellen Variablen, die vom Betriebssystem bereitgestellt wird, und das Programm kann darauf Wait()- und Notify()-Operationen ausführen.

Nachrichtenwarteschlange

Die oben genannten drei Methoden eignen sich nur für die Übertragung kleiner Nachrichtenmengen. Der POSIX-Standard definiert eine Nachrichtenwarteschlange, die für die Kommunikation großer Datenmengen zwischen Prozessen verwendet werden kann. Prozesse können Nachrichten zur Warteschlange hinzufügen, und Prozesse, denen eine Leseberechtigung erteilt wurde, können auch Nachrichten aus der Warteschlange konsumieren. Die Nachrichtenwarteschlange überwindet die Mängel des Signals, das weniger Informationen überträgt, die Pipeline kann nur für unformatierte Byteströme verwendet werden und die Puffergröße ist begrenzt, aber die Echtzeitleistung ist relativ begrenzt.

Geteilte Erinnerung

Die effizienteste Form der Kommunikation zwischen Prozessen besteht darin, mehreren Prozessen den Zugriff auf denselben gemeinsamen Speicherbereich zu ermöglichen. Ursprünglich waren die Speicheradressräume der einzelnen Prozesse voneinander isoliert, aber das Betriebssystem stellt eine Programmschnittstelle bereit, die es Prozessen ermöglicht, aktiv einen bestimmten Speicherbereich zu erstellen, zuzuordnen, zu trennen und zu steuern. Wenn ein Teil des Speichers von mehreren Prozessen gemeinsam genutzt wird, wird jeder Prozess oft in Kombination mit anderen Kommunikationsmechanismen, wie z. B. Semaphoren, verwendet, um prozessübergreifende Synchronisation und gegenseitige Ausschlusskoordinierungsoperationen zu erreichen.

Lokale Socket-Schnittstelle (IPC Socket)

Nachrichtenwarteschlangen und gemeinsam genutzter Speicher eignen sich nur für die Kommunikation zwischen mehreren Prozessen auf einer einzelnen Maschine, während die Socket-Schnittstelle ein allgemeinerer Kommunikationsmechanismus zwischen Prozessen ist, der für die Prozesskommunikation zwischen verschiedenen Maschinen verwendet werden kann. Socket (Socket) wurde ursprünglich vom BSD-Zweig des UNIX-Systems entwickelt und wurde nun auf alle gängigen Betriebssysteme portiert. Aus Gründen der Effizienz wird die Socket-Schnittstelle optimiert, wenn sie auf die lokale Kommunikation zwischen Prozessen beschränkt ist, den Netzwerkprotokollstapel nicht durchläuft und keine Vorgänge wie Ein- und Auspacken, Berechnung von Prüfsummen und Wartung erfordert Sequenznummern und Antworten. Es kopiert einfach die Daten der Anwendungsschicht von einem Prozess zu einem anderen. Diese prozessübergreifende Kommunikationsmethode ist die lokale Socket-Schnittstelle (UNIX Domain Socket), auch bekannt als IPC Socket.

Drei Probleme, die RPC lösen muss

wie man Daten darstellt

Zu den Daten gehören hier die an die Methode übergebenen Parameter und der Rückgabewert nach Ausführung der Methode. Das heißt, ein Prozess übergibt Parameter an einen anderen Prozess oder erhält einen Rückgabewert von einem anderen Prozess und wie wird das Datenformat ausgedrückt? Es mag für Sie seltsam sein, dass beispielsweise Programme, die in der Java-Sprache geschrieben sind, nicht ausreichen, um String, int und andere Typen zu übergeben? Verwenden Sie für den Methodenaufruf im Prozess den Datentyp derselben Sprache. Beispielsweise sind die Programme beider Parteien in der Java-Sprache geschrieben, sodass beim Aufruf kein Problem auftritt. Wenn jedoch der Anrufer in der Java-Sprache und der Angerufene in der C-Sprache geschrieben ist und ihre Datentypen unterschiedlich definiert sind, wie können sie dann kompatibel sein?

Selbst wenn beide Parteien in derselben Sprache geschrieben sind, z. B. in der C-Sprache, jedoch unter unterschiedlichen Hardware-Befehlssätzen und unterschiedlichen Betriebssystemen, kann derselbe Datentyp unterschiedliche Leistungsdetails aufweisen, z. B. Unterschiede in der Datenbreite und der Bytesequenz usw.

Was also tun?

Es ist einfach zu sagen: Konvertieren Sie zuerst die Daten, die beide Parteien kommunizieren möchten, in ein Zwischenformat, das jeder kennt, und konvertieren Sie dann die Daten im Zwischenformat in den Datentyp Ihrer eigenen Sprache. Kommt Ihnen das bekannt vor? Ja, das ist Serialisierung und Deserialisierung. Als ich Java lernte, wunderte ich mich über Serialisierung und Deserialisierung? Warum sollten Parameter serialisiert werden? Kannst du es nicht einfach weitergeben? Es stellt sich heraus, dass die Situation verschiedener Sprachen, Hardware und Betriebssysteme berücksichtigt werden muss.

Jedes RPC-Protokoll verfügt über ein entsprechendes Serialisierungsprotokoll, zum Beispiel:

  • Externe Datendarstellung (XDR) von ONC RPC
  • CORBAs Common Data Representation (CDR)
  • Java Object Serialization Stream Protocol (Java Object Serialization Stream Protocol) von Java RMI
  • gRPC-Protokollpuffer
  • XML-Serialisierung von Webdiensten
  • JSON-Serialisierung wird von zahlreichen leichtgewichtigen RPCs unterstützt

Es ist besonders berührend, die XML-Serialisierung von Web Service zu sehen. Als ich zuvor Web Service verwendet habe, war ich sehr überrascht, warum es so viel Aufwand erforderte, jedes Feld und jeden Parameter in XML zu beschreiben. Es stellte sich heraus, dass es sich um verschiedene Sprachen handelte. identifizieren.

So übergeben Sie Daten

Zusätzlich zur Serialisierung und Deserialisierung muss berücksichtigt werden, wie Daten zwischen zwei Programmen übertragen werden, d Bedürfnisse. In der Informatik gibt es einen speziellen Begriff „Wire Protocol“, der das Verhalten beim Austausch dieser Art von Daten zwischen zwei Endpunkten darstellt. Das gängige Wire Protocol lautet wie folgt:

  • Das Java Remote Message Exchange Protocol von Java RMI (Java Remote Message Protocol, JRMP, unterstützt auch RMI-IIOP)
  • Das Internet-ORB-Protokoll von CORBA (Internet Inter ORB Protocol, IIOP, ist die Implementierungsversion des GIOP-Protokolls auf dem IP-Protokoll)
  • DDS Real Time Publish Subscribe Protocol (Real Time Publish Subscribe Protocol, RTPS)
  • Webdienst Simple Object Access Protocol (Simple Object Access Protocol, SOAP)
  • Wenn die Anforderungen einfach genug sind, beide Parteien HTTP-Endpunkte sind, ist es auch möglich, das HTTP-Protokoll direkt zu verwenden (z. B. JSON-RPC).

Neben der Datenübertragung verfügt RPC über attraktivere Funktionen. Seine wahre Stärke liegt in seinen Governance-Funktionen wie Verbindungsmanagement, Zustandserkennung, Lastausgleich, ordnungsgemäßes Starten und Herunterfahren, Ausnahmewiederholung, Geschäftsgruppierung, Stromkreisunterbrechung und Strombegrenzung usw . .

Wie man Methode ausdrückt

Es stellt kein großes Problem dar, festzustellen, ob die Methode in der lokalen Methode aufgerufen wird. Der Compiler oder Interpreter wandelt die Methodensignatur des Aufrufs gemäß der Sprachspezifikation in einen Zeiger auf die Eintragsposition der Unterroutine im Prozessraum um. Sobald jedoch verschiedene Sprachen berücksichtigt werden, werden die Dinge sofort problematisch. Die Methodensignaturen jeder Sprache können unterschiedlich sein, sodass „wie man dieselbe Methode ausdrückt“ und „wie man die entsprechende Methode findet“ immer noch eine einheitliche Kreuzung erfordert. Sprachstandard. .

Dieser Standard kann sehr einfach sein, z. B. die direkte Angabe einer eindeutigen Nummer für jede Methode des Programms, die auf keinem Computer wiederholt wird. Beim Aufruf spielt es keine Rolle, um welche Methode es sich handelt oder wie die Signatur definiert ist. Übergeben Sie diese einfach Nummer direkt Sie können die entsprechende Methode finden. Diese Methode, die unhöflich und schäbig klingt, ist in Wirklichkeit die Lösung, die DCE/RPC ursprünglich vorbereitet hat. Am Ende entwickelte DCE zwar eine Reihe sprachunabhängiger Schnittstellenbeschreibungssprachen (Interface Description Language, IDL), die zur Grundlage für viele RPC-Referenzen oder -Abhängigkeiten wurden (z. B. OMG IDL von CORBA), aber der einzige Code, der sich niemals wiederholt Das Schema UUID (Universally Unique Identifier) ​​ist ebenfalls reserviert und weit verbreitet und wird in allen Aspekten der Programmentwicklung häufig verwendet.

Ebenso sind Protokolle zur Darstellung von Methoden:

  • Android-Schnittstellendefinitionssprache (Android Interface Definition Language, AIDL)
  • CORBAs OMG Interface Definition Language (OMG Interface Definition Language, OMG IDL)
  • Web Service Description Language (Web Service Description Language, WSDL) des Web Service
  • JSON-RPC JSON Web Service Protocol (JSON Web Service Protocol, JSON-WSP)

Die oben genannten drei Grundprobleme in RPC können beim Aufrufen lokaler Methoden alle entsprechende Lösungen finden. Das Design von RPC beginnt mit lokalen Methodenaufrufen. Obwohl es schon lange nicht mehr das gleiche Ziel wie lokale Methodenaufrufe verfolgt, sind seine Designideen immer noch tief von lokalen Methodenaufrufen geprägt. Die Verbindung zwischen beiden zu verstehen ist Eine Analogie für uns. Ein tieferes Verständnis der Natur von RPC kann hilfreich sein.

Um die oben genannten drei Probleme zu lösen, löst jedes RPC-Produkt das Problem aus einer anderen Perspektive. Einige konzentrieren sich auf Einfachheit, andere hoffen, mehr Sprachen zu unterstützen, um Universalität zu erreichen, und andere konzentrieren sich auf hohe Leistung. Nun gab es RMI (Sun/Oracle), Thrift (Facebook/Apache), Dubbo (Alibaba/Apache), gRPC (Google), Motan1/2 (Sina), Finagle (Twitter), brpc (Baidu/Apache). , .NET Remoting (Microsoft), Arvo (Hadoop), JSON-RPC 2.0 (öffentliche Spezifikation, JSON-RPC-Arbeitsgruppe) und andere Protokolle und Frameworks, die schwer erschöpfend aufzulisten sind. Diese RPC-Funktionen und -Eigenschaften sind nicht gleich, einige sind proprietär für eine bestimmte Sprache, einige unterstützen mehrere Sprachen, einige laufen auf dem HTTP-Protokoll der Anwendungsschicht und einige laufen direkt auf dem TCP/UDP-Protokoll der Transportschicht, aber nicht ein „perfekter RPC“.

Heutzutage strebt jedes brauchbare RPC-Framework nicht mehr nach einer großen und umfassenden „Perfektion“, sondern nimmt eine gezielte Funktion als Hauptentwicklungsrichtung an. Gleichzeitig hat dies auch zu Schwierigkeiten bei der Auswahl geführt und viele Online-Artikel und -Kurse hervorgebracht, in denen die Vor- und Nachteile jedes RPC erläutert werden. Wann wird ein RPC-König herauskommen und das vereinheitlichen? Welt?

AUSRUHEN

REST entstand aus Roy Thomas Fieldings Doktorarbeit „Architectural Styles and the Design of Network-based Software Architectures“, die im Jahr 2000 veröffentlicht wurde. Dieser Artikel ist tatsächlich die Quelle von REST. REST (Representational State Transfer, repräsentativer Zustandstransfer), der Name klingt sehr unklar, was ist „Repräsentation“, was ist der „Zustand“ von etwas und wohin wird es „übertragen“?

Um REST zu verstehen, müssen wir zunächst verstehen, was HTTP ist, und dann anhand einiger praktischer Beispiele eine Analogie zwischen den beiden ziehen, um REST klarer zu verstehen. Sie werden feststellen, dass REST tatsächlich eine weitere Abstraktion von „HTT“ (Hypertext Transfer) ist. Die Beziehung zwischen der Schnittstelle und der Implementierungsklasse ist dieselbe wie die Beziehung zwischen der Schnittstelle und der Implementierungsklasse.

Hypertext (oder Hypermedia)

„Hypertext (oder Hypermedia)“ ist eine Art „Text (oder Ton, Bild usw.), der Vorgänge beurteilen und darauf reagieren kann.“ Es wurde vollständig akzeptiert, und es ist keine Überraschung, dass ein Text im Internet vorhanden ist kann angeklickt, die Skriptausführung ausgelöst und der Server aufgerufen werden. Versuchen wir weiterhin zu verstehen, was „Repräsentation“ und andere Schlüsselkonzepte in REST aus der Bedeutung von „Hypertext“ oder „Hypermedia“ sind. Hier verwenden wir ein konkretes Beispiel, um es wie folgt zu beschreiben:

Ressource

Wenn Sie beispielsweise einen Artikel mit dem Titel „REST Design Style“ lesen, wird der Inhalt dieses Artikels (Sie können ihn als die darin enthaltenen Informationen und Daten verstehen) als „Ressource“ bezeichnet. Unabhängig davon, ob Sie ein gekauftes Buch, eine Webseite in einem Browser oder ein gedrucktes Dokument lesen, ob Sie es auf einem Computerbildschirm oder einem Mobiltelefon lesen, sind die darin enthaltenen Informationen dieselben, obwohl die Präsentation unterschiedlich ist. Sie lesen immer noch gleiche „Ressource“.

Darstellung

Wenn Sie diesen Artikel über einen Browser lesen, sendet der Browser eine Anfrage an den Server „Ich benötige das HTML-Format dieser Ressource“, und der vom Server an den Browser zurückgegebene HTML-Code wird als „Darstellung“ bezeichnet. Sie können auch übergeben Andere Möglichkeiten, PDF-, Markdown-, RSS- und andere Versionen dieses Artikels zu erhalten, sind auch mehrere Darstellungen einer Ressource. Es ist ersichtlich, dass sich „Repräsentation“ auf die Form der Darstellung bezieht, wenn Informationen mit Benutzern interagieren, was tatsächlich mit der Semantik der „Präsentationsschicht“ übereinstimmt, die in unserer Software-Schichtarchitektur häufig genannt wird.

Zustand

Wenn Sie diesen Artikel zu Ende gelesen haben und sehen möchten, was als nächstes kommt, senden Sie eine „Gib mir den nächsten Artikel“-Anfrage an den Server. Aber „nächster Artikel“ ist ein relativer Begriff und muss davon abhängen, „welchen Artikel Sie gerade lesen“, um richtig zu reagieren. Diese Art von Kontextinformationen, die nur in einem bestimmten Kontext generiert werden können, werden „Status“ genannt. Was wir als zustandsbehaftet (Stateful) oder zustandslos (Stateless) bezeichnen, bezieht sich nur auf die Serverseite. Die Serverseite muss die Anforderung „Nächsten Artikel abrufen“ abschließen oder sich den Status des Benutzers selbst merken, z. B. Welchen Artikel der Benutzer liest wird jetzt als zustandsbehaftet bezeichnet; oder der Client kann sich den Zustand merken und dem Server bei einer Anfrage klar mitteilen, dass ich beispielsweise einen bestimmten Artikel lese und jetzt den nächsten Artikel lesen möchte, der als zustandslos bezeichnet wird. Mit anderen Worten: Die Aufzeichnung des Benutzerstatus durch den Server wird als zustandsbehaftet bezeichnet; die Aufzeichnung des Status durch den Client und die Übermittlung an den Server wird als zustandslos bezeichnet.

Überweisen

Unabhängig davon, ob der Status vom Server oder vom Client bereitgestellt wird, kann die Verhaltenslogik zum „Abrufen eines Artikels“ nur vom Server bereitgestellt werden, da nur der Server Eigentümer der Ressource und ihrer Darstellung ist. Auf irgendeine Weise wandelt der Server den „aktuell vom Benutzer gelesenen Artikel“ in den „nächsten Artikel“ um, was als „repräsentativer Zustandstransfer“ bezeichnet wird.

Eines der Kernprinzipien von REST ist „Uniform Interface“. REST hofft, dass Entwickler ressourcenorientiert programmieren und hofft, dass sich der Entwurf des Softwaresystems darauf konzentriert, welche Ressourcen ein abstraktes System haben sollte, und nicht darauf, welche Verhaltensweisen (Dienste) ein abstraktes System hat System sollte haben. . Sie können dieses Prinzip in Analogie zum Vorgang der Dateiverwaltung auf einem Computer verstehen. Die Verwaltung von Dateien kann Vorgänge wie Erstellen, Ändern, Löschen und Verschieben umfassen. Die Anzahl dieser Vorgänge ist zählbar und sie sind für alle Dateien festgelegt und einheitlich . Wenn das System für Ressourcen ausgelegt ist, weist es auch ähnliche Betriebseigenschaften auf. Da REST kein neues Protokoll entwirft, werden diese Vorgänge durch Ausleihen der inhärenten Betriebsbefehle im HTTP-Protokoll abgeschlossen.

Die einheitliche Schnittstelle ist auch der Ort, an dem REST am wahrscheinlichsten kontrovers diskutiert wird. Ob ein netzwerkbasiertes Softwaresystem eher für ressourcenorientiertes oder serviceorientiertes System geeignet ist, diese Frage wird möglicherweise noch lange nicht geklärt sein, vielleicht sogar nie Sei. Grundsätzlich lässt sich jedoch eine klare Schlussfolgerung ziehen: Ressourcenorientierte Programmierung weist im Allgemeinen eine höhere Abstraktionsebene auf. Ein hoher Abstraktionsgrad hat den Nachteil, dass er oft weiter von der menschlichen Denkweise entfernt ist, und der Vorteil ist, dass der Generalisierungsgrad oft besser ist.

Die Verwendung einer solchen Sprache zur Interpretation von REST ist noch etwas abstrakt. Hier ein Beispiel zur Veranschaulichung: Zum Beispiel für die Anmelde- und Abmeldefunktionen, über die fast jedes System verfügt, wenn Sie verstehen, dass Anmeldung dem Dienst login() und Abmelden entspricht to logout ()-Dienste sind zwei unabhängige Dienste, die „im Einklang mit dem menschlichen Denken“ stehen. Wenn Sie verstehen, dass die Anmeldung eine PUT-Sitzung und die Abmeldung eine DELETE-Sitzung ist, müssen Sie nur eine „Sitzungsressource“ entwerfen, um sie zu erfüllen Die Bedürfnisse und sogar spätere andere Anforderungen an die Sitzung, wie z. B. das Abfragen der Informationen des angemeldeten Benutzers, sind nur GET Session. Andere Vorgänge wie das Ändern von Benutzerinformationen können ebenfalls in denselben Entwurfssatz einbezogen werden. Dies ist der Vorteil der „höheren Abstraktion“.

Wenn Sie die einheitliche Schnittstelle sinnvoll und angemessen im Architekturentwurf verwenden möchten, wird empfohlen, dass das System in der Lage sein sollte, die ID der Ressource in jede Anforderung aufzunehmen und alle Vorgänge über die Ressourcen-ID auszuführen. Dies wird empfohlen Jede Ressource sollte eine selbstbeschreibende Nachricht sein. Es wird empfohlen, die Übertragung des Anwendungsstatus über Hypertext voranzutreiben.

REST ist an das HTTP-Protokoll gebunden. Ressourcenorientierte Programmierung muss nicht auf HTTP aufbauen, REST jedoch schon, was sowohl einen Nachteil als auch einen Vorteil darstellt. Da HTTP ursprünglich ein ressourcenorientiertes Netzwerkprotokoll ist, besteht der Vorteil der reinen Verwendung von HTTP (anstatt das Protokoll wie SOAP über HTTP neu zu erstellen) darin, dass das Problem des Wire-Protokolls in RPC nicht berücksichtigt werden muss und REST das definierte HTTP wiederverwendet Protokoll. Konzepte und damit verbundene grundlegende Unterstützung zur Lösung von Problemen. Das HTTP-Protokoll funktioniert seit 30 Jahren effektiv und die zugehörige technische Infrastruktur ist temperiert und ausgereift. Der Nachteil besteht natürlich darin, dass Sie völlig hilflos sind, wenn Sie Funktionen berücksichtigen möchten, die HTTP nicht bietet.

Im HTTP-Protokoll wurde vorab ein Satz „einheitlicher Schnittstellen“ vereinbart, der sieben Grundoperationen umfasst: GET, HEAD, POST, PUT, DELETE, TRACE und OPTIONS. Jeder Server, der das HTTP-Protokoll unterstützt, wird sich an diesen Satz halten von Vorschriften. Der URI führt diese Aktionen aus und der Server löst den entsprechenden repräsentativen Zustandsübergang aus.

Die REST-Schnittstelle ist leicht zu verstehen. Nehmen wir als konkretes Beispiel das Schnittstellendesign eines Einkaufszentrum-Benutzerzentrums: Benutzerressourcen verfügen über mehrere verschiedene untergeordnete Ressourcen, z. B. mehrere Kurznachrichtenressourcen, eine Benutzerprofilressource und eine Warenkorbressource. Der Warenkorb verfügt über eigene Ressourcen auf niedrigerer Ebene, z. B. mehrere Buchressourcen. Sie können die festgelegte Beziehung und die hierarchische Beziehung dieser Ressourcen einfach in der Programmoberfläche erstellen. Diese Beziehungen entsprechen der langjährigen Erfahrung der Benutzer bei der Verwaltung von Daten in einer eigenständigen oder Netzwerkumgebung. Ich glaube, dass Sie das Schnittstellenhandbuch nicht speziell lesen müssen, und Sie können leicht daraus schließen, dass die REST-Schnittstelle zum Erhalten des zweiten Buches im Warenkorb des Benutzers icyfenix wie folgt ausgedrückt werden sollte: GET /users/icyfenix/cart/
2 .

Hier noch ein paar Beispiele:

  • GET /books: Alle Bücher auflisten
  • POST /books: ein neues Buch erstellen
  • GET /books/ID: Informationen zu einem bestimmten Buch abrufen
  • PUT /books/ID: Informationen zu einem Buch aktualisieren (alle Informationen zum Buch bereitstellen)
  • PATCH /books/ID: Informationen zu einem bestimmten Buch aktualisieren (einige Informationen über das Buch bereitstellen)
  • DELETE /books/ID: Ein Buch löschen

Der Unterschied zwischen RPC und RESTful

Viele Leute werden REST mit RPC vergleichen. Tatsächlich unterscheidet sich REST in Bezug auf Ideologie, Konzept und Anwendungsbereich von RPC. Im besten Fall gibt es einige Ähnlichkeiten und einige Anwendungen werden sich überschneiden. , aber nicht im Wesentlichen der gleiche Typ Ding.

Der Kern des ideologischen Unterschieds zwischen RPC und REST ist der Unterschied in den abstrakten Zielen, also der Unterschied zwischen prozessorientierten Programmierideen und ressourcenorientierten Programmierideen.

Der konzeptionelle Unterschied zwischen REST und RPC bedeutet, dass REST kein Remote-Service-Call-Protokoll ist und sogar das Attribut entfernt werden kann, sodass es sich nicht um ein Protokoll handelt. Protokolle sind standardisiert und obligatorisch. Zumindest gibt es ein Spezifikationsdokument wie JSON-RPC. Auch wenn es einfach ist, gibt es auch die „JSON-RPC-Spezifikation“, um die Formatdetails, Ausnahmen, Antwortcodes und andere Informationen anzugeben Das Protokoll. REST definiert diese jedoch nicht, und obwohl es einige Richtlinien gibt, unterliegt es keiner wirklichen Durchsetzung. Manche Leute kritisieren eine Systemschnittstelle oft als „nicht darauf ausgelegt, REST-fähig genug zu sein“. Tatsächlich ist dieser Satz selbst etwas umstritten. REST kann nur als Stil und nicht als Spezifikation oder Protokoll und als System bezeichnet werden, das die Anforderungen vollständig erfüllen kann mit allen REST-Leitprinzipien ist ebenfalls selten. .

Die Grundidee von REST besteht darin, Probleme ressourcenorientiert zu abstrahieren, was sich wesentlich von der bisher populären Programmieridee unterscheidet – der prozessorientierten Programmierung im abstrakten Fach. Bevor REST vorgeschlagen wurde, war RPC die einzige Lösung für die Entwicklung verteilter Systemdienste. RPC besteht darin, die Idee des lokalen Methodenaufrufs auf einen Remote-Methodenaufruf zu migrieren. Entwickler entwerfen die Interaktion zwischen den beiden Systemen rund um die „Remote-Methode“. Wie CORBA , RMI, DCOM usw. Die Nachteile davon führen nicht nur dazu, dass „wie man eine Methode zwischen heterogenen Systemen darstellt“ und „wie man eine Liste von Methoden erhält, die eine Schnittstelle bereitstellen kann“ zu Problemen werden, die durch ein spezielles Protokoll gelöst werden müssen (eines der drei Grundprobleme). von RPC), sondern auch für die Nutzung von Diensten Da jede Methode des Dienstes für Benutzer völlig unabhängig ist, müssen sie nacheinander lernen, diese Methoden korrekt zu verwenden. Eine solche Passage hat Google einmal im „Google API Design Guide“ geschrieben.

„In der Vergangenheit wurden RPC-APIs für Methoden wie CORBA und DCOM entworfen. Mit der Zeit gibt es immer mehr Schnittstellen und Methoden, aber sie unterscheiden sich. Entwickler müssen jede Methode verstehen, um sie richtig verwenden zu können, und das kostet Zeit.“ -aufwändig. Und es ist leicht, Fehler zu machen.“

Das heißt, der RPC-Client muss zunächst die Methoden auf der Serverseite kennen, bevor er sie aufrufen kann.

Bevor wir die Web-Service-Schnittstelle aufrufen, müssen wir den Client über die vom Server bereitgestellte WSDL-Datei generieren. Der Client kennt die Methoden und Parameter des Servers über die WSDL-Datei.

Ebenso verfügt gRPC auch über Server und Clients. Das Beispieldiagramm für gRPC-Aufrufe sieht wie folgt aus:
Fügen Sie hier eine Bildbeschreibung ein

Schauen wir uns einen Teil des gRPC-Codes an.

Server:

  /**
  * 对外暴露服务
  **/
  private void start() throws IOException {
    
    
    int port = 50051;
    server = ServerBuilder.forPort(port)
        .addService(new HelloServiceImpl())
        .build()
        .start();
    Runtime.getRuntime().addShutdownHook(new Thread() {
    
    
      @Override
      public void run() {
    
    
        HelloWorldServer.this.stop();
      }
    });
  }

Klient:

  /**
    * 发送rpc请求
    **/
    public void say(String name) {
    
    
        // 构建入参对象
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        HelloReply response;
        try {
    
    
            // 发送请求
            response = blockingStub.say(request);
        } catch (StatusRuntimeException e) {
    
    
            return;
        }
        System.out.println(response);
    }

Der Client muss zunächst die say()-Methode des Servers kennen, bevor er sie aufruft.

REST arbeitet mit Ressourcen, und wenn REST für die Reifestufe 3 ausgelegt ist: Hypermedia Controls (Hypertext-gesteuert), gibt der Server einen Hyperlink zum nächsten Vorgang zurück. Abgesehen davon, dass die erste Anfrage durch die Informationen gesteuert wird, die Sie in die Adressleiste des Browsers eingeben, sollten alle anderen Anfragen in der Lage sein, die möglichen nachfolgenden Zustandsübergänge selbst zu beschreiben, gesteuert durch den Hypertext selbst.

Schauen wir uns ein Beispiel aus dem Buch an:

HTTP/1.1 200 OK

{
    
    
    schedules:[
        {
    
    
            id: 1234, start:"14:00", end: "14:50", doctor: "mjones",
            links: [
                {
    
    rel: "comfirm schedule", href: "/schedules/1234"}
            ]
        },
        {
    
    
            id: 5678, start:"16:00", end: "16:50", doctor: "mjones",
            links: [
                {
    
    rel: "comfirm schedule", href: "/schedules/5678"}
            ]
        }
   ],
   links: [
       {
    
    rel: "doctor info", href: "/doctors/mjones/info"}
   ]
}

Auch wenn der Server keinen Link zum nächsten Vorgang zurückgibt, kann der Client nach Kenntnis der Ressource sogar die URL des nächsten Vorgangs erraten.

Zusammenfassen

RPC ruft Remote-Methoden mit der Idee auf, lokale Methoden aufzurufen, und verbirgt die Details zum Aufrufen von Remote-Methoden über verschiedene RPC-Frameworks, sodass Benutzer denken, dass sie lokale Methoden aufrufen. RPC verbirgt die Komplexität der zugrunde liegenden Netzwerkkommunikation, sodass wir uns mehr auf die Entwicklung der Geschäftslogik konzentrieren können.

REST wird über HTTP implementiert, das Benutzeranforderungen in Operationen auf Ressourcen abstrahiert. Benutzer müssen mit dem Server über sieben grundlegende Operationen des HTTP-Protokolls interagieren: GET, HEAD, POST, PUT, DELETE, TRACE und OPTIONS.

RPC ist normalerweise die Kommunikation zwischen Servern, z. B. die Kommunikation mit Middleware, MQ, verteiltem Cache, verteilter Datenbank usw.

REST ist normalerweise clientorientiert (normalerweise ein Browser) und ihre Verwendungsszenarien sind ebenfalls unterschiedlich.

Abschließend empfehle ich „Phoenix Architecture: Building a Reliable Large-Scale Distributed System“ von Zhou Zhiming. Der größte Teil des Inhalts dieses Artikels wurde aus diesem Buch kopiert.

Je suppose que tu aimes

Origine blog.csdn.net/zhanyd/article/details/120989711
conseillé
Classement