LINE LIVE 

30,000+/min
Go Hagiwara (Oklahomer) , Dev3 Center
● Oklahomer

or
● @ LINE
● LINE LIVE API
●
●
● Bot Framework
ChatOps bot
● Java/Golang/Python/Perl
● LINE
●
●
●
●
LINE LIVE
● MC
●
●
LIVE
●
●
●
●
WebSocket - Server-Client
akka actor model - Server
Redis Cluster - Pub/Sub Server 

KVS
subtitle
TITLE
WebSocket
akka Actor Model
Pub/sub Server
Lua scripting atomic
Redis Cluster
WebSocket - Server-Client
akka actor model - Server
Redis Cluster - Server
akka Actor Model
● Perl
● Java
● Effective Java
● Java
● Java
●
● Parallel::Prefork
● Parallel::ForkManager
● java.util.concurrent package
● ParallelStream
Perl v.s. Java
akka Actor Model
● actor
● actor
●
● Actor
●
●
● actor
●
Actor
Actor
● Actor mailbox
● mailbox
● mailbox
●
● Actor
● actor mailbox
●
●
● Actor
●
●
Supervisor
Supervisor
● actor actor
●
● actor actor
● let-it-crash
actor “crash”
●
Supervisor Strategy
● actor
●
● crash actor
●
Supervisor Strategy -
● One-for-One strategy
● crash actor
● All-for-One strategy
● actor
● actor actor
actor
Supervisor Strategy - Directives
● Restart - actor
mailbox
● Crash actor actor restart
●
● preRestart hook
→
● Resume - mailbox 

●
Supervisor Strategy - Directives
● Stop - actor
●
● actor
● Escalate - Supervisor Actor
● Supervisor Strategy 

Child Actor → Parent Actor → Grandparent Actor
Supervisor Strategy - Directives
Supervisor Strategy -
1 public class MyActor extends UntypedActor {
2 private static SupervisorStrategy strategy =
3 new OneForOneStrategy(10, Duration.create("1 minute"), t -> {
4 if (t instanceof ActorInitializationException) {
5 return stop();
6 } else if (t instanceof ActorKilledException) {
7 return stop();
8 } else if (t instanceof Exception) {
9 return restart();
10 }
11
12 return escalate();
13 });
14
15 @Override
16 public SupervisorStrategy supervisorStrategy() {
17 return strategy;
18 }
19
20 @Override
21 public void onReceive(Object o) throws Exception {
22 }
23 }
Actor
Actor
● Actor ActorRef
●
●
●
● etc…
● actor dead
letter
●
Actor
●
● watch actor
● Terminated
● unwatch
●
● Actor crash actor
Chat Server Actor
ChatSupervisor
● 1 JVM 1
● actor
● ” ”
actor
●
ChatRoomActor
●
●
● Redis pub/sub
● UserActor
●
●
● UserActor
●
●
UserActor
●
● WebSocket
● ChatRoomActor
●
● ChatRoomActor UserActor ChatSupervisor
● ” ” UserActor
ChatRoomActor
● WebSocket UserActor
● ChatRoomActor crash → restart UserActor restart
● ChatRoomActor UserActor
● ChatRoomActor UserActor
● ChatRoomActor UserActor watch
● UserActor WebSocket UserActor stop
● ChatRoomActor Terminated
● ChatRoomMembers
●
● Watch Terminated
● ChatRoomActor restart
● ChatRoomActor crash UserActor
●
● Restart
1 public static Props props(final AggregatedChannel channel,
2 final ChatRoom chatRoom,
3 final ChatRoomMembers chatRoomMembers) {
4 // Returns a property to construct ChatRoomActor
5 // NOTE: Those objects passed to actor's constructor are inherited on restart
6 // such as ChatRoomMembers that caches belonging UserActors
7 return Props.create(ChatRoomActor.class,
8 () -> new ChatRoomActor(channel,
9 chatRoom,
10 chatRoomMembers));
11 }
● actor
● actor
● actor Actor System
●
● Actor model
● Controller
● validate
● ChatSupervisor ChatRoomActor
● WebSocket
● WebSocket UserActor
● ChatRoomActor
WebSocket
● Controller / UserActor WebSocket
●
● UserActor crash
● Supervisor Strategy restart 

resume
● Validation
●
● UserActor
●
● Redis
● WebSocket
●
● actor
●
- Blocking API
● WebSocket Jetty issue
● https://github.com/eclipse/jetty.project/issues/272
● UserActor
●
●
● JVM
● Spring API
● Jetty issue
- Blocking API
● ThreadPool
● Jetty issue
● Watchdog
●
●
● UserActor
● ChatRoomActor Terminated 

Actor
●
●
●
●
●
●
●
●
●
● Redis Cluster pub/sub
● key ChatRoomActor pub/sub
● ChatRoomActor UserActor
● Remote Actor
● WebSocket UserActor
● ChatRoomActor
ChatSupervisor, UserActor
● Deploy Redis pub/sub
Redis
● Actor Redis Pub/
Sub
● Pub/Sub
● Subscribe
●
● Actor
Lettuce
● Redis Cluster
● Master/slave failover MOVED/ASK node
● API
● Pub/sub subscribe failover
● Lua scripting
Lettuce
●
● Redis Cluster reshard 

validation
● Redis Cluster → application
● Failover reshard
● Periodic refresh
● Adaptive refresh
Lettuce
1 /*
2 To get rid of stale connection and establish new connection when crush/failover occurs,
3 refresh its topologyView periodically.
4 */
5 ClusterTopologyRefreshOptions topologyRefreshOptions =
6 ClusterTopologyRefreshOptions.builder()
7 .enablePeriodicRefresh(30, TimeUnit.SECONDS)
8 .enableAllAdaptiveRefreshTriggers()
9 .build();
10 /*
11 Basically we use the default settings, but to avoid connection error caused by newly added
server,
12 override the validateClusterNodeMembership and skip validation for new server.
13 */
14 ClusterClientOptions clusterClientOptions =
15 ClusterClientOptions.builder()
16 .validateClusterNodeMembership(false)
17 .topologyRefreshOptions(topologyRefreshOptions)
18 .build();
● WebSocket
● Server - Client
● akka Actor Model
●
● Actor Actor
● Blocking API
● Redis Cluster
●
●
● LINE LIVE
●
● https://engineering.linecorp.com/ja/blog/detail/85
● Yet another Akka introduction for dummies
●
● http://blog.oklahome.net/2016/01/akka-introduction-for-dummies.html
● How to cook lettuce @Java casual
● Lettuce
● https://www.slideshare.net/Oklahomer/how-to-cook-lettuce-java-
casual
THANK YOU

LINE LIVE のチャットが
30,000+/min のコメント投稿を捌くようになるまで