prototype 웹 모듈에 대하여

  항상 고민한 주제가 있습니다. 선로 주변에서 작업하는 사람들의 안전문제입니다. 열차의 정확한 위치를 알아야 작업자 안전이 강화됩니다. 열차에 내비게이션을 달아서 위치를 확보했습니다. 하지만 GPS 에 의존하는 위치정보는 의외로 많은 음영구간을 가지고 있습니다. 음영구간에도 위치를 알 수 있는 데이터가 필요했습니다. 그리고 그 데이터를 찾았습니다. 정말 많은 시간이 걸렸습니다. 데이터를 패킷 단위에서 분석하여 유효한 정보를 추출합니다. 이 정보를 활용하여 좀 더 안전한 작업환경을 만들 수 없을까 고민하고 있습니다. 프로토타입 화면을 하나 만들어 보았습니다. 이 데이터를 활용하면 열차가 정확히 어느 지점을 지나는 지 알 수 있습니다. 음영구간에서도 위치정보를 알 수 있는 데이터입니다. Flutter 로 작성하여 웹 어셈블리로 포팅한 모듈입니다. 앞으로 가야할 길이 많이 남았지만 그래도 묵묵히 주어진 길을 가야겠습니다. 이게 운명이라면..., https://ctc.whenyourapprun.com

선로변 작업자 안전에 대하여

 열차가 지나다니는 선로는 굉장히 위험하다. 그 주변에서 작업을 하는 사람들이 많다. 갑자기 나타나는 열차에 치이는 사고는 잊을만 하면 일어난다. 이 문제를 해결하기 위해 많은 시도가 있었다. 그중 내가 경험한 내용만 이야기 하고자 한다. 열차에 내비게이션을 달았다. 열차위치를 파악하여 그 위치를 서버로 전송했다. 작업자 앱을 만들어서 열차 위치를 표시하였다. 이름하여 열차접근경보 앱이다. 현장의 반응은 좋았다. 하지만 곧 문제가 나타났다. 터널이나 GPS 신호를 받지 못하는 상황에선 열차 위치를 알수 없었다. 그런 상황이 의외로 많았다. 내비게이션이 무용지물일때 열차위치를 파악해야 했다. 신호설비에 주목하였다. 폐색구간이라고 열차가 들어가 있는 선로구간을 말한다. 이걸 활용하면 내비게이션이 없어도 열차위치를 파악할 수 있다. 많은 우여곡절 끝에 그 정보에 접근할 수 있는 채널만 얻었다. 정보에 대한 자세한 내용은 제공되지 않았다. 16진수로 전송되는 네트워크 패킷 속에서 찾아야 했다. 첫차를 기준으로 매일 패킷을 분석하였다. 광명역을 지날 때 항상 같은 값이 나타나는 걸 확인했다. 간단한 앱을 작성해서 특정 값이 나타나는 시점의 좌표를 찍었다. 이 값을 기준으로 내비게이션 데이터가 없을 경우에도 열차 위치를 표출해 줄 수 있었다. 현장은 좀 더 세밀한 위치와 상/하선 구분 등을 요구하였다. 그걸 구분하기 위해서는 신호정보에 대한 분석이 필요했다. 정성이 하늘에 닿았는지 우연한 기회에 신호정보 분석에 성공했다. 현재는 열차가 폐색구간을 지나면 나타나는 신호정보를 데이터베이스로 구축하고 있다. 이게 구축이 되면 이 정보를 위치정보와 Mapping 하면 상/하선 구분 및 몇번 선인지 가능하다. 서비스가 어디까지 진화할지 나도 궁금해진다.

코레일 명절 열차표 예매 대용량 트래픽 처리 경험

코레일에서 명절 열차표 예매는 전쟁이다. 예매 시작과 동시에 약 5분 동안 황금시간대 표가 예매되기 때문이다. 처음 코레일에 와서 시스템 분야를 맡으면서 본 현상은  대용량 트래픽이 발생 되었을 때 사용자 화면은 흰색으로 정지되어 있다는 것이다. 그래서 순번대기표를 적용 하자고 제안 했을 때  대부분의 결정권자들은 어차피 접속해서 시스템에 들어와도  표를 못구하는 고객들인데 꼭 돈 들여서 도입해야 하냐는 의견이었다.  어찌하여 순번대기표를 도입하기로 하였다. OOO이라는 제품이었는데 국세청 연말정산을 처리했던 업체였다. 처음에 그 업체에서 제공하는 장비수는 O대 였다. 이걸로 충분하다고 전국민 들어오는 연말정산도 널널했다는 입장이었다. 시작하자마자 죽었다. 지금은 그 장비수는 OO대로 운영중이다. 현재는 금요일 오후와 주말에 접속량이 많아서 자동으로 걸리는 수준이다. L4를 이용한 웹서버를 병렬 Scale Up 하여 최대 허용량까지 접속수준을 높이고 WAS를 통한 서비스 호출하는데 결국 데이터베이스 Update 하는 시간이 최대 능력치이다. 이 능력치를 99.9% 올리고 모니터링을 한다. 모든 수치는 빨간색으로 표시되고 CPU, Memory 등 자원을 전부 풀로 사용한다.

개발도구 경험에 대한 작은 생각

  지금까지 개발을 해오면서 경험한 내용을 공유하고자 합니다. 저의 경우는 처음 아이폰 개발을 Objective C 로 시작하였습니다. 초창기라 앱을 만들어서 올리면 유료도 꽤 다운을 받았습니다. 이후 아이폰은 Swift로 넘어가면서 같이 넘어갔고 또 그 이후로 SwiftUI 까지 개발을 하였습니다. 안드로이드 경우는 자바로 만들기 시작하였습니다. 이후 Kotlin 으로 변경 되었으며 coroutine 기능은 정말 막강하더군요. scaffold 가 너무 잘되어 있고 jetpack compose 로 넘어가니 개발 생산성이 좋더군요. 같은 앱을 서로 다른 언어로 다시 작성하는게 번거로워서 KMM(Kotlin Multiplatform Mobile) 을 사용했습니다. 비지니스 로직을 분리하니 일이 한결 쉬워 졌습니다. 하지만 화면 부분을 각각 코딩하니 다시 번거로웠어요. 이후 Flutter 를 만났습니다. scaffold 를 지원하더군요. dart 언어로 개발을 하고 안드로이드 경우는 빌드 그래들 수정을 해야 하며 아이폰의 경우 Xcode 에서 빌드와 업로드를 해야 했습니다. 서버의 경우는 처음에는 리눅스용 swift 로 Perfect 를 활용해서 서비스를 작성하였습니다. 작지만 빠른 서비스 였지만 범용성이 문제 였어요. 그리하여 노드로 변경하였습니다. 자바스크립트 정말이지 매력적인 언어입니다. 범용성이 좋아서 웬만한 모듈은 npm 에 다 존재하더군요. 현재는 Visual Code 로 Flutter 로 화면을 만들고 백엔드 서비스는 Node Koa 를 사용하고 있습니다. 기술은 계속 발전하고 사용자 편의성은 좋아집니다.

LetsEncrypt 인증서 wildcard 로 갱신하기

이미지
 letsencrypt 인증서를 사용하고 있다. 분기마다 갱신하는데 그리 귀찮지는 않다. 무료니까.... 그동안 www 로만 서비스 하던걸 앞에 다른 도메인이 필요한 상황이 되었다. 나는 가비아 도메인을 사용하고 있어서 이 명령어를 실행한다. $ sudo certbot certonly --manual --preferred-challenges dns -d example.com -d www.example.com 여기서 빨간색으로 강조된 문자열이 필요하다. 이 문자열을 가비아 페이지에서 등록하면 된다. TXT 타입에 _acme_challenge 내용에 문자열을 입력한다. 이후 ttl 시간 만큼 갱신되는데 시간이 필요하다. 성공하면 두개의 pem 파일이 생성되었다는 것이 보인다. 이 문자열을 하나로 합치면 된다. $ sudo cat /etc/letsencrypt/live/host.com/fullchain.pem /etc.letsencrypt/live/host.com/privkey.pem > /etc/haproxy/host.pem 나는 이렇게 하나의 문자열로 합쳤다. haproxy 에서 ssl 인증서를 host.pem 으로 가져오기 때문이다. 이제 적용이 되었으니 haproxy를 재기동하면 된다. $ sudo systemctl restart haproxy  브라우저에서 열쇠 아이콘을 클릭하면 인증서에 대한 정보를 볼 수 있다.

Flutter 에서 Parent Widget 강제로 Update 하는 방법

Flutter 에서 이런 경우가 종종 있다. 홈 화면에서 버튼을 터치하면 기능화면으로 이동한다. 홈화면과 기능화면에 각각 포인트의 상황을 나타내는 텍스트가 있다. 기능 화면에서 포인트를 하나 감소 시킨다. 기능 화면 상단의 돌아가기 버튼을 터치하면 홈화면의 포인트로 감소된 상태로 보여야 한다. 하지만 홈 화면의 포인트는 감소 전의 상태로 보인다. parent widget update 로 검색해도 뻘소리만 나온다. 나의 해결 방안은 이렇다. 기능화면에서 버튼 터치를 홈 화면으로 전달한다. 홈 화면에서 전달된 버튼 이벤트의 로직에 포인트 감소를 처리한다. 기능화면 소스는 이렇다 class DangYoungPage extends StatefulWidget { const DangYoungPage ({ super . key , required this .onClosed}); final Function ( bool ) onClosed; @override State < DangYoungPage > createState () => _DangYoungPageState (); } 선언은 이렇게 해야 부모 위젯에 이벤트를 전달할 수 있다. AppBar ( title : Text ( 'dangYoung' . tr ()), backgroundColor : Theme . of ( context ).colorScheme.inversePrimary, centerTitle : true , automaticallyImplyLeading : true , leading : IconButton ( onPressed : () { widget.onClosed( true ); Navigator . pop ( context ); }, icon : const Icon ( Icons .arrow_back), ), ), Scaffold 앱 바의 내용을 변경하고 여기 이벤트를

비침습 혈당 측정에 관하여

아침에 일어나면 바늘로 손가락을 찔러 피 한방울을 매일 본다. 오늘 이 피 한방울은 나에게 어떤 결과를 줄까 하면서 말이다. 정상 수치내로 결과가 나오면 어제는 잘 살았구나라는 안도감으로 수치가 높게 나오면 어제 반성하면서 자책으로 하루를 시작한다. 매일 바늘로 손가락을 찌르는 고통도 작지만 싫다. 어차피 혈액내 포도당 농도를 측정하는 것이므로 다른 방법이 있을 것이다. 애플이 지난 10년간 수백명 대상으로 실험 했다는 뉴스가 있다. 자본과 기술력도 있는데 10년에 고작 수백명이 뭔가 이 수치로 유의미한 결과가 나올까? WWDC 2023 에 해당 기능이 애플워치에 탑재될 거란 루머만 돌았다. 결국 발표내용엔 없었다. 혹시나 하여 알리 익스프레스에 무채혈 혈당 측정을 검색했더니 많은 제품들이 나왔다. 가격은 대략 3만 ~ 15만원 정도 스마트워치였다. 그중 5만원대가 가장 많이 팔리고 있었다. 어차피 아침마다 측정하는데 이거 구매해서 어느정도 정확도가 나오는지 확인해보아야겠다. 정확도를 떠나서 이런 제품을 내서 팔 수 있는 환경이 부럽다. 사용자들이 많아질수록 제품은 더 좋아질 것이고 기술은 발전한다. 이미 우리 앞에서 뛰고 있는 걸 바라만 보는 것 같아 착잡하다.