쿠키런 사례

카테고리 없음 2014. 4. 21. 18:18 Posted by 초절정고수

쿠키런 사례

KGC2013 을 참가 했었는데

이틀째 세션에는 아마존을 활용한 쿠키런 사례? 비슷한게 있었는데 개발쪽 세션입니다.

결론 부터 말하자면 대략적으로 AWS에서 자동화를 통해서 쿠키런을 운영할 수 있었다.
혼자서 서버 개발과 운영을 해야 했고 할 수 있었다.

발표 내용

서버 개발자 자기 포함2명인데 한명은 나가기로 예정되어있어서
결국적으로는 1명. 개발 / 운영을 해야되었다.

어디를 선택할지에 대해서 지인들에게 문의를 많이했었고 이런 결과를 얻게되었다.

  • 서버 IDC 입주를 고려 했었는데 선은 어디 쓰지 IDC가서 설치는 누가 하지 영세한 게임 회사로써는 여러가지 문제들이 꽃피움 그래서 IDC제외
  • 한국 클라우드 서비스를 하는 벤더들의 대한 신뢰 없음
    • ELB가 뻗는 경우가 있었다라는 말을 함.
    • 하청을 주는데 하청이 거지 같더라
    • 그래서 한국 벤더 제외

여기서 부터 AWS에 극찬이 시작됨 못하는게 없다라는 식인데 오오 하며 흥미를 갖고 보게됨

AWS

  • 다양한 서비스 제공
  • 모든 서비스는 API로 제어가 가능 (API를 제공하는 언어도 많음)
  • auto scaling, ELB, S3 등이 매력적이였다.

자동화 하기 위해서 사용한 방법

  • CloudFormation : 예를 들면 디비를 만들고 웹서버 5대를 붙여 라는걸 자동으로 해주게 끔 만들고
  • Chef : 아파치 한대를 열고 쿠키런 웹서버를 띄우고 방화벽 설정을 뭘로 잡고 이런걸 json 이나 소스코드로 인프라를 관리
  • 위에 두개를 git 을 통해서 관리
    • git 을 통해서 관리하니 서버의 변화라던지 설정의 형상 관리를 할 수있었다.

꼭 사용 하라고 하는것

  • ELB, Auto Scaling 을 꼭 사용해라 그리고 CloudFormation 을 통해서 구현
  • S3를 사용해서 게임 데이터를 제공하자 -> Ex: 신규 텍스쳐 사운드를 다운받도록 할 수 있다.
  • 모니터링은 확실하게 하자 -> 모니터링 툴을 통해서 하도록 하자

쿠키런 출시 초기

  • 첫날 9만 가입
  • 6일 120만 가입
  • 기하급수적으로 증가 auto scaling 100대가 넘는 상황
  • 잘되던 환경에서 온갖 문제들이 터지기 시작함.
    • 푸쉬를 보낼때마다 GCM push 서버가 5초간 응답이 없다고 했나 뭐 어쨋든
    • 마스터 인스턴스가 죽기도하고 슬레이브가 깨지기도 하고 트렌젝션 관리라던지
    • 기타 등등

장애의 회고

  • AWS의 직접적인 문제는 없었다.
  • AWS Bisiness Support 에 가입하라
    • 돈은 비싸지만 장애시 유일한 동반자가 되었다.
    • Engineer 에 따라서 AWS 외적인 문제도 도와주었다. (단 영어로)
    • 장애를 신속하게 파악 판단 및 해결 하는데 필수적이다.

장애의 핵심적인 원인

  • 순수한 데이터베이스 부하
    • 게임 시작 및 게임 플레이 정산 부하로 데이터베이스 쓰기 폭주
    • Checkpoint Age 문제로 throughput 급락 이후 장애
  • 생명 보내기 기능 ( 기획의 일부)
    • 매 시간 마다 N명의 사용자가 M 명의 사용자에게 생명을 “받고 보내기”
    • 최대 3* 24*N* M 의 데이터로 DB 엔트리 급격하게 증가
  • MySQL Delete 문의 테이블 락으로 성능저하
    • 데이터를 삭제 하지 않으나 데이터가 무한정 쌓임

장애 해결을 위한 기초시도

  • 이미 JOIN 이나 데이터 종속이 심하다
    • 급하게 NoSQL 솔루션을 알아보기 시작
      • Riak : 사용자 경험이 있지만 throughput이 낮음
      • Couchbase : 성능은 좋아 보이나 왠지 사용버전을 써야 할것 같다.
      • Redis : 사용하기 쉽고 관리하기 쉽고 throughput도 높다.
    • 선물 포인트 생명 갯수 등은 redis 으로 마이그레이션

노하우의 느낌

  • EC2 Auto Scaling 으로 API 서버의 확장 문제 해결
  • 출시전 AWS Instance Limit  을 미리 올려 놓을 것 (기본 20대) 무조건 해하기를 권한다
  • 개별 인스턴스의 CPU사용율을 60% 이하로 유지해야 안정적
  • 평균 CPU 사용량 2분동안 60% 이상 -> 인스턴스 2대 증가
  • 최대 CPU 사용량을 2분동안 80%이상 -> 인스턴스 2대 증가
  • 미리 AMI 를 빌드하여 인스턴스 부팅부터 서비스 시작 시간을 1분 이하로 줄여 놓을것
  • m1.medium, m1.large, m1.xlarge, c1.xlarge 순으로 인스턴스 변경
  • 인스턴스는 최대 200대로 이하로 유지할 것 (이 이상은 관리를 하는데 있어서 비효율적이였다)

  • 실시간 로그 검색 / 분석 ElasticSearch
  • 대용량 푸쉬 python, Celery
  • CouchBase – 생명 우편함 등의 대용량 소셜 정보
    • Redis 의 메모리 한계로 인해서 CouchBase 로 점차 변경중
  • 유지 보수를 하지말아야하고 최대한 자동화를 통해서 아마존을 활용해야 한다.
  • AMI, ELB, EBS 등의 조합으로 확장성 있는 고가용 서버 구축 가능
  • S3, CloudFront -> 정적인 파일 저장 및 제공은 S3와 CloudFront (CDN)으로 모두 해결 가능

아마존 기능 설명

AWS RDS

  • Replication,Backup 등을 알아서 관리해주는 편리한 서비스
  • 데이터 베이스 Scale-up 가능
  • 온라인 상태에서 IOPS증가 가능
  • 사양 변경은 꼭 테스트 후에 , 가능하면 새벽 시간에 할 것
  • 장애에 대비하여 Muiti-AZ 옵션 필수적
  • MySql 5.5 의 경우 Master Failover  시 Slave Replica 가 깨지는 경우 발생
  • RDS MySQL 5.6 에서 해결

Redis

  • 설치하기 쉽고 쓰기 간편, 쓰기 성능도 매우훌륭
  • 데이터 구조를 많이 지원 LeaderBoard 등 개발시 매우 편리
  • 메모리를 넘어서는 데이터에 대해서는 답이 없음
  • 최근 ElastiCache로 redis 를 지원하기 시작

AWS 와 IDC의 가격 비교

  • 단순 서버 vs EC2 비교의 경우 Reserved Instance 를 꼭 고려해야 3년정도 예약하면 반값정도 할인해준다
  • 로드벨런서 ,방화벽, 운영체제 설치  및 설정을 하려면 IDC에 가서 삽질 시작해야되지만 AWS은 필요없다. 마우스로 해결할 수 있다.
  • 고가용성 정적 파일 호스팅을 구현하는 비용 CDN 은 누구랑 계약 해야 하나. 기타등등
  • DB관리 Replication, Backup, Monitoring 는 누가? 누가하지?…를 고려해야 된다.
  • 필요시 바로바로 서버를 이용 할 수 있다. vs IDC는 2주 이상 기다려서 서버를 넣어야된다.
  • Capex Vs Opex :  운영비용과 자산비용의 차이
  • 혼자 서버를 관리 한다면 어떤것을 선택할 것인가?

비용의 진실

  • 전통적인 관점으로 바라보면 저렴하지 않은 AWS이다.
  • 그러나 AWS에서제공하는 다양한 서비스를 활요한다면 훨씬 절약
  • 트레픽 증감에 따라서 EC2가 Auto Scale ; 정확히 사용한 것만 지불하여 비용절감
  • 1대에서 200대 까지 Scale out 을 해야 한다면 ? AWS를 사용해서는 200대 까지는 한번도 문제가 없었다.
  • EC2 Reserved Instance 요금제로 비용을 최적화 -> 예약을 하면 비용을 줄일 수 있다.
  • 급격하게 변하는 모바일 게임 시장, AWS는 필연적 선택
  • 저렴하고 확장성있는 서버보다 성공하는 게임을 만드는게 훨씬 어렵다.
  • 재미있는 게임을 만들 수 있도록 기능 개발 자체에 투자를 해야.  -> 설정 복잡하게 하는 시간에 재미있는 게임 만들도록 하자

사용자가 늘어남에 따라서 지속적인 마이그레이션을 통하였고

mysql -> redis -> couchbase 로 변화중

이상이 발표를 적은 내용 … 입니다.


안드로이드 File 다루기

모바일/Android 2014. 4. 21. 15:30 Posted by 초절정고수

안드로이드 File 다루기


File 다루기

- 안드로이드는에는 내부, 외부의 두가지의 파일 저장 영역이 있다. (internal, external storage)


internal storage (내부)

- 항상 사용가능하며 내부에 저장된 파일은 기본적으로 해당 앱만 접근 가능하다.

- 시스템은 앱이 제거될때 내부에 저장된 파일을 모두 제거한다.


external storage (외부)

- 이곳에 저장된 파일은 다른 곳에서 읽혀질 수 있다. 따라서 다른 앱과 공유될 수 있거나 컴퓨터로 따로 관리할 파일들을 저장하는데 사용하는 것이 좋다.


참고

앱은 기본적으로 internal storage 에 저장되지만 manifest 파일내의 android:installLocation 속성으로 external storage 에 저장할 수 있다.

예) apk 파일의 사이즈가 매우 큰경우


external storage 권한 얻기

쓰기 권한

<manifest ...>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

</manifest>



읽기 권한

차후에는 external storage 에 대한 읽기 권한은 기본으로 제공될 예정

<manifest ...>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

</manifest>


internal storage 에 파일 저장하기

getFileDir()

- 앱 관련된 파일을 저장할 내부 디렉토리의 File 객체를 리턴한다.

getCacheDir()

- 앱의 임시 캐쉬 파일을 저장할 수 있는 디렉토리의 File 객체를 리턴한다.


파일 저장하기

File file = new File(context.getFilesDir(), filename);


String filename = "myfile";

String string = "Hello world";

FileOutputStream outputStream;


try{

outputStream = openFileOutput( filename, Context.MODE_PRIVATE);

outputStream.write( string.getBytes());

outputStream.close();

}catch( Exception e){

e.printStackTrace();

}


임시파일 생성

public File getTempFile( Context context, String url){

File file;

try{

String fileName = Uri.parse(url).getLastPathSegment();

file = File.createTempFile( fileName, null, context.getCacheDir());

}catch( IOException e){

}

return file;

}



external stroage 에 파일 저장하기

외부 저장소가 연결되어 있으며 사용가능한지 여부 체크

public boolean isExternalStorageWritable(){

String state = Environment,getExternalStorageState();

if( Environment.MEDIA_MOUNTED.equals( state)){

return true;

}

return false;

}


public boolean isExternalStorageReadable(){

String state = Environment.getExternalStorageState();

if( Environment.MEDIA_MOUNTED.equals( state) ||

Environment.MEDIA_MOUNTED_READ_ONLY.equals( state)){

return true;

}

return false;

}



external storage 공용 public 저장소 사용하기

public 저장소는 앱을 삭제해도 저장되어 있는 파일이 사용가능하다.

public File getAlbumStorageDir( String albumName){

File file = new File( Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), 

albumName

);

if( !file.mkdir()){

Log.e( LOG_TAG, "Directory not created");

}

return file;

}



external storage 개인 private 저장소 사용하기

앱이 제거되면 private 저장소내의 모든 파일을 삭제한다.

public File getAlbumStorageDir( String albumName){

File file = new File( Environment.getExternalFilesDir( Environment.DIRECTORY_PICTURES), 

albumName

);

// root 디렉토리 얻기

// file = new File( Environment.getExternalFilesDir( null)); 

if( !file.mkdir()){

Log.e( LOG_TAG, "Directory not created");

}

return file;

}


저장공간 확인

getFreeSpace(), getTotalSpace() 로 확인할 수 있다.



파일 삭제하기

myFile.delete();

myContext.deleteFile( fileName);


ASP에서 UTF-8 처리 외 기타

웹/ASP 2014. 4. 8. 18:34 Posted by 초절정고수

1. 모든 ASP 코드 페이지 첫줄에 다음과 같은 코드를 추가합니다
<% @CODEPAGE="65001" language="vbscript" %>
<% Option Explicit %>
<% session.CodePage = "65001" %>
<% Response.CharSet = "utf-8" %>
<% Response.buffer=true %>
<% Response.Expires = 0 %>
 
2. Meta 테그를 다음과 같이 추가 합니다.
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 
3. Response.ChaRset = "utf-8"  
ASP의 response.charset을 이용해서 문자 코드 세트명을 지정하는 부분 입니다.
설정시 <html> 태그 보다 앞에 선언 되어야 HTML 이 출력되면서 해당 속성을 인식하게 됩니다.

4. 에디트플러스나 울트라 에디터에서 수정후 저장할 때 반드시 Encoding 방식을 UTF-8 로 저장합니다
 
5.DB Insert/Update 시 숫자 타입을 제외한 모든 대상에 N을 추가 합니다
Insert 테이블이름 (칼럼a, 칼럼b) value (N'입력a', N'입력b')
update 테이블이를 set 칼럼a = N'입력a' where 고유칼럼 = '번호'
 
6.DB like 검색시 N 추가
 
7. 파일 첨부 DEXT Upload사용(영문으로 설치)
 SET uploadform = Server.CreateObject("DEXT.FileUpload")
 uploadform.DefaultPath = Server.MapPath(ESP_BBS_DATA)
 uploadform.CodePage = 65001
 wFileSize = 0
 rAttachment = uploadform("txtAttachFile")
 
 If Len(rAttachment) > 0 Then
  wFileName =  uploadform("txtAttachFile").FileName
  wFileSize =  uploadform("txtAttachFile").FileLen
 
  response.write uploadform.DefaultPath
  rAttachment = uploadform.SaveAs(uploadform.DefaultPath & "" & wFileName , False)
  rAttachment = UploadForm.LastSavedFileName
 End If
 
8. 파일 다운로드
 
<% @LANGUAGE='VBscRIPT' CODEPAGE='65001' %>
<%
 'Response.Charset = "UTF-8"
 filepath = Request.QueryString("txtFilepath") '// form으로 파라메터 전달해야 함.
 filename = Request.QueryString("txtFilename")'// form으로 파라메터 전달해야 함.
 
 If filepath = "" Then
  filepath=server.MapPath( Request.QueryString("txtFilename"))
  filename = Mid(filepath, InStrRev(filepath, "")+1)
 Else
  filepath=server.MapPath(filepath)
  filename =  Request.QueryString("txtFilename")
  If filename = "" Then
  filename = Request.QueryString("txtattachment")
  End If
 End If

 filepath = filepath &"" & filename
Call FileDown
%>
 
<%
Sub FileDown
' 참고http://www.taeyo.pe.kr/Lecture/20_TIps/Danny03.asp
 
 Response.Buffer = False
 Response.ContentType = "application/x-msdownload"
 'ContentType 를 선언합니다.
 'server.HTMLEncode
 'server.URLPathEncode
 Response.AddHeader "Content-Disposition","attachment; filename=" & server.URLPathEncode(filename) '//server.URLPathEncode 사용해야만 파일명 재대로 출력
 '헤더값이 첨부파일을 선언합니다.
 Set objStream = Server.CreateObject("ADODB.Stream")
 'Stream 을 이용합니다.
 objStream.Open
 '무엇이든 Set 으로 정의했으면 열어야 겠지요^^
 objStream.Type = 1
 objStream.LoadFromFile filepath
 '절대경로 입니다.
 download = objStream.Read
 Response.BinaryWrite download
 '이게 보통 Response.Redirect 로 파일로 연결시켜주는 부분을 대신하여 사용된 것입니다.
 Set objstream = nothing
 '초기화시키구요.
End Sub
%>
 
<%
Sub DEXTDown  ' DEXT.FileDownload 는 일본어 OS에 영문으로 설치시 한글파일 찾지 못함.(DextUpload 2.0까지는 그랬음)
 'On Error Resume Next
 Response.Buffer = False
 Response.AddHeader "Content-Disposition","inline;filename=" &  server.URLPathEncode(filename)
 set objFS = Server.CreateObject("scripting.FileSystemObject")

 set objF = objFS.GetFile(filepath)
 
 Response.AddHeader "Content-Length", objF.Size
 set objF = nothing
 set objFS = nothing
 Response.ContentType = "application/x-msdownload"
 Response.CacheControl = "public"
 Set objDownload = Server.CreateObject("DEXT.FileDownload")
 objDownload.Download filepath
 Set uploadform = Nothing
End Sub
%>
 
9. CDO Mail발송
Dim iMsg
Dim iConf
Dim Flds
Dim strHTML
Const cdoSendUsingPort = 2 '1:로컬, 2:외부 smtp
set iMsg = CreateObject("CDO.Message")
set iConf = CreateObject("CDO.Configuration")
Set Flds = iConf.Fields
Flds.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPort
Flds.item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25  '포트번호
Flds.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "localhost"
Flds.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 10
Flds.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") =  "" 'ID
Flds.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") =  "" '암호

Flds.Update
Set iMsg.Configuration = iConf
iMsg.To = "xxxx@xxx.ccx" 'ToDo: Enter a valid email address.
iMsg.From = "xxxx@xxx.ccx"  'ToDo: Enter a valid email address.
iMsg.Subject = "This is a test CDOSYS message (Sent via Port 25)"
 
'iMsg..TextBody = strHTMLMsg '// 텍스트
iMsg.HTMLBody = strHTML  '// HTML 제목 깨짐 발생..

iMsg.BodyPart.Charset="UTF-8" '/// 한글을 위해선 꼭 넣어 주어야 합니다.
iMsg.HTMLBodyPart.Charset="UTF-8" '/// 한글을 위해선 꼭 넣어 주어야 합니다.
iMsg.Send
End With
Set iMsg = Nothing
Set iConf = Nothing
Set Flds = Nothing
 
 
10. ASP에서 배달 확인/ 읽음 확인 구현 방법 http://tong.nate.com/windeo/5767827

http://support.microsoft.com/default.aspx?scid=kb;ko;286430

<%
Set oMsg = CreateObject("CDO.Message")
oMsg.Configuration.Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
‘ 생성되는 메시지가 SMTP pickup 디렉터리가 아닌 SMTP 서비스로 전송되게 합니다.
oMsg.Configuration.Fields("http://schemas.microsoft.com/cdo/configuration/sendusername") = "이름"
oMsg.Configuration.Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "xxxxx"
oMsg.Configuration.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "seo-msg-01"
‘ 생성되는 메시지의 서버, 사서함 및 암호
oMsg.Configuration.Fields.Update

oMsg.From = "smpark@microsoft.com"
oMsg.To = "smpark@microsoft.com"

oMsg.Subject = "읽음 확인 및 배달 확인"
oMsg.DSNOptions = 14
‘ 이 메시지의 배달 상태 확인(delivery status notification:DSN)값으로 14는 배달 성공, 실패 및 지연시
‘ 확인메시지 생성
oMsg.Fields("urn:schemas:mailheader:return-receipt-to") = smpark@microsoft.com <mailto:smpark@microsoft.com>
‘ 받는 사람이 이 메시지를 열었을 때 읽음 확인 메시지가 여기에서 지정된 사람에게 보내집니다.
oMsg.Fields("urn:schemas:mailheader:disposition-notification-to") = smpark@microsoft.com <mailto:smpark@microsoft.com>
‘ MDN(Message Disposition Notification)은 이 메시지의 확인 메시지가 리턴 될 수신자를 지정합니다.
‘ MDN에 대하여는 Request for Comments (RFC) 2298에 자세히 설명됩니다.
oMsg.TextBody = " SMTP 서버를 통한 읽음 확인 및 배달 확인 메시지"
oMsg.Fields.Update
oMsg.Send

Set oMsg = Nothing
%>


11. 업로드 컴포넌트 UTF-8 지원여부 확인
SiteGalaxy(사이트 갤럭시) 및 ABC 업로드 :  utf-8을 지원하지 않음
덱스트업로드는 3.x 이후 지원


' > ASP' 카테고리의 다른 글

IIS6 다운로드/업로드 크기제한  (0) 2015.09.20
IIS 6 에서 ASP 에서 대용량 파일을 업로드시 403 오류  (0) 2014.04.30
ASP DateAdd함수  (0) 2014.03.04