아니요, 연결 문자열로 VPN 터널을 시작할 수 없습니다
VPN은 운영 체제나 클라이언트가 소유하며 드라이버의 것이 아닙니다. 먼저 터널을 올리고, netonly로 도메인 자격 증명을 전달한 다음, 커서의 왕복을 확인하십시오.
개발자들은 여전히 연결 문자열, JDBC URL, tnsnames.ora 항목이 VPN을 선택하는 위치를 찾고 있다. 그런 위치는 없다. 터널은 가상 어댑터를 등록하는 운영 체제나 공급업체 클라이언트가 수립하며, 그 위의 모든 데이터베이스 라이브러리는 그 결과로 생기는 소켓 계층을 사용한다. 연결 문자열은 호스트, 포트, 자격 증명을 지정할 뿐이고, 어휘는 그게 전부다.
속설: 연결 문자열이 터널을 선택할 수 있다
드라이버는 호스트와 포트로 TCP 소켓을 연다. 터널을 올리는 API도, 터널 프로필 필드도, VPN 게이트웨이에 인증하는 방법도 없다.
그래서 경로만 있으면 도구들은 똑같이 동작한다. SSMS, DBeaver, Eclipse Data Tools, 평범한 sqlcmd는 모두 서버가 로컬 네트워크에 있는 것처럼 행동한다. 소켓의 관점에서는 실제로 그러하기 때문이다. 가상 어댑터가 데이터베이스 서브넷을 도달 가능하게 만들었고, 드라이버는 그 방법을 전혀 알지 못한다.
연결 문자열로 끊긴 터널을 고칠 수 없는 이유도 같다. 링크가 죽으면 드라이버는 시간 초과나 일반 네트워크 오류를 보고하고, 그것을 쿼리 문제로 취급하는 애플리케이션 코드는 영원히 잘못된 계층을 재시도한다.
드라이버가 실행되기 전에 터널을 올린다
공급업체나 네트워크 팀의 지침에 따라 운영 체제 수준에서 VPN에 연결하고, 그다음에 도구를 연다. 실제로는 드라이버가 호스트 이름을 해석하기 전에 데이터베이스 서브넷으로 가는 경로가 존재해야 한다는 뜻이다.
터널 감독은 애플리케이션 밖에 둔다. 링크를 스스로 올리려는 PHP나 Java 서비스는 특정 공급업체의 동작을 업무 코드에 새겨 넣고, 장애 조치가 일어날 때마다 애플리케이션 릴리스가 된다. 터널을 소유하고 지켜보고 다시 시작하는 감독자는 쿼리 경로와 별개의 관심사다.
드라이버를 탓하기 전에 경로를 확인한다. 호스트가 해석되지 않거나 셸에서 포트가 응답하지 않는다면 어떤 연결 문자열도 그것을 바꾸지 못한다.
속설: Windows 인증 실패는 경로가 끊겼다는 뜻이다
VPN을 통한 Windows 인증은 네트워크 장애처럼 보이는 오류로 자주 실패하지만 경로는 멀쩡하다. 계정이 다른 도메인에 속해 있고 노트북이 그 도메인에 가입할 수 없을 때는 데스크톱 세션의 ID 대신 명시적 자격 증명으로 클라이언트를 시작한다.
runas /noprofile /netonly /user:CORP\dbreader "C:\Program Files (x86)\Microsoft SQL Server Management Studio 18\Common7\IDE\Ssms.exe"/netonly 스위치는 그 자격 증명을 원격 인증에만 사용하게 한다. 연결 대화 상자를 믿는 대신 SELECT SUSER_SNAME()으로 서버가 실제로 무엇을 받았는지 확인한다. 서버 주소의 자격 증명을 Windows Credential Manager에 저장하는 방식은 SSMS에서는 동작하지만 다른 계정으로 실행되는 서비스에서는 항상 그렇지 않다고 보고되어 있으므로, 로그인을 바꾸기 전에 프로세스가 어떤 ID를 쓰는지 확인한다.
지연은 서버 측 커서를 시간 초과로 바꾼다
서버 측 커서는 데이터베이스에 결과를 보관하고 조금씩 가져오라고 요청하므로, 하나의 큰 결과가 수많은 작은 왕복으로 바뀐다. LAN에서는 저렴하다. 수십 밀리초의 추가 지연이 있는 터널을 지나면 같은 쿼리가 데이터를 거의 전송하지 않고도 명령 시간 초과를 넘길 수 있다.
클라이언트 측 커서로 바꾸거나, 페치 크기를 높이고 행을 일괄 처리하면 왕복 횟수가 줄어든다. 병목은 교환 횟수이지 회선의 공칭 속도가 아니므로, 처리량을 측정하면 오해하게 되고 왕복을 측정하면 그렇지 않다. 사용자가 실제로 가져오는 가장 큰 결과 집합으로 시험하고, 즉시 돌아오는 한 행짜리 쿼리로 시험하지 말라. 시간 초과가 이동만 하고 사라지지 않으면 명령 시간 초과와 페치 크기를 함께 올려 다시 측정한다.
같은 산수가 말 많은 ORM과 행마다 문 하나를 보내는 모든 클라이언트에 적용된다. 쿼리 계획이 좋고 전송량이 적다면, 데이터베이스를 조정하기 전에 네트워크 교환 횟수를 세라.
포트, 인스턴스, 로컬 필터를 확인한다
명명된 인스턴스는 동적 포트에서 수신하므로 1433이라고 가정하지 말고 포트를 확인한다. 기본 인스턴스에서는 해당 인스턴스의 SuperSocketNetLib 키 아래 TcpPort 레지스트리 값에서 읽을 수 있다. Oracle의 경우 tnsnames.ora의 호스트가 해석되는지, 주소가 응답하는지, 리스너 포트가 허용되는지 확인한다. 1521은 흔한 기본값일 뿐 보장은 아니다.
다음으로 터널 자체의 액세스 목록을 배제하고, 마지막으로 클라이언트와 서버가 같은 머신일 때도 연결을 막는 로컬 백신이나 호스트 방화벽을 배제한다. 구성을 바꾸기 전에 실패하는 단계를 기록하라. 이름 해석, TCP 도달성, TLS나 로그인은 각각 다른 메시지로 실패한다.
그 단계를 티켓에 적어라. 그렇지 않으면 다음 사람이 이 모든 것을 시작한 같은 연결 문자열 찾기를 반복하게 된다.