So sánh playframework và spring mvc

RubyNgôn ngữ

Java Hướng đối tượng. Ngôn ngữ biên dịch. Đa nền tảng Khóa học Java căn bản đến nâng cao sẽ mở ngày 1/4/2015

Ruby Hướng đối tượng. Ngôn ngữ thông dịch. Đa nền tảng Khóa học Ruby on Rails mở ngày 4/4/2015Xuất hiện năm1995 do James Gosling1995 do Yukihiro MatsumotoPhiên bản mới nhất8.4 ra tháng 3/20152.2.1 ra tháng 3/2015Ngôn ngữ biến thểC# học rất nhiều từ Java Scala viết gọn hơn, biên dịch chạy trên JVMJRuby: có thể biên dịch Ruby chạy trên JVMỨng dụngLập trình desktop, web site, web service, ứng dụng di động Android. Dải ứng dụng rộng hơn Ruby rất nhiều.Lập trình web (Rails) là chủ yếu và viết script để tự động hóa tác vụ. Chỉ mạnh ở phát triển web siteChỉ số phổ biếnLiên tục đứng top 2 trong nhiều nămĐứng thứ 18. Có xu hướng giảm một chút.Số lượng việc làmRất nhiều và đa dạng: bất kỳ công ty nào: Tây, Ta, gia công,...Tập trung ở các công ty Nhật, châu Âu, và Mỹ. Số lượng ít hơn Java nhưng cạnh tranh việc làm thấp hơn.Dạy ở đại họcRất phổ biến. Trên 60%. Đối thủ khác là C/C++ và C

Chỉ ở một số trường đại học. Ở Việt nam hầu như không dạyFrameworkRất nhiều. Vừa là ưu điểm vừa là nhược điểm. Với người mới học, không biết chọn framework nào. Với lập trình viên gia công thường phải bảo trì dự án trên framework cũ, khá ức chế.

Framework hay: Play Framework, Vaadin, Spring MVC, LifeRay So sánh các Java FrameworkCộng đồng lớn, liên tục được cải tiến cập nhất theo xu hướng mới nhất. Phương châm: đơn giản - gọn - nhẹ - dễ học - dễ làm. Framework hay: Rails (mạnh nhất), Lotus, Sinatra 12 framework cho RubyCạnh tranh khi xin việcKhá cao: 7/10. Học viên sẽ phải thi lập trình Java hoặc thi trắc nghiệm.Vừa phải: 5/10. Do số lượng lập trình viên Rails điều kiện đầu vào khá thoải mái. Học viên có một sản phẩm web site sẽ dễ dàng vượt qua vòng loạiDễ học cho người bắt đầuKhá dễ: 7/10Rất dễ: 9/10Có thể lập trình di độngNếu đã nắm vững Java, việc chuyển sang lập trình di động nền tảng Android rất dễ dàngKhông thể. Ruby và Ruby On Rails chuyển để lập trình webTính sẵn cóCác framework rất nhiều. Trong nhiều trường hợp dùng framework này thì phải thôi dùng framework kia. Gói thư viện thì khó kiểm soát tương thích phiên bản.Framework ít, nổi nhất là Ruby On Rails. Gói thư viện (gems) rất nhiều, tiện dụng để lập trình viên tái sử dụng luôn trong dự ánTốc độ thực thiNhanh 7/10 (so với ngôn ngữ C++) Đo tốc độ giữa Java và C++Chậm: 3.5/10 Đo tốc độ giữa Ruby và JavaTiêu thụ bộ nhớJava cần nhiều bộ nhớ khi thực thiCần ít bộ nhớ hơnĐối tượng khách hàngDoanh nghiệp cỡ trung - lớn.Ứng dụng web cho công ty nhỏ - trung - start upChọn ngôn ngữ nào?Bạn là người thích sự ổn định lâu dài, chắc chắn. Chấp nhận khó khăn khi học để lập trình. Thích hợp với làm việc theo nhóm từ 3 người đến 7 người. Bạn muốn lập trình cả web site và ứng dụng di độngBạn thích sự đơn giản, muốn nhìn thấy kết quả ngay. Bạn muốn chủ động, tự do và ít rào cản khi lập trình web site. Bạn muốn lập trình web site khá phức tạp trong thời gian ngắn.Sẽ lạc hậu trong 10 năm tớiXác suất là cực thấp. Quá nhiều công ty, phần mềm phụ thuộc vào Java.Xuất suất có thể có nhưng nếu bạn đã học được Ruby, thì bạn có thể dễ dàng chuyển đổi học ngôn ngữ khác. Ruby rất phù hợp cho những người mới bắt đầu lập trình.Học phí họcKhóa học 30 buổi: 7,7 triệu đối với sinh viên. Khóa học 17 buổi: 4,1 triệu đối với sinh viênKhóa học 20 buổi: 4,1 triệu đối với sinh viênSẽ lạc hậu trong 10 năm tớiXác suất là thấp. Quá nhiều công ty, phần mềm phụ thuộc vào Java.Xác suất có thể có nhưng nếu bạn đã học được Ruby, thì bạn có thể dễ dàng chuyển đổi học ngôn ngữ khác. Ruby rất phù hợp cho những người mới bắt đầu lập trình.Đăng ký họcKhai giảng ngày 1/4/2015, đăng ký học tại đâyKhai giảng ngày 4/4/2015, đăng ký học tại đây

Lập trình song song (hay còn gọi là lập trình đa luồng) là một chủ đề nâng cao tương đối khó (nếu không muốn gọi là rất khó).

Chủ đề này trải dài từ các vấn đề cơ bản như việc triển khai đa luồng bằng các API có sẵn của Java, đến việc hiểu biết sâu sắc về cơ chế hoạt động bên dưới của CPU, để tối ưu việc thiết kế và triển khai thread cho ứng dụng. Một số keyword có thể kể đến như context switching, false sharing, happens-before relationship...

Khả năng hiểu biết sâu sắc và tường tận cách hoạt động của một công cụ để có thể sử dụng nó một cách tốt nhất và tối ưu nhất được gọi là .

Một số nguồn tham khảo về multithreading và concurrency trong Java:

  • Series Concurrency của Jenkov: đây là một series đầy đủ và chi tiết về toàn bộ các khía cạnh trong lập trình đa luồng Java.
  • Sách "Java Concurrency in practice": mặc dù xuất bản từ 2006 nhưng cuốn sách này vẫn rất đáng đọc vì nó xoay quanh những nguyên lý nền tảng. Các API có thể thay đổi, nhưng nền tảng của đa luồng thì sẽ mãi bất biến với kiến trúc máy tính hiện tại.
  • Series multithreading bằng tiếng Việt của anh Phan Thanh Giang.
  • Bài phân tích nâng cao về multithreading của anh Dem Trần.

2. Websocket with STOMP

Xử lý real-time với websocket không còn là chủ đề xa lạ với các developers. Giải pháp thông dụng nhất đối với Spring là sử dụng STOMP (Stream Text-Oriented Messaging Protocol) được cung cấp trong dependency spring-messaging. Tuy nhiên việc tổ chức kiến trúc ở các hệ thống lớn sẽ phức tạp hơn, đòi hỏi có sự hỗ trợ của các concurrency framework.

3. Concurrency Framework

Lập trình đa luồng khó, nhưng nếu có sự trợ giúp của các concurrency framework, thì sẽ dễ dàng hơn nhiều, miễn là tuân theo các pattern mà framework quy định.

2 keywords quan trọng nhất liên quan đến concurrency framework chính là reactive programming và non-blocking IO. Riêng từ khóa "reactive programming" thôi là đã bao hàm rất nhiều chủ đề thú vị: functional programming, reactive streams, message driven, back-pressure, non-blocking communication... Nói cho đơn giản, thì reactive-programming sẽ giúp server tăng khả năng chịu tải và chịu lỗi (resilient), phản hồi nhanh hơn (responsive), dễ giao tiếp với nhau, dễ nâng cấp và mở rộng (highly scalable).

Một số framework có thể kể đến như:

  • Akka: một trong những concurrency framework nổi tiếng nhất, hoạt động dựa trên mô hình Actor (Actor-model) lấy cảm hứng từ ngôn ngữ Erlang. Akka hỗ trợ bằng Java lẫn Scala.
  • Play Framework: được phát triển trên nền tảng của Akka, Play chú trọng vào sự đơn giản và dễ dùng. Nếu các bạn muốn tập trung vào web MVC như HTML UI, REST endpoints, API gateway... thì Play là 1 lựa chọn phù hợp.
  • Vert.x: framework này cung cấp các tính năng tương tự như Akka, nhưng hoạt động dựa trên mô hình event-driven và hỗ trợ đa ngôn ngữ. Bởi sự gọn gàng linh hoạt, Vert.x thường được chọn để triển khai microservice.
  • Spring Webflux: từng được biết đến với tên gọi Project Reactor. Sau này khi được Pivotal tài trợ, nó trở thành một nhánh trong hệ sinh thái Spring. Nếu bạn đã từng làm việc với các thư viện ReactiveX như RxJS, thì đây chính là một framework thuộc nền tảng đó. Spring Webflux là một mảnh ghép hoàn chỉnh cho các dự án Spring MVC cần thêm giải pháp đa luồng và non-blocking IO.

5. Microservice (MSA)

Microservice không còn là trend mà đã dần trở thành một yêu cầu tất yếu đối với các lập trình viên hiện đại.

Nhưng nói đi cũng phải nói lại. Microservice khó, bao hàm rất nhiều chủ đề, kiến thức trải dài cả trong lẫn ngoài sách vở.

Một số nguồn tham khảo để học về microservice:

  • Sách "Building Microservice": cung cấp một cái nhìn tổng quan đầy đủ về MSA. Rất phù hợp với những người mới bắt đầu.
  • Playlist về "Distributed Systems" của Martin Kleppmann, giảng viên đại học Cambridge.
  • microservice.io: website học microservice miễn phí của Chris Richardson, tác giả cuốn sách Microservice Pattern.

Một số trang để theo dõi về các chủ đề software architecture:

  • martinfowler.com: website của Martin Fowler, "lão đại" trong ngành lập trình. Ông là 1 trong 16 tác giả của Tuyên ngôn Agile, có ảnh hưởng lớn đến các kiến trúc phần mềm hiện đại.
  • Grokking Vietnam: Trang công nghệ chuyên cập nhật & tổng hợp các bài viết chuyên sâu về kĩ thuật phần mềm, kiến trúc hệ thống.
  • Một số tác giả trên Viblo: anh Minh Monmen, anh Đạt Bùi.

Dưới đây là một số chủ đề liên quan đến microservice trong Java (vì một vài lý do mà mình sẽ không đề cập đến Spring Cloud).

1. Containerize with Docker

Công nghệ container chắc hẳn đã không còn xa lạ với mọi người. Mỗi khi nhắc đến microservice không thể không kể đến container, bởi những tính chất đặc biệt của nó: lightweight, isolated, immutable, stateless.

Hiện nay Docker là công nghệ phổ biến nhất cung cấp giải pháp container. Có một số alternative như Podman, Rancher... nhưng Docker vẫn chiếm vị trí hàng đầu.

Trên internet có rất nhiều nguồn học Docker miễn phí, nhưng bởi quá nhiều nên đôi khi mãi vẫn không học xong đến nơi đến chốn 😅. Nếu các bạn là newbie, mình cực kì recommend trang learndocker.online. Hoàn toàn miễn phí, cực kì chất lượng. Anh instructor có tâm đến nỗi học xong 2/4 module là donate liền cho ảnh 😄. Chỉ trong vòng 1 tháng, từ một đứa không biết gì về container & Docker, mình đã có thể tự handle toàn bộ các task deployment trong dự án, training lại cho các anh em trong team, thậm chí tự làm video hướng dẫn Docker cho 500 anh em trên Youtube và nhận được phản hồi rất tích cực 😁.

2. Container ochestration with Kubernetes

Đối với các hệ thống lớn thì số lượng container có thể lên đến hàng chục hàng trăm. Lúc này cần có một giải pháp để quản lý và điều phối các container sao cho chúng hoạt động trơn tru cùng nhau.

Các giải pháp có thể kể đến: Kubernetes (K8s), Docker Swarm, Redhat Openshift, Nomad... Trong số đó, phổ biến nhất và được ưa chuộng nhất là K8s - một khối kiến trúc đồ sộ với nhiều thứ "tinh hoa" bên trong. Có rất nhiều architecture patterns cao cấp được dùng để tạo ra K8s. Nếu có thêm kinh nghiệm với K8s, lập trình viên sẽ được đánh giá cao và có nhiều lợi thế khi tuyển dụng.

3. Spring Boot Actuator

Spring Boot Actuator là một dependency không thể thiếu khi triển khai production. Các chức năng mà nó cung cấp có thể kể đến như:

  • Health-check: việc kiểm tra trạng thái đang hoạt động của ứng dụng backend trong microservice rất quan trọng. Các công cụ như K8s sẽ dựa vào health status của container để có thể tự restart lại container trong trường hợp ứng dụng bị treo do lỗi runtime.
  • Monitoring: khi triển khai microservice, bởi có quá nhiều container chạy trên cùng một machine nên cần thiết phải giám sát chặt chẽ các tài nguyên như RAM, CPU, network bandwidth... để khi có sự cố, hệ thống sẽ tự gửi mail thông báo cho developers và có những cách xử lý tạm thời cho phù hợp.
  • Programmatically manipulation: sẽ có những trường hợp chúng ta muốn restart app Spring Boot bằng code thay vì phải gõ terminal, nhờ đó mà việc start/stop container linh hoạt hơn, thì Actuator chính là giải pháp.

4. API communication

Việc giao tiếp giữa các microservice là một khía cạnh quan trọng.

Nếu triển khai theo mô hình Spring Cloud (toàn bộ microservice đều được viết bằng Java Spring) thì chúng ta có thư viện FeignClient hỗ trợ việc gọi API và Hystrix với vai trò circuit breaker.

Circuit breaker, đúng với nghĩa tiếng Việt của nó - "cầu chì" - là một pattern nhằm tăng khả năng chịu lỗi (fault-tolerance). Trong hệ thống, khi các microservice phụ thuộc chồng chéo lên nhau, nếu một request giữa 2 service bị fail, sẽ có khả năng xảy ra 1 chuỗi thất bại dây chuyền (cascading failures) lên toàn bộ hệ thống, khiến user không thể sử dụng app. Lúc này circuit breaker đóng vai trò là điểm bảo vệ để ngăn chặn phản ứng dây chuyền đó và gửi thông báo cho developer để xử lý kịp thời.

Trong mô hình microservice hiện đại, không phải container nào cũng viết bằng Java. Do đó việc giao tiếp lúc này không khác gì gọi API thông thường. Một số thư viện hỗ trợ có thể kể đến như RestTemplate, OkHttp, Retrofit. Giải pháp circuit breaker có thể kể đến như Resilience4j, Hystrix, Alibaba Sentinel, Spring Retry.

Hiện tại gRPC là một xu thế đang được dùng để thay cho REST bởi hiệu năng vượt trội của nó - payload được gửi đi ở dạng binary thay vì text json, và sử dụng giao thức HTTP/2 thay vì 1 như của REST.

5. Message queue communication

Việc giao tiếp thông qua message queue thay vì gọi request trực tiếp đến nhau là một pattern để giảm sự phụ thuộc (loose-coupled) và tăng khả năng mở rộng (scalability) của hệ thống.

Thử tưởng tượng chúng ta có 4 service trong hệ thống. Khi toàn bộ service gọi trực tiếp lẫn nhau, chỉ cần loại bỏ một service sẽ gây ra sự sụp đổ trong hệ thống, bởi 3 service kia đều bị phụ thuộc vào service này.

So sánh playframework và spring mvc

Trong khi đó, nếu dùng message queue, các service sẽ chẳng biết đến nhau mà chỉ biết một queue duy nhất. Queue lúc này đóng vai trò như trạm bưu điện trung gian. Loại bỏ hay thêm vào một service sẽ không gây sụp đổ phụ thuộc.

So sánh playframework và spring mvc

Một số các message queue đang được sử dụng phổ biến hiện nay là Apache Kafka, RabitMQ, AmazonSQS...

6. Spring Native & GraalVM

Một trong những khuyết điểm của Spring Boot là việc cỡ file jar quá lớn, thời gian start app lâu, tiêu tốn lượng RAM nhiều - cái giá phải trả cho tốc độ xử lý tính toán cực nhanh của nó.

Đội ngũ Spring và GraalVM đã cho ra đời dự án Spring Native để xử lý các khuyết điểm này. Bằng cách tối ưu quy trình build app thành các native image, thời gian start app cũng như kích thước RAM tiêu thụ giảm đi đáng kể. Tuy nhiên đổi lại, thời gian build ở máy local sẽ lâu hơn và khối lượng RAM tiêu thụ lúc build cũng "kinh khủng" không kém. (trade-offs 😅)

Hiện Spring Native đang ở giai đoạn thử nghiệm (experimental).

6. Better source code with Kotlin

Java là một ngôn ngữ tương đối thuần khiết và dễ học. Khuyết điểm lớn nhất của nó là sự rườm rà (verbose) - nghĩa là chúng ta phải tốn quá nhiều code cho một tính năng nếu so sánh với một số ngôn ngữ khác.

Thử so sánh 2 đoạn code giữa Java và Ruby.

class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
print "Hello World!"

Mỗi ngôn ngữ lập trình có một mức độ verbosity nhất định. Có thể bạn sẽ cho rằng cứ chọn cái nào viết ngắn gọn nhất là ổn. Tuy nhiên, bản chất của sự ngắn gọn mà các ngôn ngữ có được là do nó đang che đi những đoạn code phức tạp bên dưới. Càng ngắn gọn nghĩa là tính abstract càng cao, bạn không có quyền can thiệp sâu hơn vào hệ thống bên dưới, dẫn đến việc performance không được tối ưu 100% bởi những sự lặp lại dư thừa vô hình. Điều này lý giải tại sao ngôn ngữ "rườm rà" như C, C++ lại có hiệu năng cao. Tuy nhiên, quá verbose dài dòng sẽ rất khó maintain. Trong phần mềm, khả năng bảo trì là yếu tố sống còn của dự án. Do vậy, developer cần biết cách cân bằng giữa 2 cán cân verbosity-performance để lựa chọn ngôn ngữ cho phù hợp.

Qua mỗi lần release của Java, chúng ta thấy được nỗ lực của Oracle trong việc tinh giản Java để nó trở nên "hấp dẫn", "sexy" hơn trong mắt lập trình viên.

Tuy vậy, vẫn còn một lựa chọn không kém phần hay ho, chính là Kotlin. Được giới thiệu lần đầu tiên vào năm 2011 bởi Jetbrains, syntax của Kotlin đột phá đến nỗi Google quyết định chọn Kotlin làm ngôn ngữ chính thức cho mã nguồn Android. Những năm gần đây, Kotlin luôn được bình chọn là một trong những ngôn ngữ yêu thích nhất trong các khảo sát của Stackoverflow.

Migrate source code từ Java sang Kotlin là một quyết định đáng để suy nghĩ, bởi Kotlin giúp viết code ngắn gọn đơn giản hơn, nhưng vẫn giữ được hiệu năng cao mà Java mang lại.

Kết

Như vậy mình đã tổng hợp xong một số chủ đề nâng cao trong Java.

Công nghệ thay đổi rất nhanh. Có thể 6 tháng hay 1 năm nữa, những công nghệ đề cập trong bài viết nãy đã lạc hậu. Nhưng chắc chắn một điều, kiến thức nền tảng sẽ luôn tồn tại một thời gian rất dài. Nắm vững nền tảng là chìa khóa để "cân" mọi cuộc chơi trong ngành phần mềm 😊.