Tại sao chúng ta nhận được một đột biến trong thời gian đáp ứng?


12

Chúng tôi có một API được triển khai bằng ServiceStack được lưu trữ trong IIS. Trong khi thực hiện kiểm tra tải API, chúng tôi đã phát hiện ra rằng thời gian phản hồi là tốt nhưng chúng sẽ xuống cấp nhanh chóng ngay khi chúng tôi đạt khoảng 3.500 người dùng đồng thời trên mỗi máy chủ. Chúng tôi có hai máy chủ và khi đánh chúng với 7.000 người dùng, thời gian phản hồi trung bình ở mức dưới 500ms cho tất cả các điểm cuối. Các hộp nằm phía sau một bộ cân bằng tải để chúng tôi nhận được 3.500 đồng quy trên mỗi máy chủ. Tuy nhiên, ngay khi chúng tôi tăng số lượng người dùng đồng thời, chúng tôi sẽ thấy thời gian phản hồi tăng đáng kể. Việc tăng số người dùng đồng thời lên 5.000 trên mỗi máy chủ cho chúng ta thời gian phản hồi trung bình trên mỗi điểm cuối khoảng 7 giây.

Bộ nhớ và CPU trên các máy chủ khá thấp, cả trong khi thời gian đáp ứng đều tốt và khi nào chúng bị hỏng. Ở mức cao nhất với 10.000 người dùng đồng thời, CPU trung bình chỉ dưới 50% và RAM chiếm khoảng 3-4 GB trong số 16. Điều này khiến chúng tôi nghĩ rằng chúng tôi đang đạt một số giới hạn ở đâu đó. Ảnh chụp màn hình bên dưới cho thấy một số bộ đếm chính trong perfmon trong quá trình thử tải với tổng số 10.000 người dùng đồng thời. Bộ đếm được tô sáng là yêu cầu / giây. Ở bên phải của ảnh chụp màn hình, bạn có thể thấy các yêu cầu trên biểu đồ thứ hai trở nên thực sự thất thường. Đây là chỉ số chính cho thời gian đáp ứng chậm. Ngay khi chúng tôi thấy mẫu này, chúng tôi nhận thấy thời gian phản hồi chậm trong thử nghiệm tải.

ảnh chụp màn hình perfmon với yêu cầu mỗi giây được tô sáng

Làm thế nào để chúng tôi đi về khắc phục sự cố hiệu suất này? Chúng tôi đang cố gắng xác định xem đây là vấn đề mã hóa hay vấn đề cấu hình. Có bất kỳ cài đặt nào trong web.config hoặc IIS có thể giải thích hành vi này không? Nhóm ứng dụng đang chạy .NET v4.0 và phiên bản IIS là 7.5. Thay đổi duy nhất chúng tôi đã thực hiện từ cài đặt mặc định là cập nhật giá trị Độ dài hàng đợi của nhóm ứng dụng từ 1.000 đến 5.000. Chúng tôi cũng đã thêm các cài đặt cấu hình sau vào tệp Aspnet.config:

<system.web>
    <applicationPool 
        maxConcurrentRequestsPerCPU="5000"
        maxConcurrentThreadsPerCPU="0" 
        requestQueueLimit="5000" />
</system.web>

Thêm chi tiết:

Mục đích của API là kết hợp dữ liệu từ nhiều nguồn bên ngoài khác nhau và trả về dưới dạng JSON. Hiện tại nó đang sử dụng triển khai bộ đệm InMemory để lưu trữ các cuộc gọi bên ngoài riêng lẻ ở lớp dữ liệu. Yêu cầu đầu tiên đối với tài nguyên sẽ tìm nạp tất cả dữ liệu cần thiết và mọi yêu cầu tiếp theo cho cùng một tài nguyên sẽ nhận được kết quả từ bộ đệm. Chúng tôi có một 'người chạy bộ đệm' được triển khai như một quá trình nền để cập nhật thông tin trong bộ đệm theo các khoảng thời gian nhất định. Chúng tôi đã thêm khóa xung quanh mã lấy dữ liệu từ các tài nguyên bên ngoài. Chúng tôi cũng đã triển khai các dịch vụ để lấy dữ liệu từ các nguồn bên ngoài theo cách không đồng bộ để điểm cuối chỉ nên chậm như cuộc gọi bên ngoài chậm nhất (tất nhiên trừ khi chúng tôi có dữ liệu trong bộ đệm). Điều này được thực hiện bằng cách sử dụng lớp System.Threading.T task.Task.Chúng ta có thể đạt được một giới hạn về số lượng chủ đề có sẵn cho quá trình không?


5
CPU của bạn có bao nhiêu lõi? Có lẽ bạn đang phát huy tối đa một lõi. Khi số ma thuật là 50%, 25% hoặc 12,5%, điều đó cho thấy rằng bạn đã sử dụng tối đa lõi và vì một lý do nào đó không thể sử dụng các lõi khác đang không hoạt động. Kiểm tra một lõi tối đa.
David Schwartz

1
Bạn đã có một chủ đề cho mỗi yêu cầu? Vì vậy, trong 5000 yêu cầu bạn đã có 5000 chủ đề? Nếu bạn làm thì đó có thể là vấn đề của bạn. Thay vào đó, bạn nên tạo một nhóm luồng và sử dụng nhóm luồng để xử lý các yêu cầu, xếp hàng các yêu cầu khi chúng đến trong nhóm luồng. Khi một luồng kết thúc với một yêu cầu, nó có thể xử lý một yêu cầu ngoài hàng đợi. Loại thảo luận này là tốt nhất cho stackoverflow. Quá nhiều chủ đề có nghĩa là quá nhiều chuyển đổi bối cảnh.
Matt

1
Chỉ cần kiểm tra sự tỉnh táo ở đây, bạn đã thử tắt tất cả các quy trình nền của mình chưa và xem hành vi nào chỉ dành cho JSON trả lại dữ liệu tĩnh từ bộ đệm? Nói cách khác, làm cho JSON của bạn yêu cầu dữ liệu tĩnh và loại bỏ "các cuộc gọi không đồng bộ bên ngoài" làm mới hoàn toàn bộ đệm của bạn. Ngoài ra, tùy thuộc vào lượng dữ liệu JSON được phục vụ cho mỗi yêu cầu, bạn đã nghĩ về thông lượng mạng của mình chưa và nếu các yêu cầu bắt đầu sao lưu vì các máy chủ không thể đẩy dữ liệu ra đủ nhanh?
Robert

1
+1 để đề xuất Davids ở trên. Bạn nên thực sự làm lại bài kiểm tra và xem xét cẩn thận từng cách sử dụng cốt lõi. Tôi khuyên bạn nên làm điều này càng sớm càng tốt để loại bỏ nó nếu không có gì khác. Thứ hai, tôi hơi nghi ngờ về bộ nhớ cache của bạn. Sự tranh chấp khóa có thể hiển thị chính xác loại hành vi này - tại một số khóa quan trọng gây ra sự chậm trễ, từ đó khiến khóa bị giữ lâu hơn bình thường, gây ra điểm bùng phát khi mọi thứ xuống dốc nhanh chóng. Bạn có thể chia sẻ bộ nhớ đệm và mã khóa của bạn?
steve nấu

1
Thiết lập đĩa cho các máy chủ là gì (giả sử rằng vì chúng được cân bằng tải nên thiết lập đĩa là như nhau)? Bạn có thể đăng tất cả các thông số kỹ thuật cho các ổ đĩa / máy chủ trong bài viết ban đầu của bạn? Bạn đã ném perfmon vào (các) đĩa trên (các) ổ đĩa vật lý mà IIS VÀ các tệp nhật ký IIS tồn tại chưa? Rất có thể bạn có thể gặp sự cố với đĩa trong đó có 3.500 yêu cầu = 3.500+ đăng nhập IIS. Nếu chúng nằm trên cùng một đĩa / phân vùng, bạn có thể gặp vấn đề lớn ở đó.
Techie Joe

Câu trả lời:


2

Theo sau với @DavidSchwartz và @Matt, nó trông giống như một chủ đề, khóa vấn đề quản lý.

Tôi đề nghị:

  1. Đóng băng các cuộc gọi bên ngoài và bộ đệm được tạo cho chúng và chạy thử tải với thông tin bên ngoài tĩnh chỉ để loại bỏ bất kỳ vấn đề nào không liên quan đến phía máy chủ - môi trường.

  2. Sử dụng nhóm chủ đề nếu không sử dụng chúng.

  3. Về các cuộc gọi bên ngoài mà bạn nói "Chúng tôi cũng đã triển khai các dịch vụ để lấy dữ liệu từ các nguồn bên ngoài theo cách không đồng bộ để điểm cuối chỉ nên chậm như cuộc gọi bên ngoài chậm nhất (tất nhiên trừ khi chúng tôi có dữ liệu trong bộ đệm). "

Các câu hỏi là: - Bạn đã kiểm tra xem có dữ liệu bộ nhớ cache nào bị khóa trong khi gọi bên ngoài không hoặc chỉ khi ghi kết quả cuộc gọi bên ngoài vào bộ đệm? (quá rõ ràng nhưng phải nói). - Bạn có khóa toàn bộ bộ nhớ cache hoặc các phần nhỏ của nó không? (quá rõ ràng nhưng phải nói). - Ngay cả khi chúng không đồng bộ, các cuộc gọi bên ngoài thường chạy như thế nào? Ngay cả khi họ không chạy thường xuyên, họ vẫn có thể bị chặn bởi số lượng yêu cầu quá lớn đối với bộ đệm từ các cuộc gọi của người dùng trong khi bộ đệm bị khóa. Kịch bản này thường hiển thị phần trăm cố định của CPU được sử dụng do nhiều luồng đang chờ trong các khoảng thời gian cố định và "khóa" cũng phải được quản lý. - Bạn đã kiểm tra nếu tác vụ bên ngoài có nghĩa là thời gian phản hồi cũng tăng khi kịch bản chậm đến?

Nếu sự cố vẫn còn, tôi khuyên bạn nên tránh lớp Nhiệm vụ và thực hiện các cuộc gọi bên ngoài thông qua cùng một nhóm luồng quản lý các yêu cầu của người dùng. Điều này là để tránh các kịch bản trước đó.

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.