[java] Akka와 실시간 웹 크롤링

최근에는 웹 크롤링을 통해 실시간으로 웹사이트의 데이터를 수집하는 것이 매우 중요해졌습니다. 이를 위해 여러가지 기술과 도구가 개발되고 있지만, 그 중에서도 Akka는 실시간 웹 크롤링에 아주 효과적인 도구입니다.

Akka는 Java와 Scala를 기반으로 개발된 액터 기반의 분산 컴퓨팅 프레임워크입니다. 액터 모델은 동시성 문제를 해결하기 위한 가장 일반적인 패턴 중 하나입니다. Akka의 액터 모델은 매우 경량화되어 있어서 대규모 분산 시스템에서도 뛰어난 성능을 발휘할 수 있습니다.

웹 크롤링 액터 구현하기

Akka를 사용하여 실시간으로 웹 크롤링을 수행하는 간단한 예제를 살펴보겠습니다. 다음은 Java로 작성된 웹 크롤링 액터의 예제 코드입니다.

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.routing.RoundRobinPool;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class WebCrawlerActor extends AbstractActor {

    private final ActorRef resultAggregator;

    public static Props props(ActorRef resultAggregator) {
        return Props.create(WebCrawlerActor.class, () -> new WebCrawlerActor(resultAggregator));
    }

    private WebCrawlerActor(ActorRef resultAggregator) {
        this.resultAggregator = resultAggregator;
    }

    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .match(String.class, this::crawl)
                .build();
    }

    private void crawl(String url) {
        try {
            Document doc = Jsoup.connect(url).get();
            Elements links = doc.select("a[href]");
            List<String> hrefs = new ArrayList<>();
            for (org.jsoup.nodes.Element link : links) {
                hrefs.add(link.attr("abs:href"));
            }
            resultAggregator.tell(hrefs, getSelf());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

위의 코드에서는 WebCrawlerActor라는 액터를 정의하고, crawl 메소드를 통해 웹 페이지를 크롤링하여 결과를 resultAggregator 액터로 전달합니다.

액터 시스템 구성하기

액터 시스템을 구성하기 위해서는 ActorSystem을 생성해야 합니다. 다음은 주어진 URL에 대해 웹 크롤링을 시작하는 액터 시스템을 생성하는 예제 코드입니다.

import akka.actor.ActorRef;
import akka.actor.ActorSystem;

public class Crawler {

    public static void main(String[] args) {
        ActorSystem system = ActorSystem.create("CrawlerSystem");

        ActorRef resultAggregator = system.actorOf(ResultAggregator.props(), "resultAggregator");
        ActorRef crawler = system.actorOf(WebCrawlerActor.props(resultAggregator), "crawler");

        crawler.tell("https://www.example.com", ActorRef.noSender());

        // 액터 시스템 종료
        system.terminate();
    }
}

위의 코드에서는 Crawler 클래스에서 ActorSystem을 생성하고, WebCrawlerActorResultAggregator 액터를 생성하여 액터 시스템에 등록합니다. 그리고 crawler.tell("https://www.example.com", ActorRef.noSender()) 코드를 통해 크롤링을 시작합니다.

결과 수집하기

크롤링한 결과를 수집하는 액터를 구현해야 합니다. 다음은 결과를 수집하는 액터의 예제 코드입니다.

import akka.actor.AbstractActor;
import java.util.List;

public class ResultAggregator extends AbstractActor {

    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .match(List.class, this::processResult)
                .build();
    }

    private void processResult(List<String> result) {
        // 결과 처리하는 로직 작성
    }
}

위의 코드에서는 ResultAggregator 액터를 정의하고, processResult 메소드로 결과를 처리하는 로직을 작성해야 합니다.

결론

Akka를 사용하면 실시간 웹 크롤링을 간단하고 효율적으로 수행할 수 있습니다. 이를 통해 웹사이트의 업데이트되는 데이터를 실시간으로 수집하고 처리할 수 있습니다. 많은 데이터를 처리해야 할 경우에도 Akka의 액터 모델을 활용하여 분산 처리를 수행할 수 있기 때문에 효과적입니다.