This Month What I Learned 10

주영택·2021년 10월 2일
0

This Month What I Learned

목록 보기
10/24

Hotwire

DHH 의 새 작품으로 hey 서비스의 공개된 아키텍처 중 하나인 듯 하다.

websocket 으로 능동적 통신을 구성하고 html 을 다시 전면으로 내세우는 트랜드를 주도하고 있다. Phoenix 의 LiveView 기술과 유사할 것으로 예상하는데 엘릭서는 모르니까... 그냥 추측;

전체적으로 프론트엔드 마크업에 명세를 모두 구현하고 있다. 몇 시간 샘플 코드를 구성해 보고 있는데

  • stimulus 기술을 통해 뼈대를 구성하고
  • turbo 를 통해 신경을 연결하는

형태이다.

코드는 fastify 서버를 기반으로 작성해 보고 있는데 fastify 와 hotwired/turbo 를 연동하는 샘플이 있어 다음 단계로 진행해 보기 수월하다.

개발 생산성의 딜레마

시장과 비즈니스 요구사항이 예측할 수 없고 복잡하고 모호해진다. 그래서 비즈니스가 성장할수록 뛰어난 기획자나 프로젝트 매니저가 필요하다. 그리고 더 많은 개발자가 요구된다.

그런데 사업을 계속 성공적으로 유지하기 위해서는 비즈니스는 더 기민하게 시장을 대응해야 한다.
결과적으로 더 빠르게 출시/배포를 하게 된다...

그런데 소프트웨어는 릴리즈 할수록 복잡해지고 있다. 개발자 수를 더 늘려 위에서 언급된 사항을 충족시킨다.

같은 조건이라면 개발 리소스 대비 기능의 추가 사항은 줄어들기 시작한다. 특히 출시를 거듭하면서 코드의 증가량은 현저히 줄어든다. 이를 생산성의 저하로 느끼기 시작한다면 딜레마는 시작된다.

리소스는 늘고 있지만 생산성은 줄고 있다.
개발 효율이 떨어지고 있다는 것이다.

왜일까? 초기 출시되는 소프트웨어는 모두 새로운 기능들이다. 새로 시작된 코드가 가득하다.

하지만, 릴리즈가 추가될 때마다 유지할 코드가 늘어난다. 이는 결국 신규 기능을 추가하는 것보다 기능을 안전하게 유지하는 비용이 늘어나게 된다는 것이다.

아키텍처의 필요성

새로운 기능을 추가하는 비용을 줄이기 위해서는 어떻게 해야 하나?

기능을 안전하게 추가할 수 있는 구조를 만들어야 한다. 즉, 프로젝트의 규모에 맞는 효율적인 아키텍처가 필요하다는 것이다.

소프트웨어는 두 종류의 가치를 제공한다. 하나는 현재 요구사항을 만족 시킨다. 또 다른 하나는 변화하는 요구사항을 유연하게 수용해야 한다.

아키텍처는 기능 제공을 위한 것이 아니다. 아키텍처 없이 요구사항은 만족시킬 수 있다.

극단적으로 예를 들면,

동작하지만 고칠 수 없는 소프트웨어가 있고 고칠 수 있지만 동작하지 않는 소프트웨어가 있다.
둘 중 어떤 것이 가치가 있는 소프트웨어 인가?

아키텍처는 요구 사항을 수용하고 유지 보수하는데 필요한 리소스를 최소화 하는 것이다.

기능 개발은 아키텍처 없이도 가능하다. 변하지 않는 요구 사항은 어떤 방법으로도 대응할 수 있다. 하지만 변해가는 요구 사항을 대응하기 위해서는 아키텍쳐가 필요하다.

Caveats

소프트웨어 소스코드에도 팔레토의 법칙이 적용된다. 전체 코드의 20% 정도만 자주 사용되는 코드이다.

  • 제조업에서 설계도가 있으면 재생산 가능하다.
  • 소프트웨어의 설계도는 소스 코드 그 자체이다.

또한, 개인 개발자에 대한 의존도를 낮춰야 한다. 버스 팩터를 늘려야 한다.

GCP 의 compute engine 접속 ssh 계정 설정

gcp 의 compute engine 접속시 로컬에서 ssh 를 통해 접속하는게 보통인데 인프라 변경으로 이 정보가 갱신되는 경우가 있나보다.

기존의 접속 정보를 제거하고 새로 설치하자.

zsh 기준으로 정상 동작을 확인했다. zsh 설정 파일을 여러 PC 에 공유하고 있어서 상대 경로 변경은 추가로 진행하면 된다.

$ gcloud compute config-ssh --remove
...
$ gcloud compute config-ssh

레퍼런스 인데 어떻게 검색해 찾았는지 브라우저 히스토리를 뒤적여도 찾을수가 없다.

저장소 FORK 와 멀티 사이트 운영 계획

vcs 인 git 에는 fork 개념이 없다. 순전히 저장소 관리 서비스의 계정간 활동을 원활히 하기 위한 기능이다.

계정간 이라는 말이 중요한데 같은 계정 안에서는 fork 가 가능하지 않은 구조이다. 적어도 org 단위로 분리되어야 한다.

만약 여러 사이트를 운영해야 하고 비슷비슷한 서비스들 비슷비슷한 코드들을 효율적으로 관리한다면 org 를 여럿 두고 메인 저장소를 fork 하여 upstream 중심으로 코드를 구성하고 관리한다면 좋다.

메인이 되는 저장소를 x 라 해보자. a, b, c 저장소가 downstream 타겟이라면 총 4 개의 계정 또는 org 가 필요하다.

  • x 에는 x/site 가 있고 이를 위한 x/core, x/common, x/util 등을 두자.
  • 그리고 downstream 을 위한 x/site-a, x/site-b, x/site-c 의 운영 정보를 넣어 두고
  • x/site 를 포크하여 a/site, b/site, c/site 를 구성한다.
  • a/site 는 x/site-a 를 참조하여 운영한다.
  • b/site 는 x/site-b 를 참조하여 운영한다.
  • c/site 는 x/site-c 를 참조하여 운영한다.
  • a,b,c 각 site 는 독립적인 배포 시스템을 가진다.

이렇게 fork 된 사이트는 서로간 Pull Request 가 가능하다.
하나의 커밋이 여러 저장소에 공히 적용 가능한 구조를 만드는 것이다.

물론 site by site 가 필요한 경우가 많이 있겠지만 미래의 추가 비용을 절약하기 위해 아키텍쳐링을 하는 이유는 명확하다.

링크들

profile
NodeJS 백엔드 웹 개발자입니다.

0개의 댓글