Tại sao JSF lưu trạng thái của các thành phần UI trên máy chủ?


108
  1. Cho đến thời điểm nào JSF lưu trạng thái của các thành phần UI ở phía máy chủ và khi nào chính xác thông tin trạng thái của thành phần UI được xóa khỏi bộ nhớ máy chủ? Khi người dùng đã đăng nhập vào ứng dụng điều hướng qua các trang, trạng thái của các thành phần có tiếp tục tích lũy trên máy chủ không?

  2. Tôi không hiểu lợi ích của việc giữ trạng thái các thành phần UI trên máy chủ là gì !? Việc chuyển trực tiếp dữ liệu đã được xác thực / chuyển đổi sang các bean được quản lý có đủ không? Tôi có thể hay tôi nên cố gắng tránh nó?

  3. Điều đó có tốn quá nhiều bộ nhớ ở phía máy chủ không, nếu có hàng nghìn phiên người dùng đồng thời? Tôi có một ứng dụng nơi người dùng có thể đăng blog về các chủ đề nhất định. Các blog này có kích thước khá lớn. Khi có bài đăng trở lại hoặc yêu cầu xem blog, dữ liệu trang lớn này sẽ được lưu như một phần của trạng thái các thành phần? Điều này sẽ chiếm quá nhiều bộ nhớ. Đây không phải là một mối quan tâm?


Cập nhật 1:

Bây giờ, không còn cần thiết phải lưu trạng thái trong khi sử dụng JSF. Một triển khai JSF không trạng thái hiệu suất cao có sẵn để sử dụng. Xem blog này và câu hỏi này để biết chi tiết và thảo luận có liên quan. Ngoài ra, có một vấn đề mở để đưa vào thông số kỹ thuật JSF, một tùy chọn để cung cấp chế độ không trạng thái cho JSF. (Tái bút Hãy xem xét bỏ phiếu cho các vấn đề này & điều này nếu đây là một tính năng hữu ích cho bạn.)


Cập nhật 2 (24-02-2013):

Một tin tuyệt vời rằng Mojarra 2.1.19 đã ra mắt với chế độ không trạng thái !

Xem tại đây:

http://weblogs.java.net/blog/mriem/archive/2013/02/08/jsf-going-stateless?force=255

http://java.net/jira/browse/JAVASERVERFACES-2731

http://balusc.blogspot.de/2013/02/stateless-jsf.html

Câu trả lời:


199

Tại sao JSF cần lưu trạng thái của các thành phần UI ở phía máy chủ?

Bởi vì HTTP là không trạng thái và JSF là trạng thái. Cây thành phần JSF có thể thay đổi động (có lập trình). JSF chỉ cần biết chính xác trạng thái như khi biểu mẫu được hiển thị cho người dùng cuối, để nó có thể xử lý thành công toàn bộ vòng đời JSF dựa trên thông tin được cung cấp bởi cây thành phần JSF ban đầu khi biểu mẫu đã được gửi trở lại máy chủ. Cây thành phần cung cấp thông tin về tên tham số yêu cầu, bộ chuyển đổi / trình xác nhận cần thiết, thuộc tính bean được quản lý liên kết và phương thức hành động.


Cho đến thời điểm nào JSF lưu trạng thái của các thành phần UI ở phía máy chủ và khi nào chính xác thông tin trạng thái của thành phần UI được xóa khỏi bộ nhớ máy chủ?

Hai câu hỏi đó dường như sôi sục đến cùng. Dù sao, đây là cách triển khai cụ thể và cũng phụ thuộc vào việc trạng thái được lưu trên máy chủ hay máy khách. Một chút triển khai tốt sẽ loại bỏ nó khi nó đã hết hạn hoặc khi hàng đợi đã đầy. Ví dụ, Mojarra có giới hạn mặc định là 15 chế độ xem logic khi lưu trạng thái được đặt thành phiên. Điều này có thể định cấu hình với thông số ngữ cảnh sau trong web.xml:

<context-param>
    <param-name>com.sun.faces.numberOfLogicalViews</param-name>
    <param-value>15</param-value>
</context-param>

Xem thêm Câu hỏi thường gặp về Mojarra để biết các thông số cụ thể khác của Mojarra và câu trả lời liên quan này com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews


Khi người dùng đã đăng nhập vào ứng dụng điều hướng qua các trang, trạng thái của các thành phần có tiếp tục tích lũy trên máy chủ không?

Về mặt kỹ thuật, điều đó phụ thuộc vào việc thực hiện. Nếu bạn đang nói về điều hướng từng trang (chỉ là GET yêu cầu) thì Mojarra sẽ không lưu bất cứ thứ gì trong phiên. Tuy nhiên, nếu chúng là yêu cầu ĐĂNG (biểu mẫu có liên kết lệnh / nút), thì Mojarra sẽ lưu trạng thái của từng biểu mẫu trong phiên cho đến khi giới hạn tối đa. Điều này cho phép người dùng cuối mở nhiều biểu mẫu trong các tab trình duyệt khác nhau trong cùng một phiên.

Hoặc, khi lưu trạng thái được đặt thành máy khách, thì JSF sẽ không lưu trữ bất kỳ thứ gì trong phiên. Bạn có thể làm điều đó bằng tham số ngữ cảnh sau trong web.xml:

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

Sau đó, nó sẽ được tuần tự hóa thành một chuỗi được mã hóa trong một trường đầu vào ẩn với tên javax.faces.ViewStatecủa biểu mẫu.


Tôi không hiểu lợi ích của việc giữ trạng thái của thành phần UI ở phía máy chủ là gì. Việc chuyển trực tiếp dữ liệu đã được xác thực / chuyển đổi sang các bean được quản lý có đủ không? Tôi có thể / có nên cố gắng tránh nó không?

Điều đó không đủ để đảm bảo tính toàn vẹn và mạnh mẽ của JSF. JSF là một khuôn khổ động với một điểm kiểm soát đầu vào duy nhất. Nếu không có một quản lý nhà nước, người ta sẽ có thể giả mạo / hack HTTP yêu cầu theo một cách nhất định (ví dụ như chế tác disabled, readonlyrenderedcác thuộc tính), để cho JSF làm những việc khác nhau -Và có khả năng hazardful-. Nó thậm chí sẽ dễ bị CSRF tấn công và lừa đảo.


Và điều đó sẽ không tiêu tốn quá nhiều bộ nhớ ở phía máy chủ, nếu có hàng nghìn phiên người dùng đồng thời? Tôi có một ứng dụng nơi người dùng có thể đăng blog về các chủ đề nhất định. Các blog này có kích thước khá lớn. Khi có bài đăng trở lại hoặc yêu cầu xem các blog, các blog lớn sẽ được lưu dưới dạng một phần của trạng thái các thành phần. Điều này sẽ tiêu tốn quá nhiều bộ nhớ. Đây không phải là một mối quan tâm?

Bộ nhớ đặc biệt rẻ. Chỉ cần cung cấp đủ bộ nhớ cho máy chủ ứng dụng. Hoặc nếu băng thông mạng rẻ hơn đối với bạn, chỉ cần chuyển trạng thái tiết kiệm sang phía máy khách. Để tìm ra kết quả phù hợp nhất, chỉ cần thống kê và lập hồ sơ ứng dụng web của bạn với lượng người dùng đồng thời tối đa dự kiến ​​và sau đó cung cấp cho máy chủ ứng dụng 125% ~ 150% bộ nhớ tối đa được đo.

Lưu ý rằng JSF 2.0 đã cải thiện rất nhiều trong quản lý nhà nước. Có thể để tiết kiệm nước một phần (ví dụ chỉ sự <h:form>sẽ được lưu lại thay vì toàn bộ công cụ từ <html>tất cả các cách để kết thúc). Ví dụ như Mojarra làm điều đó. Một biểu mẫu trung bình có 10 trường đầu vào (mỗi trường có nhãn và thông báo) và 2 nút sẽ không quá 1KB. Với 15 lượt xem trong phiên, tức là không quá 15KB mỗi phiên. Với ~ 1000 phiên người dùng đồng thời, không quá 15MB.

Mối quan tâm của bạn nên tập trung hơn vào các đối tượng thực (các bean được quản lý và / hoặc thậm chí các thực thể DB) trong phạm vi phiên hoặc ứng dụng. Tôi đã thấy rất nhiều mã và dự án sao chép không cần thiết toàn bộ bảng cơ sở dữ liệu vào bộ nhớ của Java theo hương vị của một bean phạm vi phiên, nơi Java được sử dụng thay vì SQL để lọc / nhóm / sắp xếp các bản ghi. Với ~ 1000 bản ghi, điều đó sẽ dễ dàng vượt quá 10MB cho mỗi phiên người dùng .


1
Bạn có thể làm rõ # 2 không? Tại sao cây thành phần không thể được tạo lại theo từng yêu cầu? Trạng thái nào thực sự cần được lưu trữ giữa các yêu cầu và tại sao? Có vẻ như lý do duy nhất để lưu cây thành phần giữa các yêu cầu là vì hiệu suất.
Ryan

Câu hỏi tập trung hơn ở đây: stackoverflow.com/questions/7349174/…
Ryan

Câu trả lời của bạn rất rõ ràng đối với tôi! Các vấn đề về hiệu suất JSF và khả năng mở rộng có mối quan hệ nội tại với việc triển khai của lập trình viên! Nó cần phải biết sử dụng công nghệ đúng cách!
Lucas Batistussi,

"Chỉ cần cung cấp đủ bộ nhớ cho máy chủ ứng dụng." Erm, tôi có ấn tượng rằng chúng ta đang nói về những thứ cấp doanh nghiệp ở đây, nếu chúng ta đang nói về hàng nghìn phiên người dùng đồng thời. Nếu bạn có thiết bị cấp doanh nghiệp trong một doanh nghiệp, bạn không thể chỉ "cung cấp cho máy chủ ứng dụng đủ bộ nhớ" như bạn có thể làm trong hộp linux ở nhà.
stu

Câu trả lời của bạn rất rõ ràng và cảm ơn vì điều đó. Tại sao phạm vi flash JSF biến mất nếu đặt javax.faces.PARTIAL_STATE_SAVING thành true. getFacesContext (). getExternalContext (). getFlash (). put ("buildingId", buildingId).
Có thể Thet
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.