#요약
개발하다보면 다양한 문제를 마주하게 되는데 여전히 그 접근방식과 해결 과정에 부족함을 느낀다.
어떤 한 기능을 개발을 하더라도 다양한 요소가 쌓이고 조립되어 어떤 '동작'을 만들어 낸다.
비유가 적절할 지 모르겠지만 어떤 동작이 완성되기 까지 피라미드 처럼 핵심 요소 - 중간 요소 - 끝점 요소 로 나눌 수 있겠다. 비유를 하자면 프로그램에서의 DB 연결 문자열이나 DB를 호출하는 코드라던가, 이런 것들을 끝점 요소라 한다라면, 핵심요소는 그 요청을 처리하는 DB 서버라고 할 수 있겠다.
이 때, 문제가 발생했을 때, 이 끝점 요소에서만 문제의 원인을 찾으려고 한다면 불필요한 시간이 소요될 수 있다. 가령 테이블에 4바이트의 emoji가 안 들어가는 이유를 연결문자열에서 찾으려고 이런 저런 옵션을 추가해 본다든가 해보았자 SQL 서버에서 받을 수 있는 건 3바이트가 최대라면, 문제는 영원히 해결할 수 없는 것이다. 그래서 유의미한 방식은 바로 이 끝점의 끝에서부터 핵심요소로 거슬러 올라가 보는 것이다. 다만, 끝점인 프로그램의 Try ~ Catch 구문에서 아래와 같은 오류를 마주쳤다면, string이라는 문자를 보고 프로그램의 문자열을 살펴볼 것인가.
Incorrect string value: 'xF0x9FxABx96 ' for column
혹은 이 오류가 WorkBench에서 쿼리를 날렸을 때도 동일하게 발생하는지 직접 이모지를 넣은 SQL구문을 실행해 보겠는가.

결론부터 말하면 워크벤치에서도 동일한 오류가 났고, 프로그램의 오류가 아니라 SQL 서버 설정의 문제였다라는 점이다.

문제의 원인을 찾아 올라갈 필요없이 바로 이 핵심요소에서 문제의 원인을 찾을 때 의외로 금방 해결되기도 한다.


# Case : emoji to DB
게시글에 🙏이런 Emoji를 넣고 싶었는데 프로그램에서 아래와 같은 오류메시지를 뱉었다.
Incorrect string value: 'xF0x9FxABx96 ' for column
원인을 분석해보았다. 그때 당시 내가 관리 중인 MySQL 서버는 utf8 형식으로 설정되어 있었다.
utf8은 4(1~4)바이트까지 저장되는 가변 데이터 구조이지만 MySQL의 경우 3바이트로 개발이 되었다.
때문에 최근에 사용되는 4바이트 문자열인 Emoji는 저장할 수가 없는 것이다.
그래서 MySQL에서도 이 점을 인지하고 4바이트 UTF8을 저장할 수 있는 문자 집합인 utf8mb4가 추가하였다. (MySQL 5.5.3)
현재 서버에서 돌아가고 있는 MySQL의 설정을 모두 utf8mb4로 변경하였지만 이상하게 같은 오류가 나서 다시 칼럼별로 데이터타입을 살펴보니 여전히 utf8로 설정되어 있는 칼럼들이 있었다.
서버의 sql config 파일을 수정한다고 해서 기존 칼럼의 데이터 타입도 함께 바뀌는 것이 아니었다.
그래서 이모지를 쓰고 싶은 칼럼의 경우 utf8mb4로 칼럼의 charset을 바꿔주었다.

P.S.
서버 설정인 지 모르고 프로그램의 연결 문자열에 옵션을 추가하는 등 삽질을 했는데 정확한 원인을 파악하지 못 할 경우 이런 삽질이 발생한다ㅜㅜ

#Case : Excel 조작
로컬 환경에서 리포트 프로그램을 개발한 적이 있다.
DB에서 데이터를 받아와서 엑셀로 내보내는 프로그램이었다.
C#에서는 interop 라이브러리를 이용해서 손쉽게 엑셀을 조작할 수 있다.(그 밖에 C#에는 자바에서는 느낄 수 없는 Datatable 클래스, LINQ 등 짜릿한 요소들이 있지만 아무도 알아주지 않는다..그렇다. 우리나라에서 C#은 이상하게 인기가 없다.) 로컬에서 개발할 당시 템플릿 파일을 만들고 그 템플릿 파일에 데이터를 떨궈주는 식으로 개발했는데 해당 템플릿 파일은 오피스 2019 버전으로 만들었었다. 그리곤 서버에 프로그램을 올리고 엑셀을 생성하려고 보니 오류가 나는 것이었다.
원인을 분석해보니 서버에 설치된 엑셀 버전은 2010이었다. 로컬에서는 프로그램이 2019버전에 호환되는 COM 라이브러리인 Microsoft Office 16.0 Object Library로 빌드됐었다. 이걸 2010버전에 호환되도록 하기 위해 프로그램을 Microsoft Office 14.0 Object Library로 재빌드해서 배포해도 오류가 났다. 또 다시 살펴보니 2019버전에서는 작동하는 특정 함수나 디자인이 2010버전으로 여니 오류가 나고 있었다. 문제가 되는 수식이나 디자인을 제거하고 2010버전으로 맞춰줬다. 마침내 서버 환경에 맞게 로컬 환경을 다 셋팅하고 다시 빌드 후 배포하고 나서야 프로그램이 정상적으로 동작하였다.

비슷한 맥락으로 쿠버네티스도 이런 불편함 때문에 생겨난 것이 아닐까싶다.

쿠버네티스의 개념은 이 유튭을 보면 동화로 풀어서 쉽게 설명하고 있다.

배댓을 보면 얼마나 쉽게 설명하고 있는지 짐작 할 수 있다



#Case : 버전 호환 오류

4바이트 emoji를 사용하기 위해 MySQL 서버의 charset을 utf8mb4으로 마이그레이션 한 후 어느 순간 프로그램에서 에러가 발생했었다.
An System.Collections.Generic.KeyNotFoundException “The given key was not present in the dictionary

이 오류가 나타나는 이유는 예전 버전의 MySQL Connector/NET 버전일 경우 나타나는 것으로 확인했다. 예전 커넥터(정확히는 6.0.8, 6.1.6, 6.2.5, 6.3.6 버전)의 경우 utf8mb4와 같은 charset이 key로 지정되어 있지 않아 맵핑 오류가 발생하는 것으로 보인다. 실제로 디버깅을 타보니 커넥션까지는 문제 없었는데 utf8mb4 캐릭터셋을 사용하고 있는 테이블에서 데이터 fetch를 시도할 때 오류가 터졌다. 이 문제는 간단히 커넥터의 버전업을 하여 해결할 수 있었다. 참고

참고로 4byte 이모지와 관련해서는 NHN Cloud에서도 비슷한 고민을 한 바 있으니 참고하길 바란다.

-

#Case : 로컬과 서버의 차이
개인프로젝트 중 하나로써 SMS 서비스 API를 이용하여 문자 알리미 서비스를 구축한 적이 있었다.
해당 SMS서비스의 기술문서를 보고 구현을 모두 마치고 로컬에서 앱을 돌리니 정상적으로 문자 송신이 되고 휴대폰에 문자 수신이 되는 것을 확인했다. 운영중인 개인 윈도우 서버에 해당 콘솔앱을 배포했고, 운영중인 타서비스를 통해 간접 호출될 수 있도록 설정하였다. 하지만 분명 해당 앱을 실행시키는 명령구문이 문제 없이 동작하는데 문자가 안 오는 것이었다. 어떤 오류 메시지도 없이.


해당 실행파일이 배포된 폴더에 IIS의 접근 권한이 없어서 그런 것인가 하여 권한도 모두 확인했고 배포 서버와 로컬 환경의 중요한 차이가 있는지까지 모두 확인했지만 별다른 문제를 확인하지 못 했다.
C#의 Process 클래스의 start함수를 이용해서 해당 프로그램을 실행하도록 설정해 두었었는데, Process 클래스에 대한 공식 기술 문서에서 '프로세스에 대한 액세스를 제공하고~' 문장을 읽다가 불현듯 생각이 스쳐 지나갔다.
"결국 이 클래스도 컴퓨터의 자원에 접근해서 요청을 하는 것일진데, 문제가 있다면 실제로 콘솔 프로그램을 클릭하여 실행해도 문제가 있지 않았었을까?"
라는 생각에 콘솔 응용 프로그램 exe 파일을 직접 클릭하여 실행시켜 보았지만 역시나 응용프로그램이 실행만 될 뿐 나머지 동작을 하지 않았다. 해당 이슈는 known issue로 여러 해결책이 나와있었지만 우선은 서버 재부팅을 한 뒤 다시 콘솔앱을 실행시키니 정상 동작하게 하였다. 그 뒤 서비스를 통해 Process.start 함수로 간접 호출해도 정상 동작을 확인하였다.


이번 오류 해결 과정에서 도움이 됐던 건 이전에 엑셀 버전 호환 문제를 해결한 경험이 컸던 것 같다.

이 오류를 해결하면서 느낀 건 문제를 빨리 해결하는 방법 중 하나라고 한다면 역시나 많은 개발을 통해 여러 문제를 해결한 경험이 쌓이는 것이 아닐까 하는 생각이 들었다. 문제를 해결한 다양한 경험이 있다면 한 문제에 대해 다양한 각도에서 접근할 수 있게 된다.그리고 스스로 문제를 해결한 경험들은 마치 고민의 지구력을 키워주는 것 같은 느낌이 든다. 끈질기게 문제를 풀기 위해 고민한 경험들은 생각의 지구력을 높여준다.