アプリケーションでは、ユーザーのトラフィックが非常に多く、毎秒約2000件のリクエストがあります。 Asp.Netコアでアプリケーションを作成し、dapperを使用しました。我々は、分散キャッシュの目的のためにredisキャッシュマネージャを使用しています。 私たちがこのサイトをホストして、毎秒リクエスト数が少ない(20または30)ことを確認したところ、うまくいきました。しかし、毎秒約50件以上のリクエストが発生した場合、サイトには
502がゲートウェイまたはプロキシサーバーとして機能している間に無効な応答を受信しました。
redisキャッシュをメモリキャッシュに変更した後、毎秒2000回のすべての要求に対して正常に動作するようになりました。 Redisバージョン3.2.100を使用しています ここではredisを使用して、より多くのリクエストに対してこのサイトを実行し、トラフィックが多い場合に502エラーを取得することはできません。 RedisのキャッシュRedisを実装したAsp.Netコアは、トラフィックが多い場合に502エラーを返します。
using Common;
using Common.DependencyInjection;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Text;
namespace Service.Caching
{
[TransientDependency(ServiceType = typeof(ICacheManager))]
public class RedisCacheManager : ICacheManager
{
private readonly string _redisHost;
private readonly int _redisPort;
private readonly string _redisPassword;
private readonly ConfigurationOptions _configurationOptions;
public RedisCacheManager()
{
_redisHost = ConfigItems.RedisHost;
_redisPassword = ConfigItems.RedisPassword;
_redisPort = ConfigItems.RedisPort;
_configurationOptions = new ConfigurationOptions();
configurationOptions.EndPoints.Add(_redisHost, redisPort);
_configurationOptions.Ssl = false;
//_configurationOptions.Password = _redisPassword;
_configurationOptions.AbortOnConnectFail = false;
_configurationOptions.SyncTimeout = int.MaxValue;
_configurationOptions.DefaultVersion = new Version(2, 8, 8);
_configurationOptions.WriteBuffer = 10000000;
_configurationOptions.KeepAlive = 180;
}
/// <summary>
/// Gets or sets the value associated with the specified key.
/// </summary>
/// <typeparam name="T">Type</typeparam>
/// <param name="key">The key of the value to get.</param>
/// <returns>
/// The value associated with the specified key.
/// </returns>
public T Get<T>(string key)
{
using (var connection = ConnectionMultiplexer.Connect(_configurationOptions))
{
var db = connection.GetDatabase(-1);
//return (T)(object)db.StringGet(key);
return (T)ConvertToObject<T>(db.StringGet(key));
}
}
/// <summary>
/// Adds the specified key and object to the cache.
/// </summary>
/// <param name="key">key</param>
/// <param name="data">Data</param>
/// <param name="cacheTime">Cache time</param>
public void Set(string key, object data, int cacheTime)
{
if (data == null)
return;
DateTime expireDate;
if (cacheTime == 99)
expireDate = DateTime.Now + TimeSpan.FromSeconds(30);
else
expireDate = DateTime.Now + TimeSpan.FromMinutes(cacheTime);
var value = (RedisValue)ConvertToByteArray(data);
using (var connection = ConnectionMultiplexer.Connect(_configurationOptions))
{
var db = connection.GetDatabase(-1);
db.StringSet(key, value, new TimeSpan(expireDate.Ticks));
}
}
/// <summary>
/// Gets a value indicating whether the value associated with the specified key is cached
/// </summary>
/// <param name="key">key</param>
/// <returns>
/// Result
/// </returns>
public bool IsSet(string key)
{
using (var connection = ConnectionMultiplexer.Connect(_configurationOptions))
{
var db = connection.GetDatabase(-1);
return db.KeyExists(key);
}
}
/// <summary>
/// Removes the value with the specified key from the cache
/// </summary>
/// <param name="key">/key</param>
public void Remove(string key)
{
using (var connection = ConnectionMultiplexer.Connect(_configurationOptions))
{
var db = connection.GetDatabase(-1);
db.KeyDelete(key);
}
}
/// <summary>
/// Removes items by pattern
/// </summary>
/// <param name="pattern">pattern</param>
public void RemoveByPattern(string pattern)
{
using (var connection = ConnectionMultiplexer.Connect(_configurationOptions))
{
var server = connection.GetServer(_redisHost, _redisPort);
var keysToRemove = server.Keys(pattern: "*" + pattern + "*");//-1, pattern);
foreach (var key in keysToRemove)
Remove(key);
}
}
/// <summary>
/// Clear all cache data
/// </summary>
public void Clear()
{
using (var connection = ConnectionMultiplexer.Connect(_configurationOptions))
{
var server = connection.GetServer(_redisHost, _redisPort);
//var keysToRemove = server.Keys(-1);
var keysToRemove = server.Keys();
foreach (var key in keysToRemove)
Remove(key);
}
}
/// <summary>
/// Converts to byte array.
/// </summary>
/// <param name="data">The data.</param>
/// <returns>System.Byte[].</returns>
private byte[] ConvertToByteArray(object data)
{
if (data == null)
return null;
string serialize = JsonConvert.SerializeObject(data);
return Encoding.UTF8.GetBytes(serialize);
}
/// <summary>
/// Converts to object.
/// </summary>
/// <param name="data">The data.</param>
/// <returns>System.Object.</returns>
private T ConvertToObject<T>(byte[] data)
{
try
{
return JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(data));
}
catch (Exception ex)
{
return (T)Activator.CreateInstance(typeof(T));
}
}
}
}