Membandingkan Container Servlet Tertanam di Spring Boot

1. Pengenalan

Peningkatan populariti aplikasi dan perkhidmatan mikro awan asli menghasilkan permintaan yang meningkat untuk kontena servlet tertanam. Spring Boot membolehkan pemaju membina aplikasi atau perkhidmatan dengan mudah menggunakan 3 bekas paling matang yang ada: Tomcat, Undertow, dan Jetty.

Dalam tutorial ini, kami akan menunjukkan cara untuk membandingkan implementasi wadah dengan cepat menggunakan metrik yang diperoleh pada permulaan dan dengan sedikit beban.

2. Kebergantungan

Persiapan kami untuk setiap pelaksanaan kontena yang tersedia akan selalu memerlukan kami menyatakan pergantungan pada spring-boot-starter-web di pom.xml kami .

Secara amnya, kami ingin menetapkan ibu bapa kami sebagai ibu bapa spring-boot-starter , dan kemudian memasukkan permulaan yang kami mahukan:

 org.springframework.boot spring-boot-starter-parent 2.2.2.RELEASE     org.springframework.boot spring-boot-starter   org.springframework.boot spring-boot-starter-web   

2.1. Tomcat

Tidak perlu lagi ketergantungan ketika menggunakan Tomcat kerana disertakan secara lalai ketika menggunakan spring-boot-starter-web .

2.2. Jeti

Untuk menggunakan Jeti, pertama-tama kita perlu mengecualikan spring-boot-starter-tomcat dari spring-boot-starter-web .

Kemudian, kami hanya menyatakan pergantungan pada spring-boot-starter-jetty :

 org.springframework.boot spring-boot-starter-web   org.springframework.boot spring-boot-starter-tomcat     org.springframework.boot spring-boot-starter-jetty  

2.3. Tunduk

Menyiapkan Undertow sama dengan Jetty, kecuali kami menggunakan spring-boot-starter-entow sebagai pergantungan kami:

 org.springframework.boot spring-boot-starter-web   org.springframework.boot spring-boot-starter-tomcat     org.springframework.boot spring-boot-starter-undertow 

2.4. Penggerak

Kami akan menggunakan Spring Boot's Actuator sebagai cara mudah untuk menekankan sistem dan membuat pertanyaan mengenai metrik.

Lihat artikel ini untuk perincian mengenai Actuator. Kami hanya menambahkan kebergantungan di pom kami untuk menyediakannya:

 org.springframework.boot spring-boot-starter-actuator 

2.5. Bangku Apache

Apache Bench adalah utiliti ujian beban sumber terbuka yang disertakan dengan pelayan web Apache.

Pengguna Windows boleh memuat turun Apache dari salah satu vendor pihak ketiga yang dihubungkan di sini. Sekiranya Apache sudah dipasang pada mesin Windows anda, anda seharusnya dapat mencari ab.exe di direktori apache / bin anda .

Sekiranya anda menggunakan mesin Linux, ab dapat dipasang menggunakan apt-get dengan:

$ apt-get install apache2-utils

3. Sukatan Permulaan

3.1. Koleksi

Untuk mengumpulkan metrik permulaan kami, kami akan mendaftarkan pengendali acara untuk diaktifkan di Spring Boot's ApplicationReadyEvent .

Kami akan mengekstrak metrik yang kami minati secara terprogram dengan bekerja secara langsung dengan MeterRegistry yang digunakan oleh komponen Actuator:

@Component public class StartupEventHandler { // logger, constructor private String[] METRICS = { "jvm.memory.used", "jvm.classes.loaded", "jvm.threads.live"}; private String METRIC_MSG_FORMAT = "Startup Metric >> {}={}"; private MeterRegistry meterRegistry; @EventListener public void getAndLogStartupMetrics( ApplicationReadyEvent event) { Arrays.asList(METRICS) .forEach(this::getAndLogActuatorMetric); } private void processMetric(String metric) { Meter meter = meterRegistry.find(metric).meter(); Map stats = getSamples(meter); logger.info(METRIC_MSG_FORMAT, metric, stats.get(Statistic.VALUE).longValue()); } // other methods }

Kami mengelakkan keperluan untuk meminta titik akhir Actuator REST secara manual atau menjalankan konsol JMX yang tersendiri dengan mencatat metrik menarik semasa memulakan dalam pengendali acara kami.

3.2. Pemilihan

Terdapat sebilangan besar metrik yang disediakan oleh Actuator di luar kotak. Kami memilih 3 metrik yang membantu mendapatkan gambaran umum tahap ciri utama masa operasi apabila pelayan aktif:

  • jvm.memory.used - jumlah memori yang digunakan oleh JVM sejak permulaan
  • jvm.classes.loaded - jumlah kelas yang dimuat
  • jvm.threads.live - jumlah utas aktif. Dalam ujian kami, nilai ini dapat dilihat sebagai kiraan benang "saat rehat"

4. Sukatan Masa Jalan

4.1. Koleksi

Selain menyediakan metrik permulaan, kami akan menggunakan titik akhir / metrik yang didedahkan oleh Penggerak sebagai URL sasaran ketika kami menjalankan Apache Bench untuk memuatkan aplikasi.

Untuk menguji aplikasi yang sebenarnya sedang dimuat, kami mungkin menggunakan titik akhir yang disediakan oleh aplikasi kami.

Setelah pelayan dimulakan, kami akan mendapat command prompt dan melaksanakan ab :

ab -n 10000 -c 10 //localhost:8080/actuator/metrics

Dalam arahan di atas, kami telah menetapkan sejumlah 10,000 permintaan menggunakan 10 utas serentak.

4.2. Pemilihan

Apache Bench is able to very quickly give us some useful information including connection times and the percentage of requests that are served within a certain time.

For our purposes, we focused on requests-per-second and time-per-request (mean).

5. Results

On startup, we found that the memory footprint of Tomcat, Jetty, and Undertow was comparable with Undertow requiring slightly more memory than the other two and Jetty requiring the smallest amount.

For our benchmark, we found that the performance of Tomcat, Jetty, and Undertow was comparable but that Undertow was clearly the fastest and Jetty only slightly less fast.

Metric Tomcat Jetty Undertow
jvm.memory.used (MB) 168 155 164
jvm.classes.loaded 9869 9784 9787
jvm.threads.live 25 17 19
Requests per second 1542 1627 1650
Average time per request (ms) 6.483 6.148 6.059

Note that the metrics are, naturally, representative of the bare-bones project; the metrics of your own application will most certainly be different.

6. Benchmark Discussion

Developing appropriate benchmark tests to perform thorough comparisons of server implementations can get complicated. In order to extract the most relevant information, it's critical to have a clear understanding of what's important for the use case in question.

It's important to note that the benchmark measurements collected in this example were taken using a very specific workload consisting of HTTP GET requests to an Actuator endpoint.

It's expected that different workloads would likely result in different relative measurements across container implementations. If more robust or precise measurements were required, it would be a very good idea to set up a test plan that more closely matched the production use case.

In addition, a more sophisticated benchmarking solution such as JMeter or Gatling would likely yield more valuable insights.

7. Choosing a Container

Selecting the right container implementation should likely be based on many factors that can't be neatly summarized with a handful of metrics alone. Comfort level, features, available configuration options, and policy are often equally important, if not more so.

8. Conclusion

Dalam artikel ini, kami melihat penerapan wadah servlet tertanam Tomcat, Jetty, dan Undertow. Kami meneliti ciri-ciri runtime setiap bekas pada permulaan dengan konfigurasi lalai dengan melihat metrik yang didedahkan oleh komponen Actuator.

Kami melaksanakan beban kerja yang dibuat terhadap sistem berjalan dan kemudian mengukur prestasi menggunakan Apache Bench.

Terakhir, kami membincangkan kelebihan strategi ini dan menyebut beberapa perkara yang perlu diingat ketika membandingkan penanda aras pelaksanaan. Seperti biasa, semua kod sumber boleh didapati di GitHub.