현재상황

Selenium을 통해 현재 크롤링이 진행된다. 크롤링을하기 위해 Selenium의 Chorme Driver를 @PostStructure을 통해 Setup 하도록 설계되어있다.

@Component
@Getter
public class WebDriverUtil {

    private WebDriver driver;

    @PostConstruct
    public void setUpDriver(){
        WebDriverManager.chromedriver().setup();
    }
    
    public void getChromeDriver(String url) {
        if (driver == null) {
            ChromeOptions chromeOptions = new ChromeOptions();
            setChromeOption(chromeOptions);
            driver = new ChromeDriver(chromeOptions);
            driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        }
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            driver.manage().addCookie(cookie);
        }
        driver.get(url);
    }
    
    // 생략
}

Setup을 하게되면 그 순간 chromdriver가 실행되고, 그 이후 getChromeDriver(url)을 통해 받은 정보를 기반으로 크롤링을 수행한다.

현재 코드에선 채용공고와 기업, 강의에 대한 크롤링이 매주 월요일에 진행되도록 설정되어 있다. 그렇다는 소리는 특정 시간을 제외한 경우, Selenium driver는 여전히 작동중이기 때문에 비효율적이다고 생각했다. 따라서, 사용자의 명령이 있을 때 작업을 진행하는 Batch를 통해 서버의 성능을 향상시킬 수 있을 것이라고 생각했다.

먼저 적용에 앞서 프로메테우스와 그라파나를 통한 크롤링 시 서버의 부하를 모니터링 해보자.

driver setup 전

driver setup 전

크롤링 후, driver 실행 중

크롤링 후, driver 실행 중

JVM 쓰레드 상태

JVM 쓰레드 상태

CPU 사용량의 7%를 차지하고 있다. 또한 JVM의 6쓰레드를 Selenium이 사용하고 있음을 알 수 있다.

따라서, 우리는 해당 부분을 해결하기 위해 크롤링 시에만 Selenium Driver를 사용하도록 수정하고자 한다.

해결

Spring AOP를 이용한 quit()의 자동 실행

spring AOP를 이용하여 크롤링이 완료된 이후, quit()을 사용하도록 해보자.

매번 이를 입력하는 방법보다 AOP를 이용한 관심사를 분리하여 @Crawling 어노테이션이 추가만하도록 설계하려고 한다.

@After("@annotation(com.teamdevroute.devroute.global.aop.crawl.Crawling)")
public void afterMethod() {
    webDriverUtil.closeChromeDriver();
}

Driver의 경우, WebDriverUtil이 빈으로 관리되기 때문에 DI를 받아 closeChromeDriver()만 실행하면 된다.