애플이 만든 프로그래밍 언어 ‘스위프트’는 프론트엔드용으로 고안됐지만, 백엔드 시스템에서도 활용가능하다. 스위프트 오픈소스 커뮤니티는 10년 간 서버사이드 시나리오를 꾸준히 홍보해왔는데, 애플이 최근 클라우드 기반 시스템에 자바 대신 스위프트를 사용해 성능과 확장성, 보안 등을 높였다는 사례를 발표해 주목된다.
리키 몬델로, 인드라바르단 싱 샤크타왓, 스펜서 반 다이크, 우메쉬 바트라 등 애플 소속 개발자들은 이달초 스위프트재단 블로그를 통해 애플의 비밀번호 앱을 지원하는 리눅스 서버에 스위프트를 채택한 사례를 공유했다.
애플 비밀번호 앱은 사용자의 비밀번호, 패스키, 인증코드 등을 관리할 수 있는 앱이다. iOS, 맥OS, 아이패드OS 등 모든 애플 기기에서 비밀번호를 관리하고 공유하게 해준다. 이 앱은 여러 보안 기능을 제공하는데, 그중 비밀번호 모니터링은 저장된 비밀번호가 데이터 유출 사고에 연루될 경우 사용자에게 경고를 보낸다. 이 비밀번호 모니터링은 애플에서 관리하는 리눅스 인프라에서 실행되는 서버 요소를 다수 포함하고 있다.
블로그 저자들에 따르면, 비밀번호 모니터링은 정기적으로 사용자의 비밀번호를 데이터 유출사고와 관련되는 최신 비밀번호 목록과 대조한다. 애플은 사용자의 개인정보보호를 인식하지 않으므로, 비밀번호 모니터링 작업은 암호화된 개인설정 교차 프로토콜(PSI)을 사용해 이뤄진다.
애초 이 비밀번호 모니터링용 서버는 자바로 구축됐다. 애플은 모니터링 서비스의 성능 향상과 확장을 위해 자바에서 스위프트로 이전하기로 했다.
계층형 암호화 모듈은 각 요청마다 대규모 연산을 필요로 하지만, 전체 서비스는 높은 부하 상황에서도 신속하게 응답해야 한다.
자바는 미션크리티컬 시스템에서 안정성과 성능을 검증받은 플랫폼이다. 그러나 자바의 메모리 관리 방식은 비밀번호 모니터링의 높은 부하 상황에서 효율성에 한계를 보였다고 한다. 애플은 하드웨어 자원 확장 대신 서버 오버헤드를 줄이면서 서비스 성장을 지원할 수 있는 더 효율적인 언어를 찾았다.
개발팀은 자바의 대체 언어를 찾기에 앞서 필요 성능을 달성하기 위해 자바가상머신(JVM) 튜닝을 모색했다고 한다. 자바의 G1 가비지콜렉터(GC)가 예측가능한 일시정지 시간, 영역 기반 수집, 동시 처리 등의 기능을 도입해 이전 버전의 한계를 일부 완화했지만 높은 부하 상황에서 장시간의 GC 일시 정지, 성능 오버헤드 증가, 다중 워크로드에 대한 미세조정 복합성 등의 문제는 쉽게 해결되지 않았다.
블로그 저자들은 “자바 서비스의 당면 과제 중 하나는 JVM 오버헤드로 인해 인스턴스를 신속하게 프로비저닝하고 해제할 수 없다는 점이었다”며 “비밀번호 모니터링 서비스는 전세계적으로 실행되므로 클라이언트 측 기술로 트래픽을 분산시켜도 서비스 부하가 하루종일 크게 변동할 수 있다”고 설명했다.
또 “하루 중 사용량이 가장 많은 지역과 가장 적은 지역은 지역별로 약 50% 차이가 났다”며 “이를 효율적으로 관리하기 위해, 지역별로 수요에 따라 규모를 조정해야 하는데, 이런 동적 확장 전략을 위해 더 빠른 부트스트랩 속도가 필수적”이라고 밝혔다.
개발팀은 애플리케이션 규모와 트래픽 양을 고려했을 때 자바를 대체할 옵션이 몇 개뿐이었다고 했다. 애플에서 만든 언어라 스위프트를 무조건 고른 게 아니라, 실제 클라우드 서비스 요건에 스위프트가 잘 부합했다는 설명이다.
개발팀은 스위프트로 이전을 결정하고 스위프트 웹 프레임워크인 베이퍼(Vapor)를 사용해 서비스 재작성에 돌입했다. 베이퍼는 라우팅, 컨트롤러, 콘텐츠 모듈 등을 제공한다. 베이퍼에 서비스 추가 요구사항을 위해 맞춤형 패키지를 만들었다고 한다. 비밀번호 모니터링, 감사, 구성, 오류 처리, 맞춤형 미들웨어 구현을 위한 타원 곡선 연산 등이 추가됐다.

스위프트는 자동 메모리 관리 기능을 제공한다. 이는 자바와 달리 자동참조계산(ARC)으로 구현된다. ARC와 GC 방식의 우위에서 이견이 있지만, 애플의 비밀번호 모니터링 시나리오에선 ARC가 메모리를 더 효율적으로 사용하게 한다. 확장성에 있어서도 스위프트는 스냅스타트(snapstart) 기술을 통해 하드웨어 부팅 시간을 단축한다.
블로그 작성자들은 스위프트의 프로토콜 강조를 가장 인상깊었던 점으로 꼽았다. 자바가 클래스 상속에 크게 의존하는 반면, 스위프트는 프로토콜과 제네릭 접근 방식을 특징으로 한다. 클래스, 구조체, 열거형 등이 공통 프로토콜을 공유하게 해 모듈화와 재사용성을 높이고, 이를 통해 더 유연하고 확장가능한 코드베이스를 구축할 수 있다는 것이다. 개발팀은 이를 통해 구체적 클래스보다 동작 관점에서 생각하게 됐고, 더 깔끔하고 유지관리하기 쉬운 코드를 얻었다고 강조했다.
자바와 비교해 안정성도 스위프트에서 달라졌다. 스위프트가 선택적 타입과 안전한 언래핑 매커니즘을 사용하므로 모든 곳에 null 체크를 하지 않아도 되고, null 포인터 예외 발생 위험이 줄고 코드 가독성을 높인다는 설명이다. 결정론적 할당 해제, 쓰기 시 복사, 값 타입 등 스위프트의 안전성 우선 접근방식이 런타임 오류 발생 가능성을 본질적으로 낮춘다고 개발팀 측은 강조했다.
스위프트는 비동기 작업 처리 방식도 간소화시켰다. 스위프트 ‘async/await’ 구문을 통해 복잡한 콜백 패턴이나 외부 라이브러리 없이도 비동기 작업 처리를 간소화해 더 직관적이고 오류 발생 가능성도 줄었다고 한다. 동기 코드처럼 읽히는 비동기 코드를 작성할 수 있어 동시성 처리에서 가독성, 테스트 가능성, 유지관리 용이성 등이 향상됐다고 하며, 높은 부하의 멀티스레드 환경에서도 유익하다고 했다.
최종적으로 비밀번호 모니터링의 백엔드를 자바에서 스위프트로 이전하면서 예상보다 빠르게 코드베이스를 재작성할 수 있었다. 코드 라인 수는 약 85% 감소했다. 하드웨어 사용률은 50% 줄고, 메모리 사용량은 90% 감소했으며, 처리량은 40% 증가했다고 한다.

로깅 프레임워크, 카산드라 클라이언트, 암호화 라이브러리 등 스위프트의 다양한 패키지 생태계를 활용할 수 있었고, 미래 변화에 대비하는 통합과 맞춤 설정도 간소화할 수 있었다.
스위프트의 결정론적 메모리 관리는 서비스의 메모리 임계값을 대폭 낮췄다. 현재 운영 중인 하드웨어에서 요청의 99.9%에 대해 1밀리초 미만의 지연시간을 기록하고, 처리량은 약 40% 증가했다. 신규 서비스는 인스턴스당 메모리 사용량이 훨씬 적어 수백 메가바이트(MB) 용량으로 만들어졌다. 기존 자바 구현체는 최대 부하 상황에서 동일한 처리량과 지연시간을 유지하는데 수십 기가바이트(GB)를 요구했다고 한다.
새로운 서비스는 쿠버네티스에서 실행되고, 마이그레이션을 통해 효율성을 향상시켜 용량의 약 50%를 다른 워크로드에 할당할 수 있었다고 한다.
블로그 작성자들은 “스위프트 구현은 프로덕션 환경에서 원활하고 효율적으로 실행돼 이전에 들인 노력이 헛되지 않았다”며 “기존 자바 기반 애플리케이션보다 높은 성능을 보이고, 메모리와 CPU를 더 효율적으로 활용해 자원 사용량을 줄이면서도 더 나은 성능 일관성, 향상된 보안 기능, 견고한 안전성을 제공했다”고 밝혔다.
또 “거의 바뀌지 않고 반복적으로 작성되는 코드를 줄이고, 디자인 패턴을 더욱 유연하게 적용함으로써 애플리케이션 유지 관리를 간소화할 것으로 기대된다”며 “스위프트는 수요가 높은 환경에서 빠르고, 복원력이 뛰어나며, 유지관리가 용이한 애플리케이션 구축에 탁월한 선택”이라고 강조했다.
글. 바이라인네트워크
<김우용 기자>yong2@byline.network