Beágyazott Jetty Server Java-ban

1. Áttekintés

Ebben a cikkben megnézzük a Móló könyvtár. A Jetty egy webszervert biztosít, amely beágyazott tárolóként futtatható, és könnyen integrálható a javax.servlet könyvtár.

2. Maven-függőségek

A kezdéshez Maven-függőségeket adunk a móló-kiszolgáló és a móló-szervlet könyvtárakhoz:

 org.eclipse.jetty móló-kiszolgáló 9.4.3.v20170317 org.eclipse.jetty móló-szervlet 9.4.3.v20170317 

3. A Jetty Server indítása a Servlet segítségével

A Jetty beágyazott tárolójának elindítása egyszerű. Példaként kell állítanunk egy újat szerver objektumot, és állítsa be, hogy elinduljon egy adott porton:

public class JettyServer {privát szerver szerver; public void start () dobja a (z) {server = new Server () Kivételt; ServerConnector csatlakozó = new ServerConnector (szerver); connector.setPort (8090); server.setConnectors (új Csatlakozó [] {csatlakozó}); }

Tegyük fel, hogy egy olyan végpontot szeretnénk létrehozni, amely 200-as HTTP állapotkóddal válaszol, ha minden jól megy, és egy egyszerű JSON-terhelés.

Létrehozunk egy osztályt, amely kiterjeszti a HttpServlet osztály az ilyen kérések kezelésére; ez az osztály egyszálú és blokkolt lesz a befejezésig:

public class BlockingServlet kiterjeszti a HttpServlet {protected void doGet (HttpServletRequest kérés, HttpServletResponse válasz) dobja a ServletException, IOException {response.setContentType ("alkalmazás / json"); response.setStatus (HttpServletResponse.SC_OK); response.getWriter (). println ("{\" status \ ": \" ok \ "}"); }}

Ezután regisztrálnunk kell a BlockingServlet osztály a ServletHandler objektumot a addServletWithMapping () módszer és indítsa el a szervert:

servletHandler.addServletWithMapping (BlockingServlet.class, "/ status"); server.start ();

Ha tesztelni akarjuk a Servlet logikánkat, akkor a korábban létrehozott szerverrel kell elindítanunk a szerverünket JettyServer osztály, amely a tényleges Jetty kiszolgálópéldány burkolója a tesztbeállításon belül:

@A nyilvános void beállítása előtt () dobja a Kivételt {jettyServer = new JettyServer (); jettyServer.start (); }

Miután elindult, küldünk egy teszt HTTP kérést a /állapot végpont:

Karakterlánc URL = "// localhost: 8090 / status"; HttpClient kliens = HttpClientBuilder.create (). Build (); HttpGet kérés = új HttpGet (url); HttpResponse response = client.execute (kérés); assertThat (response.getStatusLine (). getStatusCode ()). isEqualTo (200);

4. Nem blokkoló szervletek

A móló jó támogatást nyújt az aszinkron kérelmek feldolgozásához.

Tegyük fel, hogy óriási erőforrásunk van, amely I / O intenzív, hosszú időbe telik, míg a végrehajtó szál jelentős ideig tartó blokkolása betöltődik. Jobb, ha ez a szál felszabadítható más kérések kezelésére időközben, ahelyett, hogy valamilyen I / O erőforrásra várna.

Az ilyen logika biztosításához a Jetty-hez létrehozhatunk egy szervletet, amely a AsyncContext osztály hívásával a startAsync () módszer a HttpServletRequest. Ez a kód nem blokkolja a végrehajtó szálat, de az I / O műveletet külön szálban hajtja végre, és az eredményt visszaadja, amikor készen áll a AsyncContext.complete () módszer:

public class AsyncServlet kiterjeszti a HttpServlet {private static String HEAVY_RESOURCE = "Ez egy nehéz erőforrás, amelyet aszinkron módon fognak kiszolgálni"; védett void doGet (HttpServletRequest kérés, HttpServletResponse válasz) dobja a ServletException, IOException {ByteBuffer content = ByteBuffer.wrap (HEAVY_RESOURCE.getBytes (StandardCharsets.UTF_8)); AsyncContext async = request.startAsync (); ServletOutputStream out = response.getOutputStream (); out.setWriteListener (new WriteListener () {@Orride public void onWritePossible () throws IOException {while (out.isReady ()) {if (! content.hasRemaining ()) {response.setStatus (200); async.complete () ; return;} out.write (content.get ());}} @Orride public void onError (Throwable t) {getServletContext (). log ("Async Error", t); async.complete ();}}) ; }}

Írjuk a ByteBuffer hoz OutputStream, és amint a teljes puffer meg van írva, jelezzük, hogy az eredmény készen áll a klienshez való visszatérésre a teljes() módszer.

Ezután hozzá kell adnunk a AsyncServlet móló szervlet feltérképezése:

servletHandler.addServletWithMapping (AsyncServlet.class, "/ heavy / async");

Most kérelmet küldhetünk a / nehéz / aszinkron végpont - ezt a kérést a móló aszinkron módon kezeli:

Karakterlánc URL = "// localhost: 8090 / heavy / async"; HttpClient kliens = HttpClientBuilder.create (). Build (); HttpGet kérés = új HttpGet (url); HttpResponse response = client.execute (kérés); assertThat (response.getStatusLine (). getStatusCode ()) .isEqualTo (200); String responseContent = IOUtils.toString (r esponse.getEntity (). GetContent (), StandardCharsets.UTF_8); assertThat (responseContent) .isEqualTo ("Ez egy nehéz erőforrás, amelyet aszinkron módon fognak kiszolgálni");

Amikor alkalmazásunk aszinkron módon kezeli a kéréseket, akkor a szálkészletet kifejezetten konfigurálnunk kell. A következő részben konfiguráljuk Móló egyedi szálkészlet használatához.

5. Móló konfigurálása

Amikor webes alkalmazásunkat gyártásban futtatjuk, érdemes lehet hangolni, hogy a Jetty kiszolgáló miként dolgozza fel a kéréseket. Ez úgy történik, hogy meghatározzuk a szálkészletet és alkalmazzuk a Jetty szerverünkre.

Ehhez három konfigurációs beállítással rendelkezünk, amelyeket beállíthatunk:

  • maxThreads - Annak megadása, hogy mekkora számú szálat hozhat létre és használhat a Jetty a készletben
  • minThreads - A készletben a Jetty által használt szálak kezdeti számának beállítása
  • tétlenségi időtúllépés - Ez az érték milliszekundumban határozza meg, hogy egy szál mennyi ideig lehet tétlen, mielőtt leállítaná és eltávolítaná a szálkészletből. A készletben megmaradt szálak száma soha nem haladja meg a minThreads beállítás

Ezekkel konfigurálhatjuk a beágyazottat Móló kiszolgáló programozottan a konfigurált szálkészlet átadásával a szerver konstruktőr:

int maxThreads = 100; int minThreads = 10; int idleTimeout = 120; QueuedThreadPool threadPool = új QueuedThreadPool (maxThreads, minThreads, idleTimeout); szerver = új kiszolgáló (threadPool);

Amikor a szerverünket elindítjuk, akkor egy adott szálkészlet szálait fogja használni.

6. Következtetés

Ebben a gyors bemutatóban azt láttuk, hogyan integrálhatjuk a beágyazott szervereket a Jetty-be, és teszteltük webalkalmazásunkat.

Mint mindig, a kód elérhető a GitHubon.


$config[zx-auto] not found$config[zx-overlay] not found