У меня есть следующий код, который я использую для получения информации из кеша. Я не знаю, может быть, мое приложение открывает слишком много подключений или эта ошибка связана только с временным сбоем в кеш-памяти Redis.
Это трассировка стека
[RedisConnectionException: нет подключения для обслуживания этой операции: GET UserProfileInformation|[email protected]] StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl (сообщение сообщения, процессор ResultProcessor
1 processor, ServerEndPoint server) in c:\TeamCity\buildAgent\work\3ae0647004edff78\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs:1922 StackExchange.Redis.RedisBase.ExecuteSync(Message message, ResultProcessor
1, сервер ServerEndPoint) в c: \ TeamCity \ workAgent \ buildAgent 3ae0647004edff78 \ StackExchange.Redis \ StackExchange \ Redis \ RedisBase.cs: 80 StackExchange.Redis.RedisDatabase.StringGet (ключ RedisKey, флаги CommandFlags) в c: \ TeamCity \ buildAgent \ work \ 3ae0647004edffExchange \ StackExchange. .cs: 1431 xx.Utils.SampleStackExchangeRedisExtensions.Get (кэш базы данных, строковый ключ) в C: \ Proyectos \ xx \ xx \ Utils \ SampleStackExchangeRedisExtensions.cs: 20
xx.Cache.UserProfile.GetUserProfile (имя идентификатора строки) в C: \ Proyectos \ xx \ xx \ Cache \ UserProfile.cs: 22
x.Controllers.UserProfileController.GetPropertiesForUser () в C: \ Proyectos \ xx \ xx \ Controllers \ UserProfileController.cs: 16
lambda_method ( Закрытие, Co ntrollerBase, Object []) +61
System.Web.Mvc.ActionMethodDispatcher.Execute (контроллер ControllerBase, параметры Object []) +14
И это код
public static Models.UserProfile GetUserProfile(string identityname)
{
/// It needs to be cached for every user because every user can have different modules enabled.
var cachekeyname = "UserProfileInformation|" + identityname;
IDatabase cache = CacheConnectionHelper.Connection.GetDatabase();
Models.UserProfile userProfile = new Models.UserProfile();
object obj = cache.Get(cachekeyname);
string userProfileString;
if (obj != null)
{
//get string from cache
userProfileString = obj.ToString();
//conver string to our object
userProfile = JsonConvert.DeserializeObject<Models.UserProfile>(userProfileString);
return userProfile;
}
else
{
#region Get User Profile from AD
Uri serviceRoot = new Uri(SettingsHelper.AzureAdGraphApiEndPoint);
var token = AppToken.GetAppToken();
ActiveDirectoryClient adClient = new ActiveDirectoryClient(
serviceRoot,
async () => await AppToken.GetAppTokenAsync());
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
Microsoft.Azure.ActiveDirectory.GraphClient.Application app = (Microsoft.Azure.ActiveDirectory.GraphClient.Application)adClient.Applications.Where(
a => a.AppId == SettingsHelper.ClientId).ExecuteSingleAsync().Result;
if (app == null)
{
throw new ApplicationException("Unable to get a reference to application in Azure AD.");
}
string requestUrl = string.Format("https://graph.windows.net/{0}/users/{1}?api-version=1.5", SettingsHelper.Tenant, identityname);
HttpClient hc = new HttpClient();
hc.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
HttpResponseMessage hrm = hc.GetAsync(new Uri(requestUrl)).Result;
if (hrm.IsSuccessStatusCode)
{
Models.UserProfile currentUserProfile = JsonConvert.DeserializeObject<Models.UserProfile>(hrm.Content.ReadAsStringAsync().Result);
//convert object to json string
userProfileString = JsonConvert.SerializeObject(currentUserProfile);
cache.Set(cachekeyname, userProfileString, TimeSpan.FromMinutes(SettingsHelper.CacheUserProfileMinutes));
return currentUserProfile;
}
else
{
return null;
}
#endregion
}
}
public static class SampleStackExchangeRedisExtensions
{
public static T Get<T>(this IDatabase cache, string key)
{
return Deserialize<T>(cache.StringGet(key));
}
public static object Get(this IDatabase cache, string key)
{
return Deserialize<object>(cache.StringGet(key));
}
public static void Set(this IDatabase cache, string key, object value, TimeSpan expiration)
{
cache.StringSet(key, Serialize(value), expiration);
}
static byte[] Serialize(object o)
{
if (o == null)
{
return null;
}
BinaryFormatter binaryFormatter = new BinaryFormatter();
using (MemoryStream memoryStream = new MemoryStream())
{
binaryFormatter.Serialize(memoryStream, o);
byte[] objectDataAsStream = memoryStream.ToArray();
return objectDataAsStream;
}
}
static T Deserialize<T>(byte[] stream)
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
if (stream == null)
return default(T);
using (MemoryStream memoryStream = new MemoryStream(stream))
{
T result = (T)binaryFormatter.Deserialize(memoryStream);
return result;
}
}
Вопросы: 1. Как я могу контролировать исключение подключения, подобное показанному, чтобы пользователь не получил сообщение об ошибке и вместо этого перешел в БД, если redis недоступен? 2. Есть ли способ повторить попытку обработки временных сбоев для кэша azure redis?