我有一个为用户分配用户名的Web服务。在内部我调用了一堆函数来验证AD中是否存在用户名,包括UserPrincipal,samAccountName,proxyaddresses和email。
在单元测试中,此代码需要10秒才能运行。在本地部署到Web服务器,代码运行需要9分钟。我不认为这是第一次运行的问题,因为它第二次需要很长时间。我们的域名拥有超过30,000的用户,我必须搜索整个域名,以确保名称不存在。根据要求,不能使用缓存,因为我们需要进行最新的检查。
我已经搜索了如何提高速度,但还没有找到任何东西。
任何人都有关于如何提高绩效的建议吗?
public bool DoesEmailExist(string email)
{
using (var context = GetPrincipalContext())
{
var userQuery = new UserPrincipal(context) { EmailAddress = email + "@*" };
var searcher = new PrincipalSearcher(userQuery);
var result = searcher.FindOne();
if (result == null)
{
var aliasQuery = new ExtendedUserPrincipal(context) { ProxyAddress = "*smtp:" + email + "@*" };
searcher = new PrincipalSearcher(aliasQuery);
var aliasResult = searcher.FindOne();
if (result == null)
{
return false;
}
}
return true;
}
}
private PrincipalContext GetPrincipalContext(string ou)
{
return new PrincipalContext(ContextType.Domain, dc, ou, ContextOptions.Negotiate);
}
编辑 - 我切换到使用DirectorySearcher,速度似乎有所改善。现在运行的网络API需要5分钟。我仍然想知道为什么我的单元测试明显快于web api。使用日志代码,单元测试中对DoesUserNameExist的调用需要7秒。通过运行web api需要5分钟。
public bool DoesUserNameExist(string userName)
{
string filter = "(|(samAccountName={NAME})(UserPrincipalName={NAME}@*)(mail={NAME}@*)(proxyAddresses=*smtp:{NAME}@*))";
filter = filter.Replace("{NAME}", userName);
using (var de = new DirectoryEntry("LDAP://" + domainController + "/" + rootOU))
{
var searcher = new DirectorySearcher();
searcher.Filter = filter;
searcher.PageSize = 1;
var result = searcher.FindOne();
if (result != null)
{
return true;
}
return false;
}
}
答案 0 :(得分:2)
尽管proxyAddresses属性已编制索引,但它仅对等号和启动过滤器有帮助,但不包含end-with和包含过滤器。
proxyAddresses=sth
,proxyAddresses=sth*
proxyAddresses=*sth*
,proxyAddresses=*sth
我认为没有看起来像“abcdsmtp:user@domain.com”的proxyAddresses。
您只需使用proxyAddresses=smtp:{NAME}@*