이 글의 목차
인바운드 설정을 바꾼 뒤 연결은 이미 멈췄는데 Mihomo의 CPU 사용률이 계속 높고, 다시 변경하면 유휴 사용률이 더 높아질 수도 있습니다. 이때는 '설정 로드 중 잠깐 바빠지는 것'과 '리스너 종료 뒤에도 루프가 계속 도는 것'을 구분해야 합니다. 먼저 어떤 프로세스가 바쁜지, 방금 어떤 접속 입구를 닫았는지 확인하세요.
트래픽이 없는데도 재로드 후 CPU 사용률이 내려가지 않는 이유
공식 #3314는 구형 스트림 암호를 사용하는 Shadowsocks 인바운드의 종료 문제를 다룹니다. 관련 listeners 항목을 바꾸거나 제거하거나 ss-config를 변경한 뒤 기존 리스너의 연결 수락 루프가 끝나지 않을 수 있습니다. 트래픽이 없어도 CPU를 계속 사용하며, 같은 종료 경로를 다시 거치면 누적될 수 있고 오류 로그가 나타나지 않을 수도 있습니다.
이는 프록시 노드가 느리거나 일반 SS 아웃바운드가 실패하는 문제, 모든 재로드 지연과는 다릅니다. v1.19.33에 해당 수정이 포함되어 있지만, 이런 인바운드를 쓰지 않거나 정상 트래픽을 처리할 때만 사용률이 높다면 이 글을 그대로 적용할 수 없습니다.
프로세스와 발생 시점으로 구분하기
| 관찰된 증상 | 이어서 확인할 사항 |
|---|---|
| 실제 Mihomo 프로세스가 관련 SS 인바운드 종료 후 트래픽이 없는 상태에서도 CPU를 계속 많이 사용함 | 인바운드 유형, 암호 알고리즘, 실행 코어와 종료 시점을 확인합니다. |
| 대용량 설정을 로드할 때만 잠깐 높아지고 로드가 끝나면 내려감 | 설정 검증 비용을 확인합니다. 리스너 종료 후 루프가 계속 도는 문제로 판단하지 않습니다. |
| 클라이언트 화면은 바쁘지만 Mihomo 프로세스의 사용률은 정상임 | 화면, 트레이 또는 로그 처리를 확인합니다. |
| 관련 인바운드가 없거나 대량 트래픽을 전달할 때만 높아짐 | 해당 작업과 다른 실행 원인을 기록합니다. 이 글만으로 근본 원인을 확정할 수 없습니다. |
인바운드 설정부터 찾고 구독의 SS 노드와 구분하기
인바운드는 다른 프로그램이나 장치가 이 Mihomo 인스턴스에 연결하는 입구이고, 아웃바운드는 Mihomo가 외부 서비스에 접속하는 데 쓰는 프록시 노드입니다.
클라이언트가 최종적으로 코어에 전달하는 설정에서 listeners의 type: shadowsocks를 찾고 해당 cipher를 확인하세요. 구형 간편 설정 방식은 최상위 ss-config를 확인합니다. proxies에 type: ss가 보인다는 것만으로 이 문제의 조건에 해당하지는 않습니다.
이 문제에서 다루는 스트림 암호의 예는 aes-128-ctr, aes-256-cfb, rc4-md5, chacha20, chacha20-ietf, xchacha20입니다.
v1.19.33 태그의 소스는 이 호환 알고리즘을 내장 리스너 구현으로 처리합니다. none, AEAD, 2022 암호는 다른 구현을 사용하므로 이 종료 결함의 범위에 포함되지 않습니다. chacha20-ietf와 chacha20-ietf-poly1305는 이름이 비슷하다고 같은 종류로 취급해서는 안 됩니다.
현재 Wiki의 일반적인 인바운드 암호 표는 위의 구형 스트림 알고리즘을 새 설정의 선택지로 나열하지 않습니다. 이 글은 고정 버전의 소스를 근거로 기존 설정의 호환 경로를 설명하며, 문제를 재현하려고 구형 암호 인바운드를 새로 만들 것을 권하지 않습니다. cipher를 일방적으로 바꾸지도 마세요. 이 입구를 사용하는 상대편의 설정도 일치해야 합니다.
이미 발생한 문제에서 보관할 증거
- Mihomo와 화면 프로세스를 따로 관찰하고 어떤 실제 인스턴스의 CPU 사용률이 높은지 기록합니다.
- 클라이언트 버전, 실행 중인 코어 버전과 시작 방식을 기록합니다. 단순히 '최신 버전'이라고만 적지 않습니다.
- 관련 listeners 또는 ss-config의 변경 전후 사본을 보관하고 기존 인바운드 유형, cipher, 종료 시점을 기록합니다.
- 증상이 관련 인바운드의 변경, 제거 또는 종료 직후에 발생했는지 확인합니다. 무관한 재로드 뒤에 발생했다는 이유만으로 연결하지 않습니다.
- 원본 설정은 로컬에 보관하고, 공개 제보에서는 인바운드 비밀번호, 구독 토큰, 개인 키와 서버 정보를 지웁니다.
작동하던 설정을 먼저 보관하고 반복 핫 리로드 중단하기
사용 중인 전체 설정, 오버라이드, 외부 리소스와 클라이언트 설정을 별도로 백업하고 현재 코어 버전, 시스템 프록시와 TUN 상태를 기록하세요. 이 인바운드를 다른 장치도 쓴다면 연결을 중단할 수 있는 시간대를 먼저 정하고, 여기에 의존하지 않는 관리 접속 방법을 확보하세요. 점검 중에 구독을 업데이트하거나 DNS를 바꾸거나 데이터 디렉터리 전체를 비우지 마세요.
이미 루프가 계속 돌고 있다면 인바운드를 반복해서 지우고 추가하는 방법으로 '정리'하려 하지 마세요. 구버전의 결함은 리스너가 닫힌 뒤 발생하므로, 계속 핫 리로드하면 다시 유발할 수 있습니다. 임시 복구에는 앱이나 서비스가 지원하는 정상 종료 방법을 사용하고, 해당 기존 인스턴스가 실제로 끝났는지 확인한 뒤 미리 작동을 검증한 설정으로 시작하세요. 창을 닫거나 TUN을 끄거나 연결이 보이지 않는다는 사실만으로 프로세스 종료를 확인한 것으로 볼 수는 없습니다.
이 글을 따라 하려고 구버전에서 장애를 반복해서 만들 필요는 없으며, external-controller를 개방하거나 공식 재현 및 재로드 스크립트를 복사할 필요도 없습니다. 설정 테스트 -t가 통과했다는 것은 해당 설정 검사가 끝났다는 뜻일 뿐, 실행 중인 리스너의 종료 루프가 수정되었다는 증거는 아닙니다.
수정 버전을 확보한 뒤 실제 실행 중인 코어 완전히 재시작하기
Mihomo v1.19.33 정식 릴리스 기록에는 수정 커밋 349af19가 명시되어 있습니다. 해당 태그의 listener/shadowsocks/tcp.go는 Close() 시작 부분에서 closed를 먼저 설정한 뒤 리스너를 닫으므로, 연결 수락 루프가 종료 오류를 만나면 빠져나옵니다. 이는 종료 처리 수정이며, CPU 사용 상한을 낮추거나 노드 지연 시간 측정을 바꾸는 조치가 아닙니다.
수정 사항을 실제 실행 인스턴스에 반영하기
원래 프로젝트가 지원하는 안정 업데이트 방식 사용하기
코어를 직접 쓰는 경우 MetaCubeX/mihomo의 정식 릴리스에서 운영체제와 아키텍처에 맞는 버전을 선택하세요. 그래픽 클라이언트는 해당 프로젝트가 지원하는 앱 또는 코어 업데이트 절차를 따르고, 서비스 디렉터리의 바이너리를 임의로 덮어쓰지 마세요.
업데이트에 349af19가 실제로 포함되었는지 확인하기
이 글에서 확인한 정식 수정 버전은 v1.19.33입니다. FlClash v0.9.2 변경 기록에는 Mihomo v1.19.33이 포함되었다고 명시되어 있어 근거가 있는 예로 들 수 있습니다. 다른 클라이언트와 코어 분기는 각자의 기록을 따로 확인해야 하며, 화면에 표시된 버전 번호만 비교해서는 안 됩니다.
기존 인스턴스를 정상 종료한 뒤 업데이트된 인스턴스 시작하기
설정과 리소스 사본을 보관한 채 앱이나 서비스 안내에 따라 정상적으로 재시작하세요. 기존 인스턴스가 종료되었는지, 새 인스턴스의 시작 로그에 예상한 코어가 표시되는지 확인합니다. 이전 프로세스에 남은 루프가 설정 파일만 바꿨다는 이유로 사라졌다고 판단해서는 안 됩니다. 파일을 업데이트했더라도 기존 프로세스가 종료되지 않았다면 수정이 실제 실행에 반영됐다고 볼 수 없습니다.
mihomo -vmihomo -v는 지금 호출된 프로그램의 버전을 보여 주며, PATH에 있는 다른 동명 파일일 수 있습니다. 실제 서비스나 클라이언트가 쓰는 코어와 일치해야 합니다. 관리형 코어는 프로젝트가 제공하는 버전 정보와 시작 로그를 우선 확인하고, 버전을 조회하려고 내부 프로그램을 억지로 추출하지 마세요.
유휴 사용률, 이후 재로드와 실제 연결을 모두 확인하기
같은 장치, 같은 설정, 비슷한 백그라운드 활동 조건에서 완전 재시작 전후의 Mihomo 프로세스 사용률을 비교하세요. 먼저 이 인스턴스를 거치는 테스트 트래픽을 잠시 멈추고 유휴 상태를 관찰한 다음 실제 사용을 재개합니다. 시작 순간이나 실제 트래픽이 있을 때의 최대 사용률을 리스너 종료 후 계속 도는 루프와 혼동해서는 안 됩니다.
수정이 실제 실행에 반영되어 있고 짧은 네트워크 중단이 허용되는 환경에서만 원래 필요했던 인바운드 변경이나 제거 및 복원을 진행하세요. 운영상 이런 재로드가 여러 번 필요하다면 매번 이후의 유휴 CPU 사용률을 기록하고, 관련 종료 횟수에 따라 더 높아지지 않는지 확인합니다. 횟수를 채우려고 구버전을 반복해서 켜고 끄거나 높은 부하를 만들 필요는 없습니다.
검증 결과
- 실제 실행 코어에 349af19가 포함되어 있고 기존 인스턴스가 종료되었는지 확인합니다.
- 테스트 트래픽을 멈춘 뒤 코어 사용률이 기존의 정상 유휴 상태와 비슷해지고 루프가 계속 돌지 않는지 확인합니다. 다른 사람의 CPU 백분율을 그대로 적용하지 않습니다.
- 이후 실제로 해당 인바운드를 닫거나 바꿔야 할 때 같은 지속적 사용률이나 회차별 누적이 다시 나타나지 않는지 확인합니다.
- 필요한 인바운드를 복원한 뒤 기존의 허용된 클라이언트가 다시 연결해 실제 HTTPS 요청을 완료하고, 규칙과 아웃바운드 및 연결 기록이 원래 설계와 일치하는지 확인합니다.
- 시스템 프록시나 TUN은 기존 용도로만 복원합니다. 종료하거나 비활성화한 뒤에도 장치가 미리 기록해 둔 네트워크 상태로 돌아가는지 확인합니다.
이 사이트는 실제 클라이언트, 라우터나 서버에서 이 글의 문제를 재현하지 않았으며, 성능이 특정 배수로 향상되거나 CPU를 전혀 사용하지 않을 것이라고 보장하지 않습니다. 이 점검 절차는 공식 결함 보고, 고정 소스와 수정 기록을 근거로 만들었습니다. 실제 네트워크, 다른 높은 사용률 원인과 클라이언트 통합은 별도로 검증해야 합니다.
문제가 남으면 작동하던 상태로 복구하고 최소한의 정보로 제보하기
업데이트 후 프로그램이 열리지 않거나 인바운드에 연결할 수 없거나 설정이 호환되지 않으면 첫 오류와 현재 사본을 저장하고 더 이상 재로드하지 마세요. 프로젝트가 지원하는 방식으로 미리 작동을 검증한 프로그램 버전과 그에 맞는 설정, 외부 리소스를 복원합니다. 새 프로그램과 이전 프로그램이 유일한 데이터 디렉터리를 함께 쓰지 않게 하고, 시스템 프록시와 TUN도 원래 기록에 따라 작동 가능한 상태로 복원하세요.
이전 버전에는 이 결함이 남아 있을 수 있으므로 되돌리기는 임시 대응일 뿐 수정 완료가 아닙니다. 문제가 있는 인바운드를 잠시 꺼야 한다면, 여기에 의존하는 연결과 관리 접속 경로를 먼저 확인하세요. 해당 인스턴스를 정상 종료한 뒤 작동을 검증한 설정을 사용해야 합니다. 여전히 루프가 도는 기존 프로세스에서 항목만 지우고 핫 리로드를 계속하지 마세요.
문제가 다시 생기면 프로젝트에 운영체제와 아키텍처, 실제 실행 코어, 인바운드 유형과 cipher, 종료가 발생한 구체적인 작업, 같은 조건의 유휴 CPU 추이, 완전 재시작과 이후 재로드의 차이를 제공하세요. 이런 전제가 없으면 원인 미상으로 남겨 두고, 높은 CPU 사용률을 모두 #3314 때문이라고 단정하지 않습니다. 공개 자료에는 재현에 필요한 최소한의 관계와 민감 정보를 지운 오류만 남기고, 전체 구독이나 비밀번호를 올리지 마세요.
