Năm nay chúng tôi có kế hoạch phát triển nghiêm túc các chủ đề về vùng chứa, и . Sự tiếp nối hợp lý của các chủ đề này sẽ là một câu chuyện về khung Quarkus, ở Habré. Bài viết hôm nay ít nói về thiết kế "Java siêu nhanh hạ nguyên tử" mà nói nhiều hơn về lời hứa mà Quarkus mang đến cho Enterprise.

Java và JVM vẫn cực kỳ phổ biến, nhưng khi làm việc với các công nghệ serverless và microservice có nguồn gốc từ đám mây, Java và các ngôn ngữ JVM khác ngày càng ít được sử dụng vì chúng chiếm quá nhiều dung lượng bộ nhớ và tải quá chậm, khiến chúng trở nên phổ biến. kém phù hợp để sử dụng với các thùng chứa có tuổi thọ ngắn. May mắn thay, tình hình này hiện đang bắt đầu thay đổi nhờ Quarkus.
Java hạ nguyên tử siêu nhanh đã đạt đến một tầm cao mới!
42 bản phát hành, 8 tháng làm việc cộng đồng và 177 nhà phát triển tuyệt vời - kết quả của tất cả là bản phát hành vào tháng 2019 năm XNUMX , một bản phát hành đánh dấu một cột mốc quan trọng trong quá trình phát triển dự án và cung cấp nhiều tính năng và khả năng thú vị (bạn có thể đọc thêm về chúng trong ).
Hôm nay chúng tôi sẽ chỉ cho bạn cách Quarkus kết hợp các mô hình lập trình mệnh lệnh và phản ứng thành một lõi phản ứng duy nhất. Chúng ta sẽ bắt đầu với một lịch sử ngắn gọn và sau đó đi vào chi tiết về thuyết nhị nguyên lõi phản ứng của Quarkus là gì và bằng cách nào -Các nhà phát triển có thể tận dụng những lợi ích này.
, и -chức năng – như người ta nói, tất cả những thứ này đang gia tăng ngày nay. Gần đây, việc tạo ra các kiến trúc lấy đám mây làm trung tâm đã trở nên dễ dàng và dễ tiếp cận hơn nhiều, nhưng vẫn còn nhiều vấn đề - đặc biệt là đối với các nhà phát triển Java. Ví dụ: trong trường hợp các chức năng không có máy chủ và vi dịch vụ, nhu cầu cấp thiết là giảm thời gian khởi động, giảm mức tiêu thụ bộ nhớ mà vẫn làm cho quá trình phát triển của chúng trở nên thuận tiện và thú vị hơn. Java đã thực hiện một số cải tiến trong những năm gần đây, chẳng hạn như cải thiện chức năng công thái học cho các thùng chứa, v.v. Tuy nhiên, việc làm cho Java hoạt động bình thường trong vùng chứa vẫn còn nhiều thách thức. Vì vậy, chúng ta sẽ bắt đầu bằng cách xem xét một số điểm phức tạp vốn có của Java, đặc biệt nghiêm trọng khi phát triển các ứng dụng Java hướng vùng chứa.
Đầu tiên, chúng ta hãy nhìn vào lịch sử.

Luồng và vùng chứa
Bắt đầu với phiên bản 8u131, Java bắt đầu ít nhiều hỗ trợ các thùng chứa do những cải tiến về chức năng công thái học. Đặc biệt, JVM hiện biết nó đang chạy trên bao nhiêu lõi bộ xử lý và có thể định cấu hình các nhóm luồng—thường là các nhóm phân nhánh/nối—tương ứng. Tất nhiên, điều này thật tuyệt, nhưng giả sử chúng ta có một ứng dụng web truyền thống sử dụng các máy chủ HTTP và chạy trong Tomcat, Jetty, v.v. Kết quả là, ứng dụng này sẽ cung cấp cho mỗi yêu cầu một luồng riêng biệt và cho phép nó chặn luồng này trong khi chờ các thao tác I/O, chẳng hạn như khi truy cập cơ sở dữ liệu, tệp hoặc các dịch vụ khác. Nghĩa là, kích thước của một ứng dụng như vậy không phụ thuộc vào số lượng lõi có sẵn mà phụ thuộc vào số lượng yêu cầu đồng thời. Ngoài ra, điều này có nghĩa là hạn ngạch hoặc giới hạn trong Kubernetes về số lượng lõi sẽ không giúp ích nhiều ở đây và vấn đề cuối cùng sẽ kết thúc bằng việc điều chỉnh.
Suy kiệt trí nhớ
Chủ đề là bộ nhớ. Và những hạn chế về bộ nhớ trong container không phải là thuốc chữa bách bệnh. Chỉ cần bắt đầu tăng số lượng ứng dụng và luồng, sớm hay muộn bạn sẽ gặp phải sự gia tăng nghiêm trọng về tần suất chuyển đổi và kết quả là hiệu suất bị suy giảm. Ngoài ra, nếu ứng dụng của bạn sử dụng các khung vi dịch vụ truyền thống hoặc kết nối với cơ sở dữ liệu hoặc sử dụng bộ đệm hoặc sử dụng hết bộ nhớ, rõ ràng bạn cần một công cụ cho phép bạn xem bên trong JVM và xem cách nó quản lý bộ nhớ mà không làm hỏng bộ nhớ. Bản thân JVM (ví dụ: XX:+UseCGroupMemoryLimitForHeap). Và mặc dù, bắt đầu với Java 9, JVM đã học cách chấp nhận các nhóm và điều chỉnh cho phù hợp, việc dự trữ và quản lý bộ nhớ vẫn là một vấn đề khá phức tạp.
Hạn ngạch và giới hạn
Java 11 đã giới thiệu hỗ trợ cho hạn ngạch CPU (như PreferContainerQuotaForCPUCount). Kubernetes cũng cung cấp hỗ trợ về giới hạn và hạn ngạch. Đúng, tất cả điều này đều có ý nghĩa, nhưng nếu ứng dụng lại vượt quá hạn ngạch được phân bổ, chúng ta lại kết thúc với kích thước - như trường hợp của các ứng dụng Java truyền thống - được xác định bởi số lượng lõi và phân bổ một luồng riêng cho mỗi luồng yêu cầu, thì tất cả điều này chẳng có ý nghĩa gì cả.
Ngoài ra, nếu bạn sử dụng hạn ngạch và giới hạn hoặc các chức năng mở rộng quy mô của nền tảng Kubernetes, vấn đề cũng không tự giải quyết được. Đơn giản là chúng ta dành nhiều nguồn lực hơn để giải quyết vấn đề ban đầu hoặc cuối cùng sẽ bội chi. Và nếu đó là một hệ thống có tải trọng cao trong đám mây công cộng, chúng ta gần như chắc chắn sẽ sử dụng nhiều tài nguyên hơn mức chúng ta thực sự cần.
Và phải làm gì với tất cả điều này?
Nói một cách đơn giản, hãy sử dụng các thư viện và khung I/O không đồng bộ và không chặn như Netty, hoặc Akka. Chúng phù hợp hơn nhiều để làm việc trong các thùng chứa do tính chất phản ứng của chúng. Nhờ I/O không chặn, cùng một luồng có thể xử lý nhiều yêu cầu đồng thời. Trong khi một yêu cầu đang chờ kết quả I/O, quá trình xử lý luồng yêu cầu đó sẽ được giải phóng và tiếp quản bởi một yêu cầu khác. Và khi kết quả I/O cuối cùng cũng đến, quá trình xử lý yêu cầu đầu tiên vẫn tiếp tục. Bằng cách xử lý xen kẽ các yêu cầu trong cùng một luồng, bạn có thể giảm tổng số luồng và giảm mức tiêu thụ tài nguyên để xử lý các yêu cầu.
Với I/O không chặn, số lõi trở thành một tham số quan trọng vì nó xác định số lượng luồng I/O có thể được thực thi song song. Khi được sử dụng đúng cách, điều này cho phép bạn phân phối tải giữa các lõi một cách hiệu quả và xử lý khối lượng công việc cao hơn với ít tài nguyên hơn.
Làm thế nào, đó là tất cả?
Không, có cái gì đó khác. Lập trình phản ứng giúp sử dụng tài nguyên tốt hơn nhưng cũng phải trả giá. Đặc biệt, mã sẽ phải được viết lại theo nguyên tắc không chặn và tránh chặn các luồng I/O. Và đây là một mô hình phát triển và thực hiện hoàn toàn khác. Và mặc dù ở đây có rất nhiều thư viện hữu ích nhưng nó vẫn là một sự thay đổi căn bản trong cách suy nghĩ thông thường.
Đầu tiên, bạn cần học cách viết mã chạy không đồng bộ. Khi bắt đầu sử dụng I/O không chặn, bạn cần chỉ định rõ ràng điều gì sẽ xảy ra khi nhận được phản hồi cho yêu cầu. Việc chỉ chặn và chờ đợi sẽ không còn hiệu quả nữa. Thay vào đó, bạn có thể chuyển lệnh gọi lại, sử dụng lập trình phản ứng hoặc tiếp tục. Nhưng đó không phải là tất cả: để sử dụng I/O không chặn, bạn cần cả máy chủ và máy khách không chặn, tốt nhất là ở mọi nơi. Trong trường hợp HTTP, mọi thứ đều đơn giản, nhưng cũng có cơ sở dữ liệu, hệ thống tệp, v.v.
Và mặc dù phản ứng tổng thể từ đầu đến cuối tối đa hóa hiệu quả, nhưng sự thay đổi như vậy có thể khó chấp nhận trong thực tế. Vì vậy, khả năng kết hợp mã phản ứng và mã mệnh lệnh trở thành điều kiện tiên quyết để:
- Sử dụng hiệu quả tài nguyên ở những vùng được tải nhiều nhất của hệ thống phần mềm;
- Sử dụng mã kiểu đơn giản hơn trong các phần còn lại của nó.
Giới thiệu Quarkus
Trên thực tế, đây là bản chất của Quarkus - kết hợp các mô hình phản ứng và mệnh lệnh trong một môi trường thời gian chạy duy nhất.
Quarkus dựa trên Vert.x và Netty, với một loạt các khung và tiện ích mở rộng phản ứng ở trên để trợ giúp nhà phát triển. Quarkus được thiết kế để xây dựng không chỉ các dịch vụ vi mô HTTP mà còn cả các kiến trúc hướng sự kiện. Do tính chất phản ứng, nó hoạt động rất hiệu quả với các hệ thống nhắn tin (Apache Kafka, AMQP, v.v.).
Bí quyết là làm thế nào để sử dụng cùng một công cụ phản ứng cho cả mã mệnh lệnh và mã phản ứng.

Quarkus thực hiện điều này một cách xuất sắc. Sự lựa chọn giữa mệnh lệnh và phản ứng là hiển nhiên - hãy sử dụng hạt nhân phản ứng cho cả hai. Điều nó thực sự hữu ích là mã nhanh, không chặn, xử lý hầu hết mọi thứ đi qua luồng vòng lặp sự kiện, hay còn gọi là luồng IO. Nhưng nếu bạn có các ứng dụng REST hoặc ứng dụng phía máy khách cổ điển, Quarkus đã sẵn sàng một mô hình lập trình bắt buộc. Ví dụ: hỗ trợ HTTP trong Quarkus dựa trên việc sử dụng công cụ không chặn và phản ứng (Eclipse Vert.x và Netty). Tất cả các yêu cầu HTTP mà ứng dụng của bạn nhận được trước tiên sẽ được chuyển qua vòng lặp sự kiện (IO Thread) và sau đó được gửi đến phần mã quản lý các yêu cầu. Tùy thuộc vào đích, mã quản lý yêu cầu có thể được gọi trong một luồng riêng biệt (còn gọi là luồng công việc, được sử dụng trong trường hợp servlet và Jax-RS) hoặc sử dụng luồng I/O nguồn (tuyến phản ứng).

Trình kết nối hệ thống nhắn tin sử dụng các máy khách không chặn chạy trên công cụ Vert.x. Do đó, bạn có thể gửi, nhận và xử lý tin nhắn từ hệ thống phần mềm trung gian nhắn tin một cách hiệu quả.
Trang web Dưới đây là một số hướng dẫn hay để giúp bạn bắt đầu với Quarkus:
Chúng tôi cũng đã tạo các hướng dẫn thực hành trực tuyến để dạy cho bạn các khía cạnh khác nhau của lập trình phản ứng chỉ trong một trình duyệt, không cần IDE và không cần máy tính. Bạn có thể tìm thấy những bài học này .
Tài nguyên hữu ích
- Trang web dự án Quarkus –
- Dự án Quarkus trên GitHub –
- Dự án Quarkus Twitter –
- Trò chuyện về dự án Quarkus –
- Diễn đàn dự án Quarkus – !forum/quarkus-dev
10 video bài học về Quarkus để làm quen với chủ đề
Như họ nói trên trang web , - là Ngăn xếp Java định hướng, được thiết kế riêng cho GraalVM và OpenJDK HotSpot và được tập hợp từ các thư viện và tiêu chuẩn Java tốt nhất.
Để giúp bạn hiểu chủ đề này, chúng tôi đã chọn 10 video hướng dẫn bao gồm các khía cạnh khác nhau của Quarkus và các ví dụ về cách sử dụng nó:
1. Giới thiệu Quarkus: Khung Java thế hệ tiếp theo cho Kubernetes
Bởi Thomas Qvarnstrom và Jason Greene
Mục tiêu của dự án Quarkus là tạo ra nền tảng Java cho Kubernetes và môi trường không có máy chủ, đồng thời kết hợp các mô hình lập trình phản ứng và mệnh lệnh vào một môi trường thời gian chạy duy nhất để các nhà phát triển có thể thay đổi linh hoạt cách tiếp cận của họ khi làm việc với nhiều kiến trúc ứng dụng phân tán. Tìm hiểu thêm trong bài giảng giới thiệu dưới đây.

2. Quarkus: Java hạ nguyên tử siêu nhanh
Bởi: Burr Sutter
Video hướng dẫn này của DevNation Live trình bày cách sử dụng Quarkus để tối ưu hóa các ứng dụng Java, API, vi dịch vụ và các chức năng không có máy chủ trong môi trường Kubernetes/OpenShift, làm cho chúng nhỏ hơn, nhanh hơn và có khả năng mở rộng cao hơn nhiều.

3. Quarkus và GraalVM: tăng tốc Hibernate lên siêu tốc và thu nhỏ nó xuống kích thước hạ nguyên tử
Tác giả: Sanne Grinovero
Từ bài trình bày, bạn sẽ tìm hiểu cách Quarkus ra đời, cách hoạt động và cách nó cho phép bạn tạo các thư viện phức tạp, như Hibernate ORM, tương thích với hình ảnh GraalVM gốc.

4. Học cách phát triển các ứng dụng serverless
Tác giả: Martin Luther
Video bên dưới cho thấy cách tạo một ứng dụng Java đơn giản bằng Quarkus và triển khai nó dưới dạng ứng dụng không có máy chủ trên Knative.

5. Quarkus: Chúc bạn viết mã vui vẻ
Tác giả: Edson Yanaga
Hướng dẫn bằng video để tạo dự án Quarkus đầu tiên của bạn, cho phép bạn hiểu lý do tại sao Quarkus lại chiếm được cảm tình của các nhà phát triển.

6. Java và container - tương lai của chúng sẽ ra sao
Được đăng bởi Mark Little
Bài trình bày này giới thiệu lịch sử của Java và giải thích tại sao Quarkus là tương lai của Java.

7. Quarkus: Java hạ nguyên tử siêu nhanh
Tác giả: Dimitris Andreadis
Tổng quan về những ưu điểm của Quarkus đã được các nhà phát triển công nhận: tính đơn giản, tốc độ cực cao, thư viện và tiêu chuẩn tốt nhất.

8. Quarkus và hệ thống tên lửa hạ nguyên tử
Tác giả: Clement Escoffier
Thông qua việc tích hợp với GraalVM, Quarkus cung cấp trải nghiệm phát triển cực nhanh và môi trường thời gian chạy hạ nguyên tử. Tác giả nói về khía cạnh phản ứng của Quarkus và cách sử dụng nó để xây dựng các ứng dụng phản ứng và phát trực tuyến.

9. Quarkus và sự phát triển ứng dụng nhanh chóng trong Eclipse MicroProfile
Tác giả: John Clingan
Bằng cách kết hợp Eclipse MicroProfile và Quarkus, các nhà phát triển có thể tạo ra các ứng dụng MicroProfile được đóng gói trong bộ chứa đầy đủ tính năng và khởi chạy trong hàng chục mili giây. Video đi sâu vào chi tiết về cách mã hóa ứng dụng MicroProfile được đóng gói để triển khai trên nền tảng Kubernetes.

10. Phiên bản Java, "Turbo"
Tác giả: Marcus Biel
Tác giả chỉ ra cách sử dụng Quarkus để tạo các thùng chứa Java siêu nhỏ, siêu nhanh, tạo ra những đột phá thực sự, đặc biệt là trong môi trường không có máy chủ.

Nguồn: www.habr.com
