1. vert.x를 활용한
!
대용량 트래픽 처리를 위한!
분산 서버 개발하기!
!
(vert.x & scalable architecture)
김요한
yohany@gmail.com
2. 1. 개발 패러다임의 변화!
!
!
- 비동기 Event Looping 서버의 특징!
- JVM 기반 vert.x 특징!
!
2. 분산 서버 설계 하기!
!
- 대용량 트래픽 처리 / 체팅 서비스 서버 개발 사례!
!
3. 분산 서버 설계시 알아야 할 것들!
!
- Consistent Hashing, Sharding, Proxy, MessageQueue ..!
3. 1. 개발 패러다임의 변화!
!
!
- 비동기 Event Looping 서버의 특징!
- JVM 기반 vert.x 특징
4. 1. 개발 패러다임의 변화
Question
원하는 만큼 확장할 수 있나요 ?!
대용량 트래픽을 처리 할 수 있나요 ?!
기능 추가를 얼마나 빨리 할 수 있나요 ?!
쉽고 빨리 개발할 수 있나요 ?
5. 1. 개발 패러다임의 변화
Answer
background on the C10K problem!
Event Looping!
None Blocking I/O!
Fault Tolerant!
Scalability (Scala-Out)!
......
8. 비동기 서버의 특징
Apache HTTP Server v2.4 ideally suited for Cloud environments. They include:!
!
•
•
•
•
•
•
•
Improved performance (lower resource utilization and better concurrency)!
Reduced memory usage!
Asyncronous I/O support!
Dynamic reverse proxy configuration!
Asynchronous I/O support
Performance on par, or better, than pure event-driven Web servers!
More granular timeout and rate/resource limiting capability!
More finely-tuned caching support, tailored for high traffic servers and proxies.
http://blogs.apache.org/foundation/entry/the_apache_software_foundation_celebrates
9. 비동기 서버의 특징
Java IO
Stream oriented Blocking IO
Reading data from a blocking stream.
10. 비동기 서버의 특징
Java NIO
Buffer oriented Non blocking IO Selectors
Reading data from a channel until all needed data is in buffer.
http://tutorials.jenkov.com/java-nio/nio-vs-io.html
16. 비동기 서버의 특징
“ Components + Scripts = Applications ”
see John Ousterhout, IEEE Computer, March ’98
http://www.stanford.edu/~ouster/cgi-bin/papers/scripting.pdf
19. JVM 기반 VERT.X 특징
import org.vertx.java.core.Handler;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.platform.Verticle;
public class Server extends Verticle {
JAVA 7
public void start() {
vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {
public void handle(HttpServerRequest req) {
String file = req.path().equals("/") ? "index.html" : req.path();
req.response().sendFile("webroot/" + file);
}
}).listen(8080);
}
}
> vertx run Server.java
20. JVM 기반 VERT.X 특징
import org.vertx.java.core.Handler;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.platform.Verticle;
public class Server extends Verticle {
JAVA 7
public void start() {
!
vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {
public void handle(HttpServerRequest req) {
vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>()
public void= handle(HttpServerRequest req) {
String file
req.path().equals("/") ? "index.html" : req.path();
req.response().sendFile("webroot/" + file);
}
}).listen(8080);
}
}
> vertx run Server.java
{
21. JVM 기반 VERT.X 특징
import org.vertx.java.core.Handler;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.platform.Verticle;
public class Server extends Verticle {
JAVA 8
public void start() {
!
vertx.createHttpServer().requestHandler( (HttpServerRequest req) -> {
vertx.createHttpServer().requestHandler((HttpServerRequest
{
String file = req.path().equals("/") ? "index.html" : req.path();
req.response().sendFile("webroot/" + file);
}).listen(8080);
}
}
> vertx run Server.java
req) -> {
22. JVM 기반 VERT.X 특징
import org.vertx.java.core.Handler;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.platform.Verticle;
public class Server extends Verticle {
JAVA 8
public void start() {
vertx.createHttpServer().requestHandler( (HttpServerRequest req) -> {
String file = req.path().equals("/") ? "index.html" : req.path();
req.response().sendFile("webroot/" + file);
}).listen(8080);
}
}
> vertx run Server.java
23. JVM 기반 VERT.X 특징
vert.x instance
Verticle
Verticle
Worker
Verticle
Worker
Verticle
24. JVM 기반 VERT.X 특징
vert.x instance
Verticle
Verticle
Worker
Verticle
EventBus
Worker
Verticle
25. JVM 기반 VERT.X 특징
EventBus eb = vertx.eventBus();
Handler<Message> myHandler = new Handler<Message>() {
public voidvert.x instance
handle(Message message) {
System.out.println("I received a message " + message.body);
}
};
!
Worker
// EventBus 에 이벤트 등록
Verticle
Verticle
Verticle
eb.registerHandler("test.address", myHandler);
EventBus
// EventBus 로 이벤트 실행
eb.send("test.address", "hello world");
Worker
Verticle
38. - 분산 체팅서비스 구축하기 사례
http://example.com/samplePage.html
체팅방 키
39. - 분산 체팅서비스 구축하기 사례
http://노량진수산시장 /개불.html
Chat Server
Chat Server
(vert.x sockJS)
Chat Server
(vert.x sockJS)
Chat Server
(vert.x sockJS)
(vert.x sockJS)
천승희
도문준
체팅방 KEY : 노량진수산시장/개불
40. - 분산 체팅서비스 구축하기 사례
http://노량진수산시장 /개불.html
Chat Server
Chat Server
Chat Server
천승희
Chat Server
. . .!
“Session 정보 공유하기” 문제 !
도문준
41. - 분산 체팅서비스 구축하기 사례
http://노량진수산시장 /개불.html
Restful Server
Publish
도문준
천승희
Subscribe
. . .!
Socket Server
김요한
42. - 분산 체팅서비스 구축하기 사례
http://노량진수산시장 /개불.html
Restful Server
Restful Server
Restful Server
Restful Server
Restful Server
Restful Server
HAProxy
천승희
Restful Server
도문준
Restful Server
. . .!
Socket Server
김요한
43. - 분산 체팅서비스 구축하기 사례
http://노량진수산시장 /개불.html
Restful Server
Restful Server
Restful Server
Restful Server
Subscribe
Publish
천승희
Socket Server
Socket Server
도문준
Socket Server
도문준
Socket Server
Restful Server
Restful Server
Restful Server
Socket Server
. . .!
김요한
김요한
44. - 분산 체팅서비스 구축하기 사례
http://노량진수산시장 /개불.html
Restful Server
Restful Server
Restful Server
Restful Server
Subscribe
Publish
천승희
Socket Server
Socket Server
도문준
Socket Server
도문준
Socket Server
Restful Server
Restful Server
Restful Server
Socket Server
. . .!
김요한
김요한
46. - 분산 체팅서비스 구축하기 사례
http://노량진수산시장 /개불.html
Restful Server
Restful Server
Restful Server
Restful Server
Hash()
Publish
Hash()
도문준
천승희
Subscribe
Restful Server
Restful Server
Socket Server
Restful Server
Socket Server
Socket Server
Socket Server
. . .!
Hash()
김요한
47. - 분산 체팅서비스 구축하기 사례
http://노량진수산시장 /개불.html
Restful Server
Restful Server
Restful Server
Restful Server
Hash()
Publish
도문준
천승희
Subscribe
Restful Server
Restful Server
Socket Server
Restful Server
Socket Server
Socket Server
Socket Server
. . .!
김요한
48. - 분산 체팅서비스 구축하기 사례
http://노량진수산시장 /개불.html
Restful Server
Restful Server
Restful Server
Restful Server
Hash()
Publish
도문준
천승희
Subscribe
Restful Server
Restful Server
Socket Server
Socket Server
Socket Server
Socket Server
. . .!
김요한
49. - 분산 체팅서비스 구축하기 사례
vert.x modules
Startup &
HTTP
configuration
Module
Module
Socket
Module
Distributed
Node Manager
Module
Message Queue
Module
vert.x event bus
A instance in JVM
https://github.com/stalk-io
50. - 분산 체팅서비스 구축하기 사례
Restful Server
Startup &
HTTP
configuration
Module
Module
Socket
Module
Distributed
Node Manager
Module
Message Queue
Module
vert.x event bus
A instance in JVM
https://github.com/stalk-io
51. - 분산 체팅서비스 구축하기 사례
Socket Server
Startup &
HTTP
configuration
Module
Module
Socket
Module
Distributed
Node Manager
Module
Message Queue
Module
vert.x event bus
A instance in JVM
https://github.com/stalk-io
52. 3. 분산 서버 설계시 알아야 할 것들!
!
- Consistent Hashing, Sharding, Proxy, MessageQueue ..
84. - Consistent Hashing
public
class
ConsistentHashT{
!
ConsistentHash.add(‘nodeA’,...);
!
!
ConsistentHash.add(‘nodeB’,...);
!
!
!
!
!
!
!
!
!
!
ConsistentHash.add(‘nodeC’,...);
!
!
!
!
!
ConsistentHash.add(‘nodeD’,...);
!
!
!
}
private
final
HashFunction
hashFunction
=
Hashing.md5();
private
final
SortedMapLong,
T
circle
=
new
TreeMapLong,
T();
public
void
add(String
name,
T
node)
{
circle.put(hashFunction.hashString(name).asLong(),node);
}
public
void
remove(String
name)
{
circle.remove(hashFunction.hashString(name).asLong());
}
public
T
get(String
value)
{
long
hash
=
hashFunction.hashString(value).asLong();
if
(!circle.containsKey(hash))
{
SortedMapLong,
T
tailMap
=
circle.tailMap(hash);
}
hash
=
tailMap.isEmpty()?circle.firstKey():tailMap.firstKey();
}
return
circle.get(hash);
85. - Consistent Hashing
public
class
ConsistentHashT{
!
private
final
HashFunction
hashFunction
=
Hashing.md5();
private
final
SortedMapLong,
T
circle
=
new
TreeMapLong,
T();
private
final
int
numberOfReplicas
=
100;
public
void
add(String
name,
T
node)
{
for
(int
i
=
0;
i
numberOfReplicas;
i++)
{
circle.put(hashFunction.hashString(name
+
i).asLong(),node);
}
}
public
void
remove(String
name)
{
for
(int
i
=
0;
i
numberOfReplicas;
i++)
{
circle.remove(hashFunction.hashString(name
+
i).asLong());
}
}
public
T
get(String
value)
{
long
hash
=
hashFunction.hashString(value).asLong();
if
(!circle.containsKey(hash))
{
SortedMapLong,
T
tailMap
=
circle.tailMap(hash);
}
}
!
hash
=
tailMap.isEmpty()?circle.firstKey():tailMap.firstKey();
}
return
circle.get(hash);
113. - Caching
Front-End Caching
Static Contents 만 Cache 하고 Dynamic Contents 는 Cache 하지 않는다.
varnish
varnish
HAProxy
Application
Server
HAProxy
HAProxy
HAProxy
HAProxy
117. - epilogue
Object Oriented
에서
Programming
Functional
Programming 로 바뀌고 있는가 ?
XML 말고, JSON 사용해야 하는가 ?
Java 를 배우는가, Spring Framework 를 배우는가 ?
VI 와 TMUX 를 사용하는가 ?
118. - Speaker
김요한!
• LG CNS SI 프로젝트 분석/ 설계/개발/아키텍트 등 다양한 경험!
• 최근 오픈소스를 활용한 분산 아키텍처 설계/ 개발 진행중!
• 오픈소스포럼, S/W아키텍처대회, DEVIEW, JCO 등 발표!
• NIPA 오픈프론티어 1기!
• xpush 프로젝트 - 2014 06 release !!
yohany@gmail.com!
https://www.facebook.com/JohnKim0331!