Back-End

SSHJ란 무엇인가

isTrue 2026. 3. 19. 14:35
반응형

SSHJ는 Java에서 SSH 프로토콜을 사용하기 위한 라이브러리다.
JSch의 대안으로 많이 사용되며, 더 현대적인 API를 제공한다.

주요 기능은 동일하다.

  • SFTP 파일 업로드 / 다운로드
  • SSH 명령 실행
  • 포트 포워딩

하지만 중요한 차이는

안정성과 API 사용성이 훨씬 좋다


왜 SSHJ를 사용하는가

JSch 대비 장점은 명확하다.

1. 유지보수

  • JSch → 사실상 정체
  • SSHJ → 꾸준히 업데이트

2. API 가독성

  • 스트림 처리 / 예외 처리 훨씬 직관적

3. 안정성

  • 연결 안정성 좋음
  • 타임아웃, 재시도 구현 용이

기본 구조 이해

SSHJ는 구조가 훨씬 단순하다.

SSHClient → SFTPClient

또는

SSHClient → Session → Command

SFTP 파일 업로드 예제

SSHClient ssh = new SSHClient();

// 호스트 키 검증 (개발용)
ssh.addHostKeyVerifier((h, p, key) -> true);

ssh.connect("host");

try {
    ssh.authPassword("user", "password");

    try (SFTPClient sftp = ssh.newSFTPClient()) {
        sftp.put("local.txt", "/remote/path/remote.txt");
    }

} finally {
    ssh.disconnect();
}

SFTP 다운로드 예제

try (SFTPClient sftp = ssh.newSFTPClient()) {
    sftp.get("/remote/path/remote.txt", "local.txt");
}

SSH 명령 실행 예제

try (Session session = ssh.startSession()) {
    Session.Command cmd = session.exec("ls -al");

    String output = new String(cmd.getInputStream().readAllBytes());
    System.out.println(output);

    cmd.join(5, TimeUnit.SECONDS);
}

실무에서 꼭 알아야 할 포인트

1. HostKey 검증

ssh.addHostKeyVerifier((h, p, key) -> true);
  • 개발에서는 OK
  • 운영에서는 반드시 known_hosts 기반 검증 필요

2. try-with-resources 적극 사용

SSHJ는 AutoCloseable 지원

try (SFTPClient sftp = ssh.newSFTPClient()) {
    // 작업
}

→ 리소스 누수 방지


3. 타임아웃 설정

ssh.setConnectTimeout(30000);
ssh.setTimeout(30000);

4. 예외 처리

SSHJ는 예외가 비교적 명확하게 나온다.

  • IOException
  • TransportException

→ 로그 설계하기 쉬움


5. 멀티 스레드

  • SSHClient는 thread-safe하지 않음
  • 요청마다 새로 생성하는 게 안전

JSch vs SSHJ 비교

 

항목 JSch SSHJ
유지보수 거의 없음 활발
API 불편 직관적
안정성 이슈 있음 안정적
추천 여부

실무 적용 구조 (추천)

Seonho 프로젝트 기준으로 구조 잡아보면

sftp
 ├── SftpClient (인터페이스)
 ├── SshjSftpClient (구현체)
 ├── SftpConnectionManager
 ├── SftpRetryHandler

SshjSftpClient 예시 구조

public class SshjSftpClient {

    public void upload(String host, String user, String password,
                       String localPath, String remotePath) {

        SSHClient ssh = new SSHClient();
        ssh.addHostKeyVerifier((h, p, key) -> true);

        try {
            ssh.connect(host);
            ssh.authPassword(user, password);

            try (SFTPClient sftp = ssh.newSFTPClient()) {
                sftp.put(localPath, remotePath);
            }

        } catch (IOException e) {
            throw new RuntimeException("SFTP upload failed", e);
        } finally {
            try {
                ssh.disconnect();
            } catch (IOException ignored) {}
        }
    }
}

실무에서 한 단계 더 (중요)

Seonho 지금 하고 있는 프로젝트 기준으로 중요한 포인트

1. 재시도 로직

  • 네트워크 실패는 필연적
  • retry + backoff 필수

2. MQ 연계

  • RabbitMQ → SFTP 작업
  • 실패 시 DLQ or 재큐잉

3. 파일 무결성

  • MD5 / SHA 체크
  • 업로드 후 검증

4. 연결 재사용 전략

  • 대량 파일 처리 시
    → connection pooling 고려

한 줄 정리

SSHJ는 JSch의 실무 대안으로,
안정성과 유지보수성 측면에서 훨씬 더 적합한 SSH/SFTP 라이브러리다.

반응형