gpt4 book ai didi

Java:使用异步编程优化应用程序

转载 作者:行者123 更新时间:2023-12-02 08:42:50 25 4
gpt4 key购买 nike

我必须修改 dropwizard 应用程序以提高其运行时间。基本上,该应用程序每天接收大约 300 万个 URL,并下载和解析它们以检测恶意内容。问题是该应用程序只能处理 100 万个 URL。当我查看该应用程序时,我发现它正在进行大量顺序调用。我想要一些关于如何通过异步或其他技术来改进应用程序的建议。

所需代码如下:-

/* Scheduler */
private long triggerDetection(String startDate, String endDate) {
for (UrlRequest request : urlRequests) {
if (!validateRequests.isWhitelisted(request)) {
ContentDetectionClient.detectContent(request);
}
}
}

/* Client */
public void detectContent(UrlRequest urlRequest){
Client client = new Client();
URI uri = buildUrl(); /* It returns the URL of this dropwizard application's resource method provided below */

ClientResponse response = client.resource(uri)
.type(MediaType.APPLICATION_JSON_TYPE)
.post(ClientResponse.class, urlRequest);

Integer status = response.getStatus();
if (status >= 200 && status < 300) {
log.info("Completed request for url: {}", urlRequest.getUrl());

}else{
log.error("request failed for url: {}", urlRequest.getUrl());
}
}

private URI buildUrl() {
return UriBuilder
.fromPath(uriConfiguration.getUrl())
.build();
}

/* Resource Method */
@POST
@Path("/pageDetection")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
/**
* Receives the url of the publisher, crawls the content of that url, applies a detector to check if the content is malicious.
* @returns returns the probability of the page being malicious
* @throws throws exception if the crawl call failed
**/
public DetectionScore detectContent(UrlRequest urlRequest) throws Exception {

return contentAnalysisOrchestrator.detectContentPage(urlRequest);
}

/* Orchestrator */
public DetectionScore detectContentPage(UrlRequest urlRequest) {
try {

Pair<Integer, HtmlPage> response = crawler.rawLoad(urlRequest.getUrl());
String content = response.getValue().text();

DetectionScore detectionScore = detector.getProbability(urlRequest.getUrl(), content);
contentDetectionResultDao.insert(urlRequest.getAffiliateId(), urlRequest.getUrl(),detectionScore.getProbability()*1000,
detectionScore.getRecommendation(), urlRequest.getRequestsPerUrl(), -1, urlRequest.getCreatedAt() );

return detectionScore;

} catch (IOException e) {
log.info("Error while analyzing the url : {}", e);
throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
}
}

我正在考虑以下方法:-

  • 我没有通过 POST 调用 dropwizard 资源方法,而是直接从调度程序调用 orchestrator.detectContent(urlRequest)

  • 编排器可以返回检测分数,我会将所有检测分数存储在 map /表中,并执行批量数据库插入,而不是像当前代码中那样进行单独插入。

我想对上述方法以及可能的其他技术进行一些评论,通过这些技术可以提高运行时间。另外,我刚刚阅读了有关 Java 异步编程的内容,但似乎无法理解如何在上面的代码中使用它,因此也希望获得一些帮助。

谢谢。

编辑:我可以想到两个瓶颈:

  • 下载网页
  • 将结果插入数据库(数据库位于另一个系统中)
  • 似乎一次执行 1 个 URL 的处理

系统有 8 GB 内存,其中 4 GB 似乎可用

$ free -m
total used free shared buffers cached
Mem: 7843 4496 3346 0 193 2339
-/+ buffers/cache: 1964 5879
Swap: 1952 489 1463

CPU 使用率也极低:

top - 13:31:19 up 19 days, 15:39,  3 users,  load average: 0.00, 0.00, 0.00
Tasks: 215 total, 1 running, 214 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.5%us, 0.0%sy, 0.0%ni, 99.4%id, 0.1%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 8031412k total, 4605196k used, 3426216k free, 198040k buffers
Swap: 1999868k total, 501020k used, 1498848k free, 2395344k cached

最佳答案

首先检查一下你大部分时间都在哪里丢失。

我想大部分时间都浪费在了下载网址上。

如果下载 url 花费了超过 90% 的时间,那么您可能无法改进您的应用程序,因为瓶颈不是 java,而是您的网络。

<小时/>

仅当下载时间在网络能力范围内时才考虑以下内容

如果下载时间不是太长,您可能可以尝试提高性能。标准方法是使用生产者消费者链。请参阅here了解详情。

基本上,您可以按如下方式划分工作:

Downloading --> Parsing --> Saving 

下载是生产者,解析是下载过程的消费者,保存过程是生产者,保存是消费者。

每个步骤可以由不同数量的线程执行。例如,您可以有 3 个下载线程、5 个解析线程和 1 个保存线程。

<小时/>

评论后编辑

假设瓶颈不是CPU时间,所以对java代码进行干预并不重要。

如果您知道每天下载多少千兆字节,则可以查看它们是否接近网络的最大带宽。

如果发生这种情况,有不同的可能性:

  • 使用 Content-Encoding: gzip 请求压缩内容(从而减少使用的带宽)
  • 在不同网络上工作的不同节点之间分配您的应用程序(因此在不同网络之间分配带宽)
  • 更新您的带宽(因此增加网络带宽)
  • 请务必仅下载请求的内容(因此,如果没有请求,则不要下载 JavaScript、图像、CSS 等)(以尽量减少带宽的使用)
  • 之前解决方案的组合

关于Java:使用异步编程优化应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32740637/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com