-
Design Pattern
- Singleton Design Pattern
- Factory Design Pattern
- Factory Method Design Pattern
- Abstract Factory Design Pattern
- Builder Design Pattern
- Prototype Design Pattern
- Object Pool Design Pattern
- Chain of Responsibility Design Pattern
- Command Design Pattern
- Interpreter Design Pattern
- Iterator Design Pattern
- Mediator Design Pattern
- Memento Design Pattern
- Observer Design Pattern
- Observer Design Pattern - Xử Lý Exception
- Strategy Design Pattern
- Template Method Design Pattern
- Visitor Design Pattern
- Null Object Design Pattern
- Adapter Design Pattern
- Bridge Design Pattern
- Composite Design Pattern
- Decorator Design Pattern
- Flyweight Design Pattern
- Proxy Design Pattern
- S.O.L.I.D
- Clean code
- Lập trình socket
- Java Core
- Multi-Thread
- Spring
- Java Web
- Memory Caching
- Message Queue
- DevOps
- Xây dựng một nền tảng
- MongoDB
- MySQL timestamp
- Properties vs yaml
- Kotlin
- Lập Trình Machine Learning với PyTorch
- Mã Nguồn Mở
- Ezy HTTP
- Free Chat
- Một số kinh nghiệm với Git
- Review cho đồng nghiệp!
- Setup Dev Environment
- Hello World
- Create a Server Project
- Handle Client Requests
- Using ezyfox-server-csharp-client
- Using ezyfox-es6-client
- Client React.js Interaction
- Build And Deploy In Local
Cần một chút tinh tế
Chúng ta đã quá quen với HTTP rồi, đã quá quen với các thư viện dùng sẵn rồi nhỉ? Điều này giúp chúng ta không cần quan tâm đến những thứ đau đầu như byte bit, mà chỉ cần quan tâm đến đối tượng hay dữ liệu gửi nhận mà thôi. Nhưng để chương trình của chúng ta đạt hiệu suất tối đa, đặc biệt với lập trình socket, chúng ta vẫn cần phải biết điều gì đang xảy ra với dữ liệu của mình, và chỉ cần thêm một chút tinh tế, chúng ta sẽ có thể nâng tầm cho ứng dụng của mình thậm chí với ít tài nguyên hơn so với phiên bản cũ.
Luồng gửi nhận thông thường
Trong các framework http hay các framework cho socket và websocket như netty, vertx, ... dữ liệu đều phải trải qua các bước cơ bản như:
- receive: ở bước này socket server sẽ nhận được dữ liệu sẽ đến từ internet ở dạng byte array.
- buffer: dữ liệu đến từ socket có thể sẽ không đủ một message ngay lập tức nên chúng ta cần buffer để tích lại cho đến khi nào nhận đủ số byte thì thôi.
- deserialize: một message ở dạng byte array sẽ không phù hợp để xử lý, nên chúng ta cần chuyển đổi sang dạng đối tượng request, chúng ta có thể dùng bất kì định dạng nào chúng ta muốn, nhưng tốt nhất ở thời điểm này có lẽ là json, protobuf hay msgpack sẽ giúp chúng ta giảm được rất nhiều size cho một message
- handle request: đây là nơi chúng ta sẽ xử lý logic, cập nhật, cắt ghép dữ liệu để trả về kết quả cho client
- response: ở bước này chúng ta sẽ gửi kết quả đến socket channel để phản hồi cho client
- serialize: dữ liệu để gửi được qua socket thì phải ở dạng byte array nên chúng ta cần chuyển đối tượng thành byte array và một lần sử dụng json, protobuf hay msgpack sẽ giúp chúng ta tiết kiệm được rất nhiều bit và byte.
- send: dữ liệu sau khi thành byte array sẽ được gửi xuống socket cho client
Broadcast dữ liệu
Đối với luồng gửi nhận dữ liệu thông thường, việc xử lý request từ 1 client và trả lại kết quả chỉ cho client đó thì đơn giản rồi, tuy nhiên chúng ta có một bài toán lớn hơn đó là broadcast dữ liệu. Đây là bài toán rất phổ biến mà tất cả các framework socket giải giải quyết, tuy nhiên không phải framework nào cũng hỗ trợ sẵn. Ví dụ với netty, chúng ta hay làm thế này:
channels.forEach(channel -> channel.writeAndFlush(response));
Tuy nhiên làm như vậy sẽ dẫn điến việc mỗi message khi vào từng channel sẽ bị serialize 1 lần, và điều này làm giảm hiệu năng đi đáng kể.
Cải thiện hiệu năng
Chúng ta có thể thấy rõ ràng là cùng một response mà bị serialize nhiều lần sẽ không ổn, bây giờ chúng sẽ serialize response ra byte array trước rồi mới gửi đến socket client, nó sẽ kiểu thế này:
byte[] bytes = serializer.serialize(response);
channels.forEach(channel -> channel.writeAndFlush(bytes));
Nhìn thì có vẻ đơn giản đúng không? Nhưng thực tế với những framework được thiết kế đo ni đóng giày với chain of responsibility design pattern kiểu thế này:
Thì việc chúng ta thay đổi không hề đơn giản, chúng ta sẽ phải làm rất nhiều việc để wrap lại framework đã có và phải cẩn thận để tránh tạo ra một mớ hỗn độn. Hãy khéo léo gộp chung Encoder
và ResponseHandler
vào làm một.
Tổng kết
Với những bài toán gửi nhận dữ liệu 1-1 thông thường thì không có gì phức tạp, tuy nhiên đối với bài toàn broadcast dữ liệu thì câu chuyện lại khác, cần phải serialize đối tượng thành byte array trước khi gửi xuống tất cả các socket client. Tuy nhiên việc này không hề đơn giản vì dữ liệu qua socket phải trải qua tầng tầng lớp các queue và handler trước khi được gửi xuống socket client. Nắm được điều này ezyfox-server đã đóng gọi việc chuyển dữ liệu thành byte array và gửi xuống socket client, bạn chỉ cần sử dụng đối tượng EzyResponse và thế là xong.
-
Design Pattern
- Singleton Design Pattern
- Factory Design Pattern
- Factory Method Design Pattern
- Abstract Factory Design Pattern
- Builder Design Pattern
- Prototype Design Pattern
- Object Pool Design Pattern
- Chain of Responsibility Design Pattern
- Command Design Pattern
- Interpreter Design Pattern
- Iterator Design Pattern
- Mediator Design Pattern
- Memento Design Pattern
- Observer Design Pattern
- Observer Design Pattern - Xử Lý Exception
- Strategy Design Pattern
- Template Method Design Pattern
- Visitor Design Pattern
- Null Object Design Pattern
- Adapter Design Pattern
- Bridge Design Pattern
- Composite Design Pattern
- Decorator Design Pattern
- Flyweight Design Pattern
- Proxy Design Pattern
- S.O.L.I.D
- Clean code
- Lập trình socket
- Java Core
- Multi-Thread
- Spring
- Java Web
- Memory Caching
- Message Queue
- DevOps
- Xây dựng một nền tảng
- MongoDB
- MySQL timestamp
- Properties vs yaml
- Kotlin
- Lập Trình Machine Learning với PyTorch
- Mã Nguồn Mở
- Ezy HTTP
- Free Chat
- Một số kinh nghiệm với Git
- Review cho đồng nghiệp!
- Setup Dev Environment
- Hello World
- Create a Server Project
- Handle Client Requests
- Using ezyfox-server-csharp-client
- Using ezyfox-es6-client
- Client React.js Interaction
- Build And Deploy In Local