⛅프로젝트 주제 선정
프로젝트 주제를 선정할 때 고려한 점들이 있었다.
추천받은 몇 가지 키워드 중에서 마음에 드는 키워드를 골라 그에 알맞는 프로젝트 주제를 선정하고자 했다.
따라서 시시각각 변하는 공공데이터인 도로교통정보나 항공정보 등 여러 후보 중에서 고민하다가 날씨 정보를 이용하게 됐다.
나의 현재 위치와 날씨가 비슷한
다른 지역의 사용자들과 데일리룩을 공유하는 SNS ☂️
"집에서 나갈 때마다 남들은 이런 날씨에 무슨 옷을 입었는지 참고할 수 있다면?"
이런 생각에서, 위와 같은 프로젝트 주제가 탄생했다.
날씨 공공데이터 사용하기
날씨 데이터를 사용하는 것은 꽤나 어려운 과정이었다.
openAPI 문서는 친절하지 않았고, 열심히 해석해서 활용해야 했다.
초단기실황은 '가장 최근에 만들어진, 10분 간격으로 업데이트되는 📌실황📌 데이터'를 사용하는 것이고
초단기예보는 '10분 간격으로 업데이트되는 가장 가까운 📌예보📌 데이터'를 사용하는 것이므로
초단기실황 데이터가 초단기예보 데이터보다 더 정확할 것이라 판단했다.
이에 따라 최대한 많은 날씨 데이터를 초단기실황에서 뽑아 쓰고, 초단기실황에서 제공하지 않는 정보는 초단기예보에서 가져와 쓰기로 했다.
하늘상태 데이터와 최저/최고 기온 데이터는 초단기실황 예보로 제공되지 않으므로, 초단기예보와 단기예보까지 세 가지 예보 데이터를 적절히 사용하여 현재 날씨 데이터를 만들었다.
(정확히 말하자면, 하늘상태는 실황값이 아니고 가까운 예보값이므로 현재 날씨라고 보기는 어렵다.)
⛅ '날씨가 비슷한'의 기준 ❔
처음 구상했을 땐 기온과 하늘상태, 강수형태를 가지고 파악하려고 했다.
그러나 📌적절한 옷차림을 파악하는 데에 중요한 것은 실제 기온보다는 체감기온📌이라고 생각하여, 절대적인 기온 대신 체감온도로 비슷한 날씨를 파악하기로 했다.
사람마다 기온 차이를 인지하는 것은 차이가 있지만, 일반적으로 1도~3도부터 차이를 인지하기 시작한다고 한다.
따라서 기온이 +-1도 차이나는 경우를 날씨가 비슷한 경우라고 판단했다.
맑음에 해당하는 경우는 하늘코드(0) 뿐이다.
흐린 경우는 구름많음(3), 흐림(4) 두 가지 모두 해당된다고 생각하여, 두 경우를 비슷한 날씨로 정했다.
강수형태는 딱 나누기에 애매한 부분이 있었다.
기상청에서 제공하는 날씨 정보가 비/눈이거나 빗방울눈날림인 경우는 비로 구분할지 눈으로 구분할지 애매했다.
그래서 이런 날씨는 눈과 비 모두에 해당되는 것으로 정했다.
눈 = 눈 + 비/눈 + 빗방울눈날림 + 눈날림
비 = 비 + 비/눈 + 빗방울 + 빗방울눈날림
🟥 캐싱
우리는 백엔드 서버를 거쳐 기상청으로부터 날씨 데이터를 받아오므로, 사실상 api호출은 두 번 일어나는 셈이다.
클라이언트에서 날씨 정보를 요청하면 그 때마다 외부 기상청 서버로 날씨 데이터를 또 요청해야 한다.
이에 따른 병목 문제를 해결하기 위해 날씨 정보를 캐시에 저장하기로 했다.
사용자의 위치를 Key로, 그 위치의 날씨 정보를 Value로 하여 key-value store인 Redis에 저장한다.
하지만 날씨 정보를 요청하는 위치마다 모두 위경도를 캐시에 저장하는 것은 불가능하다고 생각했다.
우리나라는 동경 124도와 132도 사이 / 북위 33도와 43도 사이에 위치하며
위경도는 소수점 아래 여섯 자리까지 표시하므로, 위치 데이터로 가능한 경우의 수가 약 33만개로 엄청나게 많아지기 때문이다.
이렇게 되면 캐시 데이터가 지나치게 많아지는 캐시 폭증 문제가 발생할 수 있고, 이 경우 캐시 메모리를 낭비하게 된다.
또한 이렇게 세밀한 단위로 캐싱하게 되면 📌hit ratio가 낮아져 캐싱의 의미가 없을 것이라 생각했다.📌
이에 대한 해결책으로, 위경도가 아닌 격자점 단위로 key값을 저장하기로 했다.
기상청은 위경도를 XY 격자좌표로 변환하여 날씨 정보를 요청하도록 하고 있다.
어차피 같은 격자점 내에서는 같은 날씨를 응답하므로, 캐시 데이터를 줄이고 hit ratio를 증가시키기 위해 격자점 단위로 저장하는 것이다.
X축 격자점 수는 149개, Y축 격자점 수는 253개이므로 경우의 수가 약 3.8만가지다.
위경도로 계산할 때보다 key값이 될 수 있는 경우의 수가 90퍼센트가량 감소된다.
날씨 정보를 캐싱하는 것은 좋은 방법이라고 생각한다. 그러나 캐시에 저장된 정보가 실제 날씨 정보와 다르면 아무 의미가 없어진다.
날씨 정보는 계속해서 업데이트되므로 캐시에 저장된 날씨도 이에 맞게 업데이트해줘야 한다.
최저/최고기온은 당일 새벽 2시에 생성된 데이터를 사용하면 되지만,
나머지 모든 날씨 정보들은 10분 간격으로 업데이트된다.
캐시 불일치 문제를 막으려면 날씨 데이터 업데이트 시간마다 캐시가 초기화되거나, 그 시간마다 캐시 업데이트가 일어나야 한다.
이런 캐시 일관성 문제를 해결하기 위해 기상청의 날씨 정보 업데이트 시간마다 캐시의 날씨 정보를 업데이트하기로 했다.
key로 저장된 격자점 좌표를 가지고 기상청 서버로 날씨 데이터를 재요청하여 날씨 정보를 업데이트한다.
원래는 격자점의 개수를 잘못 계산하여, 캐시된 모든 날씨 정보를 업데이트하는 데에 무리가 있다고 생각했다.
따라서 API호출횟수가 많은 지역만 캐시 업데이트를 스케줄러로 자동화하고, 그렇지 않은 지역들은 매 10분 단위로 캐시 삭제하려고 했다.
(이 때 10분 단위라는 것은, 저장된 후 10분이 아니고 n시 10분, 20분, 30분,,과 같은 절대적인 단위다)
(잘못된 정보로 발표했던 자료다.😅😅)
그러나 생각보다 격자점 개수는 많지 않았다. 캐시된 모든 격자점의 날씨 정보를 업데이트하는 것에 무리가 있을지 현재로서는 잘 모르겠다.
이는 개발하면서 문제가 생기면 개선해나가는 방식으로 해결할 계획이다.
➕ 앞으로 개발할 추가 기능
나의 데일리룩 사진에다가 현재 날씨에 알맞는 배경을 추가하고, 현재 날씨를 적어 인스타그램 스토리로 공유하는 기능을 개발할 계획이다.
사용자가 데일리룩을 업로드할 때, 옷 카테고리 태그와 함께 옷을 입었을 때의 후기를 업로드한다.
이에 따라 '어떤 날씨에 어느 옷을 입었을 때 어땠는지' 에 대한 데이터를 수집하고 통계를 내서 적합한 옷차림을 추천해주는 기능을 개발할 계획이다.