हैंगिंग हैं हमारे पास हमारे समाधान के लिए एसओए है। हम .net फ्रेमवर्क 4.5.1, एएसपीएनटी एमवीसी 4.6, एसक्यूएल सर्वर, विंडोज सर्वर और थिंकटेक्चर पहचान सर्वर 3 (टोकन आधारित वेबपी कॉल के लिए) का उपयोग कर रहे हैं।एमवीसी एप्लीकेशन असिंक तरीके
समाधान संरचना की तरह दिखता है;
हमारा एमवीसी फ्रंटएंड एप्लिकेशन httpClient wrapper के माध्यम से हमारे वेबपी एप्लिकेशन के साथ वार्ता करता है। यहां जेनेरिक http क्लाइंट रैपर कोड है;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace Cheetah.HttpClientWrapper
{
public class ResourceServerRestClient : IResourceServerRestClient
{
private readonly ITokenProvider _tokenProvider;
public ResourceServerRestClient(ITokenProvider tokenProvider)
{
_tokenProvider = tokenProvider;
}
public string BaseAddress { get; set; }
public Task<T> GetAsync<T>(string uri, string clientId)
{
return CheckAndInvokeAsync(async token =>
{
using (var client = new HttpClient())
{
ConfigurateHttpClient(client, token, clientId);
HttpResponseMessage response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsAsync<T>();
}
var exception = new Exception($"Resource server returned an error. StatusCode : {response.StatusCode}");
exception.Data.Add("StatusCode", response.StatusCode);
throw exception;
}
});
}
private void ConfigurateHttpClient(HttpClient client, string bearerToken, string resourceServiceClientName)
{
if (!string.IsNullOrEmpty(resourceServiceClientName))
{
client.DefaultRequestHeaders.Add("CN", resourceServiceClientName);
}
if (string.IsNullOrEmpty(BaseAddress))
{
throw new Exception("BaseAddress is required!");
}
client.BaseAddress = new Uri(BaseAddress);
client.Timeout = new TimeSpan(0, 0, 0, 10);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerToken);
}
private async Task<T> CheckAndInvokeAsync<T>(Func<string, Task<T>> method)
{
try
{
string token = await _tokenProvider.IsTokenNullOrExpired();
if (!string.IsNullOrEmpty(token))
{
return await method(token);
}
var exception = new Exception();
exception.Data.Add("StatusCode", HttpStatusCode.Unauthorized);
throw exception;
}
catch (Exception ex)
{
if (ex.Data.Contains("StatusCode") && ((HttpStatusCode)ex.Data["StatusCode"]) == HttpStatusCode.Unauthorized)
{
string token = await _tokenProvider.GetTokenAsync();
if (!string.IsNullOrEmpty(token))
{
return await method(token);
}
}
throw;
}
}
public void ThrowResourceServerException(List<string> messages)
{
string message = messages.Aggregate((p, q) => q + " - " + p);
var exception = new Exception(message);
exception.Data.Add("ServiceOperationException", message);
throw exception;
}
}
}
इसके अलावा, कभी कभी इस http ग्राहक आवरण NitoAsync प्रबंधक (कॉल सिंक के रूप में async तरीकों।), और कभी कभी हम इस सामान्य विधि सीधे उपयोग कर रहे हैं इंतजार के साथ साथ का उपयोग कर - async कार्य की तरह इंतजार;
जब हम, JMeter के साथ हमारे MVC आवेदन का परीक्षण (कुछ तरह-की लोड परीक्षण/1 सेकंड प्रति 10 धागे बनाने के लिए) कुछ मिनटों के बाद, MVC:
var result = await _resourceServerRestClient.GetAsync<ServiceOperation<DailyAgendaModel>>("dailyAgenda/" + id);
तो यहाँ हमारी समस्या है एप्लिकेशन इस लाइन पर काम करना बंद कर देता है [अपवाद कार्यकाल के कारण रद्द कर दिया गया है] (शायद केवल 1-2 अनुरोध टाइमआउट): HttpResponseMessage response = await client.GetAsync(uri);
। लेकिन उस अनुरोध के बाद, सभी अनुरोध विफल होंगे जैसे कि वे पंक्ति में हैं। तो एमवीसी आवेदन 2-15 मिनट (यादृच्छिक रूप से) के लिए लटक रहा है लेकिन उस समय मैं डाकिया से वेबपीआई में नए अनुरोध भेज सकता हूं। वे ठीक हैं, मेरा मतलब है कि वेबपी अच्छी प्रतिक्रिया दे रहा है। कुछ मिनट के बाद एमवीसी आवेदन सामान्य करने के लिए टर्नबैक।
नोट: हमारे पास एमवीसी-यूई और वेबपी के लिए लोड-बैलेंसर है। क्योंकि कभी-कभी हमें व्यस्त दिन में एक मिनट में 120 के अनुरोध मिलते हैं। लेकिन अगर वेबपै या एमवीसी एप्लीकेशन के सामने कोई लोड बैलेंसर नहीं है तो यह वही त्रुटि देता है। तो यह एलबी समस्या नहीं है।
टिप्पणी 2: हम MVC-ui और WebAPI संचार के लिए RestSharp का उपयोग करने की कोशिश की। हमें यहां एक ही त्रुटि मिली है। जब कोई पुन: प्रयास विफल हो रहा है, तो सभी अनुरोध एक पंक्ति में विफल हो जाएंगे। ऐसा लगता है कि यह एक नेटवर्क त्रुटि है लेकिन हमें इसके लिए सबूत नहीं मिल रहा है।
क्या आप मेरे httpClient wrapper पर कोई त्रुटि देख सकते हैं? या बेहतर सवाल है;
आपके समाधान में, आपका एमवीसी एप्लीकेशन आपके वेबपी एप्लिकेशन के साथ संचार कैसे कर रहा है? यहां सबसे अच्छा अभ्यास क्या हैं?
Update1: हम परियोजनाओं 4.6.1 के लिए 4.5.1 शुद्ध ले जाया गया। वही डेडलॉक फिर से हुआ। और हम अस्थायी रूप से परत के सभी स्रोत कोड स्थानांतरित किए गए: "व्यापार & रिपोजिटरी" डीएलएल स्तर के रूप में। व्यवसाय & प्रस्तुति स्तर के बीच अब कोई वेबपी नहीं है। मृत ताला हल हो गया। हम अभी भी खोज रहे हैं कि httpClientWrapper कोड ठीक से काम नहीं कर रहे हैं जब हमने अपने वेबप्लिकेशन नियंत्रकों से वेबपीआई विधियों को बुलाया।
आपने क्लाइंट साइड अनुरोध कोड साझा किया है। लेकिन मुख्य समस्या वीपी एपीआई है जो सामान्य प्रतिक्रिया नहीं दे सकती है। आपका अनुरोध लटका दिया जाएगा।वेब एपीआई पक्ष अधिक तेज़ होना चाहिए। आप टाइमआउट बढ़ा सकते हैं। मैं इसकी सिफारिश नहीं करता हूं। शायद आप थ्रेड के साथ अपना अनुरोध सो सकते हैं। वे अच्छे समाधान नहीं हैं। कृपया वीपी एपीआई पक्ष साझा करें। शायद हम आपके जवाब के लिए प्रदर्शन –
@ SercanTimoçin धन्यवाद बढ़ा सकते हैं। Howerer webapi सबसे अच्छा एपीआई है जिसे हमने लिखा है, हमारे लोड परीक्षणों में; अधिकतम प्रतिक्रिया समय <500ms है। इसलिए हमें नहीं लगता कि यह वेब एपीआई विधि है। –
आपका सबसे अच्छा शर्त एक पूर्ण मेमोरी डंप करना है जब आपका एप्लिकेशन लटकता/समय समाप्त हो जाता है। आप [WinDbg] (https://msdn.microsoft.com/en-us/windows/hardware/hh852365.aspx) जैसे कुछ का उपयोग कर सकते हैं, फिर 'एनालिज' या [डीबग डायग] चलाएं (https: // www क्या हो रहा है यह देखने के लिए .microsoft.com/en-us/download/details.aspx? id = 49924)। यह हो सकता है कि मृतक या संसाधन जारी नहीं किए जा रहे हों या कौन जानता है कि कोई भी आवेदन कोड देखे बिना और यह कैसे व्यवहार कर रहा है देखे बिना कोई भी कह सकता है। – Igor