Je recherche des idées de conception p>
J'ai un service Web ASP.NET qui consomme un site Web. L'un des appels qui prend environ 13 secondes pour récupérer environ 70000 rangées. 4 secondes sur la DB et 9 secondes pour traiter sur le serveur Web car il existe un traitement sur chaque enregistrement. Cela a été optimisé autant que je puisse et a été abattu à partir d'une 42 secondes d'origine. P>
Les données ne changent pas si souvent, mon idée est de créer un cache sur le Webservice et de sonder sur une minuterie pour mettre à jour cette cache toutes les 30 secondes environ. Ensuite, l'appel WebService récupère les enregistrements traités du cache p>
Je cherche des idées de conception pour la meilleure façon d'aborder cela. Je comprends ASP.NET dispose d'un dictionnaire de cache d'entrée mais qui ne résoudrait pas le problème de vote, donc je n'aurais donc pas besoin d'un singleton de toute façon, alors j'ai des problèmes de filetage possibles. P>
Obtenir assez confus et ne savez pas si je suis sur les bonnes lignes ou si je devais calculer les données et le stocker dans une table de base de données, toute directive serait grandement appréciée p>
En tant que rétroaction à certains des commentaires. Le site Web est conçu pour interagir avec l'AX ERP Dynamics AX sur un site des clients, alors même si j'ai un certain contrôle de la couche de DB, il est limité (je peux ajouter certaines SPS et certains index, mais les déclencheurs et les notificateurs de modifications sont probablement un NO Non) p>
La dernière mise à niveau pour Dynamics AX est à Azure et il n'y a pas d'accès à la couche DB, donc je devrai probablement héberger le serveur Web à Azure. Si c'est le cas et que je dois prendre en charge toutes les versions, il semble que je suis limité à Eith Redis ou à une autre dB NOSQL, c'est la seule option, ou j'écris le résultat à ma propre table DB et appelez de là. Est-ce définitivement le cas pour Azure? P>
5 Réponses :
Vous pouvez mettre en cache vos données avec REDIS et si les fichiers de données, vous pouvez mettre à jour le cache avec une dépendance SQL. Juste vous avez besoin de redis et de dépendance SQL, je pense. P>
Merci pour votre contribution. Je ne veux pas avoir à installer une base de données NOSQL, c'est un peu excédentaire pour mes besoins. Je ne veux pas gérer un autre serveur et je n'aurai besoin de rechercher dans le cache, prenez simplement le contenu. Je veux juste pouvoir contenir des données en mémoire et pour qu'il soit accessible par plusieurs demandes
Vous pouvez créer une classe statique. Cette classe doit avoir une liste
Si je devais implémenter votre scénario, je ne préférerais pas le sondage car il y a moins de point dans la mise en service des appels répétés au service et de maintenir le service / réseau occupé. En outre, si vous deviez mettre en place un nouveau client, vous devrez mettre en œuvre à nouveau l'interrogation. P>
Utilisez plutôt une mise en cache basée sur un dictionnaire dans une classe statique. Vous utilisez des bibliothèques existantes comme Cachemanager. L'idée générale est de créer une clé à l'aide des paramètres utilisés pour effectuer l'appel de service. Ensuite, stockez les résultats obtenus après traitement dans un Effacer le résultat stocké uniquement lorsque la table de base de données sous-jacente (?) a été mise à jour ou si elle est trop compliquée, après toutes les 30 secondes. P>
En outre, vous pouvez également implémenter un mécanisme de mise en cache similaire sur votre couche d'accès aux données pour réduire les 4 secondes que vous avez actuellement. Rincer les données en cache après les modifications de données sous-jacentes (ajoutez, mettre à jour, supprimer, insertion des opérations)! P> Concurrentdicdiction code> qui prend en charge l'accès par plusieurs threads par lui-même. P>
Nous implémentons un modèle de vote dans ASP.NET qui peut s'appliquer à votre cas d'utilisation.
dans notre où global.ashx code>, nous avons: p>
configuraitonmonitor code> ressemble à ceci: P>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class ConfigurationMonitorAttribute : Attribute
{
private Type _type;
private string _methodName;
public ConfigurationMonitorAttribute(Type type, string methodName)
{
_type = type;
_methodName = methodName;
}
public Type Type
{
get
{
return _type;
}
}
public string MethodName
{
get
{
return _methodName;
}
}
private MethodInfo _Method;
protected MethodInfo Method
{
get
{
if (_Method == null)
{
_Method = Type.GetMethod(MethodName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
if (_Method == null)
throw new ArgumentException(string.Format("The type {0} doesn't have a static method named {1}.", Type, MethodName));
}
return _Method;
}
}
public DateTime InvokeMethod(DateTime lastPoll)
{
try
{
return (DateTime)Method.Invoke(null, new object[] { lastPoll });
}
catch (System.Exception err)
{
new qbo.Exception.ThirdPartyException(string.Format("Attempting to monitor {0}/{1} raised an error.", _type, _methodName), err);
}
return lastPoll;
}
}
Il y a quelques autres choses à réfléchir dans ce scénario autre que de dire simplement "je veux ajouter la mise en cache". P>
Si vous courez dans Azure ou dans une ferme Web, vous avez besoin d'un cache centralisé (ReDIS ou The Likes) en tant que cache de mémoire sera détruit et recréé avec votre site et local sur un serveur la ferme, vous ne verrez pas nécessairement les gains de performance. P> li>
Si vous configurez un cache ReDIS, assurez-vous de prendre soin de la configuration. Le codage doit être juste pour expliquer les connexions et, si vous ne le faites pas correctement, vous finirez par dépasser votre pool de connexion. P> LI>
C'est plus juste sur votre situation, mais même 4 secondes pour renvoyer 70 000 enregistrements semblent élevés. Avez-vous parcouru un plan d'exécution pour voir s'il manque des index ou des optimisations avec des CTES pouvant être appliquées? P> LI> ol>
Vous pouvez définir des stratégies d'expiration pour un cache et une charge à la demande. Vous pouvez également avoir plus d'un niveau de mise en cache, une comme distribué et une locale car la version locale sera toujours la plus rapide. Je préfère le chargement sur demande VS interrogation comme avec le sondage que vous rafraîchissez toujours les données, même lorsque personne n'écoute. Si vous utilisez Multi niveau, vous pouvez sonder votre cache distribuée et charger le cache local à la demande. C'est à peu près aussi efficace que vous obtiendrez. P>
Le .NET Framework inclut un System.Web.Caching CODE> NAMESPACE docs.microsoft.com/en-us/dotnet/api/... qui a beaucoup de fonctionnalités, par exemple le concept de
CacheDePendance Code>. Il fournit une implémentation pour SQLServer, mais l'architecture et la conception peuvent supporter d'autres bases de données.
Afin de déterminer une implémentation de cache appropriée, cela pourrait vous aider si vous fournissez un certain contexte sur la demande. Telle que: a) est la requête pour les données paramétrées (c'est-à-dire les données résultantes identiques pour chaque demande)? Si tel est le cas, le cache pourrait potentiellement utiliser une recherche clé. b) Êtes-vous en contrôle (ou au moins notifié lorsque) les données sont mises à jour? Si tel est le cas, vous pouvez invalider le cache sur les données à jour au lieu de (ou avec) le mécanisme de vote
Votre projet ASP.NET ou ASP.NET CORE est-il? Si vous utilisez .NET CORE, vous pouvez regarder en utilisant ImemoryCache
Avez-vous le contrôle du site Web qui consomme également votre service Web? Si c'est le cas, cela pourrait être logique de mettre en cache les données dans cette application également ou au lieu de votre site Web. Également pertinent est de savoir si le site Web est déployé sur un seul serveur ou une ferme