我正在使用DjangoCMS构建一个网站,该网站具有大约10个同一应用程序实例。 这些不同的实例将仅用于在不同页面上提供不同的文件。 一切正常,除了当我转到应用程序的其他实例并转到详细信息视图时,它还原为原始应用程序的URL和名称空间。 例如,转到/university/term- ...
提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供 中文繁体 英文版本 中英对照 版本,有任何建议请联系yoyou2525@163.com。
问题摘要:我需要调用 HTTP 资源 A,同时使用从先前 HTTP 请求到同一主机上的资源 B 的名称解析。
案例 1. 对同一资源的连续调用在第一次调用后产生更快的结果。 Profiler 告诉我,第一次和第二次调用之间的区别在于 DNS 名称解析 (GetHostAddresses)
var request = (HttpWebRequest)WebRequest.Create("https://www.somehost.com/resources/b.txt");
using (var response = (HttpWebResponse)request.GetResponse()) {}
var request = (HttpWebRequest)WebRequest.Create("https://www.somehost.com/resources/b.txt");
using (var response = (HttpWebResponse)request.GetResponse()) {}
情况 2. 对同一主机上不同资源的连续调用产生相同的延迟。 Profiler 告诉我,它们都会调用 DNS 名称解析。
var request = (HttpWebRequest)WebRequest.Create("https://www.somehost.com/resources/a.txt");
using (var response = (HttpWebResponse)request.GetResponse()) {}
var request = (HttpWebRequest)WebRequest.Create("https://www.somehost.com/resources/b.txt");
using (var response = (HttpWebResponse)request.GetResponse()) {}
我想知道为什么如果 2 秒调用不能从第一次调用开始使用 DNS 缓存? 它是同一个主机。
主要问题 - 如何改变?
编辑上述行为还涵盖了 HttpClient 类的使用。 看来这是我使用的少数网络服务器所特有的,并且这个问题在其他服务器上不会发生。 我无法弄清楚具体发生了什么,但我怀疑有问题的网络服务器(Amazon CloudFront 和 Akamai)在提供服务后强制关闭连接,忽略我的请求保持活动标头。 我现在要结束这个,因为不可能有意识地提出一个问题..
System.Net.Http.HttpClient
不存在您的问题,请改用它。 它可以重用现有的连接(此类调用不需要 DNS 缓存)。 看起来这正是您想要实现的目标。 作为奖励,它支持 HTTP/2(可以在HttpClient
实例创建时通过属性分配启用)。
WebRequest
是古老的,Microsoft 不推荐用于新开发。 在 .NET 5 HttpClient
中更快(两倍?)。
为每个应用程序创建一次HttpClient
实例( 链接)。
private static readonly HttpClient client = new HttpClient();
模拟您的请求。 注意await
仅在标记为async
方法中可用。
string text = await client.GetStringAsync("https://www.somehost.com/resources/b.txt");
您也可以一次执行多个请求而不会产生并发线程。
string[] urls = new string[]
{
"https://www.somehost.com/resources/a.txt",
"https://www.somehost.com/resources/b.txt"
};
List<Task<string>> tasks = new List<Task<string>>();
foreach (string url in urls)
{
tasks.Add(client.GetStringAsync(url));
}
string[] results = await Task.WhenAll(tasks);
如果您不熟悉异步编程,例如async/await
,请从本文开始。
您还可以设置一次处理多少请求的限制。 让我们做 1000 次相同的请求,一次限制为 10 个请求。
static async Task Main(string[] args)
{
Stopwatch sw = new StopWatch();
string url = "https://www.somehost.com/resources/a.txt";
using SemaphoreSlim semaphore = new SemaphoreSlim(10);
List<Task<string>> tasks = new List<Task<string>>();
sw.Start();
for (int i = 0; i < 1000; i++)
{
await semaphore.WaitAsync();
tasks.Add(GetPageAsync(url, semaphore));
}
string[] results = await Task.WhenAll(tasks);
sw.Stop();
Console.WriteLine($"Elapsed: {sw.Elapsemilliseconds}ms");
}
private static async Task GetPageAsync(string url, SemaphoreSlim semaphore)
{
try
{
return await client.GetStringAsync(url);
}
finally
{
semaphore.Release();
}
}
你可以测量一下时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.