Bullshitting Blog

개소리하는 블로그

회고록 - 7. 성인식

탈진

라크로스 동아리 주장을 하는 사이 기계공학 복수전공도 시작했다. 수업시간이 너무 좋았다. 밤새며 과제를 해도 행복했다. 동아리의 그런 것들에서 자유로워질 수 있는 유일한 시간이었다. 결국 2016년 2학기에 중앙동아리로 인준하는데 성공하자 마자 긴장이 풀려 몸이 무너졌다. 혈뇨를 보기 시작하더니, 신기능이 떨어졌다. 중도 휴학을 했다. 무너지는게 당연한 일이었다. 맞지 않는 일을 하면서 학교생활 내내 긴장 상태로 지내는 것도 모자라, 안그래도 늦게 시작한 복수전공을, 학석사 연계과정으로 인해 초과학기가 제한된 상태에서 이수해내야 했기 때문이었다. 대학수학과 전공 역학수업과 설계를 동시에 들어야 하는 그런 식이었다. 그 와중에 그놈의 양심이 뭐라고, 족보를 보는 것은 스스로 절대 용납하지 못했다. 주에 3일씩 밤을 새는건 기본이고, 5일 연속으로 잠을 못자기도 했다. 그런 생활을 하면서 안 죽은 걸 감사히 여겨야 한다. 결국 학점관리에 실패하여 학석사 연계과정도 잘렸다.

몸이 어느정도 회복되고, 중앙동아리 인준 성공으로 주장도 넘겨줄 수 있게 되면서 장기간의 집권(?)으로 인해 하나도 정리되어 있지 않았던 동아리 업무를 문서화해서 일종의 인수인계 자료를 만들고 주장을 넘겨줬다. 그리고 이후부터는 밤샘을 가능한 피했다.

데드캣 바운스

어차피 학석사 연계도 잘렸겠다, 기계공학과 수업들을 그저 온전히 즐겼다. 수치해석 수업을 통해 프로그래밍에 흥미가 붙었다. 그런데 라크로스 경력이 아주 짧은 사람이 다음 주장을 맡게 됐다. 그래서 미국의 라크로스 훈련 드릴 공개본을 수집한 후 라크로스 훈련 계획을 작성하는 웹앱을 만들기로 했다. 그 목표를 가지고 2017년 여름, 코딩야학 2기를 수료했다. 반복적이고 불필요한 쿼리로 떡칠된 첫 작품이 탄생했다. 아 물론, 안쓴다. 그냥 재미로 만든게 되었다. 이후부터는 취미로 코딩을 하기 시작했다. 이것이 나중에 나에게 밥을 먹여줄 줄은 꿈에도 몰랐다. 혼자 계획표를 웹으로 작성해서 사용하기도 하면서, 소소한 프로젝트를 하며 실력을 갖춰나갔다.

새로운 꿈이 생겼다. Exoskeleton 로봇을 연구하는 것이었다. 그중에서도 군사용 근력증강 로봇에 관심이 있었다. 일단 이걸 하려면 대학원 진학은 필수라 생각했다. 하지만 난 대학원 생활을 모르므로, 한번 체험해 보기로 했다. 그래서 다짜고짜 KIST 인턴 연구원 채용공고를 보고 콜드메일을 하나 보냈다. 이런걸 연구하고 싶은데, 뭘 준비해 갈까요? 하고. 그 메일을 본 한 박사가 나에게 관심이 있으니 때가 되면 지원하라고 했다는 답을 받았다. 이후 졸업 직전, 인턴 지원 대상 자격이 생겼을 때 연구소에 지원했고, 합격했다. 기대에 부풀어 C언어도 미리 공부했다.

졸업 후 인턴 연구원으로 입사했다. 애석하게도, 내 연구 관심사와 관련없는 연구실에 채용되었다. 이름은 지능로봇연구단이지만, 연구실엔 로봇이 없었다. 그당시엔 소프트웨어 프로젝트를 하고 있었다. 내가 가고 싶었던 연구실의 박사가 해외에 체류하게 되었기 때문에 나에게 관심있는 다른 박사가 데려갔던 것이다. 설명을 들으니 재미는 있어 보여서 그냥 입사했다. 연구활동을 체험하는게 목적이기 때문이다.

좌절

결과는 대실패였다. 유저테스트를 하게 되었는데, 데이터 쿠킹을 유도했다. 정해진 논문의 내용에 들어갈 근거자료가 필요한 것이지, 테스트의 결과가 중요한게 아니었다. 박사들은 아웃라이어로 데이터를 제외한 후, 충분한 설명을 덧붙일 것이라 했지만, 이미 신뢰가 깨진 시점에서 난 시야가 좁아졌다. 내가 실행한 실험이고 내가 낸 통계이므로 책임은 나한테 있다. 나름의 발악으로, 실험설계를 바꾸고, 테스트 시나리오의 task를 바꾸고, 프로그램의 일부 알고리즘까지 개선해서 실제로 유의한 결과를 얻어내서 해결했다.

지금 생각해 보면 박사들은 실제로 데이터를 제외하더라도 충분한 설명을 덧붙이긴 했을 것이라 생각한다. 굳이 조작하지 않아도 밥벌이와 성과에 크게 문제는 없을 사람들이기 때문이다. 하지만 그 당시의 혈기왕성한 나는, 사회초년생부터 불의라 생각하는 일에 타협하면 돌이킬 수 없을 것이라 생각했다. 타협은 동아리를 위해 했던걸 마지막으로 하기로 결심했기 때문에, 물러서지 않았다. 책임질게 없는 개인은 무서웠다. 자르든가!

19년 9월, 인턴 계약이 만료되어 연구소를 나왔다. 난 바로 연구의 꿈을 완전히 접어버렸다. 그리고 취업활동을 하려던 나에게 다시금 브레이크가 걸렸다. 요로결석이 생긴 것이다. 모든 일에 집중이 되질 않았다. 오히려 다행이었다. 막연하게 세상에 내던져진 사람은, 키를 어느 방향으로 둬야 하는지 모르던 참이었다.

갭이어

잠시 푹 쉬는 사이, 연구계에 대한 분노는 줄어들었고, 이성적인 상태로 돌아왔다. 그리고 지금처럼 회고의 시간을 가졌다. 할 줄 아는 것, 할 수 있는 것, 배울 수 있는 것을 나열했다. 할 수 있는 것으로서 취미로 하고 있던 개발이 불쑥 튀어나왔다. 하지만, 고작 만들 줄만 아는 나에겐 전공생들이 가진 것들이 없었다. 해킹에 관심을 가지게 되었다. 배우기로 했다. 내일배움카드에 대해 알게 되었고, 이를 이용해 아싸리 모의해커 취업반 과정을 신청했다.

코로나가 창궐했다. 딱 취업반이 시작되는 그 때. 그 시기, 2020년 2월이었다. 인턴을 하며 모아둔 돈을 갉아먹으며 해킹을 배우면서 동생과 함께 살고 있었는데 입이 늘었다. 음력설을 지내기 위해 기차를 타러 집을 나섰는데, 박쥐같이 말라 비틀어진 검은 새끼 고양이 한 마리가 차 밑에서 튀어나와 동생을 부여잡더니 다리를 타고 올라가 품에 안겼다. 살려달라는 것이었다. 눈과 코는 어디서 얻어맞아서 부어 있었고, 털도 듬성듬성했다. 뭐 어쩌나. 살려달라는데 살려야지. 데려와서 치료를 하기 시작했다. 마침 자취방 주인도 예전부터 동물을 키워도 된다고 먼저 이야기했었다. 주인집 강아지가 너무 시끄러워서 일종의 민원방지책으로 그랬던 것 같다.

그 고양이는 검은 턱시도였는데, 목, 흉부, 복부, 뒷발에 흰 털이 나 있었다. 까치가 생각났다. 이름을 까치로 지었다. 공교롭게도 설연휴에 만났기 때문에 잘 지은게 되었다. 사실 강력하게 자라라는 의미로 코로나로 할까도 했는데 주변의 만류로 포기했다.

병원비는 월에 50만원씩 날아갔다. 치료와 함께 예방접종들도 빠짐없이 했다. 좀 있으니 피부병이 옮았다. 수의사에게 사람도 치료받았다. 오해는 마라. 사람이 진료를 받은건 아니고, 그냥 고양이 피부병 샴푸를 사람이 써도 효과 있다는 꿀팁 정도 얻었다. 어느정도 건강해진 후 중성화 시술도 이어서 했다. 자연에서 도태된 고양이는 그렇게 이기적 유전자의 미래를 포기당했다. 도심의 인간과 함께 살기 위해서는 어쩔 수 없다. 시골이었다면 안했을거다. 미안하다. 수컷인데 아직도 애기같은 목소리로 운다. 내시를 만들어 버렸다.

야생 적응기

까치 설날에 찾아온 까치의 활약에 힘입어 통장의 잔고는 빠르게 줄어들었다. 결국 취업반 마무리 단계에서 보안계열 취업을 포기하고 돈을 선택하게 만들었다. 보안계열은 초봉이 KIST 인턴보다도 낮다. 하지만 본격적인 면접철 직전에 선수를 치고 입사제의가 온 극초기 스타트업에서는 KIST 인턴을 경력으로 보고 상향된 연봉을 제시했다. 고양이를 키우려면 집도 나에게 필요한 것보다 더 큰 곳으로 구해야 하고, 사료, 모래 등 부가비용이 발생한다. 스타트업 조기취업으로 마무리했다. 그리고 이 선택은 돌고 돌아 옳은 선택이 되었다. 극초기인 만큼, IR도 함께 다니면서 여러 모습들을 보고, 세상이 어떻게 돌아가고 있는지 알게 되었다. 대표님도 사업이 처음이었다. 첫 직원이라 여러모로 잘해줬다. 일은 너무 쉬웠다. 주로 기계공학과에서 배웠던 것들을 이용했다. CAD로 목적을 달성할 수 있도록 구조를 설계하고 시뮬레이션하면서 최적화하고, 3D프린터로 시제품을 출력하고 가공하는 것이 내 주업무였다. 그 외 IR자료 작성, 시장조사, 동영상 편집, 홈페이지 디자인, 개발 등 여러 일들이 있었지만, 동아리 주장을 오래 하며 별의 별 일을 다 해봤기 때문에 엉성한 수준이더라도 내 선에서 다 처리할 수 있었다. 시제품의 구조나 기획 등이 정리되며 부품의 성능을 최적화할 회로개발자를 추가로 채용했고, 난 회로개발과, 대표님이 하시던 IR 발표, 정부지원사업 지원서 초안 작성, 세무, 회계를 제외한 모든 일을 했다. 그렇게 해도 하루에 4시간이면 내 일이 끝나버렸다. 주 업무인 시뮬레이션과 기구설계 부분에서 수학적 규칙을 찾으면 바로 코드를 작성해서 자동화해버렸기 때문이다. 오히려 그러는 바람에 다른 잡무에 할애하는 시간의 비중이 늘어났다. 지루하고 심심했다.

난 퇴근 후에 해킹을 계속 공부하고 있었다. Capture The Flag(CTF) 형식의 가상 해킹게임을 플래이했다. 그러다가 Offensive Security사의 OSCP 자격증 과정을 알게 되었다. 유명 모의해커 자격증이었다. 땄냐고? 놉. 수업만 신나게 듣고, 지금의 회사로 이직하는 바람에 취득은 못했다. 스타트업에서 일한 지 9개월 째, 지루함을 이기지 못하고 있던 찰나, 일산으로 이사를 가게 되었다. 이제 퇴근 후의 여유시간 따위 존재하지 않게 되었다. 난 진정 좋아하는 일을 직업으로 가지기로 결정하고 지금 회사로 이직했다. 고생길이 열렸다.

사이드프로젝트도 시작했다. 사이드비즈니스 플랫폼을 만드는 사이드프로젝트이자 사이드비즈니스였다. 실제로 사업화를 진행하고 있었다. 투자는 얼마나 받을 것인지, 지분과 수익은 어떻게 배분할지까지 함께 이야기했다. 투자는 가능한 최소로 받아 내부인의 지분을 높이고 최소 비용으로 빠르게 안정적인 매출을 내는데 주력해야 한다는걸 알게 되었다. 투자를 가능한 거하게 땡겨서 기업가치 높게 평가받고 수습은 이후에 하려는 요즘 스타트업들과는 좀 달랐다. 원격으로 일하면서 좀 더 정리된 방식으로 어떻게 일하는지도 알게 되었다. 솔직히 지금 우리 회사보다 훨씬 잘 굴러갔다. 일은 이렇게 해야 하는구나. 하지만 사람들 간의 온도차, 책임의식의 차이를 극복하지 못하고 지쳐갔다. 사이드였기 때문에 과감히 그만뒀다. 라크로스 - 회사 - 사이드프로젝트 순으로 우선순위를 가져가고 있었는데, 바빠진 라크로스 일정으로 체력적 부담이 생기니 그 상황을 더이상 버틸 수 없었다.

회고록 - 8. 정착

처음으로 소개한다. 크래프트테크놀로지스. 지금 내가 몸담고 있는 회사이다. 난 AI 강화학습 에이전트를 이용한 주문집행 소프트웨어를 주 라인업으로 가진, AI Trading Solution 부서의 개발팀에 있다. 입사 당시엔 AXE라는 이름으로 있었다. 도끼 아니다. 현재 3년을 넘겼다.

내가 입사할 때 이 회사는 30명 규모의 회사였다. 잠시후, 소프트뱅크에서 대규모 투자가 들어왔다. 인원이 80명으로 급증했다. 물론 우리팀은 예나 지금이나 비슷한 규모를 유지중이다. 회사에서 대형 프로젝트를 하기위해 팀이 신설되고 공격적인 채용이 진행됐던 것이다. 처음엔 기대했다. 그 대규모 프로젝트에서 우리팀은 나중에 이런걸 하고 있겠지. 물론 그 프로젝트는 실패했다. 우리 팀은 그냥 평온하게 하던거 하고 있다. 회사는 다시 대박을 칠 무언가를 기다리며 여러 시도들을 하고 있다.

우리 팀은 팀의 제품을 증권사에 납품하는 형식의 사업을 하고 있었다. 여타 기술기업들이 의례 그렇게 실수하듯, “좋은거 만들어두면 쓰겠지"라는 마인드가 좀 있었다. 제품과 니즈는 충돌했고, 우리에겐 “이럴거면 왜 AI를 도입하려는거지?”하는 불만이 좀 있었다. 하지만, 을은 갑이 원하는걸 해줘야 하니까, 일단 들어줬다. 결론부터 말하면 잘했다. 여기서 들이받았으면 제품은 영영 제자리걸음이었을 것이다. 강력한 성능의 못쓰는 물건으로.

제품은 현재 4.0버전까지 와 있다. 내가 입사할 당시는 1.0에서 2.0 버전으로 넘어가던 시기였다. 1.0의 성능에 만족한 고객사와 대형 프로젝트로 2.0을 기획하고 개발을 진행했다. 난 이 버전을 설치하고 세팅하는 시기에 입사했다. 해킹 공부로 얻은 인프라쪽 지식과 개발능력을 동시에 가지고 있었기 때문에 입사할 수 있었다. 딱 그런 사람이 필요한 시기였기 때문이다. 하지만 온보딩 시스템이 없는, 사수조차 없는 이 팀에서는, 프로그램이 뭘 하는 것인지 등 소개 문서 하나 없이 다짜고짜 일부 마이크로서비스의 코드를 분석하고 리펙터링하라는 지시가 내려왔다. 난 트레이딩에 대해서는 겉핥기 식으로 잠시 주식투자를 해본게 다였기 때문에, 프로그램이 뭘 하는지 이해하려니 막연하고 막막했다. 심지어 마이크로서비스 시스템은, 서비스의 목적을 더 알기 어렵게 만들었다. 삽질을 하기 시작했다. 그나마 설치 업무에 적응하는게 더 수월했다. 설치업무를 하면서, 시스템을 파악하여 코드베이스를 파악해나갔다.

2.0은 한가지 큰 과제가 있었다. 초대형이라는거다. B2B2C를 목표로 하고 있었다. 최신 개발 트렌드와 기술스택도 대거 도입했다. 2021년이었던 당시에 이미 Rust를 도입했고, 펄서를 메시지큐로 도입하고, 쿠버네티스를 도입하고, IaC도 하겠다며 helm과 Terraform까지 이용했다. 그것도 증권사의 폐쇄망 Cloud에서! 천재들의 세계는 엄청나군! 난 그저 그걸 내것으로 흡수하고, 그 원대한 계획을 실제로 실현해내는데 집중했다. 2.0 막바지에 갔을 땐, 모르는건 많지만 겁먹진 않는 개발자가 되어 있었다. 가장 비효율적인 곳에 들어왔기에 가능한 성장이였다. 이런 기회는 이제 주어지기 어려울 것이다. 회사는 더이상 이런 삽질을 기다려주지 않는다. 이제 성과를 내야 하는 시기이다. 나 또한 이런 개고생을 경험할 기회를 줄 생각은 없다. 버틸 확률이 10%일 것이다. 만든 사람들도 나중에 다 퇴사했을 정도니까. 진짜 중간에 별의 별 생각을 다했다. 무사히 넘겼으니까 이정도로 이야기할 수 있는 것이다. 기술이 어려운게 문제가 아니다. 설치 마무리 후 장애로 인해 매일같이 오는 긴급전화와, 긴급 출장업무가 문제였다.

초기 B2B2C로 기획되었던 프로젝트는 시간이 지나며 B2B로 축소됐다. 동시작업 10000건 목표는 없던 일이 되었다. 10000건을 감당하기 위해 만들어진 제품은 B2B에서 그냥 돼지가 되어버렸다. 심지어 먹이는 많이 먹는데 고기는 팔 곳이 없는 그런 돼지였다. 2.0 프로젝트의 주역들은 모두 퇴사했다. 충원은 이보다 덜했다. 프로젝트가 축소되었으니 당연한 수순이었다. 이후 잠시 팀을 맡던 팀장도 퇴사했다. 유지보수하는 입장에서 너무 힘들었다. 여기저기 함정이 도사리고 있고, 커다란 사이즈 만큼 버그도 많았다. 천재 개발자들이 만든 힙한 야심작은, 아무리 그들이 천재였어도 허점이 많았다. 당연하다. 버그 없는 프로그램은 없다. 매일 오전 카톡이 울리면 고객사 연락인가 하고 스트레스를 받으며 서비스를 안정시키기 위해 고군분투했다.

2.0의 주역들과 그 다음 팀장이 모두 퇴사하고, 팀장 제의를 강력히 거절했다. 동아리에서의 그 경험은 팀장직에 대한 본능적인 공포로 다가왔다. 다시는 그런거 안하기로 했다. 팀에서 조용히 계시던 시니어 개발자가 팀장이 되었다. 대신 나에게 많은 권한을 주셨다. 시니어 팀장님은 혼자 다른 언어를 쓰고 계셨기 때문이다. 당시 3.0 프로젝트가 진행중이었고, QA가 입사하며 버전 및 품질관리도 시작했다. 쓸데없는 중복을 버리고 안정성을 높이는게 3.0의 목표였다. 팀장님은 중복된 기능을 가진 세 개의 서비스를 통합했다. 3.0 프로젝트는 커졌다. 난 내가 담당하던 마이크로서비스도 완전 새로 개발했다. 그리고 아싸리 쓸데없는걸 다 들어내기로 했다. 인프라도 불필요한 것들을 다 날려버렸다. 이제 내가 아니어도 기본적인 설치나 디버깅 업무가 가능하게 되었다. 맞다. 제발 이 지옥같은 업무를 좀 분산시켜 달라는 아우성같은 것이었다. 그리고 그 시기에 새로 들어온 매우 협조적인 팀원이 간소화된 제품 설치 과정을 따라다니며 배우면서 설치 업무를 돕고자 부단히 노력했다.

3.0 버전으로 넘어가면서, 일에 여유가 좀 생겼다. 리서치팀과 함께 새로운 프로젝트를 진행했다. 매일 회사에 쌓이고 있는 데이터를 분석해서 우리 팀의 모델 학습에 사용할 수 있도록 기존에 사용하던 고가의 구매 데이터 형태로 변환하는 프로젝트였다. 이것이 진행되면, 데이터 구매 비용 부담으로 인해 잠시 멈췄던 학습을 다시 재개할 수 있었고, 타 거래소로의 확장도 용이해질 것이었다. CTO님의 퇴사 전 인수인계로 이 프로젝트에 대한 기획을 넘겨받았고, 무사히 개발해서 사용중이다.

시니어 팀장님이 이민을 가면서 퇴사하고, 잠시 팀장을 하다가 퇴사했던 팀장이 재입사했다.

다음은 4.0 프로젝트에 돌입했다. 4.0의 목표는 코드의 가독성, 유지보수성이다. 여기에 모든 기능의 완전한 이중화까지 지원한다. 개발언어를 Rust로 통일하고, 중앙화할 수 있는 것을 모두 공통 라이브러리로 관리한다. 모노리포 구조로 말이다. 코딩컨벤션도 정해졌다.

그러던 중 또다른 문제를 함께 해결해야 했다. 4.0 프로젝트 도중 DMA 프로토콜을 병행해서 개발해야 하게 되었다. 일정이 겹쳐서 끼어들어온 것이다. 하지만 난 허리 디스크가 파열되었다. 하지만 대체가 없어서 재택근무로 전환해서 마지막까지 프로젝트를 마무리해야 했다. 힘들긴 하다. 집에 갇혀서 일하는 느낌이다. 그 상태로 새벽 3시까지 작업을 하기도 했다. 하지만 그렇게 하라고 시킨 사람은 없다. 근데 하지 않으면 일정을 맞출 수가 없다. 뭐, 언젠간 지나갈 일이다.

회고록 - 9. 라크로스

대학 졸업 후, 나에게 좌절을 선사했던 연구소의 생활은 득과 실이 확실했다. 라크로스 연습을 하기엔 최고였다. 야외 스쿼시장에서 월볼(벽에 공을 치며 던지고 받는 것)이 가능했고, 웨이트 시설도 공짜였다. 필드도 있었다. 동아리 인준이니 주장이니 하는 부담도 없었다. 그 시기에 실력이 많이 늘었다. 마치 밥먹고 약을 먹듯이 퇴근하면서 연습을 했다. 연구실에서 받은 스트레스의 해방구이기도 했다. 대학원생들이 고강도 크로스핏을 왜 많이 하는지 알 것 같았다.

2019 아시아 환태평양 선수권대회에서는 일본에 사는 두 선수와 함께했다. 전설적인 골리와 탑 레벨 수비수였다. 그리고 졸업 후부터 심심해서 다니던 토요라크로스의 모임장이자, 현재 서울진도스 팀의 시초가 된 사람과, 한국외대 여자팀을 창단하고, 호주에 유학까지 가서 라크로스 선진국의 문화를 경험하고 돌아온 사람을 만났다. 대학 졸업 후 이 대회를 마지막으로 그만두려 했던 라크로스는 그렇게 수명이 연장됐다. 오프데이 때 그들이 함께 이야기하던 비전인 “즐거운 라크로스”를 마지막으로 믿어보고 싶었다. 연구소를 다니며 자유인으로서 즐긴 라크로스 또한 생각보다 즐거웠기 때문이다. 이제 즐길 수 있구나. 서울진도스 설립에 함께했다. 역시나 즐거웠다.

대학 생활을 통째로 앗아간 이 애증의 스포츠는 지금 삶에 있어 주를 차지했다. 난 회사에도 라크로스가 1순위라고 대놓고 밝혔다. 면접 자리에서 대표팀 일정으로 인해 휴가를 길게 쓸 수 있다는 사실에 대해 미리 이야기하고 허락까지 받아놓았다. 대신 이런 사례가 나쁜 사례가 아닌 좋은 선례로 남게 하고자 고생스러운 업무도 마다하지 않고 기한에 목숨걸고 책임감을 가지고 일했다. 관성같은 것이었다. 대학생 때 라크로스를 하는 내내 책임자 자리에 있었다보니, 행동 하나 하나 함부로 하기 어려웠는데, 이게 습관이 되었다. 특히나 생소한 스포츠 특성 상, 내 행동이 라크로스를 하는 이들을 대표하게 되기 때문에, 틀린 것도 아니었다. 나를 비롯, 선배들이 나쁜 선례를 남기면 후배들은 라크로스에 열정적이었을 수록 사회에서 힘들어질 것이라고 생각했다. 라크로스가 아니였으면 나도 가벼운 마음으로 대충 늑장을 부리며 일하고, 고생길일 것이라는 팀내 SRE 역할을 자처하지도 않았을 뿐더러, 팀에서 대퇴사 바람이 불며 타 회사에서 오퍼레터를 받았을 때도 바로 이직했을 것이다. 대규모 트레픽과 SaaS에 대한 기대를 충족하며, 파격적인 연봉인상을 얻어내며 말이다. 물론 오퍼레터보다는 조금 적지만, 회사에서는 이직하는 수준으로 연봉을 파격적으로 올려줬다. 고군분투하는 과정에서 서비스를 실제로 판매할 수 있는 수준으로 개선하고 안정화한 경험도 얻었고, 기술독재에 대한 경각심도 얻었다. 이곳은 당장 어렵더라도 언젠간 하는 만큼 대가를 얻는 곳이구나. 운좋게도 나름 좋은 선택이 되었다. 아, 물론 요즘은 좀 막나가고 있다. 에너지가 고갈되었기 때문이다. 그저 풀린 정신으로 실수나 하지 않을까 걱정이다. 그래서 더더욱 제대로 쉬기로 했다.

2022년, 코로나로 무기한 연기됐던 월드컵이 드디어 열렸다. 역대 최악이었다. 우리가 코로나를 핑계로 멈춰있는 사이 다른 나라들은 앞으로 나아갔다. 20점차 가까이 이기던 중국에게 조차 패배했다. 우리는 멈춰있는 수준이 아니라 오히려 후퇴했다. 그와중에 난 허리에 갑자기 극심한 통증을 느끼며 의무실로 향하게 되었다. 하지만 그곳에서도 마취 파스나 온찜질 이외에 해줄 수 있는 것이 없었다. 디스크 파열일지도 모르는 증상이었기 때문이다. 앓다가 좋아졌다를 반복하면서 후회 가득한 대회를 치렀다. 귀국 후 신경차단술을 받았다. 디스크 파열은 아니였지만, 내 허리는 이미 한 곳이 작살난 채 오래되어 있었다. 그곳을 시작으로 차례차례 작살날 것이라 했다. 이미 치료는 늦었고, 언제 은퇴할지 모르니 마음의 준비를 하라고 했다.

난 소속팀인 서울진도스에서 라크로스 인생 2막을 그저 즐겼다. 이미 대학교 졸업 이후부터는 플러스 알파를 지내고 있었던 것과 다름없다. 어차피 마지막이다. 후회없이 즐기기로 했다.

서울진도스의 “즐거운 라크로스”라는 추상적인 비전은 생각보다 강력했다. 그리고, 이곳엔 쓸 곳엔 쓰자는 진취적인 사람들이 모였다. 이왕이면 더 좋은 구장을 빌리려 하고, 양질의 훈련을 추구하고, 코치도 모셨다. 코치들 또한 적은 사례비에도 불구하고 열정이 넘쳤다. 코치의 비전은 “라크로스다운 라크로스”였다. 난 이들에게 항상 감사하다. 자칫 잘못하면 대학생활을 통째로 앗아간 라크로스를 버림과 동시에 라크로스를 시작한 것에 대한 후회로 가득한 삶을 살 뻔 했는데, 즐거운 라크로스를 경험한 덕에 그런 결말은 맞이하지 않을 수 있었다. 행운이었다.

2023년부터는 라크로스 선진국인 일본에서 매년 개최되는 오키나와 오픈에 참가하게 되었다. 이 대회를 기점으로, 서울진도스는 한국에서 따라올 팀이 없게 되었다. 이후 모든 국내 리그를 우승하고 있다. 오키나와 오픈에 그저 참여하는게 아니라, 그 대회에서 성적을 거두기 위해 그간의 대표팀 준비보다도 더한 열정을 퍼부었기 때문이다. 나 또한 이 대회에서 사상 최고로 많이 늘었다. 아니 곧 은퇴할 사람이 아쉽게 왜이러나…

2024년 오키나와 오픈에서는 디펜스 주장을 하게 되었다. 다시는 하지 않기로 했을 터인 주장이었는데, 그냥 결정되어 통보되는 바람에 거절할 타이밍을 놓쳤다. 내정을 다른 운영진에게 맡겼던, 성격에 맞지도 않는 바깥일이나 꾸역꾸역 하던 그런 주장 경험만 있었기 때문에 꽤나 막막했다. 사실 그런 주장 경험은 나에게 트라우마와 다를 바 없었다. 다행히도 함께 주장을 맡았던 두 명이 이 약점을 다 커버해 줬다. 주변에게 큰 기대치를 가지고 팀을 이끄는 성격을 가진 한 명은 팀의 동기 수준을 높게 가져갈 수 있도록 이끌었다. 언변이 좋고 성격도 둥글둥글한 다른 한 명은, 갈등이 빚어질 수 있는 상황들을 잘 해결하고 각종 공지 내용도 유도리 있게 잘 작성했다. 팀원 간의 조화를 이끄는 일에도 일가견이 있었다. 난 그런 능력들은 없었다. 장비 담당으로서 무슨 일이 있어도 차를 끌고 장비를 운동 장소로 가져가는게 내 임무였다. 그리고 난 그런 단순하고 몸만 좀 고생하면 되는 역할이 참 좋았다. 난 타인에게 기대를 거는 타입도 아니다. 말을 조리있게 즉석으로 만들어내지도 못한다. 그저 글을 쓰는 것이 그나마 가능했으므로, 훈련이 끝나고 귀가하면 그날의 디펜스 훈련중 들었던 피드백을 요약해서 업로드하고, 꾸중을 잔뜩 들었던 디펜스 팀원들에게 그래도 잘한 것, 발전한 것이 있음을 기억케 해주기 위해 나름 생각나는 잘한 점들도 피드백에 추가했다.

2년간 오키나와 오픈에 참여하면서, 가장 큰 행복이 찾아왔다. 드디어 미래를 맡길 만한 골리 후배들이 생겨나기 시작한 것이다. 2023년 대회에선 불시에 당할 은퇴에 대한 두려움이 줄어들기 시작했다. 선구안과 눈과 손의 협응이 좋고 안정적이며 힘도 좋은 골리가 나타났다. 특유의 안정성을 무기로 미래에 강력한 골리로 성장할 수 있을 것이다. 2024년 대회에선 체구가 작고 힘은 좀 떨어지지만, 승부욕이 강하고 이에 맞게 노력을 아끼지 않는 선수가 나타났다. 노력은 가장 강력한 재능이다. 그리고 다리에 시퍼렇게 든 멍을 보고도 그저 공 하나 막았다며 좋아하는 모습을 보며 과거의 자신이 떠올랐다. 후에 강력한 멘탈을 장착한 선수가 될 것이다. 이 친구는 지금 일본으로 교환학생을 가서 그곳의 팀에 들어가 거의 매일 연습을 하고 있다. 강력한 기본기와 멘탈을 가지고 돌아올 그날이 기대된다.

그리고 지금은 2025년 아시아-환태평양 권역에서 월드컵 출전권을 놓고 겨루는 퀄리파이어 대회를 준비중이다. 난 지금 허리 디스크 파열로 인해 장기간 휴식중이다. 스트레스가 생각보다 크다. 출전권 따야하는데. 하지만 이번에 신우신염을 얻어맞고, 폐에 물이 차고, 코로나까지 걸리면서, 집중해서 휴식 기간을 빠르고 밀도 높게 가져가기로 했다. 지금은 완전히 마음을 놓고 쉬고 있다. 그게 제일 빠른 길이다. 버텨라.

디스크가 호전되며 일상을 조금씩 회복하고 병치레로 무너지기 전까지의 기간 사이에, 이곳에서 또 한 명의 골리를 만났다. 골리는 이번이 처음이었다. 하지만 운동신경이 매우 뛰어났다. 공을 던지는 것만 봐도 몸을 사용할 줄 안다는 것이 눈에 바로 보였다. 빠르게 성장할 것임은 틀림없다. 운동 능력은 문제가 없고, 오히려 몸에 힘을 빼고 긴장을 풀고 머리를 비우는 것이 주된 과제가 될 것이다. 과거 힘만 넘쳐서 튀어다니던 나처럼 말이다.

그리고 또 한 명의 골리 지망자가 나타났다. 아직 장비가 없어서, 수비수 훈련을 하면서 훈련을 기록하고 있는 선수가 있었다. 그 습관 자체가 바로 미래의 성장을 암시한다. 기록은 누적을 만들기 때문이다. 나 또한 과거 훈련 내용과, 그날의 멘탈 등을 기록한 노트가 있다.

회고록 - 10. 미래

퀄리파이어에 대한 걱정은 산더미지만, 지금 난 나름 행복하다. 한국의 골문을 지킬 후배들이 4명이나 나타났다. 덕분에 난 은퇴 다음의 스텝을 고민하고 있다. 내가 할 수 있는 것은 무엇인가.

사실 난 내가 나이가 더 많고, 이미 더 성공해 있었으면 좋겠다는 생각을 자주 한다. 오키나와 오픈을 시작으로, 대회 준비에 집중하기 위해 퇴사까지 감행하는 수준의 열정있는 이들이 우후죽순 생겨나고 있다. 하지만, 그런 열정에 대한 보답을 해줄 수 있는 사람이 지금은 없다. 그들 스스로 헤쳐나가야 한다. 사실 그들이 퇴사할 때 나도 퇴사하고 싶었다. 하지만 이미 몸이 맛이 가고 있는 지금, 은퇴가 가까워지고 있음을 느끼고 있었고, 은퇴 후에도 기여할 수 있는 사람이 되기 위한 준비를 하는 것이 더 맞다고 생각했다.

꽤 많은 동료들은 지금 사회로 나오기 위해 알을 까는 시기에 있다. 불경기라서 계속 눈에 밟힌다. 나에게 이들을 지원하고 끌어줄 수 있는 더 큰 힘이 있었더라면 하는 아쉬움이 크다. 난 그런 역경들을 좀 일찍 맞이해서 괜찮은 경제 사이클 위에서 나름의 연착륙을 했지만, 이들은 지금 불경기 사이클 위에서 겪고 있다. 물론 모두들 강하고 능력있는 사람들이고, 충분히 이겨낼 사람들이다.

사회의 성인으로 성장하고 독립해서 자리를 잡기 위해 필히 수반되는 일들은 언제나 더럽게 힘들고, 불안하고, 자존심이 상하고, 우울한걸 알기에 좀 측은하다. 내가 지금 할 수 있는건 그저 그들이 안정될 때까지 믿고 기다리면서, 말하고자 하는걸 듣고, 말하기 싫은걸 묻지 않으며, 그들이 하고자 하는 일을 능력껏 돕는 것 뿐이다. 마치 내가 대학교 생활을 버텨낼 수 있도록 도와줬던 수많은 사람들처럼 말이다.

난 지금 가진건 별로 없지만, 어차피 라크로스에 인생을 빼앗긴 김에, 살면서 할 수 있는 최대를 해보고 싶다. 빼앗긴 인생이라도, 그 인생이 의미를 가지면 그만 아닌가. 그 의미를 준게 지금 동료들이다. 내가 가진걸 이용해서 내가 원하는 세상을 사고 싶다. 인간은 죽지만, 세상은 남는다. 내가 원하는 세상을 사려면 가진 것이 많아야 한다. 그러려면 많이 가져야 한다. 어떻게 많이 가질 수 있는지는, 머리로는 대충 안다. 이룰 줄 몰라서 문제일 뿐. 일단 월급쟁이로는 불가능하다. 하지만 뭐, 그건 나중에 가서 생각할 예정이다. 지름길따윈 없다. 지금은 그저 지금 할 수 있는 것을 하고 있다. 일단은 후배들의 열정을 사는 일을 시도중이다. 물론 선택은 후배의 몫이지만, 약간의 염원과 기대를 담아.

역경 탈출법

서론

난 삶의 등락이 뚜렷한 편이다. 그리고 지금은 낙의 시기에 있다. 건강이 무너지면서 브레이크가 제대로 걸렸다. 파열된 디스크만 회복하면 되는 줄 알았는데, 신우신염이 온 것도 모자라 폐에 물이 차더니, 코로나까지 꼽사리 껴서 협공을 당하는 중이다. 가히 나당연합군에 뚜드려맞는 고구려의 신세와 유사하다 할 수 있겠다. 이정도 신호는 모든 것을 멈추고 쉬어가라는 신호다. 물론 이런 낙의 시기는 처음이 아니다. 고등학교 때 한 번, 대학교 때 한 번, 사회초년생 때 한 번, 이미 총 3번 겪었고, 지금이 4번째다. 때문에 어떻게 헤쳐나가야 하는지 이미 알고 있다. 하지만 그와 별개로 역시 힘들긴 더럽게 힘들다. 뭐 그래도 이정도인게 어디인가. 암같은 뒤끝 지독한 질병이 아님에 감사하다.

난 보통 고난의 시기를 맞이하는 시점을 스스로의 선택이나 정신적 번아웃으로 맞이하기보다는, 몸이 못버텨서 얻어맞는 방법으로 맞이한다. 정확히는 인식을 그 시점에 한다는 것이 맞을 것 같다. 고등학교땐 위출혈, 대학교땐 신기능 저하와 혈뇨, 사회초년생땐 요로결석, 이번엔 신우신염이 그 시점이었다. 디스크 파열은 시발점이긴 하지만, 이때까지 난 완전히 낙의 시기라고 인식하지 못하고 있었다. 이때까지 그냥 쉬면 다 해결됐기 때문에, 그냥 두번째 요로결석처럼, 슥 지나가는 기우인 줄 알았다.

매번 이렇게 건강 문제로 무너지다보니, 하루이틀 사이에 급격히 안좋아진다. 대신 몸만 회복되면 알아서 잘 회복되는 편이다. 그리고 몸이 회복될 때 진행하는 일련의 과정이 항상 있었다.

1. 사람을 만나지 않는다.

안 괜찮은데 괜찮다고 하는 것도 일이다. 사람을 만나면 필히 그 이를 안심시키기 위해 에너지를 쓰게 된다. 그렇다고 안 괜찮다고 떠벌리고 다니는 것도 스스로에게 스트레스로 다가온다. 주변에도 스트레스를 전파하는 일이 될 수 있기 때문이다. 가장 가까운 몇몇에게 안 괜찮음을 알리고, 이후부턴 말을 아끼고 고독에 익숙해져야 한다. 그리고 고독을 즐기는 것은 후에 자신의 능력이 될 것이다. 내가 군자녀로서 잦은 이사와 이별을 유년시절부터 겪어 오며 단련되었듯 말이다. 혼자 있는 시간에 엄습하는 불안은 실체가 없고, 근거도 없고, 쓸모도 없다.

2. 생각하지 말고 몸이 이끄는 대로 생활한다.

자고싶으면 자고, 먹고싶으면 먹고싶은걸 먹는다. 억지로 생활 습관이니 뭐니, 보양식이 어쩌니 영양제가 어쩌니 요란하게 챙기지 않는다. 그런거 알아보고 계산하는 것이 더 스트레스다. 몸은 필요한게 뭔지 스스로 알고 있다. 이상하게 땡기는 음식을 놓치지 않고 먹는다. 난 이번에 아프면서 바깥 음식이 별로 땡기지 않았다. 몸이 알아서 염분을 거부하고 있었던 것이다. 그러더니 항생제를 먹기 시작하고 신우신염 증상이 완화하니 뜬금없이 닭강정이 땡기고 식욕이 올랐다.

보통은 자신을 망가뜨린 원인은 휴식을 하면서 차단되므로 이미 충분한 조치가 이루어졌다. 보통 사람의 의지력으로는 몸을 완전히 회복 불가능한 죽음의 사이클로 올려놓기 어렵다. 왠만하면 회복 사이클이 해결해 준다. 각종 생각은 버리고, 그저 조금 긴 감기에 걸렸다 생각하며 꿀같은 휴식을 온전히 즐겨야 한다. 자신을 믿어야 한다.

3. 집중력을 회복의 척도로 삼는다.

집중력이 크게 저하되어 있는 상태일 것이다. 하지만 이런 위기가 찾아온다는 것은, 그간 열심히 살았기 때문이다. 그렇게 살아왔던 관성에 의해 앞으로도 하고 싶은 것들이 산더미인 상태일 것이다. 하지만 몸상태는 이를 받쳐주지 못한다. 떨어진 집중력이 본인의 의지력이라 오판해서 자괴감이 들기 십상이다. 하지만 초조해 하지 않아도 된다. 이야기했다시피, 생각을 멈춰야 한다. 어차피 당장 안될거다. 악담이나 저주가 아니다. 팩트다. 어차피 안될 일에 스트레스 받는 것은 어리석은 짓이다. 그 일은 회복되고 나서 해도 전혀 늦지 않는다. 회복을 빠르게 하는 편이 더 이득이고, 회복을 가속하기 위해서는 불필요한 스트레스를 차단해야 한다. 대신 자신이 평소 좋아하고 재밌어하는 일들 중에서 기한없는 목표를 하나 정해 놓고, 하고 싶을 때 툭툭 건드려 보며 집중력을 체크하면 현재 상태를 진단할 수 있다. 스트레스도 받지 않으면서, 언제 자리를 박차고 일어나야 하는지 알 수 있다. 어느날 갑자기 의욕이 돋으면서 일을 손에 잡더니 시간 가는 줄 모르고 집중하고 있는 상태에 도달한다면, 몸은 스트레스를 다시 받아들일 준비가 되었다는 신호를 주고 있는 것이다. 그 일에 집중하다 보면 어느새 일상을 찾아가게 된다.

4. 인생에 대해 회고를 진행한다.

최고 속력을 내기 위해선 앞만 보고 달려야 한다. 때문에, 멈춰선 지금은 뒤를 돌아볼 절호의 기회이다. 이럴 때가 아니면 언제 뒤를 돌아보나. 그리고 이 과정을 통해 인생의 터닝 포인트가 생긴다. 회고를 진행하다 보면, 그동안 놓치고 있었던 것, 인생의 우선순위 등이 정리된다. 우선순위가 명확해지면 앞으로의 일에 있어 판단 기준을 세우는데 큰 도움이 된다. 때로는 성격까지 크게 변화하기도 한다. 회고는 언제 진행하면 되냐고? 3번이 힌트를 줄 것이다. 어느날 갑자기 하고싶어지면 하면 된다. 자신을 믿어라.

회복 후

회복이 되었다는 판단은 스스로 할 수 있을 것이다. 일상으로 복귀하고, 하고싶은 일을 하는데 거리낌이 없는 상태가 바로 회복이 완료되었다는 증거이다. 하지만, 비슷한 고난은 여러번 찾아온다는 것을 기억하고 있어야 한다. 사람이 사는 방식은 쉽게 변화하지 않는다. 내가 매번 건강 이슈가 터져서 더이상 앞으로 갈 수 없는 시점이 되어야 멈춰서는 것처럼, 같은 방식으로 또다시 고난이 찾아올 것이다. 왜 또 이런 시련이 주어지는가에 대해 한탄하지 말고, 그냥 “아 또 쉴 때가 됐군!” 하고 회복 사이클을 돌려라. 원래 반복된다. 그리고 그 때 제대로 쉬고 싶다면, 평소에 열심히 살아서 이럴 때 제대로 쉴 기회를 얻을 수 있도록 준비를 해두는걸 추천한다. 직장인으로서는 이번이 처음인데, 디스크 파열이라는 신호탄이 터졌을 때 팀에서 비로소 나에게 몰려 있던 버스펙터를 높이기 위한 급진적인 개혁이 이뤄졌다. 좀 늦어서 고생이긴 했지만, 그래도 그 개혁에 힘입어 이번에 완전히 무너졌을 때 휴가를 마음놓고 쓸 수 있었다(심지어 돌발적으로). 2년 근속 때 받는 리프레시 휴가를 라크로스 국제대회 때 사용하겠다고 1년 넘게 안쓰고 아껴 뒀던 것도 이번에 큰 도움이 됐다. 국제대회는 연차로도 충분하지만, 혹시 모를 일에 대비해 계속 쟁여뒀었다. 그 리프레시 휴가, 정말 리프레시하기 위해 사용하고 있다.

이 글이 올라왔다는 것은?

맞다. 난 지금 무사히 회복 중이고, 방금 집중력 회복이라는 강력한 신호를 받았다. 현재시각 새벽 3시 43분이다. 잠을 자다가 불편한 호흡, 흉통, 기침으로 뒤척이던 중, 갑자기 떠올라 글을 써내려갔다. 일단, 지금 매일밤 찾아오던 발열 증상이 멎었다. 잠을 청할 때만 해도 열이 났는데, 지금은 열이 내렸다. 이 시간에 쉬어도 모자랄 판에 왜 각잡고 글을 쓰냐고? 몸이 이끄는 대로 했다. 어차피 숨이 불편하고 열이 나서 잠을 잘 수 없는 상태였다. 이제 열도 내렸으니 다시 잠을 청하고, 눈떠지면 일어날 것이다. 이번 휴가는 이번주 내내이다. 강력한 회복 신호는 받았지만, 꿀같은 휴가를 더 신나게 누려서 확실히 회복할 생각이다.

Arch Linux를 사용할 때 각오해야 하는 것

오늘 아침에, 리눅스를 업데이트했다. 그리고 재부팅 하는 순간, 모니터 하나가 죽어버림.

리눅스 상에서 인식은 되고, 작동은 다 되는데, 한가지, 화면만 안나온다. 커널 업그레이드 과정에서 하드웨어쪽이 깨졌음을 알 수 있다. 참고로 업그레이드된 버전은 6.6.37-1-lts 이다.

그래픽카드 드라이버 재설치

  • 그래도 안됩니다.

롤백

  • 싫은뒈?

위의 이유로, 그냥 모니터 두개만 쓰는 중이다. 해결될 때까지 매일 업글 돌려야지.

아치리눅스를 이용한다면, 이건 각오해야 한다. 만약 모니터 세 개가 다 죽었다면, usb로 부팅해서 ssd 드라이브에 있는 커널을 롤백해줘야 하는데, 그게 아닌게 어디인가.

인생이 지루할 때 쯤이면 한번씩 안 지루하게 해줘서 좋다. (!@$#!$)

왜 계속 쓰는지 궁금할 것이다. 예전엔 재미있어서라고 답했을텐데, 지금은 그냥 남이 이해할 수 없는 재미의 존재에 대해 길게 설명하기 귀찮아서, 스스로를 변태로 간주하고 대충 넘기는 중이다.

죽은 FIX 라이브러리 살려내기

회사에서 리드 역할에 더 충실하기 위해 실제 작업은 팀원에게 넘기고 그 전에 계획하고 개발 후에 리뷰 및 관리하는 역할로 차차 넘어가고 있다.

이번엔 FIX 프로토콜을 개발해야 한다. FIX 프로토콜은 금융 거래에서 사용되는 하나의 표준 프로토콜이다. 처음엔 그냥 머리속에서, DMA 프로토콜을 개발하면서 짜내려간 코드를 재활용하면서, TagValue 인코딩만 구현하면 되겠다고 생각하고 있었다. 그런데, 실제로 팀원이 수행하도록 업무를 구상하려 하니, 가장 쉬운 방법을 고민하게 됨. 결국 FIX는 표준이므로, Rust 라이브러리 또한 존재했다.

문제는 이 라이브러리가 관리되지 않고 있다는 것이다. Rust 1.29부터 deprecated되는 문법들을 그대로 둔 채... 현재 Rust 버전은 1.79다. 결국 현재 사용이 불가한 상태다. 그럼 여기서 포기해야 하나 했는데, 사용법을 보니 너무 편해서 고치고 싶다는 생각이 들었다. 고치기만 하면, 개발 업무는 개꿀이 될 것이라는 확신이 들었음.

그래서 달려들었다. 매크로가 굉장히 많아서 디버깅이 좀 힘들긴 했는데, 그래도 새로 짜는 것보다는 분명 낫다. 오늘 약 2-3일쯤 되었는데, 역시 하다가 익숙해지니 속도가 붙어서 방금 끝났다. 꽤 재밌었다. 매크로를 이렇게 맛깔나게 쓰다니, 감탄하면서 고쳤다. 그냥 고친거 갖다 써도 되지만, 겸사겸사 오픈소스 기여도 할 겸 PR을 올려 뒀다.

통증 민감도 문제

2015년 겨울, 발목에 연골이 찢어져서 수술로 제거하고 뼈에 미세천공술을 받았었다. 마취가 깼는데, 진통제를 놓아 줄까요? 하는 간호사의 말에 아무 고민 없이 "아니요"라고 대답했다. 그냥 발목이 좀 삔 것 같은 느낌이었다. 물론 아무 생각 없이 발을 딛었다가 번개침.

2019년 가을이였나, 속이 안좋으면서 허리도 많이 뻐근해서 시름시름 하다가 밤에 잠을 잘 수가 없어서 응급실에 방문했다. 통증강도를 찍으라길래 6정도를 찍었다. 그런데 요로결석이었다.

2021년이었나? 또 요로결석이 발생했는데, 속이 안좋으면서 날카로운 통증이 옴. 하지만 재택근무로 일 다 했다.

2022년에는 허리가 좋지 않아 검사를 받았는데 요추뼈 몸체 모서리가 부러진 채 한참 지났다는걸 알게 되었다. 쉬몰결절도 있고, 디스크의 수핵이 완전 빠져나간 뒤였다. 뼈가 충격을 다 받는 바람에 허리 통증이 자주 발생하기 시작했고, 번개도 자주 쳤다.

딱히 치료가 안된다 하여, 그냥 버티다가 결국 올해 4월엔 문제되는 요추뼈 아래의 디스크가 터져버렸다. 4월이 맞나 싶긴 하다. 원인이 되는 날짜가 두개 정도 예상되는데, 어디서 결정적으로 터진건지 모르겠음.

3월 대회 마지막날에, 진통제 가지고 있는걸 다 털어먹고 경기를 뛰었다. 경기 다 끝나고 나서 긴장이 풀렸더니, 위가 꼬여서 급하게 가지고 있던 진경제를 먹음. 이후 일정 끝나고 파한 후 호텔로 가는데, 진통제가 풀리면서 허리가 끊어질 것 같은 느낌이 났다. 거긴 일본이었는데, 다짜고짜 약국을 찾아가서 진통제 코너 물어보고, 느릿느릿 일본어를 읽어가며 어떻게든 제일 쎄보이는 진통제를 사다 먹음. 아 이거, 신기한데, 일본의 소염진통제에는 카페인무수물이 첨가되어 있다... 자야 하는데? 그래도 일단 통증을 잡는게 우선이므로 약 먹고, 그날 잠 거의 못잠.

아 그리고 당시 새끼손가락도 부러져 있었는데, 의외로 이 손가락은 아무 느낌이 없었다. 그냥 땡땡하게 부었다. 한국 돌아와서 검사해보니 쪼개져 있었음. 올...? 허리 아프고, 손가락 부러진 와중에 회사 갈 것 다 가고, 훈련도 갔다. 그러다가 회사에서 한 번 더 체크메이트 당했다. 사무실에서 자리 이동을 해야 해서 PC를 다시 설치해야 했다. 책상 밑으로 들어가 앉아서 선을 꽂고 나서, 자리에 앉았는데, 뭔가 잘못되었음을 크게 느꼈다. 바로 퇴근. 이후 좀 나아지는 것 같던 허리통증이 다시 극심해졌다.

근데 그 와중에, 오른쪽 엄지발가락쪽 앞꿈치에 석회가 생겼다. 어릴 때 팽이를 밟았을 때 그 느낌이 났다. 가장 심할 땐 발가락이 터질 것 같았다. 하지만 역시 할 일은 다했다. 발날로 운전하고, 발날로 걸어다니고, 회사도 다 가고, 어떻게든 돌아다님.

결국 그러다가 한쪽 다리가 마비되어서, 좀비모드로 돌아다닐 권리마저 빼앗겼다. 다행스럽게도 쭉 마비된건 아니고, 완전 마비의 경우 일시적으로 한 1~2분 정도 발생했고, 그 이후엔 감각마비가 지속되면서 방사통이 발생했던 듯 하다. 근데 이 방사통도 원래는 많이 아프다고 들었는데, 오히려 방사통이 나한텐 허리통증보다 나았음. 그냥 탄산수에 다리를 담궈둔 듯한 느낌이었다. 감각마비 덕인가? 근데 일단, 이건 제대로 잘못된게 맞다는건 확실했다. 그래서 바로 가장 빠른 일정으로 MRI 촬영 진행. 파열 진단을 받았다.

통증 인식 체계 변경

이렇게 통증의 최대치가 통상적인 기준보다 아래인 상황에서 신체의 오랜 사용을 위해 캘리브레이션을 진행하기로 했다.

위의 사례 중 가장 큰 통증은 "번개가 친다" 혹은 "끊어질 것 같다"이다. 둘 사이에 우열을 가리기는 조금 힘들다. 왜냐하면 번개는 정신을 못차릴 정도의 큰 통증이 갑자기 훅 치고 빠지는 식이다. 순간 통증 자체의 크기는 제일 크다. 반대로 끊어질 것 같은건, 끊어질 것 같아서 못움직이는데, 최대한 덜 아픈 자세를 찾아서 안움직이면 또 괜찮음. 그래서 둘 사이에 우열을 가리기는 조금 힘들다.

이 번개가 치거나 끊어질 것 같은 통증은 이제 제대로 잘못되었다고 보고 병원 진료를 받아야 하는 것으로 이해하기로 했다. 추가로, 속이 안좋을 때인데, 난 이게 그동안 위염이라고 생각했다. 하지만 내시경은 깨끗함. 다들 있는 표재성 위염 정도? 이번에 허리 통증이 심할 때 속도 같이 아프거나 안좋아지는 현상을 발견해서, 속이 안좋을 때 또한 허리에 문제가 아닌지 감별해 봐야 하게 되었다.

다음은 욱씬거리는 통증인데, 주로 안에서 뭐가 터지거나 손상을 받아서 부을 때 발생한다. 추가로, 현재 디스크 회복기에 들어간 것 같은데, 가끔 무리해서 허리가 아프면 이런 박동성 통증이 온다. 허리에서 맥박이 뛰는 느낌이 남. 그리고 그건 바로 오늘이다. 재활운동 중에, 안전을 위해 허리 보조기 차고, 수건 말아서 허리 받치고, 스미스 머신에서 벤치프레스를 35kg로 했음. 위로 좀 던져지길래 괜찮은 무게인가보다 하고 그대로 12개씩 4세트를 했음. 이후 사이드 래터럴 레이즈를 하던 도중 허리 통증이 발생했다. 내생각엔 35kg를 한 것보다 35kg를 던지면서 한게 문제인 것 같은데, 혹시 모르니, 허리통증 회복 후 운동 땐 30kg로 던지지 말고 해야겠음. 아니 근데 몸통에 힘 하나도 안줬는데? 왜...? 뭐 여튼, 이런 욱씬거리는 통증은, 뭐되기 전에 경고하는 통증이라고 봐야 할 듯 하다.

다음은 뻐근한 통증이다. 이중에서도 묵직하고 둔탁하면서 불편한 느낌이 있고, 근육통일 때처럼 거칠게 당기는 느낌이 있다. 후자는 근육통. 환영. 전자는 통증 자체의 크기는 크지 않은데, 무시하면 안된다. 방사통이었다. Iliac crest, 꼬리뼈 위쪽 좌측 엉덩이로 통증이 주로 온다. 딱 L2, L3 척추신경이 연결되는 부위인 듯 함. 좀 더 진행되거나, 다리쪽으로 가면, 또 탄산수처럼 청량(?)한 느낌이 난다. 그런거 보면 아마 감각마비 때문에 다리쪽은 통증이 안 심했구나 싶다. 다만 이거, 평소에 올 때는 그냥 묵직하니 불편한 정도인데, 심하게 오면 마치 곧 폭발할 것 같은 느낌이 나서 움직이지 못한다. 끊어질 것 같은 느낌과 폭발할 것 같은 느낌의 차이는, 끊어질 것 같은 느낌은 아주 날카로우면서 속이 울렁거리는 증상이 같이 오는데 반해, 폭발할 것 같은 느낌은 말 그대로 폭발할 것 같은 느낌이다. 움직이면 마치 공기가 가득 차서 터질 것 같은 풍선을 발로 차는 듯한 느낌이 난다.

마지막으로 얼얼한 통증이다. 멍들면 발생함. 신경 안써도 됨. 물론 따가운 통증도, 보통 눈에 보이는 곳에 발생한 상처로 인한 것이므로 신경 안써도 된다. 근데 가끔 신기하게도 따가운 통증이 속에서 날 때가 있음. 지금 욱씬거리는 그 허리가 따가운 느낌도 같이 난다. 근데, 욱씬거리는 통증을 센싱할 것이므로 따가운건 무시할 예정이다.

이렇게 해서 나름의 통증 인식 체계를 만들어가야 할 듯 함. 못버티기 전에 알아서 중단해야 하는걸 알게 되었음. 심지어 다리 마비가 올 때까지 어떻게든 요래조래 돌아다니고 일상생활을 다한 것을 보면, 이건 꽤나 중요한 문제인 것 같다.

해당 문제의 득과 실

비가역적인 상태가 되고 나서야 문제를 알아채는 경우가 많다. 발목 또한, 연골이 찢어진지 2년이 지나서 알았고, 결국 수술로 제거. L3 모서리가 골절된건 심지어 도대체 언제 그랬는지조차 모름. 그래서, 의외의 문제가 있다. 상해보험 처리를 못받고, 이미 만성화가 다 진행되고 나서 생돈을 들이며 처치를 받는 편이다.

하지만 득도 있다. 인체는 어차피 소모품이다. 결국 언젠간 죽을텐데, 이때의 고통이 덜해질 것이기 때문에 꽤나 큰 득이다. 게다가 조금 더 핑계대고 나태해지는 방법으로 나름 건강도 찾을 수 있다. 감당할 수 있는 고통의 그릇은 큰데, 좀더 느긋하게 적은 통증을 느끼며 편안한 여생도 누릴 수 있으니, 일석이조임. 그걸 늦게 알아서 좀 고통받긴 했지만 ㅋㅋㅋ. 아 그리고 노인이 되면 어차피 여기저기 고장나 있을텐데, 이때 어떻게든 일상생활 누리기 스킬이 빛을 발할 것이다. 장수의 비결이다. 아니 근데 오래 살 생각은 없는데...?

허리 디스크 파열

L2-3 사이 디스크 회복 불가한 퇴행으로 인해 후관절증후군과 통증으로 고생하던 중, 결국 응당한 대가를 치르게 되었다.

예측된 결과이다. 다음 차례는 L3-4라고 했으니. 그 L3-4 사이 디스크가 결국 파열되어 왼쪽 다리로 가는 신경에 문제를 일으켜서 왼쪽 다리가 일시적으로 완전히 마비되었다. 다행히 완전 마비는 잠시 후 풀렸지만, 감각이 무디고 마치 탄산수에 다리를 담궈둔 듯한 느낌이 계속 났음.

지금은 약 6-7주째이다. 다행히 마비는 생각보다 빨리 회복되어 수술 없이 치료중이다. 다음에도 터지면 다시 3-4번이 될 예정. 3-4번이 2-3번처럼 되면 그 다음은 4-5번이 터진다.

디스크 파열로 인해 훈련을 못나가는 것은 물론, 운전, 대중교통까지 금지되었다. 직업적인 이유로 무조건 회사를 출근해야 했다면, 사실 휴직을 했어야 하는 상태. 하지만 다행스럽게도 재택근무 제도가 있어서 집에서 일하고 있다. 근데 프로젝트 마감 갑자기 땡겨저서 근무시간 치솟고 1시간 마다 누워서 찜질하던 루틴이 다 깨져서 회복 더뎌진건 안비밀 ㅋㅋㅋ. 다행스럽게도 마비 어느정도 회복되고, 좀 버틸만 할 때 치솟아서 추가적인 마비나 사고는 없었다. 어느정도 마무리된 지금, 다음주 1주간 휴가를 냄.

정선근 교수의 책도 세트로 사서 읽었다. 걷기, 렛풀다운, 힙업덕션 운동을 조금씩 하는 중인데 혹시나 하여 푸시업을 해볼까? 하고 엎드려 뻗치는 순간 뭔가 느낌이 이상하더니 지금 통증으로 벌받는 중이다. 그래서 지금 단계는 걷기, 렛풀다운, 힙업덕션만 가능한 상태이다. 이것도 많이하면 좀 힘듦. 근데 훈련 복귀하려면,
가능한 선은 계속해야 함.

재밌는건, 대회 가기 전에 자꾸 경기 중에 몸이 마비되는 꿈을 꿨다. 뇌의 신비. 그래도 꿈에선 온몸이 마비되었는데, 현실에선 다리만 마비됨. 물론 허리 문제로 온몸이 마비될 일은 없으니 꿈쪽이 호들갑이다. 그리고 실제로 터지고 나니까 그 꿈은 더이상 안꿈.

크런치 모드로 인해 한동안 깨졌었지만, 회복을 위해 진행하던 루틴은 아래와 같다.

  1. 오전 8시 기상
  2. 아침식사 후 물 크게 한 컵 마시면서 약 복용
  3. 자세 신경쓰면서 산책: 현재 1.5km가 상한
  4. 귀가 후 허리에 쿠션 대고 누워서 온찜질 20분, 원하는 만큼 휴식
  5. 재택으로 업무 및 1시간 마다 눕기 + 가능하면 온찜질도
  6. 점심식사 및 물 크게 한 컵
  7. 저녁식사 및 물 크게 한 컵 마시면서 약 복용
  8. 랫풀다운, 힙업덕션 적당히(양 정해두지 말고 상태 따라서 조절)
  9. 23시 취침(이거 좀 많이 어려움. -> 그래서 기상을 8시로 해둠)

지금 힘든건, 통증도 통증이지만 체질적으로 혈압을 높일 만한 무언가(즉 운동)을 하지 않으면 기립성 저혈압이 심해진다. 일어날 때 어지럼증이 좀 오고, 잘못 일어나면 앞이 깜깜해지는 것에 더해서 숨이 멈췄다가, 잠시 후 돌아오는데, 이때 심장도 엄청 빨리 뛰면서 숨을 몰아쉼. 그래서 이거 해결하려면 음... 딴생각 하지 말고 그냥 허리 빨리 회복이나 하자 ㅋㅋㅋㅋㅋㅋㅋㅋ. 나름 저런 문제 때문에 행동을 조심하게 되니, 회복 가속 스킬이라고 봐도 될 듯 함. 이번에 디스크도 회복이 된다는 것을 알게 되었더니, 나름 인체에 믿음을 가지게 되었음. 암이 아니라면 그냥 쉬면 알아서 해결되는 것 같음. 안쉬는게 문제지.

뽀개짐

2024-03-14 ~ 2024-03-17에 진행된 라크로스 오키나와 오픈, 내가 보기에 이건 인생 마지막 대회였던 것 같다. 아니, 사실은 그렇지 않기를 바란다. 하지만, 너무 강한 단서가 나를 괴롭힌다.

사실, 과로를 했던 이후 아직도 몸이 온전히 회복되지 않은 상태로 대회에 나갔던 차이다. 그래서 마지막날엔 허리통증이 극에 달했다. 아침에 눈을 뜨자마자 그날이 마지막이라는 기분이 강하게 들었다. 오전 경기엔 통증으로 인해 참전하지도 못했다. 하지만 경기가 만족스럽지 않게 끝나 팀원들이 모두 기가 죽어버렸다. 마지막 경기마저 그렇게 찝찝하게 끝나면 절대 안된다. 그런 경험을 팀에서 극복하는덴 몇 년이 걸린다. 그리고 난 그 때 주장이었다. 그래서 결정했다. 이왕 마지막일 수도 있는거, 모든 것을 불태우기로 했다. 가방에 있던 진통제를 다 털어먹고 몸을 인정사정 없이 제대로 풀었다. 그런데 마지막 경기 직전의 슛업(슈팅을 실제로 받아내는 웜업) 과정에서 오른손 새끼손가락이 골절됐다. 뼈나 인대가 나간 것은 확실한데, 난 이미 아드레날린에 쩔어 있었다. 툴툴 털고 마지막 경기를 뛰었다.

초반 공세를 막으며 버틴 끝에 경기 분위기가 우리 쪽으로 넘어왔다. 결국 5:2로 승리했다. 경기 종료 후, 마지막 단체사진을 찍자마자 난 위가 꼬여 드러누워 움직이지 못했다. 물론 그 상황도 이미 다 대비가 되어 있었다. 팀원에게 내 가방의 진경제를 가져다달라고 부탁해서 그 약을 먹고 잠시 후 살아났다.

한국에 돌아오고 나서 병원에 가서 손가락 엑스레이를 찍었더니, 관절면끼리 부딪히면서 쪼개졌다고 했다. 일단 자기 위치를 아직 벗어나지 않아서 수술은 킵하고 경과 지켜보되, 건이 붙는 자리라서 깁스로 손목까지 고정하고, 꼼짝도 하지 마라고 했다. (근데 그 상태로 경기도 뛰었는데, 원래 안벗어날 골절이 아닌가?)

뭐 여튼 꼼짝도 하지 마라고 하니, 일단 오른손은 팔걸이에 쳐박아 두고 살아보기 시작했다. 문제는, 허리 통증도 다시 엄청 심해졌다는 것이다. 좀 있으니 오른쪽 발 앞꿈치에 석회도 생겼다. 뭐 그건 그냥 아픈거고, 문제는 허리를 못쓰는 와중에 손도 못쓴다는 것이었다. 일단, 운전이 문제였다. 시동, 내비게이션, 변속, 사이드브레이크, 안전밸트 체결부 모두 오른쪽이다. 그래서 며칠간 운전을 못했다. 그러다 허리가 영 안되겠다 싶어서, 태릉쪽에 있는 병원에 가기 위해 방법을 찾았다.

  1. 오른쪽을 바라보고 운전석 사이드에 걸터앉아서 왼손으로 안전밸트를 체결
  2. 시동을 걸고, 내비를 설정
  3. 변속기 변경
  4. 고쳐앉기
  5. 액셀 밟으면 사이드브레이크 풀리는 기능 이용

이렇게 해서 병원에 갔다. 돌아오는 길에는, 집으로 가기 음성인식으로 네비 설정이 가능하다. 페달은, 발날로 밟았다…

추가로 터치펜과 펜을 붙여서 길이 연장해서 제대로 앉고 나서도 왼손으로 내비게이션 조작 가능하게 해봤다. 근데 터치 감도가 좀 별로라서 결국 허리 써야 해서 실패. 대신 안전밸트 풀 때 이걸로 푸니까 허리 안돌려도 돼서 좀 편해졌다. 시동도 이거로 켜고 끈다.

여튼 병원에서 여느 때처럼 신경차단술을 받았는데... 이번엔 뭔가 해결이 안된다. 계속 아프다. 속도 뒤집어질거같고 그냥 뭐 어떻게 저떻게 시간은 흘려 보낸거같은데... 뭐 그건 그렇다 치고, 밥줄...! 오른손 없는 개발자라니? 그와중에 허리 아프다고 조기퇴근 남발?

그래서 일단은 코파일럿을 VIM에 설치했다. 그렇게 어떻게 저떻게 버티다가, 뜬금없는 희소식이 발생했다. 손 치료받던 동네 병원에서, 허리 물리치료도 받고 있는데, 견인치료 중에 갑자기 속에서 뭔가 뚝 하고 뒤틀리는거같더니, 통증이 확 줄어들었다. 아니 뭔 회당 8만원 16만원 하는 주사치료로도 안되던게, 8천원짜리 물리치료로 확 괜찮아다지다니? 그리고 왜 이 간단한 치료는 그동안 아무데서도 안해줬는지?

다만 한가지 문제점은 있는데, "안좋아지면 물리치료 오세요" 하길래 금요일에 신난다! 하고 안가고, 진통제도 안먹었더니 퇴근하는데 또 안좋아졌다. 그래서 다시 약먹고 물리치료를 갔다. 이건 거의 뭐 신장 투석 환자마냥 일일 활동권을 병원에서 끊어와야 하는 듯 하다. 뭐 그래도 방법을 찾은게 어디인가.

여튼 그 몸 상태 좋아진 그날, 너무 신나서 코드를 5천줄 넘게 썼다. 코파일럿과의 합도 잘 맞아지고, 완전 날아갈거같았다. 마침 지금 개발하는게 프로토콜쪽이라서 노가다성이 짙은데, 코파일럿이 너무 좋아한다. 특기분야인 듯 하다. Private repo 접근 권한 안주고, 회사가 아닌 개인 계정으로 결제해서 기능에 한계는 있겠지만, 일단 초반에 시범으로 좀 짜주고 나면, 이후부터는 척척 추천해준다. 게다가, Rust랑 궁합도 좋다. 컴파일러가 strict할수록 코파일럿이 삽질했을 때 더 잘 잡아줄 것이기 때문일 듯 하다. 코파일럿은 언어를 이해하기보다, 단순히 이런 케이스의 코드가 어떻게 짜여졌는지에 대한 패턴을 학습하는 듯 하다. 그래서 예시로 짜주지 않은 형태는 스스로 유추하지 못한다. 아직 그냥 코더이다. 내 밥그릇은 아직 남아있는 듯 하다.

난중일기

1

2024년 1월 22일, 특정 마이크로서비스에 큰 변화를 가하는데 아주 무리한 일정이 내려왔다. 하루하루 한 단계가 해결되지 않으면 다음 단계를 넘어가지 못하는데 다음 단계로 한 번이라도 못넘어가면 바로 일정을 지킬 수 없는 수준이었다.

그렇다고 그걸 미룰 수도 없었다. 당장 새 모델의 성능에 악영향을 끼칠 것이었고, 새 모델의 배포 또한 ASAP인 상태였기 때문이었다.

러시한지 4일차, 다음날이 배포인 상황. 고객사에서 연락이 왔다고 한다. 미루자고. 모델 배포와 함께 진행하기로 한 타 회사의 기능 개발이 부진한 탓이었다. 무엇 때문에 이렇게 달린 것인가...

여튼 우여곡절 끝에 스프린트 마지막날에 배포하면서 마무리되었다. 시간이 더 생긴 만큼 테스트도 더 많이 진행됐다.

2

그리고, 해당 서비스는 내 담당 서비스는 아니었다. 그래서 내 담당 서비스의 신규 버전 개발 Task도 그대로 남아있었음. 물론 결국 다른 일들에 밀려 일시정지되었다....

이런 식으로 일 중단되는거 제일 싫어한다.... 그래도 공통 라이브러리 모으는 task는 첫주에 다 진행함. 다른 서비스에도 영향이 있으므로 좀 러시했음.

3

그리고, 고객사에서 요청한 피쳐의 반영도 해야 했다. 그건 퇴사한 전 팀장님의 서비스에서 처리해야 하는 일인데, 내가 또 이런거 땜빵 전문이다. C#으로 되어 있지만 다행히 예쁘게 짜서 유지보수하는데 어려움은 딱히 크지 않다.

4

이와중에 예전에 고객사에서 서비스 장애 시 SMS 알림을 해달라고 하며 추후 API 호출 방법을 보내주겠다고 했는데, 그 메일이 왔다. 심지어.... 담당자가 없어서 API 호출을 못열어준다며, 그냥 직접 소켓 연결해서 붙어서 메시지 쏘는 C 코드를 툭 던져줌. 그리고 그 코드는 include문들도 다 빼먹고, 직접 선언해서 사용했을 함수도 포함되어 있지 않았다. 그와중에, 내부에 들어가는 정보는 보안상 알려줄 수 없다며 그날 가져오면 정보 채워주겠다고 함. C로 가져가야 거기서 빌드할 수 있겠다 판단, 일단 C인 상태로 진행하고 추후 바꿔도 된다면 유지보수 가능하도록 Rust로 재작성하기로 함. 일단 근데 C언어이므로, 내가 진행해야 했다.

반환 타입, 함수 파라미터, 예상되는 결과값 유추해서 빈칸들 끼워맞춰서 개발 완료했음. 개발 완료되었다며, gcc 있는지 확인해달라고 하니, 없다고 함(롸?). gcc 없는데 c 파일을 준다고? 그럼 진작에 Rust로 만들었지... 여튼 그래서 debian 이미지에 gcc, build-essentials 깔아서 가져가서 정보 받고 빌드해서 쏴봄. 안됌. 왜냐하면? 개발계에는 세팅을 안했다고 한다. 운영계에서 테스트 하라고 함(와우). 그래서 또 쏴봄. 안됌. 왜냐하면? 방화벽을 안열어 놨다고 한다. 요쪽에선 자주 있는 일이라 이제 놀랍지도 않다. 대충 처음에 가져가면 안될걸 예상했기 때문에, 테스트 가능하도록 SMS send는 send만 하고, 장애 모니터링도 따로 짜서 가져갔기 때문에, SMS send 테스트 방법 알려준 후 넘기고 옴.

5

그리고, 새 모델을 개발하고 테스트하기 위해 부산 IDC에 서버를 넣기로 했는데, 이게 또 일정이 가까이 다가왔다. VPN 세팅 등을 더이상 미룰 수 없어서 인프라팀과 계속 이것저것 주고받는데 생각보다 이 망대망 연결을 하기에 사내 네트워크가 너무 개떡같았다(네떡이라고 부르심...). 그도 그럴게 30명 규모였던 회사 규모에서 별다른 준비도 없이 80명 규모로 인원을 뽑아댔고, 당시 인프라 전담 팀도 없었기 때문에 그 네떡이 80명규모인 지금까지 넘어왔던 것이다.

여튼 그 네떡 위에서 문제가 된 것은 VLAN 설정이다. 현재 네트워크 토폴로지는 그냥 방화벽 밑에 스위치 3개가 데이지체인으로 엮여있는 방식인데, 스위치 3개에 아무 호스트가 막 연결되어 있는 방식이다. 제일 먼저 방화벽에서 VLAN Switch 밑에 VLAN 대역을 추가했는데, 역시나 호스트에서 그 VLAN으로 연결 안됨. 왜 안되는지 찾기 위해 난리를 쳤다. 심지어 네트워크 작업은 아무리 빨라도 일단 증권 거래가 이루어지지 않는 장 마감 후에 진행해야 한다. 그러다 결국 속도를 내기 위해 네트워크 장비들 어드민 패스워드까지 받게 되었다.

여튼 원인을 열심히 파보니, 밑의 스위치들이 그 VLAN의 존재를 모르기 때문이라는 의심이 가장 많이 들었다. 내가 알기로 방화벽은 방화벽일 뿐 실제로 VLAN은 Layer 2이다. 스위치가 그 VLAN을 알고 있어야 한다. 그래서 스위치에서 arp cache를 조회하여 내 호스트가 어느 스위치의 어느 포트인지 파악해서 해당 포트에서 vlan id에 새 vlan을 이용하도록 설정함. Tag에 대해서 모르고 있었기 때문에 그냥 Untagged port를 vlan으로 할당해버림.

네 안됩니다. 다른 스위치에도 다 설정해야 함. 그런데 문제가 있다. 스위치끼리 연결한 인터페이스(1/2/1)에 Untagged Port VLAN을 적용해버리면, 전체 스위치의 vlan이 바뀌어버릴 것 같아서 건드릴 수가 없었다.

해결한 방법은, IEEE Tag를 이용하는 것이다. 원래 패킷 상에 vlan id는 안들어가는데, 이걸 들어가게 할 수 있다. 그럼 스위치는 해당 tag를 보고 vlan id를 읽을 수 있게 됨. 그래서 전체 포트에 대해 tagged라면 새 vlan을 사용하도록, untagged라면 defalut vlan을 이용하도록 설정했다. 여기서, 호스트에서는 그 IEEE Tag를 패킷에 심어줘야 한다. 그건 VLAN 인터페이스를 생성하면 된다. 여기서 VLAN ID를 주면 그 태그에 들어감.

6

그와중에 갑자기 2월 1일 밤에, 회사 서버실의 에어컨이 고장나서 서버실 온도가 치솟았다. 연락을 받고 우리팀 서버에 필요한 파일만 후다닥 백업한 후 싹 긴급정지했다. 네트워크 장비도 그 서버실에 있어서, 혹시 작업 중에 죽어버릴까봐 설정 원복 후 작업 중단했다. 그리고 다음날 다시 켰더니 결국 한 서버가 커널 패닉을 내며 부팅 실패... 하지만 지금 급한건 이 서버가 아니였어서 다음 스프린트 때 볼 예정.

7

일이 너무 동시에 끝없이 진행되고, 일만 끝나면 집에 와서 뻗어자고 눈뜨면 바로 샤워하고 출근을 하다보니, 집에서 점심을 챙겨가던 습관까지 무너지고, 점심시간을 놓치는게 일상이 되었다. 사실 아무때나 먹어도 상관 없는데, 점심시간이 지나면 또 이런저런 일로 계속 호출된다. 저녁도 보통은 일이 계속 질질 끌리다가 야근을 해버리기 때문에 까먹는 경우가 많다. 저혈당으로 어지러우면 급한대로 회사 냉장고에 있는 요거트를 먹거나 해서 해결.

시간이 없는건 한가지 사례로 바로 알 수 있는데, 저번주 토요일에 회식자리에서 고기를 먹은 후, 패딩에 고기냄새가 심하게 났는데, 그걸 처리할 방법을 찾을 시간이 없어서 패딩을 못입고 다녔다. 꽤 추웠다.

승전보

  • 오늘 낮에 극적으로 VLAN 설정 해결책을 발견, 적용하면서 이번 전쟁은 끝났다.

결과

  • 2주만에 체중 5kg이 빠졌다.
  • 치매와 비슷한 증상이 나타났다. 기억도 잘 안나고, 기억을 끄집어내는데 오랜 시간이 걸린다. 마치 기억들을 정리되지 않은 창고의 문을 열고 냅다 던져놓고 바로 닫아둔 느낌이다. 다행스럽게도, 이 증상은 목요일부터 완화되는 중이다. 그간 계속 3-4시간 자다가 수요일 밤에 결국 부정맥이 왔는데 멈추질 않아서 강제로 밤에 잠을 잤기 때문이다.
  • 허리 통증 악화, 5분 이상 서있기 힘든 상태이다. 내일 병원에 갈 예정이다.
  • 대회 전에 러시해서 허리 나갈 가능성을 방지하려고 대회 전에 4영업일 간 더 휴가를 냈다.
  • 하지만 고쳐야 할 것은, 일을 눈앞에 두고 자리를 못뜨는 습관을 좀 버려야 한다. 평시에도 밥은 일하면서 먹는다. 한손엔 점심, 한손은 키보드에 있음. 이 습관이 무서운게 그 한손에 점심이 들려있지 않으면, 점심을 먹으러 나가는게 아니라, 점심을 안먹어버린다.

커널 패닉으로 인한 부팅 불가 현상 해결하기

어제, 정말 기괴한 일을 했다. 리서치용 서버에 서버행이 떠서 재부팅을 했는데 커널 패닉이 반복되며 부팅이 안되는 현상이 발생함. 그리고 이걸 고치는 과정에서 세상 강제적인 방법을 다 동원했다.

시스템

  • 우분투 20.04
  • 다른건 알 필요 없음. 다만 이 문제를 잘 야기하는 하드웨어에는 리얼텍 NIC가 있다고 함.

문제 원인

  • 하드웨어를 인식하는 과정에서 잘못된 메모리 참조
  • 아치리눅스 부팅USB로 부팅해서 살펴보니, /dev에 ssd, hdd, 기타 디바이스 모두 없었음

해결방법

  • 하드웨어는 누가 잡는다? -> 커널 -> 커널을 업데이트
  • 커널을 어떻게 업데이트? -> apt upgrade하면 편한데 -> 부팅USB로 부팅한 후 파티션을 /etc/fstab과 맞춰서 마운트 -> chroot -> apt update && apt upgrade
  • 네임서버 설정 안됨 -> apt source url을 /etc/hosts에 강제로 박아넣고 진행

결과

  • 깔끔-
  • 이게 된다고???

후기

  • 다덤벼

crates.io 배포

자체 개발하여 업무 및 개인 용도로 사용하고 있던 actor 라이브러리를 crates.io에 배포했다(xan-actor).

원래 이 라이브러리는 업무용으로 필요한 기능만 구현해서 사용하고 있었는데, tokio를 너무 애용하는 바람에 main 함수를 async 함수로 만들어야 하는 단점이 있었다. 이게 async 키워드만 붙인다고 되는게 아니라 tokio::main을 이용해야 한다. 따라서 tokio를 쓰고싶지 않은 사람도 tokio를 이용해야만 이 라이브러리를 사용할 수 있었음. 그런데 또 비동기에 사춘기가 들어서 그런지, 동기 메인함수를 이용하고 싶었다. 그래서 동기로 만드는데, 이김에 tokio도 걷어내보고 싶어서 걷어내다 보니, 전체 구현를 tokio 없이 할 수 있는 피쳐가 만들어졌다.

근데, 매번 이 라이브러리를 add하는데 Cargo.toml에 깃허브 리포를 매번 넣어주는게 귀찮아오던 참에 crates.io에 배포해 보기로 했다. 보니까 4년째 관리 안하는 actor 라이브러리도 떡하니 자리를 잘 차지하고 있는데, 나라고 안될까.

일단 이걸 하면 편해지는건 그냥 cargo add xan-actor 하면 라이브러리가 add된다는 것이다. 개꿀.

배포 방법

Crates.io에 크레이트 배포하기

Rust의 모노리포 - 개꿀

내가 속한 조직은 각 구성원이 믿을 만한 사람들로 구성되어 있다. 따라서 요구조건을 전달하고, 상대방이 어려워하는 경우 힌트만 좀 공유해서 이해시키면 됨. 그래서 마이크로서비스 구조로 잘 지속되어 왔다.

하지만 이것은 한계에 봉착하고 있다. 현재 우리 제품은 지속적으로 개선을 하고 있기 때문에 업데이트 빈도가 매우 빠르다. 그 업데이트들은 DB 스키마까지도 변경될 수 있을 정도로 큰 경우가 빈번하다. 심지어 개발속도도 빨라서 개발 중에 다른 서비스에 큰 변화가 생기는 경우도 발생한다. 또한 cargo update를 깜빡해서 버전에 안맞는 코드를 작성했는데, Cargo.lock파일 또한 커밋되지 않았으므로 CI 테스트를 그냥 통과하는 경우도 발생했다.

최근엔 작업 관리 서비스와 엔드포인트 서비스를 통합하는 과정에 있다. 그래서, 통합하는 김에 모노리포를 채택하기로 하였다. Rust에서 모노리포? 그거 아주 쉽다.

Rust에는 cargo라는 패키지 툴이 있다. cargo로 컴파일, 빌드, 라이브러리 import 모두 진행한다. 이뿐만이 아니라 workspace라는걸 이용하면, 최상위 디렉터리에서 여러 개의 cargo workspace를 구성하고 상호간 라이브러리처럼 import할 수 있음. 각 마이크로서비스는 마이크로서비스로 그대로 가져가지만, 리포만 하나로 통합할 수 있다. 이렇게 되면 다른 마이크로서비스의 버전 변화가 있을 때, 그냥 pull만 당겨주고 맞춰서 작업하면 됨. 브렌치 머지할 때도, conflict가 있는지 볼 수 있고, CI를 하는 것도 용이해진다. 또한, 각 마이크로서비스에서 이용하는 라이브러리의 버전도 자연스럽게 통합된다. 각 workspace의 Cargo.toml파일을 따로 세팅하긴 하지만, 최상위 디렉터리의 Cargo.lock파일에서 싸그리 관리하기 때문이다. 추가로, 이건 사소해 보이긴 하지만, 수정이 있을 때마다 깃허브 알림설정이 모두에게 날아가게 될 것이다. 자기 서비스에만 신경쓸 땐, 일부 리포는 알림이 안되어 있는 경우가 생기기 때문에, 따라가기 힘들 때가 있었는데, 해결될 듯 하다.

여튼 그래서, 아주 쉽게 모노리포 구성해서 작업중이다. 개꿀.

기술적 분석

허리도 괜찮아지는 중이고, 뭔가 최근들어 머리가 팽팽 도는 상태이다. 이유는 모른다. 허리 아프다고 안쓴게 보관되나. 아 그러고보니, 불면증이 해결되는 중이구나.

여튼 그래서 오늘은 훈련 가기 전에 서적의 기술적 분석 부분을 다시 복습했다. 이미 수치 계산은 trading-toolkit에 만들어 놓은 상태였는데, 이때는 계산식 자체를 구현하는데 초점이 맞춰져 있었다면, 이번엔 기술적 분석을 통한 거래 방법에 초점을 맞추고 읽었다.

참고로 서적은 아래와 같다.

나의 트레이딩 룸으로 오라! - 알렉산더 엘더

조금 공격적인 느낌의 이름이긴 하다. 근데 뭐 영어로 "Come to my trading room"이면 그렇게 들리진 않을듯? 각설하고, 읽은 내용을 요약해 보겠다.

종목 선택 - 무엇을 살 것인가

일단 기본적으로, 채널이 넓어야 한다. 채널이 넓지 않으면 많이 못먹기 때문. 이게 그냥 단순히 많이 못먹는게 문제가 아니다. 트레이딩의 성적을 계산할 때에는 이 채널에서 얼마나 많이 먹었는지를 기준으로 한다. 따라서, 채널이 좁은 경우, 아무리 좋은 성적을 내도 이득을 크게 보지 못한다. 그리고 거래비용을 지불해야 함. 남좋은 일만 하는 꼴이다.

또 한 가지, 많은 종목을 전체적으로 보기보다, 주종목으로 할 몇몇 종목을 골라서 그것만 파는게 유리하다고 함.

이동평균선을 통한 추세 파악 - 지금 어떤가

이동평균선, 그 중 지수이동평균을 권장함. 여튼 이 선을 이용해서 상승장인지 하락장인지 추세를 파악하면 된다.

예상되는 추세 반전 지점이 있는지 확인 - 특별한 기회가 있나

MACD 히스토그램. 이 중 다이버전스를 포착한다면 좋은 기회가 될 수 있음. 다이버전스는 여러번 읽고 나서야 이해할 수 있었다. 상승 다이버전스는 가격이 두 번 이상 저점을 찍을 때, MACD 히스토그램의 두 바닥을 비교하면 상승하는 경우이다. 하락 다이버전스는 가격이 두 번 이상 고점을 찍을 때, MACD 히스토그램의 두 천정을 비교하면 하락하는 경우. 이 다이버전스의 경우, 자주 있는 일은 아니지만, 일어나는 경우 꽤 좋은 신호가 된다고 함. 약간 이벤트같다고 해야 하나.

매수/매도 시점 파악 - 언제 사고 팔 것인가

책의 저자가 개발한 강도지수라는게 있다. 이걸 이용해서 이동평균을 구하면 매수/매도 시점을 파악하기 좋다고 함. 2일 강도지수 이동평균을 이용했을 때, 만약 상승장의 경우 이 값이 음수인 경우 매수 타이밍, 반대로 하락장에서 이 값이 양수인 경우 매도 타이밍이라 함. 일시적으로 반전이 일어나는 케이스를 포착할 수 있음.

추세 재개여부 파악 - 지금 이 상태는 일시적인 것인가

이 역시 책의 저자가 개발한 엘더-레이라는게 있다. 반전이 포착되었을 때, 이전의 추세를 여전히 가져갈것인가를 알 수 있다고 함. 상승추세에서 매도 강도가 음수에서 양수로 올라가는 경우 상승이 재개되고, 하락 추세인데 매수강도가 양수에서 음수로 전환되는 경우 하락이 재개된다. 그냥 보면 당연해 보이기도 하다.

아 참고로, 매도강도는 작을 수록 강한 것이다.

위험요소 회피 - 이 포지션을 취해도 괜찮을 것인가

스토캐스틱이라는 지표가 있다. 이 지표는 과매수/과매도 상태를 나타낼 수 있음. 저자는 주로 극단적인 상황을 막기 위해 이 지표를 본다고 한다. 마지막 단계에서 이용하면 될 것 같다. 예를 들어, 매수하고 싶은데 스토캐스틱의 상단기준선 위로 올라가 있다면 매수하지 않는다. 반대로 공매도하고 싶은데 스토캐스틱의 하단기준선 아래라면 하지 않는다.

펀더멘털에 의한 변수

아무리 다이버전스를 포착하고, 매수/매도 시점 찾고 스토캐스틱으로 검증한다고 해도, 결국 기본적인 펀더멘털의 변화가 심하면 이 신호들이 의미없게 되는 경우가 있다고 한다. 저자는 이럴 때 반대 포지션을 즉시 취한다던가 하는 트레이딩적 노하우를 맛보기로 소개해 줬는데, 나같은 쩌리는 그냥 펀더멘털에 큰 변화가 찾아올 만한 주식은, 트레이딩이 아니라 투자적 관점에서 바라봐야 할 듯 하다.

Linux에 카카오톡 설치

리눅스의 최대 단점은 바로 카카오톡이 아닐까 싶다. 그동안 카카오톡 설치가 번거로워서 PC로는 이용 안하고 있었는데, 최근 업무 중 윈도우 어플리케이션을 돌릴 일이 있어서 wine을 좀 파보게 되면서, 다시 자신감이 붙음. 다 덤벼라.

그래서 다시 카카오톡 설치에 도전했다. 아주 가장 간단하고 기본에 가깝게. 방법은 아래와 같다.

wine, wine-mono, wine-gecko 설치

배포판은 신경쓰지 말자. wine은 말그대로 wine, wine-mono는 wine의 .NET 프레임워크 이용을 위한 패키지, wine-gecko는 Internet Explorer를 위한 패키지이다. IE에 대한 본능적 거부감에 일단 wine-mono까지만 설치하고 카톡 실행을 해봤더니, 결국 안돼서 이것도 마저 설치했음.

wine 환경설정

winecfg

winecfg

위의 커맨드를 실행하면 뭔 창이 하나 뜰 것이다. 그냥 OK 하면 wine 환경이 구성됨. 구성되는 환경은 아래와 같다.

$HOME/.wine

여기를 들어가보면 매우 익숙한 구조가 나옴. 맞다. 말그대로 윈도우의 디렉터리구조가 보인다.

한글 폰트 추가

카톡을 설치할 때, 설치 프로그램에서 한글이 깨지지 않게 나오게 하고싶다면, 한글 폰트를 설치하자.

방법은 간단하다. $HOME/.wine/system.reg에 들어가서 MS Shell Dlg 항목을 한글 지원되는 폰트 이름으로 바꾸면 된다. 폰트 리스트는 해당 라인 위로 올라가면서 쭉 보면 있을 것이다(리눅스에서 한글을 사용하는 이상 아마 있을 것).

한글 입력 활성화

wine reg add "HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver" /v InputStyle /t REG_SZ /d root /f

아, 참고로 kime 입력기를 이용하는 경우, kime-xim이란걸 이용해야 하는데 후술하겠다.

또, 카카오톡 설치할 때 한글 버전으로 안하고 영어 버전으로 했는데, 기본 폰트가 Arial로 되어 있어서, 한글 입력 시 다 깨졌다. 혹시 한글 입력이 안되는 문제가 있다면 카톡 설치 후 설정에서 폰트 변경하자.

카카오톡 설치

지금부터 wine이 어떻게 도는지 간결하게 이해할 필요가 있다. wine <exe file> 를 실행하면, 아까 구성된 $HOME/.wine 디렉터리 내에서 윈도우 환경처럼 exe 파일을 실행하게 된다. 아 물론, 정확히 코드 까보거나 공식문서 정독한건 아니지만, 실행하는덴 이 정도 이해만 하면 된다. 그럼, 이제 어떻게 해야 하는지 슬슬 눈치챘을 것이다.

카카오톡 설치파일 다운로드 및 실행

카카오톡 PC버전 설치파일을 다운로드하고 해당 exe 파일을 wine으로 실행한다. (wine KakaoTalk_Setup.exe)

카카오톡 실행파일 실행

설치 중에 특별히 설치 디렉터리를 변경한게 아니라면 아마 $HOME/.wine/drive_c/Program\\ Files\\ (x86)/Kakao/KakaoTalk/ 디렉터리에 KakaoTalk.exe 실행파일이 들어가 있을 것이다. 이걸 그냥 wine으로 설치파일 실행한 것과 동일한 방법으로 실행하면 된다.

난 매번 찾기 귀찮아서 스크립트로 빼놨다.

#!/bin/bash
wine "$HOME/.wine/drive_c/Program Files (x86)/Kakao/KakaoTalk/KakaoTalk.exe"

kime 사용자 한글입력 문제 해결

카카오톡 실행 전에 kime-xim을 실행해 놓아야 한다. 그렇지 않으면 한글 입력이 안됨.

슬슬 귀찮아질 것이다. 귀찮으면 조금만 더 힘내서 서비스로 등록하는걸 추천한다.

Rust의 개꿀 라이브러리들

개인적으로 개발을 할 때, 당장 어떻게든 만들어내는건 어렵지 않게 하지만, 개발 도구를 맛깔나게 활용하지는 않는 편이다. 그냥 '요래요래 하면 될거같은데?' 하고 손부터 가는 타입. 그래서 개꿀 라이브러리를 놓치고 깡으로 손으로 짜는 경우가 많다.

그러던 중, CTO가 관리하던 코드를 물려받게 되었다. 코드가 아름답다고 한다면 이런 것일 것이다. LSTM + 강화학습 모델의 학습 인프라를 구성하는 코드리포인데, 시뮬레이션은 기본, 데이터 프로세싱까지 모두 담겨있다. 마이크로서비스를 섣불리 도입해서 삽질을 하지도 않고 바로 모노리포 구조로 잘 짜여 있었다. 여튼 개쩐다는 표현은 대충 이쯤에서 마무리하고...

structopt: Argument를 편리하게 받자

일단 난 CLI를 더 선호한다. 그래서 왠만하면 CLI로 툴을 만드는 편이다. 그런데, bash scripting을 하는 경우가 많아서, argument를 가져올 때 손이 알아서 아래와 같이 입력한다.

if [ $# -ne 2 ]; then
    echo "Usage: $0 <hello> <world>"
    exit -1
fi
HELLO=$1
WORLD=$2

그리고 이 습관은 rust까지 따라왔다.

fn main() {
    let args = std::env::args().collect::<Vec<String>>();
    if args.len() != 3 {
        eprintln!("Usage: {} <hello> <world>", args[0]);
    }
    let hello = &args[1];
    let world = &args[2];
}

그리고 난 CTO가 물려준 코드에서 structopt를 발견했다. 아 물론, 다른 마이크로서비스에도 있었는데, 내 담당은 아니라 대충 넘겼었긴 했다. structopt를 이용하면 아래와 같이 이용할 수 있다.

use structopt::StructOpt;

#[derive(StructOpt)]
#[structopt(name = "opt", about = "hello world")]
struct Opt {
    #[structopt(short, long)]
    hello: String,
    #[structopt(short, long)]
    world: String,
}

fn main() {
    let Opt { hello, world } = Opt::from_args();
}

코드 줄 수는 별다른 차이가 없어 보일 수 있지만, eprintln이 사라진 것을 볼 수 있다. argument를 입력받기 위한 안내를 굳이 내가 입력하지 않아도 되는 것이다. 게다가 커맨드라인 상에서 더 깔끔하게 나온다. 추가적으로, Opt struct에서 타입을 정의했다. 자료형에 대해 걱정할 필요가 없이 가져다 쓰면 된다.

serde: 데이터 파싱? 직렬화? 그냥 add하자

이 라이브러리는 내부 프로토콜로서 프로토버프를 이용하면서 예전부터 이용하고 있었다. 꽤 깔끔하게 구조체를 표현할 수 있어서 좋다 정도였고, api 클라이언트를 만들 때, 사용이 아주 권장되지만, 개인적으로 작업을 진행할 때는 귀찮다고 대충 손으로 써내려가면서 만들어 왔다. 하지만, API 클라이언트를 만드는 일이 생각보다 많다. 당장, 개인적으로 작업중인 한국투자증권OpenAPI, open-banking-api만 해도 API 클라이언트다. 또한 회사에서 메시지큐의 공식 라이브러리에서 지원하지 않는 Admin API를 날리는 라이브러리도 개발했는데, 이 또한 API 클라이언트이다. 그리고 이 클라이언트가 날린 리퀘스트에 대한 리스폰스를 파싱하기 위해서는... 그냥 serde 쓰자. 나처럼 손으로 다 빚어내지 않았음 한다 ㅋㅋㅋㅋㅋㅋ. 체대 아니랄까봐 신체의 스피드로 개발속도를 내고 앉아있다. 개인적으로 불편함이 어느정도 쌓여야 해소를 위해 움직이기 때문에, open-banking-api를 작업하면서 serde를 도입하게 되었다. 물론 한국투자증권API에도 serde 라이브러리를 add해놓긴 했지만, 사용해야 할 모든 곳에 제대로 사용하지는 않고 있다. 조만간 바꿔야지.

serde는 데이터의 serialize, deserialize를 지원하는 라이브러리다. derive를 통해 쉽게 serialize/deserialize 매서드를 가져올 수 있다. 만약 이게 없으면 아래와 같이 작성해야 한다.

use json::json;

fn main() {
    // deserialize
    let raw = b"{\\"hello\\":1,\\"world\\":\\"universe\\"}";
    let parsed_json = json::parse(&raw).unwrap();
    let mut hello = 0;
    let mut world = String::new();
    match parsed_json {
        json::JsonValue::Object(o) => {
            match o.get("hello") {
                Some(hello) => {
                    match hello {
                        json::JsonValue::Short(n) => {
                            let (positive, mantissa, exponent) = n.as_parts();
                            hello = positive as i64 * mantissa as i64 * 10i64.pow(exponent as u32);
                        },
                    }
                }
                None => todo!(),
            };
            match o.get("world") {
                Some(world) => {
                    match world {
                        json::JsonValue::String(s) => {
                            world = s.to_owned();
                        },
                    }
                }
                None => todo!(),
            }
        },
        _ => {
            todo!();
        },
    }

    // serialize
    let hello = 1;
    let world = "universe".to_string();
    {% raw %}
    let serialized_message = format!("{{\\"hello\\":{},\\"world\\":\\"{}\\"}}", hello, world);
    {% endraw %}
}

json::parse가 모든 것을 꼬아버렸다. 아주 귀찮다. 이걸 serde와 serde_json을 이용하면 아래와 같이 간단하게 해결된다.

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct ParsedJson {
    pub hello: u8,
    pub world: String,
}

fn main() {
    // deserialize
    let raw = b"{\\"hello\\":1,\\"world\\":\\"universe\\"}";
    let parsed_json: ParsedJson = serde_json::from_slice(raw).unwrap();

    // serialize
    let message = ParsedJson {
        hello: 1,
        world: "universe".to_string(),
    };
    let serialized_message = serde_json::to_string(&message).unwrap();
}

serde 만세

PC의 OS로써 Arch Linux를 사용하는 이유

난 아치리눅스(Arch Linux)를 메인 OS로 이용하고 있다. PC는 물론, 노트북, 회사 업무용 PC까지 모두 아치리눅스이다.

아치리눅스를 쓰게 된 계기는, 회사의 CTO가 아치리눅스를 사용하셨는데, 꽤 재미있어 보였기 때문이었다. 뭔가 저걸 하면, 그냥 자연스럽게 따라오는 것들이 있을 것 같았다.

백문이 불여일견. 바로 트라이했다.

관문들

관문 1. OS 설치

당시까지 써봤던 설치 USB는 설치를 위한 GUI가 뜨는게 대부분이었다. 최소한 TUI더라도 설치를 진행하는게 바로 진행되는, 설치만을 위한 절차가 진행되었다.

그런데 아치리눅스 설치 USB를 만들어서 USB로 부팅했더니, 그저 검은 리눅스 커맨드라인이 하나 나왔다. 띠용? 하고 찾아보니, 설치를 위한 리눅스가 실행된 것이다. 아치리눅스를 PC에 설치하기 위해서는 커맨드라인을 이용하여 파티셔닝과 마운트를 진행하고, 이걸 부트로더에 등록하는 절차를 거치고, 마운트한 디렉터리 중, / 디렉터리가 되는 곳에서 아치리눅스 환경을 설치해야 했다. 이 때 필요한 것을 설치하지 않으면 리눅스 부팅에 성공한다고 해도 반쪽짜리가 된다. 특히 노트북에 설치하는데, 와이파이를 이용해야 하는 경우... 그냥 집 가서 랜선 이용하는걸 추천한다. 정신건강에 좋지 않다.

관문 1로 얻은 것: 만능 해킹USB

아니 이거 지금보니, USB로 부팅하면, 루트잖아? 어딜 가든 이 USB 하나 있으면 이 USB로 부팅해서 자료를 뜯어낼 수 있다. 아 물론 암호화되었다면 할 수 없겠지만. 근데 암호화 파티션 구성하는게 꽤 귀찮아서 거의 안할 것이다. 물리적 보안이 중요한 이유다.

뭐 그렇더라도 내가 이걸 진짜 해킹에 이용하진 않는다. 굳이 밥벌어먹는데 문제 없는데 할 이유가 없다. 아 밥 벌어먹는데 문제 있어도 굳이 앞으로 더 힘들어지게 그럴 이유가 없다. 가끔 퇴사자가 남겨둔 PC에 로그인이 불가한데 OS를 재설치해야 하는 경우 자료 백업을 위해 이용한다.

관문 2. GUI 설치

사용자친화적인 리눅스들은 처음에 gui 설치 여부를 선택하면 알아서 설치해 준다. 그래서 왠만하면 건들지 않고, 최적화된 윈도우 매니저를 이용하게 된다. 아치리눅스는? 그런거 없다. 그래서 CTO가 자신이 아치리눅스에 bspwm 올리고 뭐시기 뭐시기로 개발한다 했던 것을 떠올려서 bspwm을 검색해서 겨우 하나 찾아서 따라했음. 그리고 쓸만한 환경을 구성하기 위해서는 bspwm 뿐만 아니라 설치할 것들이 더 많았다.

관문 2로 얻은 것: OS 설치를 다시 할 때 편하게 하기 위한 꾀를 부리기 시작함

사실 OS 설치 자체는 그리 어렵지 않았다. 유선 환경이면 몇 번 해보면 익숙해지고, 까먹으면 살짝 검색해 보면 됨. 문제는 GUI 구성은 자잘자잘한게 많아서 다 기억하기 어려움.
그래서 GUI 구성을 위해 이용했던 ~/.config 디렉터리를 백업해 두게 되었다. 사실 설치 스크립트도 만들까 하다가 안했는데, 정말 한 번만 더 재설치할 일 있으면 정말 만들 것이다. 그리고, 외장 SSD를 구매해서 거기에 아치리눅스와 GUI를 설치했다. 그리고 intel, amd cpu 모두 호환되도록 설치해서 intel cpu인 PC와 amd cpu인 노트북 모두 이 SSD로 부팅해서 동일한 환경을 이용하고 있다. 짐이 좀 늘고, 부팅하기 위해 외장SSD를 꽂는게 조금 불편하긴 한데, 아무데서나 동일한 환경으로 부팅할 수 있으니 좋다. 아 그리고 이것도, 따지고 보면 만능 해킹 외장 SSD다. 그리고 가끔 수틀리면, 주인의 동의를 구하고 이 SSD를 이용해서 다른 사람의 PC를 빌릴 수 있다. 그리고 내 환경 그대로 이용할 수 있음.

관문 3. 각종 프로그램 설치

아치리눅스의 패키지 매니저는 pacman이다. 그리고 AUR이라는걸 이용할 수 있는데, 난 AUR Helper로 yay를 이용한다. 그런데 아치리눅스가 마이너하다 보니, pacman은 물론 yay에서도 조회되지 않는 프로그램이 가끔 있다. 그럼 공식 홈에서 받게 될텐데, 데비안 계열이나 페도라 계열은 쉽게 설치할 수 있는 패키지 파일이 제공되지만, 다른 리눅스는 그런거 없다. tar.xz를 대부분 이용한다. 받아서 makepkg 등의 절차를 거쳐야 한다.

관문 3으로 얻은 것

tar.xz만 있으면 어디든 설치 가능한거네? 를 깨우침

아치리눅스를 사용한다면?

Vim

vim 써줘야 한다. 이게 완전체라고 본다.

vim으로 개발하면 좋은 점?

일단, vim 세팅을 제대로 하면, 꽤 편하다. 게다가 ssh 접속만 하면 굳이 다른 프로그램 필요 없이 코딩이 가능하다. 추가적으로, 마우스 사용 빈도가 줄어든다. 과거 손목에 문제가 생긴 경험이 있는데 그 때 문제의 원인은 과도한 마우스 사용이었다. 당시 고객사의 클라우드에 제품을 설치하기 위해, 회사의 클라우드에서 이것저것 테스트해보고 실습해보면서 고객사에서 발생한 문제 재현해서 해결하기 위해 밤낮없이 일했던 때였다. 그 때, 하다하다 안돼서 결국 버티컬마우스를 구매했다. 지금은 12시간 코딩만 해도 손목에 아무 문제가 없다.

아 그리고, tui에 익숙해지게 된다. 보통 리눅스를 사용하더라도 vs-code같은걸 깔아두게 되면 터미널은 code .을 입력하기 위해 cd를 반복하는데 사용한다. vs-code를 켠 이후, 커맨드라인을 사용할 일은 빌드/컴파일 할 때 정도이다. 하지만 vim으로 개발하는 경우, 왠만한건 다 명령으로 해결하기 때문에 편해지기 위해 명령을 잘 하는 법을 찾게 되고, 실력이 는다. 게다가 language server를 설치하지 않았더라도, 대충 라이브러리 위치 찾아가는 센스가 생김. 언어가 추가될 때마다 vim 세팅을 진행해야 하는데, 보통 처음엔 그냥 불편한 대로 사용하기 때문이다. 그러다가 사용 빈도가 올라가서 불편함이 가중되면 세팅을 진행한다. 그 때는 이미 해당 언어에 대해 어느정도 익숙해진 후이다.

그냥 불편한게 다인 것 같은데?

맞다. 불편하기 때문에 편해지기 위해 발악하는 과정에서 이해도가 높아진다. 그런데, 주니어일 때 아치리눅스를 사용한건 신의 한 수였던 것 같다. 왠만한 문제는 당황하지 않는다. ㅋㅋㅋㅋㅋㅋ

주석의 중요성

모델이 할 수 있는 주문의 상/하한을 결정하는 공식을 고객사가 수정해달라고 하는 경우가 종종 있다. 문제는, 모델은 해당 공식에 대해 학습되어 있지 않은 채 프로덕션 단에서 수정해야 했다는 것이다. 빨리 고쳐야 하니 말이다. 물론 성능이 떨어질 것임은 숙지시켰지만, 이럴거면 왜 AI를 쓰는가 하는 의문이 생긴다. 여튼 우리는 개쩌는 AI를 만들어 낼 것이므로 성능 향상을 계속 지향하고 있다.

하지만 걸림돌이 몇 가지 있었다. 해당 공식에 대한 설명은, 전-전 팀장님에게 들은, 고객사에서 수정요청해서 급하게 반영한 공식에 대한 설명 뿐이었다. 심지어 내 머리 속에 유일하게 남아있었다. 대충, "합성함수를 사용한다 + 그래서 이런저런 요건을 만족하는 방정식을 만들려고 하는데 + 빡세서 수치 몇 개 대입해서 하드코딩 했다". 딱 이 내용이었다. 그리고 이 내용에 대한 주석은 전혀 없었다.

이렇게 되면 코드만 보면 절대로 의도를 알아차릴 수 없다. 공식을 자세히 밝힐 수는 없지만, 파라미터의 값에 따른 case문 형식의 하드코딩이 들어간 시점에서, 이미 그 방정식의 성질은 유추할 수 없게 된다. 여튼 그래서 기억을 더듬어 다시 해당 공식의 의미는 정리해 놨다. 팀원들에게도 설명해 두긴 했는데, 문서화 했었나, 안했었나... 여튼 내 노트에 있는데 조만간 업데이트해야겠다. 주석도...

또, 고객사에서 수정해달라고 하기 전부터 이용되고 있던, 모델이 학습된 환경과 동일한 공식의 의도 또한, 주석이 없다. 다만 다행인 것은, 이건 하드코딩은 아니다. 1차함수, 지수함수, 로그함수, 합성함수가 이용되었는데, 몇 가지 상수는 있지만, 괜찮은 수준이다. 하지만 처음에 코드에서 이 공식을 뽑아낸 직후엔 의도를 파악하지 못했다가, 어제 학습 데이터 프로세싱 돌리면서 시간이 떠서 이걸 보다보니, 그제서야 파악할 수 있었다.

이 공식은 완벽하지는 않지만 생각보다 현재 고객사가 요청했었던 요건들을 어느정도 반영하고 있었다. 이걸 모르고 있었기 때문에, 현재 고객사가 요청한 것들을 만족시키기 위해, 쓸데없이 프로토콜에 새로운 필드를 심고, 두 개의 파라미터로 공식을 만들게 되었다. 그냥 하나의 파라미터로 이용하는 공식을 좀 더 가다듬으면 되었는데 말이다.

이렇게 또 소중한 경험을 쌓게 되었다(리버스 엔지니어링). 나도 평소에 주석은 좀 장황한 절차가 있는 경우 스텝에 대한 설명 정도를 적는 정도인데, 앞으로는 해당 함수의 의도도 잘 적어놔야겠다. 특히 1차함수 혹은 사칙연산의 범위를 벗어난 경우는 그 식의 의도는 물론, 함수의 성질까지 무조건 적어야겠다.

Simple is the best

simple-is-the-best.md

이전까지는 회사에서 제품 설치 난이도를 줄이기 위해 쿠버네티스 설치를 간편하게 하는데 집중하고 있었다. 그러다가 문득, 쿠버네티스를 사용하는 이유에 대해 고민해보게 되었다. 고민해보게 된 이유는 간단하다. 매번 장애가 나면 대부분 네트워크인데, 이 네트워크 문제를 더 복잡하게만 만들고, 스케일아웃을 하지 않는 온프레미스 서버이기 때문에 클라우드처럼 비용 최적화를 위해 오토스케일을 할 필요가 없기 때문이다.

결론은 금방 나왔다.

쿠버네티스를 사용하는 이유

쉽게 말해서 한 명의 인프라 관리자가 커버할 수 있는 서버를 늘리는 것이다(일자리 냠냠). 이전엔 각 서버를 따로따로 관리하면서 진행했겠지만, 쿠버네티스를 서버에 설치하고 노드를 엮는 순간 한 관리자가 API 호출을 통해 프로세스를 원하는 노드에 쉽게 올릴 수 있다. 심지어 인프라를 코드로서 관리할 수 있게 된다. 인프라 구성을 yaml파일로 만들어 두면, 그냥 kubectl apply -f filename.yaml 한 방에 구성된다. 코드로서 관리한다는 것은 라이브러리화가 가능하다는 것도 시사한다. 마치 npm처럼 사용할 수 있는 helm이 등장한다. 클라우드 세팅까지 함께 진행 가능한 Terraform도 등장한다. 꽤 큰 변화가 아닌가 싶다.

문제점

소프트웨어를 제품을 타사에 설치해주는 경우, 쿠버네티스가 여기에 포함된다면, 그리고 상주인력을 파견하지 않는 형태라면, 대참사가 벌어진다. 일단 겪어본 것만 나열해 보겠다.

  1. 서비스에 장애가 발생했는데, 다수의 Restart 후 etcd의 리소스 사용량이 치솟더니 호스트가 죽어버린 케이스가 발생했다. 문제를 전달받고 방문했을 땐 이미 디버깅조차 할 기회가 없었다. 디버깅을 위해 루트 권한이 필요함은 물론 기본이다.
  2. Calico CNI를 오랫 동안 켜두면 어느 순간 멈춘다. → 매일 서비스 가동과 함께 재시작한다.
  3. 로그 용량을 제한할 정책을 제대로 만들지 않고 서비스를 방치하면 거래량이 많거나 다른 문제가 있는 경우 터진다.
  4. 리눅스의 자동 업데이트 기능으로 인해 도커 데몬이 영향을 받으면 다 터진다. → 자동 업데이트를 해제한다.
  5. Kubeadm으로 설치할 때 발급된 API call 시 사용할 인증서의 유효기간은 1년이다. → 1년 마다 모든 고객사를 방문해서 루트 권한을 받아 인증서를 갱신해야 한다.
  6. 고객사의 쿠버네티스 버전을 업데이트하기 위해서는 루트 권한을 받아서, 현재 클러스터를 내리고, kubelet도 내리고, kubelet, kubeadm, kubectl 바이너리를 새 것으로 교체하고, 쿠버네티스의 새 버전 이미지들을 로드하여 kubeadm init만 하는 과정이면 정말 쉬울텐데... 1.18버전에서 1.21버전 올라갈 땐 몇몇 피쳐가 정식 피쳐로 바뀌면서 서비스의 yaml 파일들을 싹 업데이트해야 했고, 1.26버전을 올라갈 땐 도커 지원을 중단하는 큰 변화가 발생해서 containerd를 추가로 세팅해야 했다. 솔직히 또 1년 안에 무슨 큰 변화가 발생할 지 겁이 난다.

보다시피, 쿠버네티스는 인프라를 직접 관리하는 운영자가 사용하기 위한 것이지, 타사에 납품할 제품에 심는 그런 것이 아니다.

그럼 어떻게?

이미 내 눈 밖에 났다. 쿠버네티스를 날려버렸다. 내가 관리하는 마이크로서비스가 쿠버네티스에 요청을 날려서 모델을 로드할 워커의 개수와 모델에 등록할 작업의 개수를 관리하는 역할을 하는데, 여기서 쿠버네티스 환경인지 아닌지를 탐지해서 쿠버네티스가 아닌 경우 해당 피쳐를 off시키도록 바꿨다. 애초에 제품이 스케일아웃을 고려하여 stateless하게 개발되었기 때문에 다른 마이크로서비스들엔 딱히 이슈가 없었다. 그리고, 도커 이미지가 아닌, 바이너리로 그대로 가져다 쓰는 것도 문제 없도록 했다. 물론, 새 고객사엔 podman으로 서비스를 운영한다. 도커 이 살찐고래는 너무 많은 권한을 가지고 있다. 단지 포트 열고 통신하고 로직을 돌릴 프로그램을 적재하는데 루트권한은 투머치다. podman은 루트가 필요없다. 만만세. 아, 그리고 이후 시간이 날 땐 rpm, deb 패키징도 해볼 생각이다.

결과

편해졌다.

그런데, 뜬금없이 이 과정에서 엄청난 일이 발생했다. 사용하고 있는 메시지큐의 리소스 요구량이 확 줄어든 것이다. 기존엔 2000개 동시작업을 처리하기 위해 broker와 bookie를 3개씩 올리고 거기다 각각 3cpu를 할당하고, 워커에 4개를 할당하고 zookeeper, proxy까지 합하면 최소 25cpu를 할당해야 했는데, 그냥 standalone 이미지 하나로 올리니, 12-thread cpu 서버에서 2000개 잡을 비슷한 수준의 레이턴시를 보이며 돌려버렸다.

결국, 2.0의 흔적은 신규 학습에서 제외된 몇몇 모델을 제외하고, 대부분 사라졌다. 물론 사내에서 실장 레코드를 쌓기 위한 서버는 여전히 쿠버네티스를 이용 중이다. 실시간으로 관리하고 있으니까 말이다.