SlideShare une entreprise Scribd logo
1  sur  44
Télécharger pour lire hors ligne
PYCON KR 2017
Youngil Cho
인테이크 주식회사
조영일 / http://www.choyoungil.com / jeffrey@intakefoods.kr
현재
• 식품 스타트업 ‘인테이크’ 창업(2012~) : http://www.intakefoods.kr
• CTO : 서비스 기획/개발/운영
과거
• 모바일 게임 개발사 ‘어썸피스’ : 동기/비동기 게임 서버 개발(Python, Java)
• GIS SW 개발사 ‘자올소프트’ : 브라우저 기반 웹 지도 엔진 개발(Javascript)
기술
• Languages : Python, Java, Javascript
• Framework/Library : Django, Flask, Celery, Node.js
• Cloud : AWS / AWS Solutions Architect Associate 취득
• 기타 : Google Analytics / GAIQ 취득
https://www.shopintake.com
• ‘인테이크’ 라는 자사 브랜드 온라인 쇼핑몰
• 2014년 8월 런칭
• 누적 주문 수 7만+
• 누적 회원 수 5만+
• 월간 주문 수 5000+
• 월간 PV 30만+
• 쇼핑몰, 직접 구축 할 것인가?
• 쇼핑몰 개발
• 제품
• 장바구니
• 결제연동
• 관리자 페이지
• 매출 통계
• 비동기 작업/작업 스케쥴링
• AWS를 통한 서비스
• ElasticBeanstalk
• S3/CloudFront
• Appendix.
• 메일링
• 버그트레킹
• 측정 및 분석
Pros
• 차별화된 UI/UX 제공 가능
• 자유도 높은 프로모션/이벤트 진행 가능
• 방문 고객에 대한 세밀한 분석
• 나는 PHP 가 싫다.
Cons
• Why reinvent the wheel?
• 지속되는 유지보수 이슈
제품 장바구니 결제
고객
관리자 페이지 매출 통계 비동기 작업
관리자
메일링/메세징
운영/측정 및 분석
이 많은걸 언제 다 개발하나?
믿을 건 Django 뿐…
The web framework for Perfectionists with deadlines.
=
패키지 자체에 웹 개발에 필요한 수 많은 요소들이 기본 탑재되어 있음.
사용하기 쉬운 ORM.
풍부한 Django 관련 Third-Party 생태계.
• 제품에 딸린 정보가 생각보다 많음
• 고객 side, 물류 side, 관리자 side에서 필요한 정보를 모두 합하면 30개 이상의 attribute 필요
• 하나의 Model에 모두 넣을 경우 유지보수 어려워 짐
• 모든 곳에서 공통적으로 참조할 만한 attribute만 핵심 Model로 남기고 Model을 분리하자.
• 핵심 모델의 예시
class Product(models.Model):
management_code = models.CharField(max_length=10, blank=True, null=True, help_text=u"상품 관리용 코드")
name = models.CharField(max_length=128, help_text=u"상품 이름")
standard_price = models.IntegerField(default=0, help_text=u"정가")
original_sell_price = models.IntegerField(default=0, help_text=u"기준 판매가")
sell_price = models.IntegerField(default=0, help_text=u"현재 판매가")
original_cost = models.IntegerField(default=0, help_text=u"기준 제조 원가/공급가액")
cost = models.IntegerField(default=0, help_text=u"현재 제조 원가/공급가액")
sales_count = models.IntegerField(default=0, help_text=u"총 판매 수량")
current_stock = models.IntegerField(default=0, help_text=u"현재 재고 수준")
safety_stock = models.IntegerField(default=30, help_text=u"안전 재고 수준")
logistics_code = models.CharField(max_length=64, blank=True, null=True, help_text=u"물류센터 상품 관리 코드")
is_soldout = models.IntegerField(default=SoldOutStatus.INSTOCK, choices=(
(SoldOutStatus.INSTOCK, u"재고 있음"),
(SoldOutStatus.TEMPORARY_SOLDOUT, u"일시 품절"),
(SoldOutStatus.PERMANENT_SOLDOUT, u"영구 품절"),
), help_text=u"품절 상태")
• 기타 모델의 예시
• ShopProduct(고객에게 표시될 상품 상세페이지, 상품 표기 사항 등)
• ShopProductThumbnail(제품 썸네일 이미지)
• ShopProductReview(고객 상품 후기)
• ProductStockTransaction(제품 재고 변화 기록 모델)
• …
• 기능적 구분에 따라 추가적인 정보를 저장하는 Model을 추가
• 각 Model은 핵심 Model(Product)를 Foreign Key로 참조
• 대부분의 쇼핑몰에서 카테고리 기능은 필수
• 1-depth 혹은 2-depth 정도의 복잡하지 않은 카테고리 구조를 가지는 쇼핑몰이라면 :
카테고리 정보를 일반적인 Model로 구성하고 Product 모델이 ManyToMany를 이용하여 카테고리를 참조하도록 개발
class Category(models.Model):
name = models.CharField(max_length=32, help_text=u"식품 유형별 카테고리 이름")
index = models.IntegerField(default=0, help_text=u"카테고리 표시 순서(모바일), 적을 수록 먼저 표시됨")
class SubCategory(models.Model):
category = models.ForeignKey(Category)
name = models.CharField(max_length=32, help_text=u"서브 카테고리 이름")
index = models.IntegerField(default=0, help_text=u"서브 카테고리 표시 순서, 적을 수록 먼저 표시됨")
class ShopProduct(models.Model):
categories = models.ManyToManyField(Category)
sub_categories = models.ManyToManyField(SubCategory)
• 카테고리가 3-depth 이상 복잡한 구조를 가지는 경우
• Foreign Key로 구현하면.. : Foreign Key Hell
• Django-mptt : Django ORM을 확장하여 RDBMS 상에서 계층적(Hierarchical)인 데이터를 처리 할 수
있도록 해주는 라이브러리, Django Manager를 확장하여 트리 탐색을 도와주는 Method를 제공
• 상품 주문을 위한 시작점
• 필요 기능 : 상품 담기, 수량 변경, 삭제, 가격 계산 기능
• Django-carton : Django 기반의 장바구니 라이브러리. Django에서 사
용자가 설계한 제품 Model을 장바구니에서 바로 사용 가능하며, 위의 기초
적인 장바구니 기능들을 지원.
• Session 을 기반으로 장바구니 내용 저장
추가적인 요구 사항
• 주문 총액, 장바구니 내에 담긴 상품 종류에 따른 배송비 처리 기능 구현
• 로그인 한 유저에 대해, 장바구니 내용 보존을 위해 장바구니 내용을 JSON으로 serialize 하여 DB에 저장
=> 주문 완료되지 않은 장바구니 내용의 경우 서로 다른 종류의 브라우저/Device에서 로그인 했을 경우에도 내역 보존
=> 고객이 장바구니에 담은 내역을 실시간으로 분석 가능
(eg. 어떤 상품을 주로 장바구니에 많이 담나?, 어떤 상품을 장바구니에 담았다가 결제하지 않나?)
• 개발 초기에는… PG사에서 Python SDK를 지원하지 않는 관계로… PHP SDK 코드를 보면서 1:1 Python
버전으로 포팅하여 사용
• 하지만, 우리나라 PG사 결제 연동을 직접 하는 것은..지옥의 시작
• Python SDK 지원 X, 난해한 개발 매뉴얼, 결제 서비스 특성 상 테스트 하기 어려운 환경, 카카오페이/페이코 등의
간편결제로 인한 복수의 PG 연동 필요성 등..
PG 직접 연동은 제가 해봐서 알아요… 하지마세요…
• 결제 기능을 개발해야 한다면… ‘아임포트’를 쓰세요.
• 읽기 쉬운 API 문서
• 복수 PG사 연동 가능
• 복수의 PG사를 연동하는 경우에도 single code base로 구현 가능
• API를 통한 주문 상태 조회 / 결제 취소 가능
• Python rest client 도 있음
• 관리자 페이지 UI 100% 직접 구현은 힘들다.
• 하지만 Django admin은 일반적으로 사용하기에는 불편함.
• 목적 및 사용 대상에 따라 Django admin과 직접 제작한 UI로 이분하여 사용
• Django admin
• Model의 내용을 새로 등록 하거나 검색, 수정하는 작업
• 컨텐츠 등록 작업, low-level CRUD 작업 등
• 사용 대상 : 개발자, 쇼핑몰 최종관리자[MD] 등
• 직접 제작 UI
• Model 내용을 등록/수정을 빈번하게 하지는 않지만 복잡한 View logic을 가진 작업
• 사용성이 중요한 작업
• 매출 통계, 주문/배송 조회, 고객센터 문의 관리 등
• 사용 대상 : 모든 멤버
• Django admin
• Django-grappelli : Django 기본 Admin 부족한 부분을 보완
• 좀 더 미려한 UI
• 향상된 Filter 기능
• jQuery 기반의 Date Picker 등 편리한 Widget 탑재
• Foreign key 자동완성 기능
• Django admin
• Django-summernote : Summernote의 Django Add-on
• 이벤트, 공지사항, 제품 상세페이지 등 쇼핑몰 많은 부분에 HTML 편집이 필요 => 하지만 쇼핑몰 관리
담당자는 HTML을 사용하지 못함
• WYSIWYG : What You See Is What You Get
• WYSIWYG 에디터인 Summernote를 Django Admin 에 손쉽게 통합 가능
• Django admin
• Django Form Assets
• 사용자 정의 CSS/JS 파일을 Admin Form 에 삽입 하는 기능
• 일부 UI 개선
• Javascript 를 이용한 추가 기능 삽입
class MainCategoryBestProductForm(forms.ModelForm):
class Meta:
model = MainCategoryBestProduct
fields = ('__all__')
class Media:
css = {
'all': ('css/admin.css',)
}
• 직접 제작 UI
• AdminLTE
• Bootstrap 기반 관리자 페이지용 무료 템플릿
• Bootstrap 마크업을 그대로 사용 해도 예쁜 관리자 페이지를 제작 할 수 있습니다.
• Chart, Date Picker, Slider 등 관리자 페이지에 필요한 요소들을 기본 탑재
• Django Aggregation
• .annotate(), .extra(), .aggregate() 등을 조합하여 사용하면 꽤 복잡한 SQL 구문도 Django ORM을
통해 개발 가능 함.
• ORM으로 구현하기에 너무 복잡한 일부 join 구문에 대해서는 .raw() method를 사용하여 직접 raw
SQL을 실행하도록 함.
• Django-cacheops
• Django Queryset에 대한 실행 결과를 Redis에 쉽게 caching 할 수 있는 라이브러리
• 변할 여지가 적고, 자주 통계 기능에서 Access 되는 Queryset들을 Caching.
if "cacheops" in settings.INSTALLED_APPS:
monthly_sales_aggregation = orders.values('month').annotate(Sum('order_sum'), Count('id')).order_by('month').cache(timeout=60*60)
else:
monthly_sales_aggregation = orders.values('month').annotate(Sum('order_sum'), Count('id')).order_by('month')
• Google Chart
• HTML/SVG 기반의 차트를 표시하는 라이브러리
• 폭넓은 차트 종류 지원
• 커스텀 가능한 다양한 옵션 지원
• 매출 담당자의 요구에 따라서 다양한 형태의 그래프로 출력
• 쇼핑몰에서 왜 비동기 작업이 필요할까?
• 고객의 액션(주문완료 등)과 함께 작업이 실행되어야 하나 그 작업이 사용자 경험에 해로운 Blocking을 유발할 우
려가 있는 작업들
(eg. 외부 API와의 I/O 작업이 필요한 Email/SMS/카카오톡 발송)
• 실행 시간이 긴 작업
(eg. 회원 대상 대량 SMS 발송, 넓은 기간 범위에 대한 관리자의 매출 통계 조회)
• 쇼핑몰에서 왜 작업 스케쥴링이 필요 할까?
• 일정 주기마다 자동으로 실행되어야 하는 작업들
(eg. 매일 자정 멤버 대상 매출 통계 메일 발송, 물류 센터 API로 부터 운송장 가져오기, 회원 휴면 계정 처리, 회원
등급 평가)
• Celery
• Python에서 가장 유명한 분산형 비동기 작업 Worker 패키지
• Celery가 제공하는 decorator 기능을 사용하면 Django 코드와 유연하게 통합 가능
• Task 부하가 늘어 날 경우 Worker를 손쉽게 확장 가능
• Celery
• Decorator를 이용한 task 등록 예시
• Celery에 등록된 task를 비동기로 실행하는 예시
from celery import Celery
app = Celery('intake-async')
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
@app.task
def expire_coupon():
"""
관리자가 요청 할 경우 사용기간이 지난 쿠폰을 만료 처리함
“””
for c in CouponModel.objects.filter(status=COUPON_STATUS.ISSUED,
expiration_date__isnull=False):
c.expire_coupon()
from async.celery import expire_coupon
expire_coupon.delay()
• Celerybeat : Celery에 내장된 작업 스케쥴러
• 다양한 방식으로 schedule을 지정 가능
• 설정 예시(Django settings.py 에 통합 )
CELERYBEAT_SCHEDULE = {
# 매일 밤 11시 55분 매출 통계 메일링 발송
'daily_sales_stats': {
'task': 'emailer.celery.sales_stat',
'schedule': crontab(minute=55, hour=23)
},
# 매주 수요일 마다 장바구니에 담기만 하고 구매하지 않은 고객에게 프로모션 메일 발송
'cart_promotion': {
'task': 'emailer.celery.send_cart_email',
'schedule': crontab(minute=5, hour=15, day_of_week='wednesday')
},
}
• Celery Flower
• 비동기/분산형으로 동작하는 Celery의 특성 상 모니터링의 어려움 발생
• Celery Monitoring Tool
• Celery Task의 실행 결과와 Celery Worker를 Web UI를 통해서 모니터링 가능
• 서비스 초창기에는 국내 호스팅/IDC를 사용 하였습니다만…
• 점점 더 늘어만 가는 서버 유지보수 부담
• 소규모 개발팀을 위한 DevOps에 있어서 클라우드는 필수적인 선택
• 난 그냥 Django 서비스를 올리고 싶을 뿐인데.. AWS가 너무 어렵다면….
• 개발된 코드를 업로드 하기만 하면 아래와 같은 AWS상의 리소스를 자동으로 생성하고 서비스 가능한 상태
로 서로 연결 시켜줌.
• AWS EC2 : 서버 인스턴스
• AWS ELB : 로드밸런서
• AWS VPC/Security Group : Private Cloud 네트워크 및 보안 방화벽 설정
• Autoscaling Group : 서비스 부하에 따른 자동화된 Autoscaling
• AWS RDS : Managed RDBMS(MySQL/PostgreSQL)
• AWS Cloud Watch/SNS : 인프라 관련 지표/알림 서비스
• 개발언어/버전에 따라 일종의 Template을 제공
• Nginx, Apache / Gunicorn, uWSGI 등 Python/Django 서비스를 위한 서비스 스택을 자동으로 구성
• requirements.txt 에 따른 project dependency 자동 설치
• GUI 기반의 다양한 설정 기능 : Auto-Scaling, Load Balancing 등.
• 간편한 배포/무중단 배포 기능
• 압축파일 업로드를 통한 배포
• git push 혹은 CLI 를 통한 배포
Apache
/
Nginx
Django
App
WSGI
/
uWSGI
Static File
Directory
(img, js, css…)
• 일반적인 Django App 서비스 Stack
• Collect static을 하는 이유 : 일반적으로 static file의 경우 Apache/Nginx 등의 웹서버가 제공하는 것이
더 좋은 퍼포먼스를 보장함.
• 쇼핑몰은 특히 용량이 크고 많은 이미지 파일을 사용하기 때문에 Static File에 많은 신경을 써야 합니다.
(상품 썸네일, 긴 상품 상세페이지 등)
• AWS S3 : AWS에서 제공하는 내구도 높은 Static file 저장 서비스
• Static file 제공 기능을 웹 서버에서 완전히 분리하여 더욱 빠르고 내구도 높은 AWS S3가 Static file을
Serving 하도록 변경
• Django-storages : Django의 Static/Media 파일을 AWS S3상에 저장 할 수 있도록 해주는 Django
Storage Backed 라이브러리(Azure, Google Cloud 등도 가능)
Apache
/
Nginx
Django
App
WSGI
/
uWSGI
AWS S3
(img, js, css…)
• Django-storage를 이용한 AWS S3 사용
• Apache/Nginx 대신 AWS S3가 Static File Serving
• collectstatic 을 할 경우 static file이 AWS S3 bucket으로 저장됨
• Static File - 더 빠르고, 더 안정적으로 제공하고 싶다면..
• AWS CloudFront : AWS에서 제공하는 CDN 서비스
• 48개 도시/79개 Location을 통한 지리적 Caching
• S3만으로 서비스하는 것보다 많은 경우에 비용 효율적
• 무료 HTTPS 인증서 적용, 커스텀 도메인 적용 가능
• 다양한 Caching 정책을 활용하여 Django가 생성하는 컨텐츠 일부에 대해서도 Caching 가능
(eg. 브랜드 소개페이지 등 장시간 변화가 없는 페이지)
Apache
/
Nginx
Django
App
WSGI
/
uWSGI
AWS
S3
(img, js,
css…)
• AWS S3+CloudFront 사용
AWS
Cloud
Front
• Django에 의해 동적으로 생성되어야 하는 리소스(eg. 로그인, 세션 데이터 등)를 제외하고
웹페이지와 S3상의 Static File을 모두 CloudFront에 캐싱
• MailChimp
• Email 발송 기능의 경우 직접 개발 시 생각보다 많은 난관이 존재 합니다.
(Email Blacklist/Whitelist 처리 등)
• 전 세계적으로 가장 성공적인 이메일 마케팅 서비스
• Webhook, REST API, Python SDK 지원
• 전자 상거래 통합 기능으로 고객의 장바구니/구매내역에 기반한 상세한 고객 타게팅 메일링 가능
• Sentry
• 실시간 버그 트레킹 도구
• 오류 발생 시 Stacktrace 를 포함한 상세한 버그 레포팅을 제공
• 자체 서버 구축(무료)/호스팅 서비스(유료)
• Django logger에 손쉽게 통합됨
• 이메일, 슬랙 등을 통한 알림 기능
• Google Analytics
• 방문자 유입 경로, 행동 분석 도구
• Google Analytics Ecommerce Plugin : 쇼핑몰에 반드시 적용 해야함!
• 제품별 매출 실적
• 쇼핑 행동 분석
• 결제 단계별 이탈률 분석
(제품 상세페이지 -> 장바구니 -> 결제 시작 -> 결제 완료)
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축

Contenu connexe

Tendances

Celery의 빛과 그림자
Celery의 빛과 그림자Celery의 빛과 그림자
Celery의 빛과 그림자Minyoung Jeong
 
Service Worker Presentation
Service Worker PresentationService Worker Presentation
Service Worker PresentationKyle Dorman
 
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현NAVER Engineering
 
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기경원 이
 
Springを何となく使ってる人が抑えるべきポイント
Springを何となく使ってる人が抑えるべきポイントSpringを何となく使ってる人が抑えるべきポイント
Springを何となく使ってる人が抑えるべきポイント土岐 孝平
 
Service workers
Service workersService workers
Service workersjungkees
 
Kubernetes Forum Seoul 2019: Re-architecting Data Platform with Kubernetes
Kubernetes Forum Seoul 2019: Re-architecting Data Platform with KubernetesKubernetes Forum Seoul 2019: Re-architecting Data Platform with Kubernetes
Kubernetes Forum Seoul 2019: Re-architecting Data Platform with KubernetesSeungYong Oh
 
톰캣 운영 노하우
톰캣 운영 노하우톰캣 운영 노하우
톰캣 운영 노하우jieunsys
 
[112]rest에서 graph ql과 relay로 갈아타기 이정우
[112]rest에서 graph ql과 relay로 갈아타기 이정우[112]rest에서 graph ql과 relay로 갈아타기 이정우
[112]rest에서 graph ql과 relay로 갈아타기 이정우NAVER D2
 
[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How To[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How ToJi-Woong Choi
 
SQL Server에서 Django를 추구하면 안 되는 걸까?
SQL Server에서 Django를 추구하면 안 되는 걸까?SQL Server에서 Django를 추구하면 안 되는 걸까?
SQL Server에서 Django를 추구하면 안 되는 걸까?태환 김
 
The effective use of Django ORM
The effective use of Django ORMThe effective use of Django ORM
The effective use of Django ORMYaroslav Muravskyi
 
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020Johnny Sung
 
なぜ初心者は webpackが解らないのか?- Why can’t you understand the webpack? -
なぜ初心者は webpackが解らないのか?- Why can’t you understand the webpack? - なぜ初心者は webpackが解らないのか?- Why can’t you understand the webpack? -
なぜ初心者は webpackが解らないのか?- Why can’t you understand the webpack? - 健人 井関
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSBrainhub
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유Hyojun Jeon
 

Tendances (20)

Celery의 빛과 그림자
Celery의 빛과 그림자Celery의 빛과 그림자
Celery의 빛과 그림자
 
Service Worker Presentation
Service Worker PresentationService Worker Presentation
Service Worker Presentation
 
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
 
TypeScript Overview
TypeScript OverviewTypeScript Overview
TypeScript Overview
 
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
 
Springを何となく使ってる人が抑えるべきポイント
Springを何となく使ってる人が抑えるべきポイントSpringを何となく使ってる人が抑えるべきポイント
Springを何となく使ってる人が抑えるべきポイント
 
Service workers
Service workersService workers
Service workers
 
Kubernetes Forum Seoul 2019: Re-architecting Data Platform with Kubernetes
Kubernetes Forum Seoul 2019: Re-architecting Data Platform with KubernetesKubernetes Forum Seoul 2019: Re-architecting Data Platform with Kubernetes
Kubernetes Forum Seoul 2019: Re-architecting Data Platform with Kubernetes
 
톰캣 운영 노하우
톰캣 운영 노하우톰캣 운영 노하우
톰캣 운영 노하우
 
[112]rest에서 graph ql과 relay로 갈아타기 이정우
[112]rest에서 graph ql과 relay로 갈아타기 이정우[112]rest에서 graph ql과 relay로 갈아타기 이정우
[112]rest에서 graph ql과 relay로 갈아타기 이정우
 
[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How To[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How To
 
Angular
AngularAngular
Angular
 
SQL Server에서 Django를 추구하면 안 되는 걸까?
SQL Server에서 Django를 추구하면 안 되는 걸까?SQL Server에서 Django를 추구하면 안 되는 걸까?
SQL Server에서 Django를 추구하면 안 되는 걸까?
 
The effective use of Django ORM
The effective use of Django ORMThe effective use of Django ORM
The effective use of Django ORM
 
Angular
AngularAngular
Angular
 
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
 
SpringBootTest入門
SpringBootTest入門SpringBootTest入門
SpringBootTest入門
 
なぜ初心者は webpackが解らないのか?- Why can’t you understand the webpack? -
なぜ初心者は webpackが解らないのか?- Why can’t you understand the webpack? - なぜ初心者は webpackが解らないのか?- Why can’t you understand the webpack? -
なぜ初心者は webpackが解らないのか?- Why can’t you understand the webpack? -
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
 

Similaire à 2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축

Polymer따라잡기
Polymer따라잡기Polymer따라잡기
Polymer따라잡기Han Jung Hyun
 
장고로 웹서비스 만들기 기초
장고로 웹서비스 만들기   기초장고로 웹서비스 만들기   기초
장고로 웹서비스 만들기 기초Kwangyoun Jung
 
모바일 게임과 앱을 위한 오픈소스 게임서버 엔진 프로젝트 CloudBread 프로젝트
모바일 게임과 앱을 위한 오픈소스 게임서버 엔진 프로젝트 CloudBread 프로젝트모바일 게임과 앱을 위한 오픈소스 게임서버 엔진 프로젝트 CloudBread 프로젝트
모바일 게임과 앱을 위한 오픈소스 게임서버 엔진 프로젝트 CloudBread 프로젝트Dae Kim
 
알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web AnimationsChang W. Doh
 
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)Sang Don Kim
 
Data-binding AngularJS
Data-binding AngularJSData-binding AngularJS
Data-binding AngularJSEunYoung Kim
 
성공적인 게임 런칭을 위한 비밀의 레시피 #3
성공적인 게임 런칭을 위한 비밀의 레시피 #3성공적인 게임 런칭을 위한 비밀의 레시피 #3
성공적인 게임 런칭을 위한 비밀의 레시피 #3Amazon Web Services Korea
 
R.java가 사라졌어요 어떻하죠?:Aquery라이브러리와 안드로이드 개발팁
R.java가 사라졌어요 어떻하죠?:Aquery라이브러리와 안드로이드 개발팁R.java가 사라졌어요 어떻하죠?:Aquery라이브러리와 안드로이드 개발팁
R.java가 사라졌어요 어떻하죠?:Aquery라이브러리와 안드로이드 개발팁창규 김
 
비트교육센터-AWS활용 1주차: EC2, S3, Elastic Beanstalks 사용
비트교육센터-AWS활용 1주차: EC2, S3, Elastic Beanstalks 사용비트교육센터-AWS활용 1주차: EC2, S3, Elastic Beanstalks 사용
비트교육센터-AWS활용 1주차: EC2, S3, Elastic Beanstalks 사용고포릿 default
 
Embedded project presentation
Embedded project presentationEmbedded project presentation
Embedded project presentationJae-yeol Lee
 
Open standard open cloud engine (3)
Open standard open cloud engine (3)Open standard open cloud engine (3)
Open standard open cloud engine (3)uEngine Solutions
 
20131217 html5
20131217 html520131217 html5
20131217 html5DK Lee
 
Google Cloud NEXT'17 정리
Google Cloud NEXT'17 정리Google Cloud NEXT'17 정리
Google Cloud NEXT'17 정리Yongyoon Shin
 
하이브리드앱 성능 극복
하이브리드앱 성능 극복하이브리드앱 성능 극복
하이브리드앱 성능 극복sung hwan Park
 
하이브리드앱 성능 극복
하이브리드앱 성능 극복하이브리드앱 성능 극복
하이브리드앱 성능 극복Mu-ik Jeon
 
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912Yooseok Choi
 
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020 AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020 AWSKRUG - AWS한국사용자모임
 

Similaire à 2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축 (20)

Polymer따라잡기
Polymer따라잡기Polymer따라잡기
Polymer따라잡기
 
장고로 웹서비스 만들기 기초
장고로 웹서비스 만들기   기초장고로 웹서비스 만들기   기초
장고로 웹서비스 만들기 기초
 
모바일 게임과 앱을 위한 오픈소스 게임서버 엔진 프로젝트 CloudBread 프로젝트
모바일 게임과 앱을 위한 오픈소스 게임서버 엔진 프로젝트 CloudBread 프로젝트모바일 게임과 앱을 위한 오픈소스 게임서버 엔진 프로젝트 CloudBread 프로젝트
모바일 게임과 앱을 위한 오픈소스 게임서버 엔진 프로젝트 CloudBread 프로젝트
 
알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations
 
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)
 
Data-binding AngularJS
Data-binding AngularJSData-binding AngularJS
Data-binding AngularJS
 
Angularcdk
AngularcdkAngularcdk
Angularcdk
 
성공적인 게임 런칭을 위한 비밀의 레시피 #3
성공적인 게임 런칭을 위한 비밀의 레시피 #3성공적인 게임 런칭을 위한 비밀의 레시피 #3
성공적인 게임 런칭을 위한 비밀의 레시피 #3
 
R.java가 사라졌어요 어떻하죠?:Aquery라이브러리와 안드로이드 개발팁
R.java가 사라졌어요 어떻하죠?:Aquery라이브러리와 안드로이드 개발팁R.java가 사라졌어요 어떻하죠?:Aquery라이브러리와 안드로이드 개발팁
R.java가 사라졌어요 어떻하죠?:Aquery라이브러리와 안드로이드 개발팁
 
7. html5 api
7. html5 api7. html5 api
7. html5 api
 
비트교육센터-AWS활용 1주차: EC2, S3, Elastic Beanstalks 사용
비트교육센터-AWS활용 1주차: EC2, S3, Elastic Beanstalks 사용비트교육센터-AWS활용 1주차: EC2, S3, Elastic Beanstalks 사용
비트교육센터-AWS활용 1주차: EC2, S3, Elastic Beanstalks 사용
 
Embedded project presentation
Embedded project presentationEmbedded project presentation
Embedded project presentation
 
Open standard open cloud engine (3)
Open standard open cloud engine (3)Open standard open cloud engine (3)
Open standard open cloud engine (3)
 
Html5
Html5 Html5
Html5
 
20131217 html5
20131217 html520131217 html5
20131217 html5
 
Google Cloud NEXT'17 정리
Google Cloud NEXT'17 정리Google Cloud NEXT'17 정리
Google Cloud NEXT'17 정리
 
하이브리드앱 성능 극복
하이브리드앱 성능 극복하이브리드앱 성능 극복
하이브리드앱 성능 극복
 
하이브리드앱 성능 극복
하이브리드앱 성능 극복하이브리드앱 성능 극복
하이브리드앱 성능 극복
 
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
 
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020 AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
 

2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축

  • 1. PYCON KR 2017 Youngil Cho 인테이크 주식회사
  • 2. 조영일 / http://www.choyoungil.com / jeffrey@intakefoods.kr 현재 • 식품 스타트업 ‘인테이크’ 창업(2012~) : http://www.intakefoods.kr • CTO : 서비스 기획/개발/운영 과거 • 모바일 게임 개발사 ‘어썸피스’ : 동기/비동기 게임 서버 개발(Python, Java) • GIS SW 개발사 ‘자올소프트’ : 브라우저 기반 웹 지도 엔진 개발(Javascript) 기술 • Languages : Python, Java, Javascript • Framework/Library : Django, Flask, Celery, Node.js • Cloud : AWS / AWS Solutions Architect Associate 취득 • 기타 : Google Analytics / GAIQ 취득
  • 4. • ‘인테이크’ 라는 자사 브랜드 온라인 쇼핑몰 • 2014년 8월 런칭 • 누적 주문 수 7만+ • 누적 회원 수 5만+ • 월간 주문 수 5000+ • 월간 PV 30만+
  • 5. • 쇼핑몰, 직접 구축 할 것인가? • 쇼핑몰 개발 • 제품 • 장바구니 • 결제연동 • 관리자 페이지 • 매출 통계 • 비동기 작업/작업 스케쥴링 • AWS를 통한 서비스 • ElasticBeanstalk • S3/CloudFront • Appendix. • 메일링 • 버그트레킹 • 측정 및 분석
  • 6. Pros • 차별화된 UI/UX 제공 가능 • 자유도 높은 프로모션/이벤트 진행 가능 • 방문 고객에 대한 세밀한 분석 • 나는 PHP 가 싫다. Cons • Why reinvent the wheel? • 지속되는 유지보수 이슈
  • 7. 제품 장바구니 결제 고객 관리자 페이지 매출 통계 비동기 작업 관리자 메일링/메세징 운영/측정 및 분석
  • 8. 이 많은걸 언제 다 개발하나? 믿을 건 Django 뿐… The web framework for Perfectionists with deadlines. = 패키지 자체에 웹 개발에 필요한 수 많은 요소들이 기본 탑재되어 있음. 사용하기 쉬운 ORM. 풍부한 Django 관련 Third-Party 생태계.
  • 9. • 제품에 딸린 정보가 생각보다 많음 • 고객 side, 물류 side, 관리자 side에서 필요한 정보를 모두 합하면 30개 이상의 attribute 필요 • 하나의 Model에 모두 넣을 경우 유지보수 어려워 짐 • 모든 곳에서 공통적으로 참조할 만한 attribute만 핵심 Model로 남기고 Model을 분리하자.
  • 10. • 핵심 모델의 예시 class Product(models.Model): management_code = models.CharField(max_length=10, blank=True, null=True, help_text=u"상품 관리용 코드") name = models.CharField(max_length=128, help_text=u"상품 이름") standard_price = models.IntegerField(default=0, help_text=u"정가") original_sell_price = models.IntegerField(default=0, help_text=u"기준 판매가") sell_price = models.IntegerField(default=0, help_text=u"현재 판매가") original_cost = models.IntegerField(default=0, help_text=u"기준 제조 원가/공급가액") cost = models.IntegerField(default=0, help_text=u"현재 제조 원가/공급가액") sales_count = models.IntegerField(default=0, help_text=u"총 판매 수량") current_stock = models.IntegerField(default=0, help_text=u"현재 재고 수준") safety_stock = models.IntegerField(default=30, help_text=u"안전 재고 수준") logistics_code = models.CharField(max_length=64, blank=True, null=True, help_text=u"물류센터 상품 관리 코드") is_soldout = models.IntegerField(default=SoldOutStatus.INSTOCK, choices=( (SoldOutStatus.INSTOCK, u"재고 있음"), (SoldOutStatus.TEMPORARY_SOLDOUT, u"일시 품절"), (SoldOutStatus.PERMANENT_SOLDOUT, u"영구 품절"), ), help_text=u"품절 상태")
  • 11. • 기타 모델의 예시 • ShopProduct(고객에게 표시될 상품 상세페이지, 상품 표기 사항 등) • ShopProductThumbnail(제품 썸네일 이미지) • ShopProductReview(고객 상품 후기) • ProductStockTransaction(제품 재고 변화 기록 모델) • … • 기능적 구분에 따라 추가적인 정보를 저장하는 Model을 추가 • 각 Model은 핵심 Model(Product)를 Foreign Key로 참조
  • 12. • 대부분의 쇼핑몰에서 카테고리 기능은 필수 • 1-depth 혹은 2-depth 정도의 복잡하지 않은 카테고리 구조를 가지는 쇼핑몰이라면 : 카테고리 정보를 일반적인 Model로 구성하고 Product 모델이 ManyToMany를 이용하여 카테고리를 참조하도록 개발 class Category(models.Model): name = models.CharField(max_length=32, help_text=u"식품 유형별 카테고리 이름") index = models.IntegerField(default=0, help_text=u"카테고리 표시 순서(모바일), 적을 수록 먼저 표시됨") class SubCategory(models.Model): category = models.ForeignKey(Category) name = models.CharField(max_length=32, help_text=u"서브 카테고리 이름") index = models.IntegerField(default=0, help_text=u"서브 카테고리 표시 순서, 적을 수록 먼저 표시됨") class ShopProduct(models.Model): categories = models.ManyToManyField(Category) sub_categories = models.ManyToManyField(SubCategory)
  • 13. • 카테고리가 3-depth 이상 복잡한 구조를 가지는 경우 • Foreign Key로 구현하면.. : Foreign Key Hell • Django-mptt : Django ORM을 확장하여 RDBMS 상에서 계층적(Hierarchical)인 데이터를 처리 할 수 있도록 해주는 라이브러리, Django Manager를 확장하여 트리 탐색을 도와주는 Method를 제공
  • 14. • 상품 주문을 위한 시작점 • 필요 기능 : 상품 담기, 수량 변경, 삭제, 가격 계산 기능 • Django-carton : Django 기반의 장바구니 라이브러리. Django에서 사 용자가 설계한 제품 Model을 장바구니에서 바로 사용 가능하며, 위의 기초 적인 장바구니 기능들을 지원. • Session 을 기반으로 장바구니 내용 저장
  • 15. 추가적인 요구 사항 • 주문 총액, 장바구니 내에 담긴 상품 종류에 따른 배송비 처리 기능 구현 • 로그인 한 유저에 대해, 장바구니 내용 보존을 위해 장바구니 내용을 JSON으로 serialize 하여 DB에 저장 => 주문 완료되지 않은 장바구니 내용의 경우 서로 다른 종류의 브라우저/Device에서 로그인 했을 경우에도 내역 보존 => 고객이 장바구니에 담은 내역을 실시간으로 분석 가능 (eg. 어떤 상품을 주로 장바구니에 많이 담나?, 어떤 상품을 장바구니에 담았다가 결제하지 않나?)
  • 16. • 개발 초기에는… PG사에서 Python SDK를 지원하지 않는 관계로… PHP SDK 코드를 보면서 1:1 Python 버전으로 포팅하여 사용 • 하지만, 우리나라 PG사 결제 연동을 직접 하는 것은..지옥의 시작 • Python SDK 지원 X, 난해한 개발 매뉴얼, 결제 서비스 특성 상 테스트 하기 어려운 환경, 카카오페이/페이코 등의 간편결제로 인한 복수의 PG 연동 필요성 등.. PG 직접 연동은 제가 해봐서 알아요… 하지마세요…
  • 17. • 결제 기능을 개발해야 한다면… ‘아임포트’를 쓰세요. • 읽기 쉬운 API 문서 • 복수 PG사 연동 가능 • 복수의 PG사를 연동하는 경우에도 single code base로 구현 가능 • API를 통한 주문 상태 조회 / 결제 취소 가능 • Python rest client 도 있음
  • 18. • 관리자 페이지 UI 100% 직접 구현은 힘들다. • 하지만 Django admin은 일반적으로 사용하기에는 불편함. • 목적 및 사용 대상에 따라 Django admin과 직접 제작한 UI로 이분하여 사용 • Django admin • Model의 내용을 새로 등록 하거나 검색, 수정하는 작업 • 컨텐츠 등록 작업, low-level CRUD 작업 등 • 사용 대상 : 개발자, 쇼핑몰 최종관리자[MD] 등 • 직접 제작 UI • Model 내용을 등록/수정을 빈번하게 하지는 않지만 복잡한 View logic을 가진 작업 • 사용성이 중요한 작업 • 매출 통계, 주문/배송 조회, 고객센터 문의 관리 등 • 사용 대상 : 모든 멤버
  • 19. • Django admin • Django-grappelli : Django 기본 Admin 부족한 부분을 보완 • 좀 더 미려한 UI • 향상된 Filter 기능 • jQuery 기반의 Date Picker 등 편리한 Widget 탑재 • Foreign key 자동완성 기능
  • 20. • Django admin • Django-summernote : Summernote의 Django Add-on • 이벤트, 공지사항, 제품 상세페이지 등 쇼핑몰 많은 부분에 HTML 편집이 필요 => 하지만 쇼핑몰 관리 담당자는 HTML을 사용하지 못함 • WYSIWYG : What You See Is What You Get • WYSIWYG 에디터인 Summernote를 Django Admin 에 손쉽게 통합 가능
  • 21. • Django admin • Django Form Assets • 사용자 정의 CSS/JS 파일을 Admin Form 에 삽입 하는 기능 • 일부 UI 개선 • Javascript 를 이용한 추가 기능 삽입 class MainCategoryBestProductForm(forms.ModelForm): class Meta: model = MainCategoryBestProduct fields = ('__all__') class Media: css = { 'all': ('css/admin.css',) }
  • 22. • 직접 제작 UI • AdminLTE • Bootstrap 기반 관리자 페이지용 무료 템플릿 • Bootstrap 마크업을 그대로 사용 해도 예쁜 관리자 페이지를 제작 할 수 있습니다. • Chart, Date Picker, Slider 등 관리자 페이지에 필요한 요소들을 기본 탑재
  • 23. • Django Aggregation • .annotate(), .extra(), .aggregate() 등을 조합하여 사용하면 꽤 복잡한 SQL 구문도 Django ORM을 통해 개발 가능 함. • ORM으로 구현하기에 너무 복잡한 일부 join 구문에 대해서는 .raw() method를 사용하여 직접 raw SQL을 실행하도록 함.
  • 24. • Django-cacheops • Django Queryset에 대한 실행 결과를 Redis에 쉽게 caching 할 수 있는 라이브러리 • 변할 여지가 적고, 자주 통계 기능에서 Access 되는 Queryset들을 Caching. if "cacheops" in settings.INSTALLED_APPS: monthly_sales_aggregation = orders.values('month').annotate(Sum('order_sum'), Count('id')).order_by('month').cache(timeout=60*60) else: monthly_sales_aggregation = orders.values('month').annotate(Sum('order_sum'), Count('id')).order_by('month')
  • 25. • Google Chart • HTML/SVG 기반의 차트를 표시하는 라이브러리 • 폭넓은 차트 종류 지원 • 커스텀 가능한 다양한 옵션 지원 • 매출 담당자의 요구에 따라서 다양한 형태의 그래프로 출력
  • 26. • 쇼핑몰에서 왜 비동기 작업이 필요할까? • 고객의 액션(주문완료 등)과 함께 작업이 실행되어야 하나 그 작업이 사용자 경험에 해로운 Blocking을 유발할 우 려가 있는 작업들 (eg. 외부 API와의 I/O 작업이 필요한 Email/SMS/카카오톡 발송) • 실행 시간이 긴 작업 (eg. 회원 대상 대량 SMS 발송, 넓은 기간 범위에 대한 관리자의 매출 통계 조회) • 쇼핑몰에서 왜 작업 스케쥴링이 필요 할까? • 일정 주기마다 자동으로 실행되어야 하는 작업들 (eg. 매일 자정 멤버 대상 매출 통계 메일 발송, 물류 센터 API로 부터 운송장 가져오기, 회원 휴면 계정 처리, 회원 등급 평가)
  • 27. • Celery • Python에서 가장 유명한 분산형 비동기 작업 Worker 패키지 • Celery가 제공하는 decorator 기능을 사용하면 Django 코드와 유연하게 통합 가능 • Task 부하가 늘어 날 경우 Worker를 손쉽게 확장 가능
  • 28. • Celery • Decorator를 이용한 task 등록 예시 • Celery에 등록된 task를 비동기로 실행하는 예시 from celery import Celery app = Celery('intake-async') app.config_from_object('django.conf:settings') app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) @app.task def expire_coupon(): """ 관리자가 요청 할 경우 사용기간이 지난 쿠폰을 만료 처리함 “”” for c in CouponModel.objects.filter(status=COUPON_STATUS.ISSUED, expiration_date__isnull=False): c.expire_coupon() from async.celery import expire_coupon expire_coupon.delay()
  • 29. • Celerybeat : Celery에 내장된 작업 스케쥴러 • 다양한 방식으로 schedule을 지정 가능 • 설정 예시(Django settings.py 에 통합 ) CELERYBEAT_SCHEDULE = { # 매일 밤 11시 55분 매출 통계 메일링 발송 'daily_sales_stats': { 'task': 'emailer.celery.sales_stat', 'schedule': crontab(minute=55, hour=23) }, # 매주 수요일 마다 장바구니에 담기만 하고 구매하지 않은 고객에게 프로모션 메일 발송 'cart_promotion': { 'task': 'emailer.celery.send_cart_email', 'schedule': crontab(minute=5, hour=15, day_of_week='wednesday') }, }
  • 30. • Celery Flower • 비동기/분산형으로 동작하는 Celery의 특성 상 모니터링의 어려움 발생 • Celery Monitoring Tool • Celery Task의 실행 결과와 Celery Worker를 Web UI를 통해서 모니터링 가능
  • 31. • 서비스 초창기에는 국내 호스팅/IDC를 사용 하였습니다만… • 점점 더 늘어만 가는 서버 유지보수 부담 • 소규모 개발팀을 위한 DevOps에 있어서 클라우드는 필수적인 선택
  • 32. • 난 그냥 Django 서비스를 올리고 싶을 뿐인데.. AWS가 너무 어렵다면…. • 개발된 코드를 업로드 하기만 하면 아래와 같은 AWS상의 리소스를 자동으로 생성하고 서비스 가능한 상태 로 서로 연결 시켜줌. • AWS EC2 : 서버 인스턴스 • AWS ELB : 로드밸런서 • AWS VPC/Security Group : Private Cloud 네트워크 및 보안 방화벽 설정 • Autoscaling Group : 서비스 부하에 따른 자동화된 Autoscaling • AWS RDS : Managed RDBMS(MySQL/PostgreSQL) • AWS Cloud Watch/SNS : 인프라 관련 지표/알림 서비스
  • 33. • 개발언어/버전에 따라 일종의 Template을 제공 • Nginx, Apache / Gunicorn, uWSGI 등 Python/Django 서비스를 위한 서비스 스택을 자동으로 구성 • requirements.txt 에 따른 project dependency 자동 설치 • GUI 기반의 다양한 설정 기능 : Auto-Scaling, Load Balancing 등.
  • 34. • 간편한 배포/무중단 배포 기능 • 압축파일 업로드를 통한 배포 • git push 혹은 CLI 를 통한 배포
  • 35. Apache / Nginx Django App WSGI / uWSGI Static File Directory (img, js, css…) • 일반적인 Django App 서비스 Stack • Collect static을 하는 이유 : 일반적으로 static file의 경우 Apache/Nginx 등의 웹서버가 제공하는 것이 더 좋은 퍼포먼스를 보장함.
  • 36. • 쇼핑몰은 특히 용량이 크고 많은 이미지 파일을 사용하기 때문에 Static File에 많은 신경을 써야 합니다. (상품 썸네일, 긴 상품 상세페이지 등) • AWS S3 : AWS에서 제공하는 내구도 높은 Static file 저장 서비스 • Static file 제공 기능을 웹 서버에서 완전히 분리하여 더욱 빠르고 내구도 높은 AWS S3가 Static file을 Serving 하도록 변경 • Django-storages : Django의 Static/Media 파일을 AWS S3상에 저장 할 수 있도록 해주는 Django Storage Backed 라이브러리(Azure, Google Cloud 등도 가능)
  • 37. Apache / Nginx Django App WSGI / uWSGI AWS S3 (img, js, css…) • Django-storage를 이용한 AWS S3 사용 • Apache/Nginx 대신 AWS S3가 Static File Serving • collectstatic 을 할 경우 static file이 AWS S3 bucket으로 저장됨
  • 38. • Static File - 더 빠르고, 더 안정적으로 제공하고 싶다면.. • AWS CloudFront : AWS에서 제공하는 CDN 서비스 • 48개 도시/79개 Location을 통한 지리적 Caching • S3만으로 서비스하는 것보다 많은 경우에 비용 효율적 • 무료 HTTPS 인증서 적용, 커스텀 도메인 적용 가능 • 다양한 Caching 정책을 활용하여 Django가 생성하는 컨텐츠 일부에 대해서도 Caching 가능 (eg. 브랜드 소개페이지 등 장시간 변화가 없는 페이지)
  • 39. Apache / Nginx Django App WSGI / uWSGI AWS S3 (img, js, css…) • AWS S3+CloudFront 사용 AWS Cloud Front • Django에 의해 동적으로 생성되어야 하는 리소스(eg. 로그인, 세션 데이터 등)를 제외하고 웹페이지와 S3상의 Static File을 모두 CloudFront에 캐싱
  • 40.
  • 41. • MailChimp • Email 발송 기능의 경우 직접 개발 시 생각보다 많은 난관이 존재 합니다. (Email Blacklist/Whitelist 처리 등) • 전 세계적으로 가장 성공적인 이메일 마케팅 서비스 • Webhook, REST API, Python SDK 지원 • 전자 상거래 통합 기능으로 고객의 장바구니/구매내역에 기반한 상세한 고객 타게팅 메일링 가능
  • 42. • Sentry • 실시간 버그 트레킹 도구 • 오류 발생 시 Stacktrace 를 포함한 상세한 버그 레포팅을 제공 • 자체 서버 구축(무료)/호스팅 서비스(유료) • Django logger에 손쉽게 통합됨 • 이메일, 슬랙 등을 통한 알림 기능
  • 43. • Google Analytics • 방문자 유입 경로, 행동 분석 도구 • Google Analytics Ecommerce Plugin : 쇼핑몰에 반드시 적용 해야함! • 제품별 매출 실적 • 쇼핑 행동 분석 • 결제 단계별 이탈률 분석 (제품 상세페이지 -> 장바구니 -> 결제 시작 -> 결제 완료)