대충 서론적으로 표현하자면 EMMA 는 인포뱅크에서 만든 문자메세지 발송 서비스이다. AWS aurora RDS 8.0 으로 버전업그레이드를 하게 되면서 여러가지 불편한 사항이 많았는데, 특히 이번 문제는 추가적으로 전체적인 시스템을 간과하지 못해서 일어났던 실수이다.
대충 moyamo 의 내부 instance를 모듈별로 나눠보자면 아래와 같은데
moyamo-rest (주로 API 에 대한 부분을 전반적으로 담당하고 있다.)
moyamo-tools (ElasticSearch 라던지, EMMA (Client), EMMA-Server, Scheduler 를 통합 담당한다.)
- 특히 이 친구의 경우 moyamo-schedule 인스턴스에서 모듈이 동시에 돌아가게 되는 경우에는 망할놈의 랭킹을 2배로 집계시킨다거나 하는 비정상적인 현상을 발현시킨다.
- 아직까지도 그 퇴사한 개발자들이 해당 인스턴스를 Deprecated 시키고 퇴역시키지 않고, History 조차 남기지 않아서 혼란을 주게 하는 이유는 아직도 파악할 수 없다.
뭐 등등의 인스턴스가 있지만 대충 이 정도로 포함해본다.
Information gathering
가장 의아했던것은, moyamo-tools 가 예전에 한번 말썽을 일으킨 적이 있기도 하고 Volume 확장의 문제가 있기도 했어서 재부팅이 한번 들어갔던 적이 있었다. (그 뒤로는 HA 구성을 잡았지만.)
그 뒤에도 이 안에 있던 EMMA 라는 문자 메세지 발송 서비스는 정상적으로 작동되고 있었는데, 언제인가부터 문자 메세지 발송 서비스가 정상적으로 작동하지 않았다.
아까 위에서도 써놨지만 이 EMMA 라는 놈의 구조는 총 2가지로 나뉘어져 있는데
EMMA-Server 라고 불리는 Server 와, 그냥 EMMA로 표시되어 있는 Client 로 나뉜다.
문제는 Server는 정상적으로 작동하고 있는데 (가끔 포트 부분에서 Duplicated 문제가 발생하긴 했지만) Client 에서 다음과 같은 에러를 뿜으면서 작동하지 않았다.
인스턴스 내의 syscheck 라는 shell 을 가동했을 시
ubuntu@ip-172-31-40-155:~/workspace/emma$ ./syscheck
DB[jdbc:mysql://moyamo-product.cluster-c7mmfvbcxzve.ap-northeast-2.rds.amazonaws.com:3306/emma_db?useUnicode=true&noAccessToProcedureBodies=true] Check [NOK]
ib.frame.exception.DBException: Unknown initial character set index '255' received from server. Initial client character set can be forced via the 'characterEncoding' property.||Unknown initial character set index '255' received from server. Initial client character set can be forced via the 'characterEncoding' property.
at ib.emma.db.GDBConnector.getConnection(GDBConnector.java:159)
at ib.emma.main.DBCheck.connect(DBCheck.java:75)
at ib.emma.main.SysCheck.main(SysCheck.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.exe4j.runtime.LauncherEngine.launch(Unknown Source)
at com.install4j.runtime.Launcher.main(Unknown Source)
java.sql.SQLException: Unknown initial character set index '255' received from server. Initial client character set can be forced via the 'characterEncoding' property.
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)
at com.mysql.jdbc.Connection.configureClientCharacterSet(Connection.java:2412)
at com.mysql.jdbc.Connection.initializePropsFromServer(Connection.java:4139)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2789)
at com.mysql.jdbc.Connection.<init>(Connection.java:1555)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at ib.emma.db.GDBConnector.getConnection(GDBConnector.java:155)
at ib.emma.main.DBCheck.connect(DBCheck.java:75)
at ib.emma.main.SysCheck.main(SysCheck.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.exe4j.runtime.LauncherEngine.launch(Unknown Source)
at com.install4j.runtime.Launcher.main(Unknown Source)
-----------------------------
log4j:WARN No appenders could be found for logger (ib.emma.db.GDBConnector).
log4j:WARN Please initialize the log4j system properly.
이 로그에서 저 오류는
은 MySQL 클라이언트 드라이버와 서버 간의 문자셋 호환 문제에 기반한다. 구체적으로는, JDBC 드라이버가 서버에서 보낸 문자셋 인덱스 255를 인식하지 못해 생기는 오류다.
해결 방법으로는 아래와 같은 접근이 가능하다.
✅ 1. JDBC URL에 characterEncoding 추가
JDBC 연결 문자열에 characterEncoding=UTF-8 또는 useUnicode=true&characterEncoding=UTF-8을 명시적으로 추가
- 이미 해당하는 경우에는 EMMA 에 대해서 잘 아는 것은 아니지만 EMMA 가 불러다 사용하는 db.cnf 파일 안에 정의가 되어 있는 것을 확인할 수 있었다.
정확하게는 character Set은 EUC-KR 을 사용중이였다. 해당 부분을 바꾸면 안되는 이유는 아마도 추가적으로 통신하는 인포뱅크의 내부 시스템이 EUC-KR을 사용하고 있는 것을 생각해볼 수 있을 것 같다.
✅ 2. JDBC 드라이버 버전 확인 및 교체
이 문제는 구형 MySQL JDBC 드라이버에서 종종 발생한다. 드라이버를 최신 버전으로 교체해야 한다.
- 예를 들어 mysql-connector-java-3.x 또는 5.1.x를 사용 중이라면, 8.0.x 이상으로 교체
- 이 부분에서 가장 크게 의심했던 것이 Aurora RDS 에 대한 버전 업그레이드 이슈와 동일 선상에 있다고 판단했다. 생각해보면 Aurora RDS의 버전 업그레이드 이후에 moyamo-product(REST) 쪽은 전부다 수정했지만, EMMA 쪽에 대해서는 내가 손댈 수 있는 것을 생각해본 적이 없기에 (정확히는 몰랐다.) 라이브러리 업데이트가 필요하다고 생각했다.
다만 추가적으로 생각했던 부분은 해당하는 EMMA 에 대해서 직접적으로 컴파일을 할 수 없는 상황이기에 lib 에 추가하고 클래스패스 내에서 갱신하는 방법을 고려했다.
✅ 3. MySQL 서버 설정 확인
MySQL 서버의 문자셋 설정이 너무 생소한 설정일 수 있을 가능성.
확인해 보니 다음과 같았다.
역시 나의 감대로 버전 이슈가 매우매우 눈에 들어오는 것이 아주 강한 냄새를 날려주고 있었다.
진격의 시작
################################################################################
#------------------------------------------------------------------------------#
# Emma Database Configuration File #
# EMMA Database ȯ°æ ¼³Á¤ ÆÄÀÏ #
# ÆÄ ÀÏ ¸í : db.cf #
#------------------------------------------------------------------------------#
# NOTE: ÀÌ ÈÀÏÀ» ¼öÁ¤ÇÏ°í ¹Ý¿µµÇ±â¸¦ ¿øÇϸé EMMA¸¦ »õ·Î ±âµ¿ÇØ¾ß ÇÑ´Ù. #
#------------------------------------------------------------------------------#
################################################################################
#*******************************************************************************
# Database Connection Information
#*******************************************************************************
#-------------------------------------------------------------------------------
# ¿¬°áÇÒ DBMS °³¼ö
#-------------------------------------------------------------------------------
db.count = 1
#-------------------------------------------------------------------------------
# µ¥ÀÌÅͺ£À̽º ¿¬°áÀ» À§ÇÑ ¼³Á¤
# (db0.type : 1-Oracle, 2-MSSQL, 3-MySQL, 6-DB2, 7-Tibero, 8-Maria, 9-Sybase)
#-------------------------------------------------------------------------------
db0.type = 3
db0.driver = org.gjt.mm.mysql.Driver
#db0.url = jdbc:mysql://172.27.218.169:3306/emma_db?useUnicode=true&noAccessToProcedureBodies=true
db0.url = jdbc:mysql://moyamo-product.cluster-c7mmfvbcxzve.ap-northeast-2.rds.amazonaws.com:3306/emma_db?useUnicode=true&noAccessToProcedureBodies=true
db0.charset = EUC-KR
db0.monum =
이게 대충 해당하는 내용의 일부인데, 딱 보면 알겠지만 드라이버가 굉장히 구식 버전을 사용하고 있다. 해당 드라이버는 2002년에 단종된 드라이버인데, 이걸 아직까지 쓰고 있었다는게 좀 많이 놀라운 부분이였다.
해당하는 부분을 다음과 같은 드라이버 클래스로 변경해줬다.
db0.driver = com.mysql.cj.jdbc.Driver
dbcheck
이후에 dbcheck 라고 되어있는 shell 파일을 실행했다. (내용도 다 까본건 안비밀)
ubuntu@ip-172-31-40-155:~/workspace/emma$ ./dbcheck
ib.frame.exception.DBException: com.mysql.cj.jdbc.Driver||com.mysql.cj.jdbc.Driver
at ib.emma.db.GDBConnector.getConnection(GDBConnector.java:157)
at ib.emma.main.DBCheck.connect(DBCheck.java:75)
at ib.emma.main.DBCheck.main(DBCheck.java:267)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.exe4j.runtime.LauncherEngine.launch(Unknown Source)
at com.install4j.runtime.Launcher.main(Unknown Source)
java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver
at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at ib.emma.db.GDBConnector.getConnection(GDBConnector.java:154)
at ib.emma.main.DBCheck.connect(DBCheck.java:75)
at ib.emma.main.DBCheck.main(DBCheck.java:267)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.exe4j.runtime.LauncherEngine.launch(Unknown Source)
at com.install4j.runtime.Launcher.main(Unknown Source)
-----------------------------
log4j:WARN No appenders could be found for logger (ib.emma.db.GDBConnector).
log4j:WARN Please initialize the log4j system properly.
예상은 했지만 못찾는 문제가 발생했다. 당연히 구식 드라이버를 명시해주고 있었으니, 컴파일을 할 당시에 구식 드라이버를 포함시키는 컴파일을 해서 라이브러리 안쪽에 구식으로 올라가 있을 것이 분명했다.
drwxrwxr-x 2 ubuntu ubuntu 4096 Sep 2 2020 .
drwxrwxr-x 13 ubuntu ubuntu 4096 May 23 09:35 ..
-rw-r--r-- 1 ubuntu ubuntu 1627539 Sep 2 2020 bcprov-jdk16-138.jar
-rw-r--r-- 1 ubuntu ubuntu 121757 Sep 2 2020 commons-dbcp-1.2.2.jar
-rw-r--r-- 1 ubuntu ubuntu 261809 Sep 2 2020 commons-lang-2.4.jar
-rw-r--r-- 1 ubuntu ubuntu 87077 Sep 2 2020 commons-pool-1.4.jar
-rw-r--r-- 1 ubuntu ubuntu 155858 Sep 2 2020 cubrid_jdbc.jar
-rw-r--r-- 1 ubuntu ubuntu 2833724 Sep 2 2020 db2jcc.jar
-rw-r--r-- 1 ubuntu ubuntu 1015 Sep 2 2020 db2jcc_license_cu.jar
-rw-r--r-- 1 ubuntu ubuntu 7192 Sep 2 2020 dbguard_mob.jar
-rw-r--r-- 1 ubuntu ubuntu 168644 Sep 2 2020 eb-standard-billing-1.2.15.jar
-rw-r--r-- 1 ubuntu ubuntu 910690 Sep 2 2020 emma-3.4.12.jar
-rw-r--r-- 1 ubuntu ubuntu 28067 Sep 2 2020 emma-bridge-alerter-1.0.0.jar
-rw-r--r-- 1 ubuntu ubuntu 34147 Sep 2 2020 emma-bridge-custom-emma1-1.0.0.jar
-rw-r--r-- 1 ubuntu ubuntu 62642 Sep 2 2020 emma-bridge-custom-emma3-1.0.0.jar
-rw-r--r-- 1 ubuntu ubuntu 679 Sep 2 2020 emma-was-1.0.0.jar
-rw-r--r-- 1 ubuntu ubuntu 481220 Sep 2 2020 google-collect-snapshot-20080820.jar
-rw-r--r-- 1 ubuntu ubuntu 190418 Sep 2 2020 gson-2.2.4.jar
-rw-r--r-- 1 ubuntu ubuntu 227991 Sep 2 2020 ibframe-1.1.4.jar
-rw-r--r-- 1 ubuntu ubuntu 447867 Sep 2 2020 ibpdu-1.1.3.jar
-rw-r--r-- 1 ubuntu ubuntu 301946 Sep 2 2020 jtds-1.2.8.jar
-rw-r--r-- 1 ubuntu ubuntu 391834 Sep 2 2020 log4j-1.2.15.jar
-rw-r--r-- 1 ubuntu ubuntu 287022 Sep 2 2020 msbase.jar
-rw-r--r-- 1 ubuntu ubuntu 67115 Sep 2 2020 mssqlserver.jar
-rw-r--r-- 1 ubuntu ubuntu 59074 Sep 2 2020 msutil.jar
-rw-r--r-- 1 ubuntu ubuntu 540852 Sep 2 2020 mysql-connector-java-5.0.8-bin.jar
-rw-r--r-- 1 ubuntu ubuntu 1555682 Sep 2 2020 ojdbc14.jar
-rw-r--r-- 1 ubuntu ubuntu 448141 Sep 2 2020 postgresql-8.3-604.jdbc3.jar
-rw-r--r-- 1 ubuntu ubuntu 475580 Sep 2 2020 postgresql-8.3-604.jdbc4.jar
-rw-r--r-- 1 ubuntu ubuntu 22338 Sep 2 2020 slf4j-api-1.5.6.jar
-rw-r--r-- 1 ubuntu ubuntu 9678 Sep 2 2020 slf4j-log4j12-1.5.6.jar
-rw-r--r-- 1 ubuntu ubuntu 583286 Sep 2 2020 sqljdbc.jar
-rw-r--r-- 1 ubuntu ubuntu 584207 Sep 2 2020 sqljdbc4.jar
-rw-r--r-- 1 ubuntu ubuntu 725602 Sep 2 2020 tibero4-jdbc.jar
-rw-r--r-- 1 ubuntu ubuntu 137211 Sep 2 2020 unisqljdbc3_0_7.jar
1주일 굶은 곰마냥 무언가 단서를 찾아서 찾아 해매다가 꿀단지를 발견했다. 그리고 다음과 같은 조치를 취해줬다.
일단 멀쩡하게 살고있던 녀석은 backup 본으로 밀어넣어주고
mv ~/workspace/emma/lib/mysql-connector-java-5.0.8-bin.jar ~/workspace/emma/lib/mysql-connector-java-5.0.8-bin.jar.bak
최신 드라이버를 낼름 가져와서 클래스패스 내에서 다시 연결시켜줬다.
cd ~/workspace/emma/lib
wget https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.3.0/mysql-connector-j-8.3.0.jar
ln -s mysql-connector-j-8.3.0.jar mysql-connector-java.jar
cd ~/workspace/emma
java -cp ".:./lib/*" ib.emma.main.DBCheck
UTF-8을 못알아 든는 친구가 존재했다.
ubuntu@ip-172-31-40-155:~/workspace/emma$ java -cp ".:./lib/*" ib.emma.main.DBCheck
log4j:WARN No appenders could be found for logger (ib.emma.db.GDBConnector).
log4j:WARN Please initialize the log4j system properly.
Console 한글 테스트
Driver Version: mysql-connector-j-8.3.0 (Revision: 805f872a57875f311cb82487efcfb070411a3fa0)
Server Version: 8.0.32
DB connection check is completed.
DB privileges check is completed.
query : call sp_em_smt_tran_select(?, ?, ?, ?, ?);
55987 / 01066814446 / [???] ???? 942677? ??? ???.
55988 / 01066814446 / [???] ???? 282570? ??? ???.
55989 / 01025617240 / [???] ???? 874947? ??? ???.
55990 / 01031871559 / [???] ???? 380585? ??? ???.
55991 / 01027772119 / [???] ???? 821225? ??? ???.
55992 / 01027772119 / [???] ???? 940578? ??? ???.
55993 / 01027772119 / [???] ???? 558572? ??? ???.
55994 / 01037710374 / [???] ???? 278919? ??? ???.
55995 / 01033570189 / [???] ???? 674359? ??? ???.
55996 / 01033570189 / [???] ???? 763137? ??? ???.
55997 / 01033570189 / [???] ???? 360590? ??? ???.
55998 / 01039008813 / [???] ???? 720691? ??? ???.
55999 / 01039008813 / [???] ???? 542344? ??? ???.
56000 / 01039008813 / [???] ???? 463278? ??? ???.
56001 / 01039008813 / [???] ???? 905421? ??? ???.
56002 / 01047992956 / [???] ???? 351778? ??? ???.
56003 / 01047992956 / [???] ???? 929949? ??? ???.
SMSMT check is completed.
일단 데이터베이스 체크는 신박하게 잘 돌아갔기 때문에, 돌아갈 것으로 예상하고 있었는데 db.cnf 파일 안에 EUC-KR 을 UTF-8 로 바꿔주었더니 문자를 받을 때에 한글이 ??? 로 오는 문제가 발생됬다.
따라서 EUC-KR로 재변경을 하는 부분이 있었다.
추가적으로 shell로 만들어진 파일이 2가지가 존재했는데
emma 와
emmasvc 라는 파일 이였다.
emma의 경우 데몬화시키지 않은 파일로써, 해당 쉘 파일을 실행시키면 컴파일된 프로그램이 프로세스가 되어 가동되고 화면에 그대로 보여지는 파일을 작성해 놓은 것이였다.
추가적으로 emmasvc 의 경우 start, stop, status 인 추가적인 options 를 포함하고 있는데, start를 시키면 nohup 이 걸리면서 데몬화가 되어지고 서비스로 가동되게 되어 있다.
- 다만 왜때문에 로그가 안남았는지는 모르겠으나 log4j에 대한 적절한 설정이 없었던 것 같은 느낌이 스물스물?
결론 = 문자메세지 잘 오게 정상적으로 잘 고쳤다.
'Java' 카테고리의 다른 글
Method: projects.messages.send (1) | 2024.10.01 |
---|---|
FCM HTTP v1 Firewall Port bound (4) | 2024.09.30 |
MyBatis Mapper Setting (0) | 2024.09.24 |
Class Verify (0) | 2024.09.23 |
Java - Json 과 Gson 이란? (0) | 2024.09.23 |