響應式微服務框架Flower——快速上手

快速上手

Flower框架的主要元素包括:Flower Service(服務)、Flower 流程和Flow容器。Service實現一個細粒度的服務功能,Service之間經過Message關聯,前一個Service的返回值(Message),必須是後一個Service的輸入參數(Message),Service按照業務邏輯編輯成一個Flow(流程),Flower容器負責將前一個Service的返回消息,傳遞給後一個Service。java

系統要求

Flower要求Java 8做爲基礎。若是使用servlet開發,最低要求是servlet 3.1+,才能支持異步請求。在開始前,最好確認當前安裝的JDK版本號是否符合要求。web

$ java -version

安裝

Flower當前最新發布版本是1.0.3。shell

Maven

<dependency>
  <groupId>com.ly.train</groupId>
  <artifactId>flower.core</artifactId>
  <version>A.B.C</version>
</dependency>

Gradle

compile group: 'com.ly.train', name: 'flower.core', version: 'A.B.C'

SBT

libraryDependencies += "com.ly.train" % "flower.core" % "A.B.C"

Ivy

<dependency org="com.ly.train" name="flower.core" rev="A.B.C"/>

Flower初始化

Flower使用前須要進行初始化,這裏演示最簡單的方式。編程

Flower初始化api

FlowerFactory flowerFactory = new SimpleFlowerFactory();

定義Flower服務

開發Service類必須實現Flower框架的Service接口或者繼承AbstractService基類,在process方法內完成服務業務邏輯處理。app

UserServiceA框架

public class UserServiceA implements Service<User, User> {
  static final Logger logger = LoggerFactory.getLogger(UserServiceA.class);
  @Override
  public User process(User message, ServiceContext context) throws Throwable {
    message.setDesc(message.getDesc() + " --> " + getClass().getSimpleName());
    message.setAge(message.getAge() + 1);
    logger.info("結束處理消息, message : {}", message);
    return message;
  }

}

UserServiceB異步

public class UserServiceB implements Service<User, User> {
  static final Logger logger = LoggerFactory.getLogger(UserServiceB.class);
  @Override
  public User process(User message, ServiceContext context) throws Throwable {
    message.setDesc(message.getDesc() + " --> " + getClass().getSimpleName());
    message.setAge(message.getAge() + 1);
    logger.info("結束處理消息, message : {}", message);
    return message;
  }

}

UserServiceC1async

public class UserServiceC1 implements Service<User, User> {
  static final Logger logger = LoggerFactory.getLogger(UserServiceC1.class);
  @Override
  public User process(User message, ServiceContext context) throws Throwable {
    message.setDesc(message.getDesc() + " --> " + getClass().getSimpleName());
    message.setAge(message.getAge() + 1);
    logger.info("結束處理消息, message : {}", message);
    return message;
  }

}

服務註冊

Flower提供兩種服務註冊方式:配置文件方式和編程方式。maven

編程方式

ServiceFactory serviceFactory = flowerFactory.getServiceFactory();
 serviceFactory.registerService(UserServiceA.class.getSimpleName(), UserServiceA.class);
 serviceFactory.registerService(UserServiceB.class.getSimpleName(), UserServiceB.class);
 serviceFactory.registerService(UserServiceC1.class.getSimpleName(), UserServiceC1.class);

配置文件方式

服務定義配置文件擴展名: .services,放在classpath下,Flower框架自動加載註冊。
flower_test.services

UserServiceA = com.ly.train.flower.base.service.user.UserServiceA
UserServiceB = com.ly.train.flower.base.service.user.UserServiceB
UserServiceC1 = com.ly.train.flower.base.service.user.UserServiceC1

服務流程編排

Flower框架提供兩種服務流程編排方式:配置文件方式和編程方式。

兩種編排方式的結果是同樣:

UserServiceA -> UserServiceB -> UserServiceC1

編程方式編排流程

// UserServiceA -> UserServiceB -> UserServiceC1
final String flowName = "flower_test";
ServiceFlow serviceFlow = serviceFactory.getOrCreateServiceFlow(flowName);
serviceFlow.buildFlow(UserServiceA.class, UserServiceB.class);
serviceFlow.buildFlow(UserServiceB.class, UserServiceC1.class);
serviceFlow.build();

配置文件方式編排流程

流程配置文件擴展名: .flow,放在classpath下,Flower框架自動加載編排流程。
flower_test.flow

UserServiceA -> UserServiceB
UserServiceB -> UserServiceC1

調用Flower流程

前面定義了3個Flower服務,並編排了名稱爲flower_test的服務流程。那麼怎麼使用它呢?

  1. 同步調用,須要Flower服務流程響應結果。
  2. 異步調用,不須要Flower服務流程響應結果。
  • 同步調用
final FlowRouter flowRouter = flowerFactory.buildFlowRouter(flowName, 16);
Object result = flowRouter.syncCallService(user);
  • 異步調用
final FlowRouter flowRouter = flowerFactory.buildFlowRouter(flowName, 16);
flowRouter.asyncCallService(user);

完整示例

FlowerFactory flowerFactory = new SimpleFlowerFactory();
    ServiceFactory serviceFactory = flowerFactory.getServiceFactory();
    serviceFactory.registerService(UserServiceA.class.getSimpleName(), UserServiceA.class);
    serviceFactory.registerService(UserServiceB.class.getSimpleName(), UserServiceB.class);
    serviceFactory.registerService(UserServiceC1.class.getSimpleName(), UserServiceC1.class);

    final String flowName = "flower_test";
    ServiceFlow serviceFlow = serviceFactory.getOrCreateServiceFlow(flowName);
    serviceFlow.buildFlow(UserServiceA.class, UserServiceB.class);
    serviceFlow.buildFlow(UserServiceB.class, UserServiceC1.class);
    serviceFlow.build();

    final FlowRouter flowRouter = flowerFactory.buildFlowRouter(flowName, 16);

    User user = new User();
    user.setName("響應式編程 ");
    user.setAge(2);

    Object o = flowRouter.syncCallService(user);
    System.out.println("響應結果: " + o);

    flowRouter.asyncCallService(user);

運行結果

2019-07-11 15:13:19.739 [main] INFO  c.ly.train.flower.config.parser.FlowerConfigParser - parse FlowerConfig, configLocation : flower.yml
2019-07-11 15:13:19.839 [main] INFO  c.ly.train.flower.config.parser.FlowerConfigParser - flowerConfig : FlowerConfig [name=LocalFlower, host=127.0.0.1, port=25005, basePackage=com.ly.train.flower, registry=null]
2019-07-11 15:13:19.840 [main] DEBUG com.ly.train.flower.common.lifecyle.AbstractInit - init class : com.ly.train.flower.core.service.container.simple.SimpleFlowerFactory@39aeed2f
2019-07-11 15:13:19.844 [main] DEBUG com.ly.train.flower.common.lifecyle.AbstractInit - init class : com.ly.train.flower.core.service.container.ServiceFactory@724af044
2019-07-11 15:13:19.844 [main] DEBUG com.ly.train.flower.common.lifecyle.AbstractInit - init class : com.ly.train.flower.core.service.container.ServiceLoader@4678c730
2019-07-11 15:13:19.957 [main] INFO  c.l.t.flower.core.service.container.ServiceLoader - find service, path : file:/Volumes/Data/opt/code/yilong/flower/flower.core/target/test-classes/sample.services
2019-07-11 15:13:19.966 [main] DEBUG c.l.t.flower.core.service.container.ServiceLoader - init ServiceMeta. service1 : ServiceMeta [serviceName=service1, paramType=com.ly.train.flower.base.model.User, resultType=com.ly.train.flower.base.model.User, serviceClassName=com.ly.train.flower.base.service.user.UserServiceA, configs=[]]
2019-07-11 15:13:19.966 [main] INFO  c.l.t.flower.core.service.container.ServiceLoader - register service type -> service1 : class com.ly.train.flower.base.service.user.UserServiceA
2019-07-11 15:13:19.967 [main] DEBUG c.l.t.flower.core.service.container.ServiceLoader - init ServiceMeta. service2 : ServiceMeta [serviceName=service2, paramType=com.ly.train.flower.base.model.User, resultType=com.ly.train.flower.base.model.User, serviceClassName=com.ly.train.flower.base.service.user.UserServiceB, configs=[]]
2019-07-11 15:13:19.967 [main] INFO  c.l.t.flower.core.service.container.ServiceLoader - register service type -> service2 : class com.ly.train.flower.base.service.user.UserServiceB
2019-07-11 15:13:19.968 [main] DEBUG c.l.t.flower.core.service.container.ServiceLoader - init ServiceMeta. service3 : ServiceMeta [serviceName=service3, paramType=com.ly.train.flower.base.model.User, resultType=com.ly.train.flower.base.model.User, serviceClassName=com.ly.train.flower.base.service.user.UserServiceC1, configs=[]]
2019-07-11 15:13:19.968 [main] INFO  c.l.t.flower.core.service.container.ServiceLoader - register service type -> service3 : class com.ly.train.flower.base.service.user.UserServiceC1
2019-07-11 15:13:20.017 [main] DEBUG c.l.t.f.common.scanner.filter.AbstractClassFilter - scan url : file:/Volumes/Data/opt/code/yilong/flower/flower.core/target/test-classes/com/ly/train/flower
2019-07-11 15:13:20.059 [main] DEBUG c.l.t.f.common.scanner.filter.AbstractClassFilter - add class:com.ly.train.flower.base.service.OpenTracerService
2019-07-11 15:13:20.061 [main] DEBUG c.l.t.f.common.scanner.filter.AbstractClassFilter - add class:com.ly.train.flower.base.service.user.UserServiceD
2019-07-11 15:13:20.062 [main] DEBUG c.l.t.f.common.scanner.filter.AbstractClassFilter - add class:com.ly.train.flower.base.service.str.StringServiceD
2019-07-11 15:13:20.062 [main] DEBUG c.l.t.f.common.scanner.filter.AbstractClassFilter - scan url : file:/Volumes/Data/opt/code/yilong/flower/flower.core/target/classes/com/ly/train/flower
2019-07-11 15:13:20.123 [main] DEBUG c.l.t.f.common.scanner.filter.AbstractClassFilter - scan url : file:/Volumes/Data/opt/code/yilong/flower/flower.common/target/classes/com/ly/train/flower
2019-07-11 15:13:20.156 [main] DEBUG c.l.t.f.common.scanner.filter.AbstractClassFilter - scan url : file:/Volumes/Data/opt/code/yilong/flower/flower.config/target/classes/com/ly/train/flower
2019-07-11 15:13:20.157 [main] DEBUG c.l.t.f.common.scanner.filter.AbstractClassFilter - scan url : file:/Volumes/Data/opt/code/yilong/flower/flower.filter/flower.filter.api/target/classes/com/ly/train/flower
2019-07-11 15:13:20.160 [main] DEBUG c.l.t.f.common.scanner.filter.AbstractClassFilter - scan url : file:/Volumes/Data/opt/code/yilong/flower/flower.registry/flower.registry.api/target/classes/com/ly/train/flower
2019-07-11 15:13:20.164 [main] DEBUG c.l.t.f.common.scanner.filter.AbstractClassFilter - scan url : file:/Volumes/Data/opt/code/yilong/flower/flower.serializer/flower.serializer.hessian/target/classes/com/ly/train/flower
2019-07-11 15:13:20.166 [main] DEBUG c.l.t.f.common.scanner.filter.AbstractClassFilter - scan url : file:/Volumes/Data/opt/code/yilong/flower/flower.serializer/flower.serializer.api/target/classes/com/ly/train/flower
2019-07-11 15:13:20.167 [main] INFO  c.l.t.flower.core.service.container.ServiceFactory - scan flowerService, basePackage : com.ly.train.flower, find flowerService : 3
2019-07-11 15:13:20.168 [main] DEBUG c.l.t.flower.core.service.container.ServiceLoader - init ServiceMeta. UserServiceD : ServiceMeta [serviceName=UserServiceD, paramType=java.util.List, resultType=java.util.List, serviceClassName=com.ly.train.flower.base.service.user.UserServiceD, configs=[]]
2019-07-11 15:13:20.168 [main] INFO  c.l.t.flower.core.service.container.ServiceLoader - register service type -> UserServiceD : class com.ly.train.flower.base.service.user.UserServiceD
2019-07-11 15:13:20.168 [main] DEBUG c.l.t.flower.core.service.container.ServiceLoader - init ServiceMeta. OpenTracerService : ServiceMeta [serviceName=OpenTracerService, paramType=com.ly.train.flower.base.model.User, resultType=com.ly.train.flower.base.model.User, serviceClassName=com.ly.train.flower.base.service.OpenTracerService, configs=[]]
2019-07-11 15:13:20.168 [main] INFO  c.l.t.flower.core.service.container.ServiceLoader - register service type -> OpenTracerService : class com.ly.train.flower.base.service.OpenTracerService
2019-07-11 15:13:20.168 [main] DEBUG c.l.t.flower.core.service.container.ServiceLoader - init ServiceMeta. StringServiceD : ServiceMeta [serviceName=StringServiceD, paramType=java.util.List, resultType=java.util.List, serviceClassName=com.ly.train.flower.base.service.str.StringServiceD, configs=[]]
2019-07-11 15:13:20.168 [main] INFO  c.l.t.flower.core.service.container.ServiceLoader - register service type -> StringServiceD : class com.ly.train.flower.base.service.str.StringServiceD
2019-07-11 15:13:20.661 [main] INFO  com.ly.train.flower.core.akka.FlowerActorSystem - akka config :akka.actor.provider = "remote"
akka.remote.enabled-transports = ["akka.remote.netty.tcp"]
akka.remote.netty.tcp.hostname = "127.0.0.1"
akka.remote.netty.tcp.port = "25005"
dispatcher.fork-join-executor.parallelism-min = "8"
dispatcher.fork-join-executor.parallelism-max = "256"
dispatcher.fork-join-executor.parallelism-factor = "8"

2019-07-11 15:13:21.378 [flower-dispatcher-4] INFO  akka.event.slf4j.Slf4jLogger - Slf4jLogger started
2019-07-11 15:13:21.411 [flower-dispatcher-4] INFO  akka.remote.Remoting - Starting remoting
2019-07-11 15:13:21.622 [flower-dispatcher-4] INFO  akka.remote.Remoting - Remoting started; listening on addresses :[akka.tcp://flower@127.0.0.1:25005]
2019-07-11 15:13:21.624 [flower-dispatcher-4] INFO  akka.remote.Remoting - Remoting now listens on addresses: [akka.tcp://flower@127.0.0.1:25005]
2019-07-11 15:13:21.677 [main] INFO  com.ly.train.flower.common.util.ExtensionLoader - url : file:/Volumes/Data/opt/code/yilong/flower/flower.serializer/flower.serializer.hessian/target/classes/META-INF/services/flower/com.ly.train.flower.serializer.Serializer
2019-07-11 15:13:21.677 [main] INFO  com.ly.train.flower.common.util.ExtensionLoader - url : file:/Volumes/Data/opt/code/yilong/flower/flower.serializer/flower.serializer.api/target/classes/META-INF/services/flower/com.ly.train.flower.serializer.Serializer
2019-07-11 15:13:21.705 [main] INFO  com.ly.train.flower.common.util.ExtensionLoader - load extend(hessian) : class com.ly.train.flower.serializer.hessian.HessianSerializer
2019-07-11 15:13:21.775 [flower-dispatcher-4] WARN  akka.serialization.Serialization(akka://flower) - Using serializer [com.ly.train.flower.core.akka.serializer.hessian.HessianSerializer] for message [akka.actor.ActorSelectionMessage]. Note that this serializer is not implemented by Akka. It's not recommended to replace serializers for messages provided by Akka.
2019-07-11 15:13:21.787 [main] DEBUG com.ly.train.flower.common.lifecyle.AbstractInit - init class : com.ly.train.flower.core.akka.ServiceActorFactory@7f132176
2019-07-11 15:13:21.788 [main] DEBUG com.ly.train.flower.common.lifecyle.AbstractInit - init class : com.ly.train.flower.core.akka.FlowerActorSystem@68b32e3e
2019-07-11 15:13:21.788 [main] INFO  c.l.t.f.c.s.container.simple.SimpleFlowerFactory - start FlowerFactory
2019-07-11 15:13:21.788 [main] DEBUG c.l.t.flower.core.service.container.ServiceLoader - init ServiceMeta. UserServiceA : ServiceMeta [serviceName=UserServiceA, paramType=com.ly.train.flower.base.model.User, resultType=com.ly.train.flower.base.model.User, serviceClassName=com.ly.train.flower.base.service.user.UserServiceA, configs=[]]
2019-07-11 15:13:21.788 [main] INFO  c.l.t.flower.core.service.container.ServiceLoader - register service type -> UserServiceA : class com.ly.train.flower.base.service.user.UserServiceA
2019-07-11 15:13:21.788 [main] DEBUG c.l.t.flower.core.service.container.ServiceLoader - init ServiceMeta. UserServiceB : ServiceMeta [serviceName=UserServiceB, paramType=com.ly.train.flower.base.model.User, resultType=com.ly.train.flower.base.model.User, serviceClassName=com.ly.train.flower.base.service.user.UserServiceB, configs=[]]
2019-07-11 15:13:21.788 [main] INFO  c.l.t.flower.core.service.container.ServiceLoader - register service type -> UserServiceB : class com.ly.train.flower.base.service.user.UserServiceB
2019-07-11 15:13:21.789 [main] DEBUG c.l.t.flower.core.service.container.ServiceLoader - init ServiceMeta. UserServiceC1 : ServiceMeta [serviceName=UserServiceC1, paramType=com.ly.train.flower.base.model.User, resultType=com.ly.train.flower.base.model.User, serviceClassName=com.ly.train.flower.base.service.user.UserServiceC1, configs=[]]
2019-07-11 15:13:21.789 [main] INFO  c.l.t.flower.core.service.container.ServiceLoader - register service type -> UserServiceC1 : class com.ly.train.flower.base.service.user.UserServiceC1
2019-07-11 15:13:21.790 [main] INFO  c.l.t.flower.core.service.container.ServiceFlow -  buildFlow : flower_test, preService : UserServiceA, nextService : UserServiceB
2019-07-11 15:13:21.790 [main] INFO  c.l.t.flower.core.service.container.ServiceFlow -  buildFlow : flower_test, preService : UserServiceB, nextService : UserServiceC1
2019-07-11 15:13:21.790 [main] INFO  c.l.t.flower.core.service.container.ServiceFlow -  build flower_test success.
 ServiceFlow [ flowName = flower_test
  UserServiceA(1) ---> UserServiceB(1),
  UserServiceB(1) ---> UserServiceC1(0)
]
2019-07-11 15:13:21.790 [main] INFO  c.l.t.flower.core.service.container.ServiceFlow - start register ServiceConfig : ServiceConfig [flowName=flower_test, serviceName=UserServiceA, jointSourceNumber=0]
2019-07-11 15:13:21.790 [main] DEBUG com.ly.train.flower.common.lifecyle.AbstractInit - init class : com.ly.train.flower.core.akka.router.FlowRouter@bcef303
2019-07-11 15:13:21.790 [main] INFO  com.ly.train.flower.common.util.ExtensionLoader - url : file:/Volumes/Data/opt/code/yilong/flower/flower.core/target/classes/META-INF/services/flower/com.ly.train.flower.core.loadbalance.LoadBalance
2019-07-11 15:13:21.791 [main] INFO  com.ly.train.flower.common.util.ExtensionLoader - load extend(round) : class com.ly.train.flower.core.loadbalance.RoundLoadBalance
2019-07-11 15:13:21.791 [main] DEBUG com.ly.train.flower.common.lifecyle.AbstractInit - init class : ServiceRouter [loadBalance=RoundLoadBalance [name=RoundLoadBalance], number=1, serviceConfig=ServiceConfig [flowName=flower_test, serviceName=UserServiceA, jointSourceNumber=0]]
2019-07-11 15:13:21.792 [main] INFO  com.ly.train.flower.core.akka.ServiceActorFactory - build service Router. serviceName : UserServiceA, actorNumber : 1
2019-07-11 15:13:21.793 [main] INFO  com.ly.train.flower.core.akka.ServiceActorFactory - build service Router. flowName : flower_test, serviceName : UserServiceA, flowNumber : 1
2019-07-11 15:13:21.928 [main] DEBUG com.ly.train.flower.common.lifecyle.AbstractInit - init class : com.ly.train.flower.core.akka.router.FlowRouter@5ef6ae06
2019-07-11 15:13:21.928 [main] DEBUG com.ly.train.flower.common.lifecyle.AbstractInit - init class : ServiceRouter [loadBalance=RoundLoadBalance [name=RoundLoadBalance], number=16, serviceConfig=ServiceConfig [flowName=flower_test, serviceName=UserServiceA, jointSourceNumber=0]]
2019-07-11 15:13:21.935 [main] INFO  com.ly.train.flower.core.akka.ServiceActorFactory - build service Router. serviceName : UserServiceA, actorNumber : 16
2019-07-11 15:13:21.936 [main] INFO  com.ly.train.flower.core.akka.ServiceActorFactory - build service Router. flowName : flower_test, serviceName : UserServiceA, flowNumber : 16
2019-07-11 15:13:21.953 [flower-dispatcher-20] INFO  c.l.t.flower.core.service.container.ServiceLoader - load flower service --> UserServiceA : com.ly.train.flower.base.service.user.UserServiceA@55967dc0
2019-07-11 15:13:21.958 [flower-dispatcher-20] INFO  com.ly.train.flower.base.service.user.UserServiceA - 結束處理消息, message : User [name=響應式編程 , desc= --> UserServiceA, age=3]
2019-07-11 15:13:21.961 [flower-dispatcher-20] DEBUG c.l.t.f.core.akka.actor.wrapper.ActorRefWrapper - Local message. serviceName : UserServiceB, actor : Actor[akka://flower/user/flower/UserServiceB_1#-39642247], message : ServiceContext [id=b66cc2e27fea491593b9e862e1b311a6, flowName=flower_test, currentServiceName=UserServiceB, sync=true, attachments=null, flowMessage=FlowMessage [transactionId=6e440adf3f8c41f793d7c700a4a36deb, message=[B@611ed8fb], web=null], sender : Actor[akka://flower/user/flower/UserServiceA_1#518152440]
2019-07-11 15:13:21.963 [flower-dispatcher-19] INFO  c.l.t.flower.core.service.container.ServiceLoader - load flower service --> UserServiceB : com.ly.train.flower.base.service.user.UserServiceB@ffcaad2
2019-07-11 15:13:21.963 [flower-dispatcher-19] INFO  com.ly.train.flower.base.service.user.UserServiceB - 結束處理消息, message : User [name=響應式編程 , desc= --> UserServiceA --> UserServiceB, age=4]
2019-07-11 15:13:21.964 [flower-dispatcher-19] DEBUG c.l.t.f.core.akka.actor.wrapper.ActorRefWrapper - Local message. serviceName : UserServiceC1, actor : Actor[akka://flower/user/flower/UserServiceC1_1#-1935204307], message : ServiceContext [id=b66cc2e27fea491593b9e862e1b311a6, flowName=flower_test, currentServiceName=UserServiceC1, sync=true, attachments=null, flowMessage=FlowMessage [transactionId=6e440adf3f8c41f793d7c700a4a36deb, message=[B@40065f66], web=null], sender : Actor[akka://flower/user/flower/UserServiceB_1#-39642247]
2019-07-11 15:13:21.964 [flower-dispatcher-19] INFO  c.l.t.flower.core.service.container.ServiceLoader - load flower service --> UserServiceC1 : com.ly.train.flower.base.service.user.UserServiceC1@2a46d78e
2019-07-11 15:13:21.964 [flower-dispatcher-19] INFO  c.ly.train.flower.base.service.user.UserServiceC1 - 結束處理消息, message : User [name=響應式編程 , desc= --> UserServiceA --> UserServiceB --> UserServiceC1, age=5]
響應結果: User [name=響應式編程 , desc= --> UserServiceA --> UserServiceB --> UserServiceC1, age=5]
2019-07-11 15:13:21.965 [main] DEBUG c.l.t.f.core.akka.actor.wrapper.ActorRefWrapper - Local message. serviceName : UserServiceA, actor : Actor[akka://flower/user/flower/UserServiceA_2#1690671066], message : ServiceContext [id=2e6fcef3852a48eeb7cb182d2bd62ef4, flowName=flower_test, currentServiceName=UserServiceA, sync=false, attachments=null, flowMessage=FlowMessage [transactionId=52565043086d49abaa2ca88c3527883e, message=[B@54dcfa5a], web=null], sender : null
2019-07-11 15:13:21.966 [flower-dispatcher-19] INFO  com.ly.train.flower.base.service.user.UserServiceA - 結束處理消息, message : User [name=響應式編程 , desc= --> UserServiceA, age=3]
2019-07-11 15:13:21.967 [flower-dispatcher-19] DEBUG c.l.t.f.core.akka.actor.wrapper.ActorRefWrapper - Local message. serviceName : UserServiceB, actor : Actor[akka://flower/user/flower/UserServiceB_2#1505663876], message : ServiceContext [id=2e6fcef3852a48eeb7cb182d2bd62ef4, flowName=flower_test, currentServiceName=UserServiceB, sync=false, attachments=null, flowMessage=FlowMessage [transactionId=52565043086d49abaa2ca88c3527883e, message=[B@3ccff905], web=null], sender : Actor[akka://flower/user/flower/UserServiceA_2#1690671066]
2019-07-11 15:13:21.967 [flower-dispatcher-20] INFO  com.ly.train.flower.base.service.user.UserServiceB - 結束處理消息, message : User [name=響應式編程 , desc= --> UserServiceA --> UserServiceB, age=4]
2019-07-11 15:13:21.968 [flower-dispatcher-20] DEBUG c.l.t.f.core.akka.actor.wrapper.ActorRefWrapper - Local message. serviceName : UserServiceC1, actor : Actor[akka://flower/user/flower/UserServiceC1_2#-770155619], message : ServiceContext [id=2e6fcef3852a48eeb7cb182d2bd62ef4, flowName=flower_test, currentServiceName=UserServiceC1, sync=false, attachments=null, flowMessage=FlowMessage [transactionId=52565043086d49abaa2ca88c3527883e, message=[B@76ecc10a], web=null], sender : Actor[akka://flower/user/flower/UserServiceB_2#1505663876]
2019-07-11 15:13:21.969 [flower-dispatcher-19] INFO  c.ly.train.flower.base.service.user.UserServiceC1 - 結束處理消息, message : User [name=響應式編程 , desc= --> UserServiceA --> UserServiceB --> UserServiceC1, age=5]
相關文章
相關標籤/搜索