2023 파이썬으로 웹 서비스를 만드는게 잘 하는 짓일까?

최근에 본 글 두가지

하이퍼커넥트 기술블로그

https://hyperconnect.github.io/2023/05/30/Python-Performance-Tips.html
고성능 ML 백엔드를 위한 10가지 Python 성능 최적화 팁
2023-05-30

페이스북 인스타그램 메타의 스레드스

이름도 좌까치 지었어
– 장사의 신

https://github.com/facebookincubator/cinder

드장고로 만들고 런타임을 자기들이 고쳐서 썼다고 한다.
cinder…. 빠르다고 하는데… 진짜로 빠를까?
내년쯤에 인프라비용을 핑계로 자바나 고로 리뉴얼 해 버리는건 아닐까?

파이썬으로 대충 돌아가게 만들기

ML은 모든게 프로토타이핑이기 때문에
그리고 다른 모든 부분보다 학습에 코스트가 크게 발생하기 때문에
그리고 API호출시 응답보다 모델 돌리는데도 코스트가 크기 때문에
파이썬의 성능따위 신경 안 써도 되는거 아닐까

스레듯는 프로토타이핑이잖아
사용자가 많아질 때 까지 대충 돌리려고 하는거 아니었을까
하지만 언젠가 리뉴얼을 해야한다.

파이썬으로 만들던건 어떻게 할까

파이썬은 토이 프로젝트나 스크립트 용도 정도로만 썼는데
규모가 좀 있는걸 만들려고 보니….

어차피 스프링 프레임워크같은 구조가 되어버리고 있다.
괜히 성능만 떨어지는 쓰레기를 만드는건 아닐까 하는 불안감이 엄습한다.

이럴거면 spring, ktor, quarkus, go, node 중 하나로 지금이라도 옮겨야 하는거 아닌가 하는 생각이 들기도 하지만
그래도 프로토타이핑은 파이썬으로 끝내는게 좋다고 본다.

생산성은 조금 괜찮은 것 같기도…

나는 pandas dataframe도 pydantic validation도 마구마구 쓸 생각이다.

어차피 리뉴얼당할 운명
파이썬으로 웹 프로토타이핑 하면서 성능따위는 신경끄는게 현명한 것 아닐까?

K8s IaC 도구들 뭘 쓸까?

목적

  • 인프라 코드화 관리
  • 인프라 반복생성
  • 공개된 인프라 설정 사용
    helm chart, operator

사용 케이스

개인 서버 설치시

helm차트 traefik, coredns, haproxy, mariadb, postgresql, 등등 각각을 여러번 실행시키는게 귀찮아서

  1. helm차트 하나에 넣어보기도 하고
  2. helmsman, helmfile 등 helm여러개 실행시키는 툴을 써보기도 했는데

결국엔 python으로 helm차트를 받아서 실행시키는 방법을 쓰게 됐다.

요구사항이 복잡하면 어떻게 해도 공개된 라이브러리만으로 해결이 안된다.

  1. helm 차트는 특정 templates만 편집하는 기능이 없어서 차트를 로컬에 –untar로 받은 후 deployment.yaml만 덮어씌운다던가 하는 방법을 썼다.
  2. helm 설치 전 후로 secret이나 volume을 관리 해 줘야 하는 경우가 있는데 수동으로 하려면 복잡하고 늘 실수를 한다.

회사 서비스 DevOps 관리시

회사에서는 단순 설치가 아니라 직접 개발한 애플리케이션을 배포하는거라서 공개된 helm차트를 쓰지 않는다. 보통 두세단계로 분리해서 실행하게 된다.

  1. 미들웨어 설치 istio, traefik, gateway, kafka, redis 등 k8s 클러스터 또는 서버에 직접 설치할 것들
    helm, ansible, bash 스크립트 등 활용
    자주 안 하는거라 기록만 해 놓고 노가다로 처리하는 경우가 많다.
    회사에 따라… 기록을 안 해서 할 때 마다 잘못되는 경우가 더 많다.
  2. deployment, service 정도만 정의 해 놓고 dev,
    helm차트 한개로 만들거나 kustomization, 등등을 쓴다.

용도별

템플릿 관리

  • https://github.com/helm/helm 24.7k
  • https://github.com/kubernetes-sigs/kustomize 9.9k
  • https://github.com/grafana/tanka 2k
    https://tanka.dev
  • https://github.com/kapicorp/kapitan 1.7k
    https://kapitan.dev
  • https://github.com/GoogleContainerTools/kpt 1.5k
    https://kpt.dev
  • https://github.com/kubecfg/kubecfg 160
  • https://github.com/boltops-tools/kubes 81
    https://kubes.guru
  • https://jsonnet.org – erb, mustache, freemarker처럼 그냥 템플릿엔진에 가까워보임
  • kssonet – 멈춰

런타임 관리 Operator

operator는 패턴이다.
kube api와 통신하는 서버를 한개 올려놓는걸로 이해하는게 쉽다.
kube클러스터에 definition이 올라가면 이 설정에 따라 인프라를 실행시켜주는 것

요즘은 operator를 많이 쓴다는 것 같은데…(진실???)
여러개의 인프라를 동적으로 관리할게 아니라면 helm을 쓰는게 나을 것 같다.
대부분의 상황에서 operator를 왜 써야하는지 잘 모르겠다.
definition.yaml만 apply하면 되서 사용자 입장에서는 조금 더 쉽게 받아들여지는걸까
helm에서 values.yaml만 편집하는거랑 다를게 없는데
helm이 너무 주먹구구식으로 만들어져 있는데 비해 operator의 설정파일이 조금 더 이해하기 쉬워서 인기가 좋은 것 같다.
복잡하게 사용하려면 어렵거나 직접 만들어야 하는건 비슷하다.

공식 도큐먼트 Operator 소개
https://kubernetes.io/ko/docs/concepts/extend-kubernetes/operator/

Operator 도구 선택

도구의 순위보다는 각각 특성이 있어서 선택이 더 어렵다.
선택 기준을 먼저 적어보면

  • 단순 설치는 helm으로 할거니까 operator는 커스텀 기능 개발이 쉬울 것
  • 템플릿이 많아서 웬만한거 가져다가 쓸 수 있을 것

kudo 뭔가 그냥 helm차트 비스무리하게 kafka를 설치 해 버리는데… 오퍼레이터를 관리 해 주는 툴인가?
juju도 좀 그런 느낌이다. lxd컨테이너 기술로 미들웨어 쉽게 설치 해 주는… charm이라는 미리 정의된걸 설치

코딩이 되는 툴은

  • java operator sdk
  • py kops <- 제일 간단해 보임
  • go kubebuilder
  • rust ~
  • dotnet ~

~

  • helm차트와 스크립트 언어로 직접 설치코드 만들기
  • operator는 kops

2023 Python 프로젝트 시작하기

서버개발 시장에서 사라질 줄 알았던 언어… 파이썬…
어차피 서버는 켜 놓는거고 접속자는 얼마 안되니
성능은 개나줘버려 편한게 장땡인 생산성의 시대를 맞아
그리고 AI시대 tensorflow의 언어로 한자리 차지하게 된 파이썬
ChatGPT가 가장 선호하는 언어 1위

좆같은 문법체계가 마음에 안들기도 하지만… 막상 쓰면 편하기도 한 언어

프로젝트 언어의 선택 기준

  • Kotlin-Spring – 대충 잘 모르겠을 때
  • Python – 계산이나 외부API호출이 많고 API호출이 많지 않을 때
  • Go – 별 기능 없고 API호출 많을 때
  • Rust – 본인이 햄스터라면
  • Clojure – 정신병 걸렸을 때
  • RubyOnRails – 쓰지마 병ㅅ니아

WebFramework – FASTAPI

Fastapi: 차세대 빠른속도 API
Django: Meta에서 만든 Theads가 Django로 되어 있다고 한다. 런타임 환경은 cinder라는 cpython3.8의 fork. 서버 비용이 중요한 대규모 서비스인데 왜 그런 선택을….???
cinder를 이용해서 성능개선을 이뤄낼 역량이 되니 다른 회사에서 감히 같은 선택을 하기는 힘들다.

Flask: 빠른속도를 내세웠는데 속도가 쳐지면… 사라질 때… 이제는 FastAPI를 쓴다

ORM – peewee

옛날 사람들은 SqlAlchemy를 떠올리겠지만…
https://github.com/coleifer/peewee 의 Stargazers 10.2k
SqlAlchemy는 7.5k
ponyorm/pyny 3.3k

코드만 보면 뭐가 특별히 좋아 보이진 않는다. 대표들이 데이나화이트랑 같이 만나서 한판뜨고 인터넷 생중계 한 다음에 이긴쪽으로 합쳐버리면 좋을 것 같다.

class Customer(db.Entity):
    email = Required(str, unique=True)
    password = Required(str)
    name = Required(str)
    country = Required(str)
    address = Required(str)
    cart_items = Set("CartItem")
    orders = Set("Order")

class Address(Base):
     __tablename__ = "address"

     id = Column(Integer, primary_key=True)
     email_address = Column(String, nullable=False)
     user_id = Column(Integer, ForeignKey("user_account.id"), nullable=False)

     user = relationship("User", back_populates="addresses")

     def __repr__(self):
         return f"Address(id={self.id!r}, email_address={self.email_address!r})"

class Tweet(BaseModel):
    user = ForeignKeyField(User, backref='tweets')
    message = TextField()
    created_date = DateTimeField(default=datetime.datetime.now)
    is_published = BooleanField(default=True)
  • prisma처럼 reverse로 디비 스키마를 가지고오는 기능
    http://docs.peewee-orm.com/en/latest/peewee/playhouse.html#pwiz
  • activerecord, flyway처럼 쿼리로 하는 것 보다 migration_api가 지원되서 좋다.
    스크립트와 함께 작성하면 좋으니.. 마이그레이션이 단순히 디비 스키마만 변경하면 되는게 아니라서
    http://docs.peewee-orm.com/en/latest/peewee/playhouse.html#schema-migrations
    https://github.com/klen/peewee_migrate
    ->
    1. 백업 후 마이그레이션
    2. 스냅샷 백업 후 백업 후 복원

실행 – unicorn

https://fastapi.tiangolo.com/deployment/docker/

docker에서 unicorn으로 실행

버전관리 – Poetry

파이썬에서 버전관리 툴로 거쳐간것들이 꽤 된다.

기본 패키지 관리툴: pip install -r requirements.txt
가상환경: conda, pipenv, venv
npm따라한거: poetry

생각 해 보니 이것들 특성이 제각각이라 분류를 하기 애매하다.
poetry에 와서야 노드 npm처럼 패키지가 관리된다. .lock파일도 있고

Lint – pylint

pylint, flake8, bandit, bandit

~

쓰는 사람이 많으니 계속 발전하는 것 같다.

대신 문법 자체가 바뀔 여지는 더 줄었다.

ChatGPT가 가장 잘 알려주는 언어라는 장점도

돌아가는 작은걸 빨리 만드는 연습

개발 못하는 개발팀 특

ex) 부동산 서비스를 만들자

대표/PO/기획자

부동산 서비스니까 네이버 부동산과 부동산114, 한방, 직방, 다방에 있는 기능을 다 추가하고 데이터도 다 가져와서 만들자
직방에 3d뷰 기능이 있네 이것도 꼭 있어야지

부동산 정보 서비스라고 했지만 나중에 서비스가 커지면 부동산매매, 탐방, 임대서비스가 추가될 것 같으니 TODO리스트에 담아놔

해외 부동산 서비스 사례는 뭐가 있을까?
경쟁사보다 뛰어난 서비스를 만들어야지
경쟁사 기능을 다 추가하고 한걸음 더 나아가야돼

진짜 완벽한 기획서를 완성했다!!
이것만 완성하면 전세계 부동산서비스 1위 확정이야

개발자

이번에 새로나온 Springboot와 Webflux, HibernateReactive가 좋다던데 다 적용해야겠다.
사용자가 많아질지 모르니까 시간당 10000TPU 정도는 버티게 Scaleout도 가능해야 하고
클라우드가 터질지도 모르니까 멀티클라우드도 적용해야지

부동산정보 서비스에 부동산매매, 탐방, 임대서비스가 추가된다고?
부동산 개발까지 추가로 만들어야겠다.

요구사항을 다 적용해 주려면 MSA로 만들어야겠다.

일 잘하는 개발팀

게시판에 부동산 관련 필드 추가해서 화면개발 후 3일안에 프로토타입 서버에 배포
2주단위 배포가능한 기능단위로 개발해서 지속 배포하며 기능추가

잘 아는 기술로 작은걸 빠르게 완성시키기

이런걸 프로토타이핑, MVP, 최소기능제품 등등으로 부른다.

해커톤에서 많이 하는 방식이다
모든 프로젝트는 이 단계에서 시작해야한다.
개인적으로 3일안에 만들 수 있는 수준으로 기능을 잡아야한다고 생각한다. 개발자의 역량에 따라 3일안에 나오는 수준이 달라질 수는 있겠지만 잘 한다고 이것저것 기능을 추가하면 안된다.

일 잘 하는 사람은 기술을 많이 알거나 머리좋은 사람이 아니다.

  • 개발자라면 요구사항에 맞는 제품을 빠르게 만들어내는 사람
  • PM이라면 최소의 요구사항을 잘 뽑아내는 사람
  • 디자이너는 최소의 아름다움을 갖춘 단순한(만들기쉬운) 형태를 만드는 사람

프로젝트 시작시 최악의 선택

개발자

최신기술 다 도입
완벽한 설계로 서버비용을 최소화하고
완벽한 ScaleOut
멀티클라우드 환경을 적용해서 99.9999% 가동률 달성

PM/PO/기획자

완벽한 기획으로 다 죽여버리겠다 -> 개발자 다 죽음

디자이너

토스처럼 만들어주세요

대규모 SI 서비스의 실패

소프트웨어는 끊임없는 개선이 필요하다.
정부나 은행의 대규모 SI프로젝트가 항상 좆같이 나오는건 대규모 프로젝트를 한방에 끝내기 때문이다.

SI 인력은 다 병신인 줄 아는 사람도 있던데… 그럴리가

병신이 아닌데 결과물은 왜 그따위일까?

소프트웨어는 개발 후 테스트 기간이 필요하다.
프로토타입을 만들었는데 정부 서비스에 적용 해 버리니… 초기에 계속 터진다. 안정화되는데 몇개월에서 몇년의 시간이 걸리는게 당연하다.

초기에 욕먹던 것들 지금보면 잘 쓰고 있다.

유지보수와 리뉴얼

새로운 요구사항이 나올 때 마다 기능을 추가하다 보니 코드가 더러워진다.

하지만… 이걸 정리했다가 오류가 터지면 무슨 욕을 먹을지 모르니 덮어둔다.
욕만 먹으면 다행이겠지….
이렇게 10년 아무도 수정할 수 없게 된 프로젝트는 폐기되고 또 차세대 진행

Java-Spring으로 된 프로젝트를 또 Java-Spring으로 차세대를 한다???
이런문제가 종종 있떤데

~

개발 못하는 개발자가 아니려고 노력 중

일 잘하는 사람은 타고나는 부분도 있지만
이건 트레이닝이 가능하다

회사에서 해커톤을 자주 해서 빠른 프로토타이핑을 훈련시켜보면 어떨까

Spring Cloud Contract vs Swagger

왜 나왔나?

1. Why use Spring Cloud Contract?

Spring Cloud Contract works great in a polyglot environment. This project has a lot of really interesting features. Quite a few of these features definitely make Spring Cloud Contract Verifier stand out on the market of Consumer Driven Contract (CDC) tooling. The most interesting features include the following:

  • Ability to do CDC with messaging.
  • Clear and easy to use, statically typed DSL.
  • Ability to copy-paste your current JSON file to the contract and edit only its elements.
  • Automatic generation of tests from the defined contract.
  • Stub Runner functionality: The stubs are automatically downloaded at runtime from Nexus or Artifactory.
  • Spring Cloud integration: No discovery service is needed for integration tests.
  • Ability to add support for any language & framework through Docker.

맞나? 좀 아닌듯

swagger와 역할이 겹친다.
swagger의 문제는

  • response의 Schema가 불확실하게 표현되는 경우가 많다.
  • Spring같은 경우 자동으로 생성되기 때문에 자꾸 변한다.
  • 파라미터 케이스별로 값을 확인할 수 없다.

이런 부족한 부분에서 기능을 확장시키는 방향으로 하는게 낫지 않았을까?

소비자 주도? 말도 안된다. Client에서 response Contract를 정의해서 보내준다고 Server에서 거기에 다 맞춰서 만들어줄 수는 없다. 결국 요구사항만 전달하는 정도에 그쳐야한다는거다.
graphql도 client주도인 착각을 할 수도 있지만 결국엔 서버에서 정의된 항목을 선 가공해서 전달받는 것 뿐이다.

어설프게 도입하는 회사는 좆되겠네

대신에 정의를 잘 해 두면 이걸 요구사항으로 두고 서버,클라이언트 모두 개발 및 테스트를 할 수 있을 것 같다. 하지만 그렇게 잘 정의될만한 프로젝트가 많지 않다.
특히 초기 서비스 개발시에는 불가능. 리팩토링 단계에서나 적용해야할 것 처럼 보이는데…
이미 돌아가는 서비스에 시간을 들일 수 있을까

이걸 기반으로 한 테스트 코드작성도구가 제공되는건 장점이려나

타 언어와 호환되지 않는건 또 단점