SlideShare a Scribd company logo
1 of 29
Download to read offline
빠르게 푸시 보내기
Feat. Async / Generator
전창완
전창완

- Oponiti & Allbus 서버 개발자

- Wandu Framework
발표자 소개
1.기존의 방식

2.어떻게 개선할까? - Async

3.어떻게 개선할까? - Generator

4.결론
목차
GCM 이란?
기존의 방식
1. GCM(Google Cloud Messaging)이란, 구글 서버를 이용해서 안드로이드 기기에 푸시를 보내는 것.
기존에 알아야 할 사실
기존의 방식
1.GCM은 HTTP Request를 통해 메세지를 보낼 수 있음.

2.GCM은 한번에 1000개씩 보낼 수 있음.

3.저희 서버에 등록된 GCM Key는 약 70만개.

4.모든 사람이 공정하게 푸시를 받아야 함. (매번 푸시 발송 순서가 달라야함.)
기존의 방식
기존의 동작 방식
사용자를 1000명

단위로 그룹 지정
그룹을 랜덤으로
Shuffle
1000개 단위로

푸시 전송
로그 쌓기
끝날때까지 반복
기존의 방식
기존의 동작 방식
사용자를 1000명

단위로 그룹 지정
그룹을 랜덤으로
Shuffle
1000개 단위로

푸시 전송
로그 쌓기
끝날때까지 반복
여기까지 보통 80분 정도 소요..
기존의 방식
기존의 동작 방식
사용자를 1000명

단위로 그룹 지정
그룹을 랜덤으로
Shuffle
1000개 단위로

푸시 전송
로그 쌓기
끝날때까지 반복
기존의 방식
기존의 동작 방식
사용자를 1000명

단위로 그룹 지정
그룹을 랜덤으로
Shuffle
1000개 단위로

푸시 전송
로그 쌓기
끝날때까지 반복
여기를 개선해보자!!
Async, 간단히 이야기 하면..

(다들 아시잖아요..)
누구나 다 아는 그 그림, Sync vs Async
어떻게 개선할까? - Async
Sync Async
방금 그 그림을 반복해서 한다면..
어떻게 개선할까? - Async
Sync Async
*순서는 절대 보장되지 않아요!
HTTP Request

Async로 사용해보자!
PHP에서 Async의 지원
어떻게 개선할까? - Async
1.PHP의 모든 로직은 전부 Sync가 기반.

2.PHP에서 Async를 사용하기 위해서는 Pthread 모듈이나 Ev, Uv 등을 사용해야 함.

3.하지만, 내장 Curl의 경우 Multi Curl을 지원해서 비동기로 처리가 가능.

4.즉, Curl에 한해서는 기본 PHP로 Async스럽게 사용할 수 있음.

5.이 Multi Curl을 Async(그리고 Promise)를 통해서 구현해놓은 라이브러리가 Guzzle Http.
어떻게 개선할까? - Async
HTTP Request할때, 다들 많이 사용할 그 녀석..
어떻게 개선할까? - Async
Request 생성 매서드 하나 만들고..
public function createRequest($tokens, $message, $url = '')

{

return new Request(

'POST',

new Uri('https://android.googleapis.com/gcm/send'),

'1.1',

[

'Authorization' => "key=xxxxxxxxxxxxxxx",

'Content-Type' => 'application/json',

],

new StringStream(json_encode([

'registration_ids' => $tokens,

'data' => [

'alert' => $message,

'url' => $url

],

]))

);

}
Request, Uri, StringStream은 PSR-7 객체입니다.
어떻게 개선할까? - Async
나머진 그냥 예시 참고해서 만들면 됨.
http://docs.guzzlephp.org/en/latest/quickstart.html
$requests = [];

foreach ($this->getChunkedTokens() as $tokens) {

$message = $this->getMessate();

$url = $this->getUrl();

$requests[] = $this->createRequest($tokens, $message, $url);

}

$pool = new Pool($this->client, $requests, [

'concurrency' => 20, // 메모리에 맞춰서 알아서..

'fulfilled' => function ($response, $index) {

$this->output->writeln(date('[Y-m-d H:i:s] ') ."success in {$index} !!");

},

'rejected' => function ($reason, $index) {

$this->output->writeln(date('[Y-m-d H:i:s] ') ."fail in {$index} ..");

},

]);

$pool->promise()->wait();
테스트 환경에서 70만건 발송(단위 = 초)
어떻게 개선할까? - Async
여기까지 했을 때의 문제.
어떻게 개선할까? - Async
1.Iterator로 요청하기 때문에 GCM 키 70만건을 한번에 메모리에 올려야 함.

2.구글 문서에 따르면 GCM Key는 최대 4Kb 까지 가능함.

3.그냥 2.8Gb 정도의 메모리를 소요함.

4.굳이 이 만큼의 메모리를 소비해야 하는가?
Generator를 사용하자!

(한번쯤 들어보셨잖아요..)
어떻게 개선할까? - Generator
기존의 소스
$requests = [];

foreach ($this->getChunkedTokens() as $tokens) {

$message = $this->getMessage();

$url = $this->getUrl();

$requests[] = $this->createRequest($tokens, $message, $url);

}

$pool = new Pool($this->client, $requests, [

'concurrency' => 30, // 메모리에 맞춰서 알아서..

'fulfilled' => function ($response, $index) {

$this->output->writeln(date('[Y-m-d H:i:s] ') ."success in {$index} !!");

},

'rejected' => function ($reason, $index) {

$this->output->writeln(date('[Y-m-d H:i:s] ') ."fail in {$index} ..");

},

]);

$pool->promise()->wait();
어떻게 개선할까? - Generator
Generator 다듬어진 소스
$requests = function () {

foreach ($this->getChunkedTokens() as $tokens) {

$message = $this->getMessage();

$url = $this->getUrl();

yield $this->createRequest($tokens, $message, $url);

}

};

$pool = new Pool($this->client, $requests(), [

'concurrency' => 30, // 메모리에 맞춰서 알아서..

'fulfilled' => function ($response, $index) {

$this->output->writeln(date('[Y-m-d H:i:s] ') ."success in {$index} !!");

},

'rejected' => function ($reason, $index) {

$this->output->writeln(date('[Y-m-d H:i:s] ') ."fail in {$index} ..");

},

]);

$pool->promise()->wait();

테스트 환경에서 70만건 발송(단위 = MB)
어떻게 개선할까? - Generator
실제 서비스에서는

어떻게 개선되었는가?
실서버 걸리는 시간(단위 = 분)
결론
실서버 걸리는 시간(단위 = 분)
결론
메모리는 보통 50MB 이하..
결론
1.Async는 속도를 향상 시킬 수 있음. 따라서, Async로 할 수 있는 작업은 Async로 바꾸자.

2.Generator는 메모리를 효율적으로 사용할 수 있음. 따라서, Generator로 할 수 있다면 Generator를 사용해보자.

3.그렇지만 이게 정답은 아님.
정리
Q & A ?

More Related Content

What's hot

[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기MinGeun Park
 
채팅서버의 부하 분산 사례
채팅서버의 부하 분산 사례채팅서버의 부하 분산 사례
채팅서버의 부하 분산 사례John Kim
 
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들Brian Hong
 
행동 기반 게임오브젝트
행동 기반 게임오브젝트행동 기반 게임오브젝트
행동 기반 게임오브젝트kgun86
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유Hyojun Jeon
 
4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴Terry Cho
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략YEONG-CHEON YOU
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현noerror
 
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?내훈 정
 
게임제작개론 : #7 팀 역할과 게임 리소스에 대한 이해
게임제작개론 : #7 팀 역할과 게임 리소스에 대한 이해게임제작개론 : #7 팀 역할과 게임 리소스에 대한 이해
게임제작개론 : #7 팀 역할과 게임 리소스에 대한 이해Seungmo Koo
 
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015devCAT Studio, NEXON
 
Why Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebWhy Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebBryan Helmig
 
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버준철 박
 
[211] 네이버 검색과 데이터마이닝
[211] 네이버 검색과 데이터마이닝[211] 네이버 검색과 데이터마이닝
[211] 네이버 검색과 데이터마이닝NAVER D2
 
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지강 민우
 
게임서버 구축 방법비교 : GBaaS vs. Self-hosting
게임서버 구축 방법비교 : GBaaS vs. Self-hosting게임서버 구축 방법비교 : GBaaS vs. Self-hosting
게임서버 구축 방법비교 : GBaaS vs. Self-hostingiFunFactory Inc.
 
FIFA 온라인 3의 MongoDB 사용기
FIFA 온라인 3의 MongoDB 사용기FIFA 온라인 3의 MongoDB 사용기
FIFA 온라인 3의 MongoDB 사용기Jongwon Kim
 
ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기Yungon Park
 
게임 프로그래밍 기초 공부법
게임 프로그래밍 기초 공부법게임 프로그래밍 기초 공부법
게임 프로그래밍 기초 공부법Chris Ohk
 

What's hot (20)

[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
 
채팅서버의 부하 분산 사례
채팅서버의 부하 분산 사례채팅서버의 부하 분산 사례
채팅서버의 부하 분산 사례
 
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들
 
행동 기반 게임오브젝트
행동 기반 게임오브젝트행동 기반 게임오브젝트
행동 기반 게임오브젝트
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
 
4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현
 
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
 
Ndc12 2
Ndc12 2Ndc12 2
Ndc12 2
 
게임제작개론 : #7 팀 역할과 게임 리소스에 대한 이해
게임제작개론 : #7 팀 역할과 게임 리소스에 대한 이해게임제작개론 : #7 팀 역할과 게임 리소스에 대한 이해
게임제작개론 : #7 팀 역할과 게임 리소스에 대한 이해
 
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015
 
Why Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebWhy Task Queues - ComoRichWeb
Why Task Queues - ComoRichWeb
 
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
 
[211] 네이버 검색과 데이터마이닝
[211] 네이버 검색과 데이터마이닝[211] 네이버 검색과 데이터마이닝
[211] 네이버 검색과 데이터마이닝
 
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
 
게임서버 구축 방법비교 : GBaaS vs. Self-hosting
게임서버 구축 방법비교 : GBaaS vs. Self-hosting게임서버 구축 방법비교 : GBaaS vs. Self-hosting
게임서버 구축 방법비교 : GBaaS vs. Self-hosting
 
FIFA 온라인 3의 MongoDB 사용기
FIFA 온라인 3의 MongoDB 사용기FIFA 온라인 3의 MongoDB 사용기
FIFA 온라인 3의 MongoDB 사용기
 
ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기
 
게임 프로그래밍 기초 공부법
게임 프로그래밍 기초 공부법게임 프로그래밍 기초 공부법
게임 프로그래밍 기초 공부법
 

More from Changwan Jun

Serverless 프레임워크로 Nuxt 앱 배포하기
Serverless 프레임워크로 Nuxt 앱 배포하기Serverless 프레임워크로 Nuxt 앱 배포하기
Serverless 프레임워크로 Nuxt 앱 배포하기Changwan Jun
 
Infrastructure as Code 삽질기
Infrastructure as Code 삽질기Infrastructure as Code 삽질기
Infrastructure as Code 삽질기Changwan Jun
 
Vue SSR vs Prerender
Vue SSR vs PrerenderVue SSR vs Prerender
Vue SSR vs PrerenderChangwan Jun
 
PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기Changwan Jun
 

More from Changwan Jun (6)

Serverless 프레임워크로 Nuxt 앱 배포하기
Serverless 프레임워크로 Nuxt 앱 배포하기Serverless 프레임워크로 Nuxt 앱 배포하기
Serverless 프레임워크로 Nuxt 앱 배포하기
 
GraphQL 적용기
GraphQL 적용기GraphQL 적용기
GraphQL 적용기
 
Infrastructure as Code 삽질기
Infrastructure as Code 삽질기Infrastructure as Code 삽질기
Infrastructure as Code 삽질기
 
Vue SSR vs Prerender
Vue SSR vs PrerenderVue SSR vs Prerender
Vue SSR vs Prerender
 
PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기
 
Modern PHP
Modern PHPModern PHP
Modern PHP
 

PHP에서 GCM 푸시 빠르게 보내기 (feat. Async / Generator)

  • 1. 빠르게 푸시 보내기 Feat. Async / Generator 전창완
  • 2. 전창완 - Oponiti & Allbus 서버 개발자 - Wandu Framework 발표자 소개
  • 3. 1.기존의 방식 2.어떻게 개선할까? - Async 3.어떻게 개선할까? - Generator 4.결론 목차
  • 4. GCM 이란? 기존의 방식 1. GCM(Google Cloud Messaging)이란, 구글 서버를 이용해서 안드로이드 기기에 푸시를 보내는 것.
  • 5. 기존에 알아야 할 사실 기존의 방식 1.GCM은 HTTP Request를 통해 메세지를 보낼 수 있음. 2.GCM은 한번에 1000개씩 보낼 수 있음. 3.저희 서버에 등록된 GCM Key는 약 70만개. 4.모든 사람이 공정하게 푸시를 받아야 함. (매번 푸시 발송 순서가 달라야함.)
  • 6. 기존의 방식 기존의 동작 방식 사용자를 1000명
 단위로 그룹 지정 그룹을 랜덤으로 Shuffle 1000개 단위로
 푸시 전송 로그 쌓기 끝날때까지 반복
  • 7. 기존의 방식 기존의 동작 방식 사용자를 1000명
 단위로 그룹 지정 그룹을 랜덤으로 Shuffle 1000개 단위로
 푸시 전송 로그 쌓기 끝날때까지 반복 여기까지 보통 80분 정도 소요..
  • 8. 기존의 방식 기존의 동작 방식 사용자를 1000명
 단위로 그룹 지정 그룹을 랜덤으로 Shuffle 1000개 단위로
 푸시 전송 로그 쌓기 끝날때까지 반복
  • 9. 기존의 방식 기존의 동작 방식 사용자를 1000명
 단위로 그룹 지정 그룹을 랜덤으로 Shuffle 1000개 단위로
 푸시 전송 로그 쌓기 끝날때까지 반복 여기를 개선해보자!!
  • 10. Async, 간단히 이야기 하면.. (다들 아시잖아요..)
  • 11. 누구나 다 아는 그 그림, Sync vs Async 어떻게 개선할까? - Async Sync Async
  • 12. 방금 그 그림을 반복해서 한다면.. 어떻게 개선할까? - Async Sync Async *순서는 절대 보장되지 않아요!
  • 14. PHP에서 Async의 지원 어떻게 개선할까? - Async 1.PHP의 모든 로직은 전부 Sync가 기반. 2.PHP에서 Async를 사용하기 위해서는 Pthread 모듈이나 Ev, Uv 등을 사용해야 함. 3.하지만, 내장 Curl의 경우 Multi Curl을 지원해서 비동기로 처리가 가능. 4.즉, Curl에 한해서는 기본 PHP로 Async스럽게 사용할 수 있음. 5.이 Multi Curl을 Async(그리고 Promise)를 통해서 구현해놓은 라이브러리가 Guzzle Http.
  • 15. 어떻게 개선할까? - Async HTTP Request할때, 다들 많이 사용할 그 녀석..
  • 16. 어떻게 개선할까? - Async Request 생성 매서드 하나 만들고.. public function createRequest($tokens, $message, $url = '')
 {
 return new Request(
 'POST',
 new Uri('https://android.googleapis.com/gcm/send'),
 '1.1',
 [
 'Authorization' => "key=xxxxxxxxxxxxxxx",
 'Content-Type' => 'application/json',
 ],
 new StringStream(json_encode([
 'registration_ids' => $tokens,
 'data' => [
 'alert' => $message,
 'url' => $url
 ],
 ]))
 );
 } Request, Uri, StringStream은 PSR-7 객체입니다.
  • 17. 어떻게 개선할까? - Async 나머진 그냥 예시 참고해서 만들면 됨. http://docs.guzzlephp.org/en/latest/quickstart.html $requests = [];
 foreach ($this->getChunkedTokens() as $tokens) {
 $message = $this->getMessate();
 $url = $this->getUrl();
 $requests[] = $this->createRequest($tokens, $message, $url);
 }
 $pool = new Pool($this->client, $requests, [
 'concurrency' => 20, // 메모리에 맞춰서 알아서..
 'fulfilled' => function ($response, $index) {
 $this->output->writeln(date('[Y-m-d H:i:s] ') ."success in {$index} !!");
 },
 'rejected' => function ($reason, $index) {
 $this->output->writeln(date('[Y-m-d H:i:s] ') ."fail in {$index} ..");
 },
 ]);
 $pool->promise()->wait();
  • 18. 테스트 환경에서 70만건 발송(단위 = 초) 어떻게 개선할까? - Async
  • 19. 여기까지 했을 때의 문제. 어떻게 개선할까? - Async 1.Iterator로 요청하기 때문에 GCM 키 70만건을 한번에 메모리에 올려야 함. 2.구글 문서에 따르면 GCM Key는 최대 4Kb 까지 가능함. 3.그냥 2.8Gb 정도의 메모리를 소요함. 4.굳이 이 만큼의 메모리를 소비해야 하는가?
  • 21.
  • 22. 어떻게 개선할까? - Generator 기존의 소스 $requests = [];
 foreach ($this->getChunkedTokens() as $tokens) {
 $message = $this->getMessage();
 $url = $this->getUrl();
 $requests[] = $this->createRequest($tokens, $message, $url);
 }
 $pool = new Pool($this->client, $requests, [
 'concurrency' => 30, // 메모리에 맞춰서 알아서..
 'fulfilled' => function ($response, $index) {
 $this->output->writeln(date('[Y-m-d H:i:s] ') ."success in {$index} !!");
 },
 'rejected' => function ($reason, $index) {
 $this->output->writeln(date('[Y-m-d H:i:s] ') ."fail in {$index} ..");
 },
 ]);
 $pool->promise()->wait();
  • 23. 어떻게 개선할까? - Generator Generator 다듬어진 소스 $requests = function () {
 foreach ($this->getChunkedTokens() as $tokens) {
 $message = $this->getMessage();
 $url = $this->getUrl();
 yield $this->createRequest($tokens, $message, $url);
 }
 };
 $pool = new Pool($this->client, $requests(), [
 'concurrency' => 30, // 메모리에 맞춰서 알아서..
 'fulfilled' => function ($response, $index) {
 $this->output->writeln(date('[Y-m-d H:i:s] ') ."success in {$index} !!");
 },
 'rejected' => function ($reason, $index) {
 $this->output->writeln(date('[Y-m-d H:i:s] ') ."fail in {$index} ..");
 },
 ]);
 $pool->promise()->wait();

  • 24. 테스트 환경에서 70만건 발송(단위 = MB) 어떻게 개선할까? - Generator
  • 27. 실서버 걸리는 시간(단위 = 분) 결론 메모리는 보통 50MB 이하..
  • 28. 결론 1.Async는 속도를 향상 시킬 수 있음. 따라서, Async로 할 수 있는 작업은 Async로 바꾸자. 2.Generator는 메모리를 효율적으로 사용할 수 있음. 따라서, Generator로 할 수 있다면 Generator를 사용해보자. 3.그렇지만 이게 정답은 아님. 정리
  • 29. Q & A ?