Netty là một framework mã nguồn mở cho Java được phát triển bởi JBoss. Về bản chất, Netty được xây dựng dựa trên NIO (Non-blocking I/O) và đóng vai trò như một lớp trừu tượng hóa cao cấp hơn cho NIO, cung cấp các tính năng mạnh mẽ và phức tạp hơn. Quá trình phát triển của các công nghệ I/O có thể được tóm tắt như sau: IO -> NIO -> Netty. Trong Netty, ServerBootstrap và ClientBootstrap là hai lớp quan trọng, lần lượt dùng để khởi tạo và cấu hình máy chủ (server) và client. Để khởi tạo một máy chủ, chúng ta cần thực hiện các bước sau:
// Tạo một ChannelFactory sử dụng NIO
final ChannelFactory factoryKenh = new NioServerSocketChannelFactory(
// Boss thread pool, chịu trách nhiệm lắng nghe các kết nối
Executors.newCachedThreadPool(),
// Worker thread pool, xử lý các kết nối đã được chấp nhận
Executors.newCachedThreadPool()
);
// Khởi tạo ServerBootstrap với factoryKenh
ServerBootstrap khungMach = new ServerBootstrap(factoryKenh);
// Tạo một ServerPipelineFactory để cấu hình pipeline cho mỗi channel
ServerPipelineFactory nhaMayDuongOng = new ServerPipelineFactory(xuLyThucThi);
khungMach.setPipelineFactory(nhaMayDuongOng);
ServerBootstrap cần một ServerSocketChannelFactory để tạo các kênh (channels). Chúng ta có thể chọn NioServerSocketChannelFactory (dựa trên NIO) hoặc OioServerSocketChannelFactory (dựa trên IO thông thường). Cả hai đều yêu cầu hai thread pool: một cho Boss và một cho Worker. Boss thread lắng nghe trên một cổng cụ thể, nhận yêu cầu kết nối socket và chuyển chúng cho một Worker thread, sau đó tiếp tục lắng nghe. Worker thread chịu trách nhiệm xử lý các kết nối đã được chấp nhận. Với NIO, một Worker thread có thể quản lý nhiều Channel (kết nối socket) cùng lúc. Ngược lại, với IO thông thường, mỗi Worker thread chỉ tương ứng với một Channel. Mỗi Channel đều có một ChannelPipeline, chứa một chuỗi các Handler được sắp xếp theo thứ tự. Khi có tin nhắn đến trên một Channel, Worker thread sẽ xử lý nó bằng cách truyền qua chuỗi Handler này, tương tự như chuỗi filter trong các framework web khác. Đối với các Handler thực hiện các tác vụ IO phức tạp hoặc truy cập cơ sở dữ liệu kéo dài, chúng có thể chiếm dụng Worker thread trong thời gian dài. ExecutionHandler được dùng để giải quyết vấn đề này. ExecutionHandler cũng là một Handler, được định nghĩa trong ChannelPipeline. Nó sẽ lấy một thread từ một thread pool riêng và dùng nó để xử lý các Handler đứng sau nó trong pipeline, giúp giải phóng Worker thread nhanh chóng.
static ExecutionHandler xuLyThucThi = new ExecutionHandler(new OrderedMemoryAwareThreadPoolExecutor(16, 1048576, 1048576));
Netty cung cấp hai loại Executor: MemoryAwareThreadPoolExecutor và OrderedMemoryAwareThreadPoolExecutor. Loại đầu tiên đảm bảo không xảy ra lỗi tràn bộ nhớ bằng cách chặn nếu có quá nhiều sự kiện (Event). Loại thứ hai, ngoài việc đảm bảo an toàn về bộ nhớ, còn đảm bảo rằng các sự kiện (Event) của cùng một Channel được xử lý theo đúng thứ tự.