G*ワークショップZ
Vert.xハンズオン w/ CRaSH
2013.10.18 (10.20 updated)
須江信洋(@nobusue)
http://d.hatena.ne.jp/nobusue
https://www.facebook.com/nobuhiro.sue
自己紹介
須江 信洋(すえ のぶひろ)






Twitter: @nobusue
https://www.facebook.com/nobuhiro.sue



約10年ほどJavaEE関連の仕事をしてます
2013年10月よりフリーランス(個人事業主)



G*(Groovy関連技術)との関わり








2

JGGUGサポートスタッフ
「プログラミングGROOVY」執筆チーム
「Groovy イン・アクション」翻訳チーム
Today’s Agenda
Vert.x インストール
 Vert.x 概要 / ユースケース
 Vert.x ハンズオン










3

echo
HTTP / WebSockets
Event Bus
Vert.x module / echo with CRaSH

参考情報
Vert.xインストール
前提





JDK1.7以上 (“java –version”で確認)



curl -s get.gvmtool.net | bash
gvm install vertx
詳細は http://gvmtool.net/ 参照
Windowsの場合はcygwinが必要

GVM利用








ZIPを展開







4

http://vertx.io/downloads.html
2.0.2.finalが最新(2013/10/17現在)
適当なディレクトリに展開 ($VERTX_HOME)
$VERTX_HOME/bin にパスを通しておく
動作確認
$ vertx version
2.0.1-final (built 2013-08-13 14:29:09)

GVMでインストールした場合は
~/.gvm/vertx/<version> 以下に導入され、
~/.gvm/vertx/current にシンボリックリンクが
作成されます。
5
Vert.x 概要





http://vertx.io/

「Vert.xはJVM向けの軽量でハイパフォーマンスなアプリケー
ションプラットフォームで、モダンなモバイル/Web/エンタープラ
イズアプリケーションのために設計されています」
Founder: Tim Fox (from 2011)
2013/8 core Vert.x projectがEclipse Foundationに移管

6
Vert.x の特徴
 Polyglot
 多数のJVM言語をサポート(混在可)

 Simplicity

 スレッドセーフ、抽象化、モジュール化

 Scalability

 イベントバス、クラスター

 Concurrency

 非同期(non-blocking)、イベントループ
7
非同期(non-blocking)
Traditional
AP Server

Vert.x

thread

socket

socket

thread

socket

socket

thread

socket

socket

thread

socket

JavaVM
socket:thread = 1:1
8

thread
Event Dispatcher

socket

JavaVM
socket:thread = N:1
高効率(Efficiency)
Event
Loop
(thread)

Verticle
Instances
Verticle

socket
socket

socket

Event Dispatcher

socket

Verticle

Verticle

Verticle

CPU
Core

Verticle

Verticle

CPU
Core

Verticle

Verticle

Verticle

CPU
Core

Verticle

Verticle

Verticle

CPU
Core

Vert.x Runtime(JVM)
9
スケーラブル
Node#2

Node#1
Verticle

Verticle

socket
socket
Verticle

Verticle

Verticle

socket

Verticle

Verticle

Verticle

Vert.x Runtime(JVM)

Verticle

socket
socket

socket

Event Dispatcher

socket

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Event Dispatcher

Verticle

Verticle

socket

Verticle

Event Bus
(Based on Hazelcast)

socket

Event Dispatcher

socket

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

socket

Verticle

Verticle

Vert.x Runtime(JVM)

Verticle

socket
socket
socket

Verticle

Event Dispatcher

Verticle

socket

socket

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Verticle

Vert.x Runtime(JVM)

Node#3
10

(*)デフォルトではイベントはnon-persistent

Vert.x Runtime(JVM)
Polyglot


Verticleは以下の言語で実装可能











JavaScript / CoffeeScript (V2.0~)
Ruby (JRuby)
Java (.java/.class)
Groovy
Python (Jython)
Scala (V2.0~)
Clojure (V2.0~)

同一Vert.xランタイム上で混在可能
11
ユースケース(例)


WebSocket / SockJS Server





イベント処理ゲートウェイ






スマホアプリへのリアルタイムデータ配信(為替とか)
大量の双方向メッセージ(チャットとか)
Internet of Things
サーバーファームからのログ収集(fluentdとか)
Complex Event Processing

高性能ネットワーククライアント



負荷テストクライアント(beyond JMeter)
Web Scraping / Test Automation

12
Hello Vert.x
適当な作業ディレクトリを作成し、カレントディ
レクトリを移動します
 以下の内容で”Server.groovy”を作成します


vertx.createHttpServer().requestHandler { req ->
req.response.end("Hello World!")
}.listen(8080, 'localhost')



“vertx run Server.groovy” を実行し、
ブラウザで http://localhost:8080/
を開きます

13
Vert.x examples (本日のお題)


GitHubから入手してください





https://github.com/vert-x/vertx-examples
src /raw/groovy 以下にあるサンプルを利用します

基本的な実行方法





14

カレントディレクトリをsrc/raw/groovyに
vertx run <sample_dir>/xxx.groovy
例) vertx run echo/EchoServer.groovy
echo
vertx run echo/EchoServer.groovy
 telnet localhost 1234







何か入力してみてください
抜けるときは Ctrl + ] -> quit

vertx run echo/EchoClient.groovy




EchoServer.groovyを実行したままで
“hello”を10回送信
非同期で送信されていることに注目

15
echo/EchoServer.groovy
import static
org.vertx.groovy.core.streams.Pump.createPump
vertx.createNetServer().connectHandler { socket ->
createPump(socket, socket).start()
}.listen(1234)

Pump = Flow Controller
溢れたら、余裕ができるまで流入を止める
(余裕ができるとイベントで通知)
socket

16

Pump

socket
HTTPServer
vertx run http/Server.groovy
 http://localhost:8080/






ブラウザに ”Hello from vert.x!”

vertx run http/Client.groovy



Server.groovyを起動したままで
HTTPクライアントの実装例

17
http/Server.groovy
package http
vertx.createHttpServer().requestHandler { req ->

req.response.end "<html><body><h1>Hello from
vert.x!</h1></body></html>"
}.listen(8080, "localhost")

18
WebSockets
vertx run
websockets/WebSocketsServer.groovy
 http://localhost:8080/








WebSocket対応ブラウザで
ブラウザを開いたまま、WebSocketsServerを終了

vertx run
websockets/WebSocketsClient.groovy




WebSocketsServerを起動した状態で実行
WebSocketクライアントの実装例

19
WebSocketsServer.groovy
package websockets
vertx.createHttpServer().websocketHandler { ws ->
ws.dataHandler { data ->

ws.writeTextFrame(data.toString()) }
}.requestHandler { req ->
if (req.uri == "/") req.response.sendFile
"websockets/ws.html"

}.listen(8080)
20
SockJS
vertx run sockjs/SockJSExample.groovy
 http://localhost:8080/




WebSocket対応ブラウザでなくとも可
(SockJSがフォールバックしてくれる)

21
SockJSExample.groovy
def server = vertx.createHttpServer()
server.requestHandler { req ->
if (req.uri == "/") req.response.sendFile
'sockjs/index.html'
}
vertx.createSockJSServer(server).installApp(prefix:
'/testapp') { sock ->
sock.dataHandler { buff ->
sock << buff
}
}
server.listen(8080)
22
Event Bus(pub/sub)
vertx run
eventbus_pubsub/Receiver.groovy
-cluster
 vertx run
eventbus_pubsub/Receiver.groovy
-cluster
 vertx run
eventbus_pubsub/Sender.groovy –cluster




すべてのReceiverにメッセージが届く

23
Receiver.groovy / Sender.groovy
def eb = vertx.eventBus
eb.registerHandler("news-feed", { message ->
println "Received news: ${message.body()}"
})
def eb = vertx.eventBus
// Send a message every second
vertx.setPeriodic(1000) {
eb.publish("news-feed", "Some news!")
}
24
Cluster構成Tips


デフォルトではマルチキャストを利用





ユニキャストへの変更




Hazelcastのクラスターを構成するため、マルチ
キャストでメンバーを探す
ネットワーク環境によっては不安定になりがち
$VERTX_HOME/conf/cluster.xml の
<network>を修正

動作確認


25

$VERTX_HOME/conf/logging.properties
 com.hazelcast.level=INFOに変更
conf/cluster.xml
<network>
<port auto-increment="true">5701</port>
<join>
<multicast enabled="false">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
<tcp-ip enabled="true">
<interface>127.0.0.1</interface>
</tcp-ip>
・・・

26
conf/logging.properties
#Macではシステムのtemp領域にアクセスできない場合が
#あるので、以下のように変更することをおすすめ
#java.util.logging.FileHandler.pattern=%t/vertx.log
java.util.logging.FileHandler.pattern=/Users/<user>/.
gvm/vertx/current/vertx.log
.level=INFO
org.vertx.level=INFO
#com.hazelcast.level=SEVERE
com.hazelcast.level=INFO

27
Cluster構成時のログ
[127.0.0.1]:5701 [dev] 5701 is accepting socket
connection from /127.0.0.1:51668
[127.0.0.1]:5701 [dev] 5701 accepted socket
connection from /127.0.0.1:51668
Received news: Some news!
[127.0.0.1]:5701 [dev]
Members [3] {
Member [127.0.0.1]:5701 this
Member [127.0.0.1]:5702
Member [127.0.0.1]:5703
}
28
Event Bus(point to point)
vertx run
eventbus_pointtopoint/Receiver.groovy
-cluster
 vertx run
eventbus_pointtopoint/Receiver.groovy
-cluster
 vertx run
eventbus_pointtopoint/Sender.groovy
-cluster




メッセージはラウンドロビンで届く

29
Receiver.groovy / Sender.groovy
def eb = vertx.eventBus
eb.registerHandler("ping-address", { message ->
println "Received message: ${message.body()}"
message.reply("pong!")
})
def eb = vertx.eventBus
vertx.setPeriodic(1000) {
eb.send("ping-address", "ping!", { reply ->
println "Received reply ${reply.body()}"
})
}
30
fanout (Shared memory)
vertx run fanout/FanoutServer.groovy
 telnet localhost 1234







terminalを複数開いて試してみてください
抜けるときは Ctrl + ] -> quit

Shared Set/Map




同一Vert.xインスタンス上のvertileからのみ参照可能
な共有メモリ
同一JVM上でのみ有効(クラスター対応の計画あり)

31
FanoutServer.groovy
def conns = vertx.sharedData.getSet('conns')
def eb = vertx.eventBus
server = vertx.createNetServer().connectHandler
{ socket ->
conns << socket.writeHandlerID
socket.dataHandler { data ->
for (id in conns) { eb.send(id, data) }
}
socket.closeHandler
{ conns.remove(socket.writeHandlerID) }
}.listen(1234)
32
Vert.x Module


アプリケーションをモジュール化





Vert.x module registry





複数のVerticleを内包可能
異なる言語で記述されていてもよい

http://modulereg.vertx.io
MavenリポジトリやBintrayに配置して公開

詳細はModule Manualを参照のこと


http://vertx.io/mods_manual.html

33
Moduleの実行方法


コマンドライン


vertx runmod org.myorg~mymod~3.2






モジュールが自動的にインストールされる

vertx runzip my-mod-3.2.zip

アプリケーション内


container.deployModule(
‘org.myorg~mymod~3.2)

34
echo with CRaSH module
適当なディレクトリにEchoWithCrash.groovyを
作成
 vertx run EchoWithCrash.groovy







CRaSH moduleがインストールされる
CRaSHのSSHサーバーが実行される

ssh –p 2000 admin@localhost


password: admin

35
EchoWithCrash.groovy
import static org.vertx.groovy.core.streams.Pump.createPump
def conf = [
"crash.auth": "simple",
"crash.auth.simple.username": "admin",
"crash.auth.simple.password": "admin",
"crash.ssh.port": "2000"
]
container.deployModule("org.crashub~vertx.shell~2.0.2", conf)
vertx.createNetServer().connectHandler { socket ->
createPump(socket, socket).start()
}.listen(1234)

36
CRaSH

37

http://www.crashub.org/
CRaSH: Vert.x shell

38
CRaSH: vertx commands

39
CRaSH: threads TOP

40
Moduleの作り方


Gradle template project




http://vertx.io/gradle_dev.html

Maven archetype


http://vertx.io/maven_dev.html

41
Vert.xの情報源


Vert.x home




Vert.x資料(杉浦さん)




http://uehaj.hatenablog.com/entry/2013/06/03/225117

Vert.x がいいね!




http://www.slideshare.net/touchezdubois/vertxtaritari

内部から見たVert.xとNode.jsとの比較(上原さん)




http://vertx.io

http://acro-engineer.hatenablog.com/entry/2013/08/10/131203

G::blog 主にVert.xやYokeについての覚書


http://ofg.hatenablog.com/archive/category/Vert.x

42
Advanced Topics
File API
 Streams
 Timer
 Worker Verticle
 Reactive (RxJava)
 ・・・・


43
ありがとうございました

https://www.facebook.com/orehiji
44

Gws 20131018 vertx_handson(updated)