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.
• MailChimp
• Email 발송 기능의 경우 직접 개발 시 생각보다 많은 난관이 존재 합니다.
(Email Blacklist/Whitelist 처리 등)
• 전 세계적으로 가장 성공적인 이메일 마케팅 서비스
• Webhook, REST API, Python SDK 지원
• 전자 상거래 통합 기능으로 고객의 장바구니/구매내역에 기반한 상세한 고객 타게팅 메일링 가능
41.
• Sentry
• 실시간 버그 트레킹 도구
• 오류 발생 시 Stacktrace 를 포함한 상세한 버그 레포팅을 제공
• 자체 서버 구축(무료)/호스팅 서비스(유료)
• Django logger에 손쉽게 통합됨
• 이메일, 슬랙 등을 통한 알림 기능
42.
• Google Analytics
• 방문자 유입 경로, 행동 분석 도구
• Google Analytics Ecommerce Plugin : 쇼핑몰에 반드시 적용 해야함!
• 제품별 매출 실적
• 쇼핑 행동 분석
• 결제 단계별 이탈률 분석
(제품 상세페이지 -> 장바구니 -> 결제 시작 -> 결제 완료)
Parece que tem um bloqueador de anúncios ativo. Ao listar o SlideShare no seu bloqueador de anúncios, está a apoiar a nossa comunidade de criadores de conteúdo.
Odeia anúncios?
Atualizámos a nossa política de privacidade.
Atualizámos a nossa política de privacidade de modo a estarmos em conformidade com os regulamentos de privacidade em constante mutação a nível mundial e para lhe fornecer uma visão sobre as formas limitadas de utilização dos seus dados.
Pode ler os detalhes abaixo. Ao aceitar, está a concordar com a política de privacidade atualizada.