Phát triển gọi từ xa theo phong cách REST (RESTful Remoting) trong Dubbo

Tổng quan

Dubbo hỗ trợ nhiều kiểu gọi từ xa như Dubbo RPC (binary serialization + TCP), HTTP Invoker (binary serialization + HTTP), Hessian (binary serialization + HTTP), WebServices (text serialization + HTTP) nhưng thiếu hỗ trợ cho kiểu RESTful hiện đại (text serialization + HTTP).

Chúng tôi đã tích hợp JAX-RS 2.0 (Java API for RESTful Web Services) vào Dubbo để cung cấp hỗ trợ gần như minh bạch cho REST. Giải pháp này hoàn toàn tương thích với chuẩn Java nên dịch vụ REST xây dựng trên Dubbo có thể hoạt động độc lập với bất kỳ nền tảng REST cụ thể nào.

Ưu điểm của REST

  • Tận dụng hiệu quả bộ nhớ đệm để tăng tốc độ phản hồi
  • Phi trạng thái giúp mở rộng hệ thống tốt hơn
  • Trình duyệt có thể làm client trực tiếp
  • Phụ thuộc ít vào các cơ chế phức tạp
  • Không cần cơ chế discovery tài nguyên
  • Tương thích lâu dài với công nghệ thay đổi

Các trường hợp sử dụng

  1. Tích hợp hệ thống dị biệt trong doanh nghiệp
  2. Phát triển API mở (Open API)
  3. Hỗ trợ ứng dụng di động/tablet
  4. Hỗ trợ phát triển ứng dụng AJAX
  5. Chuẩn hóa giao tiếp giữa các hệ thống Dubbo
  6. Đơn giản hóa gọi dịch vụ từ hệ thống ngoài

Hướng dẫn nhanh

Ví dụ xây dựng API đăng ký người dùng:

@Path("nguoi-dung")
public class UserServiceImpl implements UserService {

    @POST
    @Path("dang-ky")
    @Consumes(MediaType.APPLICATION_JSON)
    public void dangKyNguoiDung(NguoiDung nguoiDung) {
        // Lưu thông tin người dùng
    }
}
<dubbo:protocol name="rest" port="8080"/>
<dubbo:service interface="com.example.UserService" ref="userService"/>
<bean id="userService" class="com.example.UserServiceImpl" />

Giới thiệu JAX-RS

JAX-RS là chuẩn API REST của Java được các tổ chức lớn như Oracle (Jersey), RedHat (RestEasy), Apache (CXF) và các ứng dụng JavaEE 6+ hỗ trợ. Phiên bản JAX-RS 2.0 được tích hợp vào Dubbo cung cấp khả năng phát triển REST chuẩn hóa.

Chi tiết triển khai REST tại phía cung cấp

Triển khai HTTP POST/GET

@GET
@Path("{id : \\d+}")
@Produces(MediaType.APPLICATION_JSON)
public NguoiDung layThongTin(@PathParam("id") Long maSo) {
    return timTheoID(maSo);
}

Đặt annotation ở interface hay class

Nên đặt annotation trong class triển khai để giữ sạch interface, trừ khi cần sử dụng bởi consumer Dubbo.

Hỗ trợ nhiều định dạng dữ liệu

@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
NguoiDung layThongTin(@PathParam("id") Long maSo);

Hỗ trợ tiếng Việt

@Produces("application/json; charset=UTF-8")
NguoiDung layThongTin(@PathParam("id") Long maSo);

Cấu hình REST Server

<dubbo:protocol name="rest" server="tomcat" port="8080"/>

Các tùy chọn hỗ trợ: Jetty, Tomcat, Netty, Tjws, Sun HTTP server hoặc servlet container bên ngoài.

Chi tiết triển khai REST tại phía sử dụng

Trường hợp 1: Hệ thống ngoài gọi REST của Dubbo

Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/users/register.json");
Response response = target.request().post(Entity.entity(nguoiDung, MediaType.APPLICATION_JSON));

Trường hợp 2: Dubbo consumer gọi REST của Dubbo

<dubbo:reference id="userService" interface="com.example.UserService"/>

Trường hợp 3: Dubbo consumer gọi REST bên ngoài

<dubbo:reference id="userService" 
    interface="com.example.UserService" 
    url="rest://api.example.com/services/"/>

Hạn chế của JAX-RS trong Dubbo

  • Chỉ hỗ trợ singleton scope
  • Không hỗ trợ @Context cho field

Các câu hỏi thường gặp

Dubbo REST tích hợp tự động với service registry và monitoring center. Khi dùng consumer Dubbo, cơ chế load balancing và failover hoạt động như các giao thức RPC khác.

Cải tiến tiềm năng

  • Giảm tính xâm nhập của RpcContext
  • Tinh chỉnh cấu hình protocol
  • Chuẩn hóa tên XML theo chuẩn Spring

Kiến trúc so sánh

So sánh REST với Thrift, Protobuf, WebServices truyền thống và Spring MVC:

  • REST phù hợp cho kiến trúc service hóa
  • Spring MVC phù hợp cho ứng dụng web
  • JAX-RS tập trung ở tầng dịch vụ

Hiệu năng

Kết quả benchmark (5 phút, 10 luồng):

Công nghệThời gian phản hồiTPS
REST+Tomcat+JSON2.082ms4796
Dubbo+Kryo1.182ms8444

Thẻ: Dubbo REST JAX-RS JSON XML

Đăng vào ngày 23 tháng 5 lúc 02:02