【发布时间】:2016-05-03 15:11:36
【问题描述】:
项目基于 MVC WebAPI。
我们将客户端的权限上下文作为请求声明标头中的序列化 JSON 对象传递给我们的 API 服务器。这不是一个巨大的对象:6 个属性和一个基于枚举的键值对集合(这里最多 6 个项目)
对 API 的绝大多数请求每分钟(有些更频繁)都来自同一组客户端。可能有 700-900 个客户(并且还在不断增加),每个客户每分钟一遍又一遍地发送相同的声明。
对于每个请求,代码的各个组件可能会反序列化这个对象 5-6 次。这种反序列化会导致服务器大量消耗 CPU。
在内存中缓存这些反序列化的最佳方法是什么?带有序列化 JSON 字符串的键的静态 Dictionary 对象是否可以正常工作,或者通过它进行搜索会太慢,因为这些字符串的大小会相当大?
编辑: 每个控制器的每个 Action 都会通过这个属性进行过滤,以确保调用具有适当的权限
public class AccountResolveAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext context)
{
var controller = (ControllerBase) context.ControllerContext.Controller;
var identity = (ClaimsIdentity) controller.User.Identity;
var users = identity.Claims
.Where(c => c.Type == ClaimTypes.UserData.ToString())
.Select(c => JsonConvert.DeserializeObject<UserInformation>(c.Value))
.ToList();
var accountId = controller.ReadAccountIdFromHeader();
if (users.All(u => u.AccountId != accountId))
{
throw new ApplicationException(string.Format("You have no rights for viewing of information on an account Id={0}", accountId));
}
}
}
在基本控制器中也有询问声明的调用,但 AccountResolve 可能会将第一次反序列化的结果缓存到控制器中,这样这些调用就不会再次尝试反序列化。但是,这些声明一遍又一遍地相同,我只是想找到一种优化方法,不会一次又一次地反序列化相同的字符串。我尝试将序列化字符串作为键和结果对象缓存到全局静态 ConcurrentDictionary 中的内存中,但它似乎没有帮助
【问题讨论】:
-
你说代码的各个组件反序列化对象。出于好奇,组件首先是如何获取序列化数据的?例如:是否从当前线程的主体获取它,主体是否作为参数传递等等?
-
除了我刚才问的问题之外的另一个问题:您使用的是 IoC 容器吗?如果是,是哪一个?
-
是的,我们正在使用 autofac
-
Principal 已针对控制器操作进行验证(它是基本 controllrr 中的一个属性)。在基本控制器的某些地方也使用它来获取默认上下文
-
您提到的组件如何获取序列化数据?
标签: c# asp.net-web-api json.net