Cách tiếp cận của thang máy đối với khả năng mở rộng nằm trong cùng một máy. Chia tỷ lệ trên các máy là một chủ đề lớn hơn, khó khăn hơn. Câu trả lời ngắn gọn là: Scala và Lift không làm bất cứ điều gì để giúp hoặc cản trở việc mở rộng theo chiều ngang. Với các diễn viên trong một máy duy nhất, Lift đạt được khả năng mở rộng tốt hơn bởi vì một cá thể đơn lẻ có thể xử lý nhiều yêu cầu đồng thời hơn so với hầu hết các máy chủ khác. Để giải thích, trước tiên tôi phải chỉ ra các sai sót trong mô hình xử lý yêu cầu theo yêu cầu cổ điển. Chịu với tôi, điều này sẽ yêu cầu một số lời giải thích.
Một khung công tác điển hình sử dụng chuỗi để phục vụ yêu cầu trang. Khi máy khách kết nối, khung công tác gán một luồng ra khỏi một nhóm. Chủ đề đó sau đó thực hiện ba điều: nó đọc yêu cầu từ một ổ cắm; nó thực hiện một số tính toán (có khả năng liên quan đến I/O đến cơ sở dữ liệu); và nó sẽ gửi phản hồi trên ổ cắm. Ở mỗi bước khá nhiều, luồng sẽ kết thúc trong một thời gian. Khi đọc yêu cầu, nó có thể chặn trong khi chờ mạng. Khi thực hiện tính toán, nó có thể chặn trên đĩa hoặc mạng I/O. Nó cũng có thể chặn trong khi chờ cơ sở dữ liệu. Cuối cùng, trong khi gửi phản hồi, nó có thể chặn nếu máy khách nhận dữ liệu từ từ và các cửa sổ TCP được lấp đầy. Nhìn chung, các chủ đề có thể chi tiêu 30 - 90% thời gian của nó bị chặn. Tuy nhiên, nó dành 100% thời gian cho một yêu cầu đó.
Một JVM chỉ có thể hỗ trợ quá nhiều luồng trước khi nó thực sự chậm lại. Lập lịch trình chủ đề, tranh chấp cho các thực thể chia sẻ bộ nhớ (như các hồ bơi kết nối và màn hình), và các giới hạn hệ điều hành gốc đều áp đặt các hạn chế về số lượng chủ đề mà một JVM có thể tạo ra.
Vâng, nếu JVM bị hạn chế về số chuỗi tối đa của nó và số lượng chủ đề xác định số lượng yêu cầu đồng thời mà máy chủ có thể xử lý, thì số lượng yêu cầu đồng thời sẽ được xác định theo số chuỗi.
(Có những vấn đề khác có thể áp đặt giới hạn thấp hơn --- GC sân đập, ví dụ. Chủ đề là một yếu tố hạn chế cơ bản, nhưng không phải là người duy nhất!)
Lift tách riêng chủ đề từ yêu cầu. Trong Nâng, yêu cầu không không kết nối một chuỗi. Thay vào đó, một luồng sẽ thực hiện một hành động (như đọc yêu cầu), sau đó gửi một thông báo tới một diễn viên. Diễn viên là một phần quan trọng của câu chuyện, bởi vì chúng được lên kế hoạch thông qua các chủ đề "nhẹ". Một nhóm các luồng được sử dụng để xử lý các thông điệp trong các tác nhân. Điều quan trọng là phải tránh các hoạt động chặn bên trong của các diễn viên, vì vậy các chủ đề này sẽ nhanh chóng trở lại hồ bơi.(Lưu ý rằng hồ bơi này không hiển thị cho ứng dụng, nó là một phần của sự hỗ trợ của Scala cho các diễn viên.) Một yêu cầu hiện bị chặn trên cơ sở dữ liệu hoặc đĩa I/O, chẳng hạn, không giữ một chuỗi xử lý yêu cầu bị chiếm đóng. Chuỗi xử lý yêu cầu có sẵn, gần như ngay lập tức, để nhận được nhiều kết nối hơn.
Phương pháp tách yêu cầu từ chuỗi cho phép máy chủ Nâng có nhiều yêu cầu đồng thời hơn so với máy chủ theo yêu cầu. (Tôi cũng muốn chỉ ra rằng thư viện Grizzly hỗ trợ một cách tiếp cận tương tự mà không có các tác nhân.) Các yêu cầu đồng thời khác có nghĩa là một máy chủ Lift đơn lẻ có thể hỗ trợ nhiều người dùng hơn một máy chủ Java EE thông thường.
Đây thực sự là một chủ đề lớn, tôi nghĩ bạn nên tập trung vào câu trả lời cho các khu vực cụ thể của phần mềm máy chủ –