2016-09-16 20 views
5

Tôi đã triển khai dịch vụ REST bằng WebAPI2, dịch vụ được triển khai để quản lý các phiên khác nhau được tạo và tham gia bởi các máy khách khác nhau đang truy cập dịch vụ.Làm cách nào để quản lý bộ nhớ cache trong ASP.NET WebApi2?

Phiên chứa thông tin về quyền truy cập chức năng ứng dụng và thông tin của những người tham gia đã tham gia cùng một phiên.

Mỗi khách hàng nhận thông tin phiên và danh sách truy cập từ máy chủ cho mục đích đồng bộ hóa vào mỗi giây. Theo quyền truy cập đã thay đổi, chức năng của máy khách sẽ thay đổi (Bật/Tắt).

Tôi đang sử dụng lớp MemoryCache để lưu trữ thông tin phiên trong dịch vụ WebAPI như dưới đây.

public static class SessionManager{ 
private static object objForLock = new object(); 
public static List<Session> SessionCollection 
{ 
    get 
    { 
     lock (objForLock) 
     { 
      MemoryCache memoryCache = MemoryCache.Default; 
      return memoryCache.Get("SessionCollection") as List<Session>; 
      // return HttpContext.Current.Application["SessionCollection"] as List<Session>; 
     } 
    } 
    set 
    { 
     lock (objForLock) 
     { 
      MemoryCache memoryCache = MemoryCache.Default; 
      memoryCache.Add("SessionCollection", value, DateTimeOffset.UtcNow.AddHours(5)); 
      //HttpContext.Current.Application["SessionCollection"] = value; 
     } 
    } 
} 

}

Vấn đề của tôi là liên quan đến hành vi không phù hợp của bộ nhớ cache.

Khi khách hàng gửi cuộc gọi đồng bộ hóa, nó sẽ cho kết quả không phù hợp. Đối với một số yêu cầu, khách hàng nhận được dữ liệu thích hợp và cho một số yêu cầu khách hàng được thay thế dữ liệu null sau khi một số yêu cầu.

Tôi đã thêm trình gỡ rối và giám sát đối tượng cho kết quả không, sau đó "memoryCache.Get (" SessionCollection ")" cũng không có giá trị. Sau khi một số yêu cầu liên tiếp nó sẽ được thích hợp một lần nữa. Tôi không hiểu tại sao đối tượng này không bền bỉ.

Cách khác, tôi đã thử "HttpContext.Current.Application [" SessionCollection "]". Tuy nhiên, vấn đề tương tự cũng có.

Tôi đã đọc khoảng "tái chế hồ bơi ứng dụng", nó sẽ tái chế tất cả bộ nhớ cache sau thời gian hạt. Nếu đối tượng được lưu trong bộ nhớ cache của tôi được tái chế bằng cách tái sử dụng pool, thì làm thế nào tôi có thể lấy lại đối tượng này?

Vui lòng một số có thể giúp tôi thoát khỏi vấn đề này. Cảm ơn trước.

+0

Chỉ muốn kiểm tra lại thời gian máy chủ của bạn cũng được đặt thành UTC. Có thể giá trị thời gian chờ thực sự xảy ra trước khi bạn mong đợi không? – ManOVision

+0

Btw, MemoryCache là chủ đề an toàn nên không cần khóa –

+0

.Bạn sử dụng phiên bản NET nào? – RAM

Trả lời

0

Chỉ cần thận trọng, MemoryCache sẽ giữ dữ liệu trong bộ nhớ trong một máy chủ. Vì vậy, nếu bạn có nhiều máy chủ web (ở phía trước cân bằng tải), bộ nhớ cache đó sẽ không khả dụng cho các máy chủ khác. Bạn cũng sử dụng tên bộ nhớ cache - "SessionCollection". Dữ liệu đó sẽ được chia sẻ cho tất cả khách hàng. Nếu bạn cần lưu trữ dữ liệu trong bộ nhớ cache duy nhất cho mỗi khách hàng, bạn cần trả lại mã thông báo (guid) cho máy khách và sử dụng mã thông báo đó để nhận/cập nhật dữ liệu trong bộ nhớ cache trong các yêu cầu tiếp theo.

Thử giới thiệu biến cấp lớp. Vì vậy, mã của bạn sẽ trông giống như dưới đây. (Một số mã loại bỏ cho rõ ràng)

private readonly MemoryCache _memCache = MemoryCache.Default; 

....

return _memCache.Get("SessionCollection") as List<Session>; 

...

_memCache .Add("SessionCollection", value, DateTimeOffset.UtcNow.AddHours(5)); 
+0

@alltejCảm ơn bạn đã trả lời. Tôi đang sử dụng máy chủ duy nhất cũng như dữ liệu "Bộ sưu tập phiên" được chia sẻ cho tất cả khách hàng. Bất kỳ đề xuất nào khác cho loại dữ liệu không thống nhất này? –

+0

@NileshWagh đã cập nhật câu trả lời của tôi. bạn có thể kiểm tra điều đó không? – alltej

+0

Hi @ alltej, tôi đã thêm thay đổi theo câu trả lời đã chỉnh sửa của bạn, Bit vẫn còn tôi đang đối mặt với cùng một vấn đề. –

1

Bạn nên lưu trữ thông tin khách hàng cụ thể trong Session thay vì Cache.Cache phải dành cho toàn bộ ứng dụng (được chia sẻ)

Tuy nhiên, không nên dùng api web được xây dựng với RESTful và dịch vụ RESTful sẽ không trạng thái (APIs không lưu bộ nhớ cache). các ứng dụng không quốc tịch có nhiều lợi ích:

  • Giảm sử dụng bộ nhớ
  • Better khả năng mở rộng: Ứng dụng của bạn quy mô tốt hơn. Hình ảnh những gì sẽ xảy ra nếu bạn lưu trữ thông tin của hàng triệu khách hàng cùng một lúc.
  • Tốt hơn trong kịch bản cân bằng tải: mỗi máy chủ có thể xử lý mọi ứng dụng khách mà không bị mất trạng thái.
  • Sự cố hết hạn phiên.

Trong trường hợp bạn muốn lưu trữ trạng thái ứng dụng, bạn vẫn có thể làm điều đó. Vui lòng thử các đề xuất trong bài đăng sau: ASP.NET Web API session or something?

Nói chung, trạng thái bộ nhớ đệm cục bộ trên máy chủ web là không hợp lệ (cả hai số Session và địa phương MemoryCache). Bộ nhớ cache có thể bị mất vì nhiều lý do:

  • Tái chế hồ bơi ứng dụng.
  • tải môi trường cân bằng
  • Nhiều quá trình lao động trong IIS

Về yêu cầu của bạn:

Mỗi khách hàng có được thông tin phiên làm việc và danh sách truy cập từ máy chủ cho mục đích đồng bộ hóa trên mỗi giây. Theo quyền truy cập đã thay đổi, chức năng của khách hàng sẽ thay đổi (Bật/Tắt).

Tôi không chắc chắn liệu bạn có muốn cập nhật danh sách truy cập mới ngay lập tức khi khách hàng gửi cuộc gọi đồng bộ hóa hay không. Nếu đúng như vậy, SignalR sẽ là lựa chọn tốt hơn.

Nếu không, bạn chỉ có thể lưu trữ danh sách truy cập được cập nhật ở đâu đó (bộ đệm chia sẻ hoặc thậm chí trong cơ sở dữ liệu) và cập nhật các ứng dụng khách khác bất cứ khi nào họ kết nối lại với yêu cầu khác.

0

@ScottHanselman đã nói về lỗi trong số .NET 4here. Tôi hy vọng sửa chữa này giúp bạn:

Việc sửa chữa tạm thời:

Tạo dụ bộ nhớ cache dưới bối cảnh thực hiện khuyết tật chảy

using (ExecutionContext.SuppressFlow())  { 
      // Create memory cache instance under disabled execution context flow 
     return new YourCacheThing.GeneralMemoryCache(…); 
} 

Các Hotfixhttp://support.microsoft.com/kb/2828843 và bạn có thể yêu cầu tại đây: https://support.microsoft.com/contactus/emailcontact.aspx?scid=sw;%5BLN%5D;1422

Các vấn đề liên quan