Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的消息调度系统设计_Java_Multithreading_Performance_Akka - Fatal编程技术网

Java中的消息调度系统设计

Java中的消息调度系统设计,java,multithreading,performance,akka,Java,Multithreading,Performance,Akka,我正在为以下用例寻找一个轻量级和高效的解决方案: 网关模块接收要为不同的接受者交付的资源 为每个接受者排队的资源(按到达顺序) 清除过程会扫描这些队列,如果资源可供某个接受者使用,那么他会将这些资源捆绑在某个标记(唯一id)下,并发送一个通知,告知有新的捆绑可用 系统特征: 受体的数量是动态的 对一个捆绑包中的资源数量没有限制 该模块将在Java7(非集群)下的Tomcat7中使用 我考虑了以下解决办法: JMS-动态队列配置对于每个接受者,是否可以使用队列中的所有可用消息?每个队列的

我正在为以下用例寻找一个轻量级和高效的解决方案:

  • 网关模块接收要为不同的接受者交付的资源
  • 为每个接受者排队的资源(按到达顺序)
  • 清除过程会扫描这些队列,如果资源可供某个接受者使用,那么他会将这些资源捆绑在某个标记(唯一id)下,并发送一个通知,告知有新的捆绑可用
系统特征:

  • 受体的数量是动态的
  • 对一个捆绑包中的资源数量没有限制

该模块将在Java7(非集群)下的Tomcat7中使用

我考虑了以下解决办法:

  • JMS-动态队列配置对于每个接受者,是否可以使用队列中的所有可用消息?每个队列的线程配置(不可扩展)
  • 阿克卡演员。没有找到合适的使用模式
  • 朴素的纯Java实现,队列将由一个线程扫描(循环)
  • 我认为这是讨论这个问题可用解决方案的正确地点。 在考虑以下几点时,请分享您的想法:

    • 适当的第三方框架
    • 资源队列可扩展扫描

    提前谢谢。

    我认为JMS将为您的问题提供适当的解决方案。您可以使用RabbitMQ,它具有路由器,可根据密钥将消息路由到不同的队列,并为消息流和消息确认机制提供内置解决方案。

    您可以使用各种技术,例如:

    • JMS动态队列

    • 扩展LMAX干扰器(例如)

    但是从高可用性和可扩展性来看,您应该使用Akka

    Akka

    实现的起点是Akka中内置的一致散列路由算法——简单地说,这种类型的路由逻辑根据提供的密钥选择一致的路由路线与您的问题描述相比是接受者

    Router actor有两种不同的风格,它为您提供了在基础设施中部署新接受器的灵活机制

    • 池-路由器将路由对象创建为子参与者,并在终止时将其从路由器中删除

    • 组-路由器参与者在路由器外部创建,路由器使用参与者选择将消息发送到指定路径,而不监视终止

    首先,请阅读Akka路由文档,以更好地了解Akka框架中的路由实现:

    您还可以查看这篇关于可扩展和高可用性系统设计的文章:

    Q1参与者是否可能知道他的路线(他的散列密钥)?

    参与者可能知道当前处理的密钥是什么,因为它可能只是消息的一部分,但您不应该基于此密钥构建跨消息逻辑/状态

    信息:

    import akka.routing.ConsistentHashingRouter.ConsistentHashable
      class Message(key : String) extends ConsistentHashable with Serializable {
          override def consistentHashKey(): AnyRef = key
      }
    
    演员:

      import akka.actor.{Actor, ActorLogging}
    
      class EchoActor extends Actor with ActorLogging {
    
        log.info("Actor created {}", self.path.name)
    
        def receive = {
          case message: Message =>
            log.info("Received message {} in actor {}", message.consistentHashKey(),             self.path.name)
          case _ => log.error("Received unsupported message");
        }
      }
    
    Q2参与者能否管理邮箱以外的状态?

    只有通过行动者之间发送的信息,才能改变行动者的状态

    如果要初始化包含对经典java/spring/的引用的actor。。bean,它将能够与非参与者的世界/状态交互,例如dao层,但是这种类型的集成应该尽可能地受到限制,并被视为反模式

    Q3是否有办法使用防碰撞的配置?

    作为API消费者,您需要自己定义抗冲突的模型,但Akka再次提供了实现这一点所需的基础设施

  • 在大多数情况下,密钥将是域的一部分,例如拍卖id、客户id

  • 如果需要按需生成密钥,您可以使用 延长期限

  • 生成器
    可以是负责生成唯一ID的
    参与者
    ,其他参与者可以使用
    ask
    模式获得新ID

    ClusterSingleton
    使用
    ClusterSingletonManager
    初始化,并使用
    ClusterSingletonProxy

    system.actorOf(ClusterSingletonManager.props(
    singletonProps = Props(classOf[Generator]),
    singletonName = "gnerator",
    terminationMessage = End,
    role = Some("generator")),
    name = "singleton")
    
    
    system.actorOf(ClusterSingletonProxy.props(
    singletonPath = "/user/singleton/generator",
    role = Some("generator")),
    name = "generatorProxy")
    

    您可以使用ApacheCamel来实现这一点。它的重量轻,并支持很多。这是一个可能的解决方案。

    谢谢您的详细回答!我阅读了Akka路由文档,仍然缺少一些要点:参与者是否可能知道他的路由(他的散列键)?除了邮箱之外,Actor还能管理其他状态吗?@MaximKirilov在上面回答,看看typesafe activator及其示例嗨,另一个问题:我发现使用一致性哈希时会发生冲突。有一种方法可以使用抗碰撞的配置。例如,我知道最多会生成100个不同的散列键。“抗冲突”是一个大主题,但对于唯一键,您可以使用单例模式