Tôi mới phát hiện ra lý do tại sao tất cả các trang web của ASP.Net đều chậm và tôi đang cố gắng tìm ra những gì cần làm về nó


275

Tôi mới phát hiện ra rằng mọi yêu cầu trong ứng dụng web ASP.Net đều có Khóa phiên khi bắt đầu yêu cầu và sau đó phát hành vào cuối yêu cầu!

Trong trường hợp ý nghĩa của việc này bị mất đối với bạn, vì nó là cho tôi lúc đầu, điều này về cơ bản có nghĩa như sau:

  • Bất cứ khi nào một trang web ASP.Net mất nhiều thời gian để tải (có thể do cuộc gọi cơ sở dữ liệu chậm hoặc bất cứ điều gì) và người dùng quyết định họ muốn điều hướng đến một trang khác vì họ mệt mỏi vì phải chờ đợi, HỌ KHÔNG THỂ! Khóa phiên ASP.Net buộc yêu cầu trang mới phải đợi cho đến khi yêu cầu ban đầu kết thúc tải chậm một cách đau đớn. Arrrgh.

  • Bất cứ khi nào UpdatePanel tải chậm và người dùng quyết định điều hướng đến một trang khác trước khi UpdatePanel cập nhật xong ... HỌ KHÔNG THỂ! Khóa phiên ASP.net buộc yêu cầu trang mới phải đợi cho đến khi yêu cầu ban đầu kết thúc tải chậm một cách đau đớn. Đôi Arrrgh!

Vậy những lựa chọn là gì? Cho đến nay tôi đã nghĩ ra:

  • Triển khai một sessionStateDataStore tùy chỉnh, mà ASP.Net hỗ trợ. Tôi đã không tìm thấy quá nhiều thứ để sao chép, và nó có vẻ như có nguy cơ cao và dễ gây rối.
  • Theo dõi tất cả các yêu cầu đang diễn ra và nếu một yêu cầu đến từ cùng một người dùng, hãy hủy yêu cầu ban đầu. Có vẻ như cực đoan, nhưng nó sẽ làm việc (tôi nghĩ).
  • Đừng sử dụng Phiên! Khi tôi cần một số trạng thái cho người dùng, tôi chỉ có thể sử dụng Cache và các mục chính trên tên người dùng được xác thực hoặc một số thứ như vậy. Một lần nữa có vẻ như cực đoan.

Tôi thực sự không thể tin rằng nhóm Microsoft của ASP.Net sẽ để lại một nút cổ chai hiệu năng lớn như vậy trong khuôn khổ ở phiên bản 4.0! Tôi có thiếu một cái gì đó rõ ràng? Việc sử dụng bộ sưu tập ThreadSafe cho Phiên sẽ khó đến mức nào?


40
Bạn có nhận ra rằng trang web này được xây dựng trên .NET. Điều đó nói rằng, tôi nghĩ rằng nó quy mô khá độc đáo.
Wheaties

7
OK, vì vậy tôi đã được một chút lịch sự với tiêu đề của tôi. Tuy nhiên, IMHO hiệu suất nghẹt thở rằng việc triển khai ngoài phiên của phiên áp đặt là đáng ngạc nhiên. Ngoài ra, tôi cá rằng các anh chàng Stack Overflow đã phải làm một chút tốt về nhà phát triển tùy chỉnh cao để có được hiệu suất và khả năng mở rộng mà họ đã đạt được - và danh tiếng cho họ. Cuối cùng, Stack Overflow là một ứng dụng MVC, không phải WebForms, mà tôi đặt cược giúp (mặc dù phải thừa nhận rằng điều này vẫn sử dụng cùng một cơ sở hạ tầng phiên).
James


4
Nếu Joel Mueller cung cấp cho bạn thông tin để khắc phục vấn đề của bạn, tại sao bạn không đánh dấu câu trả lời của anh ấy là câu trả lời đúng? Chỉ là một ý nghĩ.
ars265

1
@ ars265 - Joel Muller cung cấp nhiều thông tin tốt và tôi muốn cảm ơn anh ấy vì điều đó. Tuy nhiên, cuối cùng tôi đã đi với một lộ trình khác với con đường được đề xuất trong bài viết của mình. Do đó, đánh dấu một bài khác nhau là câu trả lời.
James

Câu trả lời:


201

Nếu trang của bạn không sửa đổi bất kỳ biến phiên nào, bạn có thể chọn không tham gia khóa này.

<% @Page EnableSessionState="ReadOnly" %>

Nếu trang của bạn không đọc bất kỳ biến phiên nào, bạn có thể chọn hoàn toàn khóa này cho trang đó.

<% @Page EnableSessionState="False" %>

Nếu không có trang nào của bạn sử dụng biến phiên, chỉ cần tắt trạng thái phiên trong web.config.

<sessionState mode="Off" />

Tôi tò mò, bạn nghĩ "bộ sưu tập ThreadSafe" sẽ làm gì để trở nên an toàn cho chủ đề, nếu nó không sử dụng khóa?

Chỉnh sửa: Tôi có lẽ nên giải thích bằng những gì tôi có nghĩa là "từ chối hầu hết các khóa này". Bất kỳ số lượng trang chỉ đọc hoặc phiên không có phiên có thể được xử lý cho một phiên nhất định cùng một lúc mà không chặn nhau. Tuy nhiên, trang phiên đọc-ghi không thể bắt đầu xử lý cho đến khi tất cả các yêu cầu chỉ đọc đã hoàn thành và trong khi nó đang chạy, nó phải có quyền truy cập độc quyền vào phiên của người dùng đó để duy trì tính nhất quán. Khóa trên các giá trị riêng lẻ sẽ không hoạt động, vì nếu một trang thay đổi một tập hợp các giá trị liên quan thành một nhóm thì sao? Làm thế nào bạn có thể đảm bảo rằng các trang khác đang chạy cùng một lúc sẽ có được cái nhìn nhất quán về các biến phiên của người dùng?

Tôi sẽ đề nghị bạn cố gắng giảm thiểu việc sửa đổi các biến phiên sau khi chúng đã được đặt, nếu có thể. Điều này sẽ cho phép bạn tạo phần lớn các trang chỉ đọc các phiên, tăng khả năng nhiều yêu cầu đồng thời từ cùng một người dùng sẽ không chặn nhau.


2
Xin chào Joel Cảm ơn bạn đã dành thời gian cho câu trả lời này. Đây là một số gợi ý tốt và một số thực phẩm cho suy nghĩ. Tôi không hiểu lý do của bạn khi nói tất cả các giá trị cho một phiên phải được khóa riêng trong toàn bộ yêu cầu. Các giá trị Cache của ASP.Net có thể được thay đổi bất cứ lúc nào bởi bất kỳ luồng nào. Tại sao điều này nên khác nhau cho phiên? Bên cạnh đó - một vấn đề tôi gặp phải với tùy chọn chỉ đọc là nếu nhà phát triển thêm giá trị vào phiên khi ở chế độ chỉ đọc, nó sẽ âm thầm thất bại (không có ngoại lệ). Trong thực tế, nó giữ giá trị cho phần còn lại của yêu cầu - nhưng không vượt quá.
James

5
@James - Tôi chỉ đoán động cơ của các nhà thiết kế ở đây, nhưng tôi tưởng tượng rằng có nhiều giá trị phụ thuộc lẫn nhau trong một phiên của người dùng hơn là trong bộ đệm có thể bị xóa vì thiếu sử dụng hoặc thấp lý do bộ nhớ bất cứ lúc nào. Nếu một trang đặt 4 biến phiên liên quan và một trang khác đọc chúng chỉ sau hai biến đã được sửa đổi, điều đó có thể dễ dàng dẫn đến một số lỗi rất khó chẩn đoán. Tôi tưởng tượng các nhà thiết kế đã chọn xem "trạng thái hiện tại của phiên của người dùng" là một đơn vị duy nhất cho mục đích khóa vì lý do đó.
Joel Mueller

2
Vì vậy, phát triển một hệ thống phục vụ cho các lập trình viên mẫu số chung thấp nhất mà không thể tìm ra khóa? Có phải mục đích để cho phép các trang trại chia sẻ một cửa hàng phiên giữa các phiên bản IIS không? Bạn có thể đưa ra một ví dụ về một cái gì đó mà bạn sẽ lưu trữ trong một biến phiên? Tôi không thể nghĩ bất cứ điều gì.
Jason Goemaat

2
Vâng, đây là một trong những mục đích. Xem xét lại các kịch bản khác nhau khi cân bằng tải và dự phòng được thực hiện trong cơ sở hạ tầng. Khi người dùng làm việc trên trang web, tức là anh ta đang nhập dữ liệu dưới dạng, giả sử, trong 5 phút và một cái gì đó trong webfarm gặp sự cố - nguồn điện của một nút bị phồng - người dùng KHÔNG nên chú ý điều đó. Anh ta không thể bị đuổi khỏi phiên chỉ vì phiên của anh ta bị mất, chỉ vì quy trình công nhân của anh ta không còn tồn tại nữa. Điều này có nghĩa là để xử lý sự cân bằng / dự phòng hoàn hảo, các phiên phải được đưa ra ngoài từ các nút công nhân ..
quetzalcoatl

6
Một mức độ từ <pages enableSessionState="ReadOnly" />chối hữu ích khác là trong web.config và sử dụng @Page để chỉ cho phép ghi trên các trang cụ thể.
MattW

84

OK, Đạo cụ lớn cho Joel Muller cho tất cả đầu vào của anh ấy. Giải pháp cuối cùng của tôi là sử dụng CustomStateModule tùy chỉnh chi tiết ở cuối bài viết MSDN này:

http://msdn.microsoft.com/en-us/l Library / system.web.sessionstate.sessionstateutility.aspx

Đây là:

  • Thực hiện rất nhanh (thực sự có vẻ dễ hơn là đi theo lộ trình của nhà cung cấp)
  • Đã sử dụng rất nhiều cách xử lý phiên ASP.Net tiêu chuẩn (thông qua lớp SessionStateUtility)

Điều này đã tạo ra một sự khác biệt lớn cho cảm giác "nhanh nhẹn" đối với ứng dụng của chúng tôi. Tôi vẫn không thể tin rằng việc triển khai tùy chỉnh Phiên ASP.Net khóa phiên cho toàn bộ yêu cầu. Điều này thêm một số lượng lớn chậm chạp như vậy cho các trang web. Đánh giá từ số lượng nghiên cứu trực tuyến tôi phải thực hiện (và các cuộc trò chuyện với một số nhà phát triển ASP.Net thực sự có kinh nghiệm), rất nhiều người đã gặp phải vấn đề này, nhưng rất ít người đã đi đến tận cùng của nguyên nhân. Có lẽ tôi sẽ viết một lá thư cho Scott Gu ...

Tôi hy vọng điều này sẽ giúp một vài người ngoài kia!


19
Tài liệu tham khảo đó là một phát hiện thú vị, nhưng tôi phải cảnh báo bạn về một số điều - mã mẫu có một số vấn đề: Đầu tiên, ReaderWriterLockđã không được ủng hộ ReaderWriterLockSlim- thay vào đó bạn nên sử dụng nó. Thứ hai, lock (typeof(...))cũng không được chấp nhận - thay vào đó bạn nên khóa trên một đối tượng tĩnh riêng. Thứ ba, cụm từ "Ứng dụng này không ngăn các yêu cầu Web đồng thời sử dụng cùng một mã định danh phiên" là một cảnh báo, không phải là một tính năng.
Joel Mueller

3
Tôi nghĩ rằng bạn có thể làm cho công việc này hoạt động, nhưng bạn phải thay thế việc sử dụng SessionStateItemCollectionmã mẫu bằng một lớp an toàn luồng (có lẽ dựa trên ConcurrentDictionary) nếu bạn muốn tránh các lỗi khó tái tạo khi tải.
Joel Mueller

3
Tôi chỉ xem xét thêm một chút nữa, và không may ISessionStateItemCollectionyêu cầu Keystài sản phải thuộc loại System.Collections.Specialized.NameObjectCollectionBase.KeysCollection- vốn không có nhà xây dựng công cộng. Gee, cảm ơn các bạn. Điều đó rất thuận tiện.
Joel Mueller

2
OK, tôi tin rằng cuối cùng tôi cũng có một chủ đề an toàn đầy đủ, không đọc khóa thực hiện Phiên làm việc. Các bước cuối cùng liên quan đến việc thực hiện một bộ sưu tập SessionStateItem tùy chỉnh, được dựa trên bài viết MDSN được liên kết trong nhận xét trên. Phần cuối cùng của câu đố với điều này là tạo ra một trình liệt kê chủ đề dựa trên bài viết tuyệt vời này: codeproject.com/KB/cs/safe_enumerable.aspx .
James

26
James - rõ ràng đây là một chủ đề khá cũ, nhưng tôi đã tự hỏi nếu bạn có thể chia sẻ giải pháp cuối cùng của bạn? Tôi đã cố gắng theo dõi bằng cách sử dụng chuỗi các bình luận ở trên nhưng cho đến nay vẫn chưa thể có được một giải pháp hoạt động. Tôi khá chắc chắn rằng không có gì cơ bản trong việc sử dụng phiên hạn chế của chúng tôi sẽ yêu cầu khóa.
bsiegel

31

Tôi đã bắt đầu sử dụng AngiesList.Redis.RedisSessionStateModule , ngoài việc sử dụng máy chủ Redis (rất nhanh) để lưu trữ (tôi đang sử dụng cổng windows - mặc dù cũng có cổng MSOpenTech ), nhưng nó hoàn toàn không khóa trong phiên .

Theo tôi, nếu ứng dụng của bạn được cấu trúc một cách hợp lý, đây không phải là vấn đề. Nếu bạn thực sự cần khóa, dữ liệu nhất quán như một phần của phiên, bạn nên tự mình thực hiện kiểm tra khóa / đồng thời.

MS quyết định rằng mọi phiên ASP.NET nên được khóa theo mặc định chỉ để xử lý thiết kế ứng dụng kém là một quyết định tồi, theo ý kiến ​​của tôi. Đặc biệt là vì có vẻ như hầu hết các nhà phát triển thậm chí không nhận ra các phiên đã bị khóa, chứ đừng nói rằng các ứng dụng rõ ràng cần phải được cấu trúc để bạn có thể thực hiện trạng thái phiên chỉ đọc càng nhiều càng tốt (từ chối, nếu có thể) .


Liên kết GitHub của bạn dường như đã chết 404. library.io/github/angieslist/AL-Redis dường như là URL mới?
Uwe Keim

Có vẻ như tác giả muốn xóa thư viện, thậm chí từ liên kết thứ hai. Tôi sẽ do dự khi sử dụng một thư viện bị bỏ hoang, nhưng có một ngã ba ở đây: github.com/PrintFleet/AL-Redis và một thư viện thay thế được liên kết từ đây: stackoverflow.com/a/10979369/12534
Christian Davén

21

Tôi đã chuẩn bị một thư viện dựa trên các liên kết được đăng trong chủ đề này. Nó sử dụng các ví dụ từ MSDN và CodeProject. Cảm ơn James.

Tôi cũng đã thực hiện các sửa đổi được tư vấn bởi Joel Mueller.

Mã ở đây:

https://github.com/dermeister0/LockFreeSessionState

Mô-đun HashTable:

Install-Package Heavysoft.LockFreeSessionState.HashTable

Mô-đun StateServer của ScaleOut:

Install-Package Heavysoft.LockFreeSessionState.Soss

Mô-đun tùy chỉnh:

Install-Package Heavysoft.LockFreeSessionState.Common

Nếu bạn muốn triển khai hỗ trợ Memcached hoặc Redis, hãy cài đặt gói này. Sau đó, kế thừa lớp LockFreeSessionStateModule và thực hiện các phương thức trừu tượng.

Mã này chưa được thử nghiệm trên sản xuất. Cũng cần cải thiện xử lý lỗi. Các ngoại lệ không được bắt gặp trong việc thực hiện hiện tại.

Một số nhà cung cấp phiên không khóa sử dụng Redis:


Nó đòi hỏi các thư viện từ giải pháp ScaleOut, không miễn phí?
Hoàng Long

1
Có, tôi đã tạo triển khai chỉ cho SOSS. Bạn có thể sử dụng các nhà cung cấp phiên Redis đã đề cập, nó miễn phí.
Der_Meister

Có thể Hoàng Long đã bỏ lỡ điểm mà bạn có lựa chọn giữa việc triển khai HashTable trong bộ nhớ và ScaleOut StateServer.
David De Sloovere

Cảm ơn sự đóng góp của bạn :) Tôi sẽ thử dùng thử xem nó hoạt động như thế nào trong vài trường hợp sử dụng mà chúng tôi có với SESSION liên quan.
Agustin Garzon

Vì nhiều người đã đề cập đến việc khóa một mục cụ thể trong phiên, nên có thể chỉ ra rằng việc triển khai sao lưu cần trả về một tham chiếu chung cho giá trị phiên qua các cuộc gọi để kích hoạt khóa (và thậm chí không hoạt động với các máy chủ cân bằng tải). Tùy thuộc vào cách bạn sử dụng trạng thái phiên, có tiềm năng cho các điều kiện cuộc đua ở đây. Ngoài ra, đối với tôi, có những khóa trong quá trình triển khai của bạn không thực sự làm gì cả vì chúng chỉ thực hiện một cuộc gọi đọc hoặc viết (sửa tôi nếu tôi sai ở đây).
nw.

11

Trừ khi ứng dụng của bạn có nhu cầu đặc biệt, tôi nghĩ bạn có 2 cách tiếp cận:

  1. Không sử dụng phiên nào cả
  2. Sử dụng phiên như hiện tại và thực hiện tinh chỉnh như joel đã đề cập.

Phiên không chỉ an toàn theo luồng mà còn an toàn trạng thái, theo cách mà bạn biết rằng cho đến khi yêu cầu hiện tại được hoàn thành, mọi biến phiên sẽ không thay đổi từ yêu cầu hoạt động khác. Để điều này xảy ra, bạn phải đảm bảo rằng phiên SILL ĐƯỢC KHÓA cho đến khi yêu cầu hiện tại hoàn thành.

Bạn có thể tạo một phiên giống như hành vi bằng nhiều cách, nhưng nếu nó không khóa phiên hiện tại, thì đó sẽ không phải là 'phiên'.

Đối với các vấn đề cụ thể mà bạn đã đề cập, tôi nghĩ bạn nên kiểm tra HttpContext.Cản.Response.IsClientConnected . Điều này có thể hữu ích để ngăn chặn các thực thi và chờ đợi không cần thiết trên máy khách, mặc dù nó không thể giải quyết vấn đề này hoàn toàn, vì điều này chỉ có thể được sử dụng bằng cách gộp chung và không đồng bộ.


10

Nếu bạn đang sử dụng bản cập nhật Microsoft.Web.RedisSessionStateProvider(bắt đầu từ 3.0.2), bạn có thể thêm phần này vào web.configđể cho phép các phiên đồng thời.

<appSettings>
    <add key="aspnet:AllowConcurrentRequestsPerSession" value="true"/>
</appSettings>

Nguồn


Không chắc chắn tại sao điều này là 0. +1. Rất hữu ích.
Pangamma

Điều này có hoạt động trong nhóm ứng dụng chế độ cổ điển không? github.com/Azure/aspnet-redis-providers/issues/123
Rusty

cái này có hoạt động với nhà cung cấp dịch vụ trạng thái inProc hoặc session mặc định không?
Nick Chan Abdullah

Lưu ý rằng các tham chiếu poster nếu bạn đang sử dụng RedisSessionStateprovider, nhưng nó cũng có thể hoạt động với các nhà cung cấp AspNetSessionState Async mới hơn (cho SQL và Cosmos) bởi vì nó cũng có trong tài liệu của họ: github.com/aspnet/AspNetSessionState Tôi đoán rằng nó sẽ hoạt động trong classicmode nếu SessionStateProvider đã hoạt động ở chế độ cổ điển, có khả năng các công cụ trạng thái phiên xảy ra bên trong ASP.Net (không phải IIS). Với InProc, nó có thể không hoạt động nhưng sẽ ít gặp sự cố hơn vì nó giải quyết được vấn đề tranh chấp tài nguyên, đó là một vấn đề lớn hơn với các kịch bản Proc.
madamission

4

Đối với ASPNET MVC, chúng tôi đã làm như sau:

  1. Theo mặc định, đặt SessionStateBehavior.ReadOnly trên tất cả hành động của bộ điều khiển bằng cách ghi đèDefaultControllerFactory
  2. Trên các hành động của bộ điều khiển cần ghi vào trạng thái phiên, đánh dấu bằng thuộc tính để đặt thành SessionStateBehavior.Required

Tạo Trình điều khiển tùy chỉnh và ghi đè GetControllerSessionBehavior.

    protected override SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType)
    {
        var DefaultSessionStateBehaviour = SessionStateBehaviour.ReadOnly;

        if (controllerType == null)
            return DefaultSessionStateBehaviour;

        var isRequireSessionWrite =
            controllerType.GetCustomAttributes<AcquireSessionLock>(inherit: true).FirstOrDefault() != null;

        if (isRequireSessionWrite)
            return SessionStateBehavior.Required;

        var actionName = requestContext.RouteData.Values["action"].ToString();
        MethodInfo actionMethodInfo;

        try
        {
            actionMethodInfo = controllerType.GetMethod(actionName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
        }
        catch (AmbiguousMatchException)
        {
            var httpRequestTypeAttr = GetHttpRequestTypeAttr(requestContext.HttpContext.Request.HttpMethod);

            actionMethodInfo =
                controllerType.GetMethods().FirstOrDefault(
                    mi => mi.Name.Equals(actionName, StringComparison.CurrentCultureIgnoreCase) && mi.GetCustomAttributes(httpRequestTypeAttr, false).Length > 0);
        }

        if (actionMethodInfo == null)
            return DefaultSessionStateBehaviour;

        isRequireSessionWrite = actionMethodInfo.GetCustomAttributes<AcquireSessionLock>(inherit: false).FirstOrDefault() != null;

         return isRequireSessionWrite ? SessionStateBehavior.Required : DefaultSessionStateBehaviour;
    }

    private static Type GetHttpRequestTypeAttr(string httpMethod) 
    {
        switch (httpMethod)
        {
            case "GET":
                return typeof(HttpGetAttribute);
            case "POST":
                return typeof(HttpPostAttribute);
            case "PUT":
                return typeof(HttpPutAttribute);
            case "DELETE":
                return typeof(HttpDeleteAttribute);
            case "HEAD":
                return typeof(HttpHeadAttribute);
            case "PATCH":
                return typeof(HttpPatchAttribute);
            case "OPTIONS":
                return typeof(HttpOptionsAttribute);
        }

        throw new NotSupportedException("unable to determine http method");
    }

Mua lạiSessionLockAttribution

[AttributeUsage(AttributeTargets.Method)]
public sealed class AcquireSessionLock : Attribute
{ }

Kết nối nhà máy điều khiển đã tạo global.asax.cs

ControllerBuilder.Current.SetControllerFactory(typeof(DefaultReadOnlySessionStateControllerFactory));

Bây giờ, chúng ta có thể có cả hai read-onlyread-writetrạng thái phiên trong một Controller.

public class TestController : Controller 
{
    [AcquireSessionLock]
    public ActionResult WriteSession()
    {
        var timeNow = DateTimeOffset.UtcNow.ToString();
        Session["key"] = timeNow;
        return Json(timeNow, JsonRequestBehavior.AllowGet);
    }

    public ActionResult ReadSession()
    {
        var timeNow = Session["key"];
        return Json(timeNow ?? "empty", JsonRequestBehavior.AllowGet);
    }
}

Lưu ý: Trạng thái phiên ASPNET vẫn có thể được ghi ngay cả ở chế độ chỉ đọc và sẽ không ném bất kỳ hình thức ngoại lệ nào (Nó không khóa để đảm bảo tính nhất quán) vì vậy chúng tôi phải cẩn thận đánh dấu AcquireSessionLocktrong các hành động của bộ điều khiển yêu cầu trạng thái phiên viết.



3

Đánh dấu trạng thái phiên của bộ điều khiển là chỉ đọc hoặc bị vô hiệu hóa sẽ giải quyết vấn đề.

Bạn có thể trang trí bộ điều khiển với thuộc tính sau để đánh dấu nó chỉ đọc:

[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]

các System.Web.SessionState.SessionStateBehavior enum có các giá trị sau:

  • Mặc định
  • Tàn tật
  • Chỉ đọc
  • Cần thiết

0

Chỉ để giúp bất cứ ai có vấn đề này (khóa yêu cầu khi thực hiện một yêu cầu khác từ cùng một phiên) ...

Hôm nay tôi bắt đầu giải quyết vấn đề này và, sau vài giờ nghiên cứu, tôi đã giải quyết nó bằng cách xóa Session_Startphương thức (ngay cả khi trống) khỏi tệp Global.asax .

Điều này hoạt động trong tất cả các dự án tôi đã thử nghiệm.


IDK loại dự án này đã được thực hiện, nhưng tôi không có Session_Startphương pháp và vẫn khóa
Denis G. Labrecque

0

Sau khi vật lộn với tất cả các tùy chọn có sẵn, cuối cùng tôi đã viết một nhà cung cấp SessionStore dựa trên mã thông báo JWT (phiên di chuyển bên trong cookie và không cần lưu trữ phụ trợ).

http://www.drupalonwindows.com/en/content/token-sessionstate

Ưu điểm:

  • Thay thế thả vào, không cần thay đổi mã của bạn
  • Quy mô tốt hơn bất kỳ cửa hàng tập trung nào khác, vì không cần phụ trợ lưu trữ phiên.
  • Nhanh hơn bất kỳ lưu trữ phiên nào khác, vì không cần lấy dữ liệu từ bất kỳ lưu trữ phiên nào
  • Không sử dụng tài nguyên máy chủ để lưu trữ phiên.
  • Triển khai không chặn mặc định: yêu cầu đồng thời sẽ không chặn nhau và giữ khóa trong phiên
  • Mở rộng quy mô ứng dụng của bạn: vì dữ liệu phiên di chuyển với chính yêu cầu, bạn có thể có nhiều đầu web mà không phải lo lắng về việc chia sẻ phiên.
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.