Heim  >  Artikel  >  Backend-Entwicklung  >  Java-Backend-Entwicklung: Implementierung eines leistungsstarken API-Servers mit Netty

Java-Backend-Entwicklung: Implementierung eines leistungsstarken API-Servers mit Netty

WBOY
WBOYOriginal
2023-06-17 11:04:481740Durchsuche

Mit der rasanten Entwicklung der Internettechnologie sind die Anforderungen an hohe Leistung, hohe Parallelität und hohe Verfügbarkeit auf der Serverseite immer höher geworden. Als leistungsstarkes, asynchrones und nicht blockierendes Netzwerkkommunikations-Framework ist Netty erfreut sich bei Entwicklern zunehmender Beliebtheit und Nutzung.

In diesem Artikel wird erläutert, wie Sie mit dem Netty-Framework einen leistungsstarken API-Server implementieren.

1. Was ist Netty? Netty ist ein asynchrones, ereignisgesteuertes Netzwerkanwendungsframework auf Basis von Java NIO, mit dem schnell leistungsstarke und zuverlässige Netzwerkkommunikationsprogramme wie Clients und Server entwickelt werden können.

Zu seinen Kernkomponenten gehören Puffer, Kanal, EventLoop, Codec usw. Buffer ist die Pufferkomponente von Netty, Channel bietet eine abstrakte Netzwerkkommunikationsschnittstelle, EventLoop ist das ereignisgesteuerte Modell von Netty und Codec ist ein Codec. Durch diese Komponenten kann das Netty-Framework leistungsstarke Netzwerkkommunikationsfunktionen mit hoher Parallelität und geringer Latenz bereitstellen.

2. Grundlegende Verwendung von Netty

Zuerst müssen wir Netty-Abhängigkeiten einführen:

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.42.Final</version>
</dependency>

Dann müssen wir ein Bootstrap-Objekt erstellen und dieses Objekt verwenden, um unseren Netty-Server zu starten:

EventLoopGroup bossGroup = new NioEventLoopGroup(); 
EventLoopGroup workerGroup = new NioEventLoopGroup(); 
try{
    ServerBootstrap bootstrap = new ServerBootstrap();
    bootstrap.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ChannelPipeline pipeline = ch.pipeline();
                     pipeline.addLast(new HttpServerCodec());
                     pipeline.addLast(new HttpObjectAggregator(65536));
                     pipeline.addLast(new ChunkedWriteHandler());
                     pipeline.addLast(new HttpServerHandler());
                  }
              });
    ChannelFuture future = bootstrap.bind(port).sync();
    future.channel().closeFuture().sync();
}finally{
      bossGroup.shutdownGracefully();
      workerGroup.shutdownGracefully();
}

Im obigen Code: hat zwei EventLoopGroup-Objekte erstellt, eine „bossGroup“ zum Empfangen von Client-Anfragen und eine „workerGroup“ zum Verarbeiten von Client-Anfragen. Konfigurieren Sie die Parameter des Netty-Servers über das ServerBootstrap-Objekt, einschließlich des Kommunikationsprotokolls (NioServerSocketChannel), des Prozessors (Handler) und der Kanalinitialisierung sowie anderer Vorgänge.

Wir können auch sehen, dass wir im obigen Code die Komponenten HttpServerCodec und HttpObjectAggregator hinzugefügt haben, um die Kodierung, Dekodierung und Aggregation von HTTP-Anfragen und -Antworten zu implementieren. Gleichzeitig haben wir ChunkedWriteHandler hinzugefügt, um die Verarbeitung großer Datenströme zu implementieren.

Schließlich binden wir den Port und starten den Netty-Server über die Methode „bootstrap.bind“, blockieren den Hauptthread und warten darauf, dass der Netty-Server über die Methode „future.channel().closeFuture().sync()“ heruntergefahren wird .

3. Verwenden Sie Netty, um einen leistungsstarken API-Server zu implementieren.

Für einen API-Server müssen wir normalerweise eine große Anzahl von Anfragen und Antworten verarbeiten und gleichzeitig die Systemverfügbarkeit und eine leistungsstarke Antwortzeit sicherstellen.

Hier nehmen wir die Implementierung eines einfachen API-Servers als Beispiel, um vorzustellen, wie das Netty-Framework zur Implementierung eines Hochleistungs-API-Servers verwendet wird.

1. Schnittstellendefinition

Lassen Sie uns zunächst eine einfache API-Schnittstelle definieren, die zur Implementierung der Funktion zum Abrufen von Benutzerinformationen verwendet wird:

GET /user/{id} HTTP/1.1
Host: localhost:8888

wobei {id} die ID-Nummer des Benutzers ist, müssen wir eine Abfrage basierend auf dieser ID-Nummer durchführen Benutzerinformationen und an den Kunden zurückgegeben.

2. Geschäftsverarbeitung

Als nächstes müssen wir die Geschäftslogikverarbeitung implementieren, das heißt, Benutzerinformationen basierend auf der ID-Nummer in der Client-Anfrage abfragen und die Abfrageergebnisse an den Client zurückgeben.

Erstens erstellen wir einen Prozessor HttpServerHandler, der von SimpleChannelInboundHandler erbt. Wir können unsere Geschäftslogik in diesem Prozessor implementieren.

public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
        HttpServerRoute route = HttpServerRoute.builder()
                .addRoute("/user/{id}", new GetUserHandler())
                .build();
        HttpServerRequest request = new HttpServerRequest(msg);
        HttpServerResponse response = new HttpServerResponse(ctx, msg);
        route.route(request, response);
    }
}

Sie können sehen, dass wir im obigen Code den Routenabgleich über das HttpServerRoute-Objekt implementieren. Wenn wir eine Client-Anfrage erhalten, konvertieren wir die Anfrage in ein HttpServerRequest-Objekt, wickeln das Antwortobjekt HttpServerResponse darin ein und verwenden dann das HttpServerRoute-Objekt, um die Routing-Regeln abzugleichen und die Anfrage zur Verarbeitung an den entsprechenden Prozessor zu verteilen.

Wir müssen den GetUserHandler-Prozessor implementieren, der zum Abfragen von Benutzerinformationen basierend auf der Benutzer-ID verwendet wird:

public class GetUserHandler implements HttpServerHandlerInterface {
    @Override
    public void handle(HttpServerRequest request, HttpServerResponse response) throws Exception {
        String id = request.getPathParam("id");
        //查询用户信息
        User user = UserService.getUserById(id);
        if (user != null) {
            JSONObject json = new JSONObject();
            json.put("id", user.getId());
            json.put("name", user.getName());
            response.sendJSON(HttpResponseStatus.OK, json.toJSONString());
        } else {
            response.sendError(HttpResponseStatus.NOT_FOUND);
        }
    }
}

Im obigen Code fragen wir Benutzerinformationen basierend auf der ID-Nummer in der Anfrage ab und erstellen den JSON des Fordern Sie eine Antwort über JSONObject-String-Daten an und geben Sie schließlich die Abfrageergebnisse an den Client zurück.

Wir müssen auch die UserService-Klasse implementieren, um die Funktion zum Abfragen von Benutzerinformationen bereitzustellen:

public class UserService {
    public static User getUserById(String id) {
        //查询数据库中的用户信息
    }
}

3. Leistungstest

Abschließend testen wir die Antwortzeit und QPS (Parallelität pro Sekunde) des Netty-Hochleistungs-API-Servers Anzahl der von uns umgesetzten Anfragen).

Mit dem Apache ab-Tool können wir mehrere gleichzeitige Client-Anfragen simulieren und Statistiken zur Antwortzeit und QPS-Informationen sammeln. Verwenden Sie den folgenden Befehl:

ab -n 10000 -c 100 -k http://localhost:8888/user/1

Parameterbeschreibung:

-n: Gibt die Gesamtzahl der Anfragen an

-c: Gibt die Anzahl gleichzeitiger Anfragen an

-k: Zeigt die Aktivierung von Keep-Alive-Verbindungen an

Durch Tests haben wir kann die Antwortzeit- und QPS-Informationen abrufen:

Server Software:
Server Hostname:        localhost
Server Port:            8888

Document Path:          /user/1
Document Length:        36 bytes

Concurrency Level:      100
Time taken for tests:   3.777 seconds
Complete requests:      10000
Failed requests:        0
Keep-Alive requests:    10000
Total transferred:      1460000 bytes
HTML transferred:       360000 bytes
Requests per second:    2647.65 [#/sec] (mean)
Time per request:       37.771 [ms] (mean)
Time per request:       0.378 [ms] (mean, across all concurrent requests)
Transfer rate:          377.12 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2   1.2      2      10
Processing:     3   32  11.3     32      84
Waiting:        3   32  11.3     32      84
Total:          6   34  11.2     34      86

Percentage of the requests served within a certain time (ms)
  50%     34
  66%     38
  75%     40
  80%     42
  90%     49
  95%     55
  98%     64
  99%     71
 100%     86 (longest request)

Wie Sie sehen können, war unser API-Server in der Lage, die Simulation von 100 gleichzeitigen Anfragen im Test effektiv zu verarbeiten und konnte 2647,65 Anfragen pro Sekunde verarbeiten, mit einer durchschnittlichen Antwortzeit von nur 37,771 Millisekunden.

4. Zusammenfassung

Durch die obige Einführung und die Schritte haben wir gelernt, wie man Netty als Netzwerkkommunikations-Framework verwendet und damit leistungsstarke API-Server entwickelt. Durch die Verwendung des Netty-Frameworks kann die Serverleistung erheblich verbessert werden, sodass unser Server über eine hohe Parallelität, hohe Zuverlässigkeit, geringe Latenz und andere Eigenschaften verfügt. Gleichzeitig verfügt das Netty-Framework über eine hohe Skalierbarkeit und Flexibilität und lässt sich problemlos in jede Anwendung integrieren.

Als Teil des Java-Back-End-Entwicklungstechnologie-Stacks gehört auch die Verwendung des Netty-Frameworks zu den Fähigkeiten, die beherrscht werden müssen.

Das obige ist der detaillierte Inhalt vonJava-Backend-Entwicklung: Implementierung eines leistungsstarken API-Servers mit Netty. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn