非终止ZeroMQ负载均衡器

时间:2016-07-24 02:25:44

标签: scala zeromq

给出以下略微修改的Load Balancer ZeroMQ代码:

package net.broker

import org.zeromq.ZMQ

object LruQueue2 {

  class ClientTask(name: String) extends Runnable {
    override def run(): Unit = {
      val context = ZMQ.context(1)
      val client = context.socket(ZMQ.REQ)
      client.setIdentity(name.getBytes)
      client.connect("tcp://localhost:5555")

      // send request, get reply
      client.send("HELLO".getBytes, 0)
      val reply = client.recv(0)
      println(s"${new String(client.getIdentity)} received: ${new String(reply)}")
    }
  }

  class WorkerTask(name: String) extends Runnable {
    override def run(): Unit = {
      val context = ZMQ.context(1)
      val worker  = context.socket(ZMQ.REQ)
      worker.connect("tcp://localhost:5556")
      worker.setIdentity(name.getBytes)
      worker.send("READY".getBytes, 0)
      while(true) {
        val clientAddr = worker.recv(0)
        val empty      = worker.recv(0)
        val clientMsg  = worker.recv(0)

        worker.send(clientAddr, ZMQ.SNDMORE)
        worker.send("".getBytes, ZMQ.SNDMORE)
        worker.send("WORLD".getBytes, 0)

        println(s"${new String(worker.getIdentity)}: 3-frames to client: ${new String(clientAddr)}")
      }
    }
  }

  def main(args: Array[String]): Unit = {
    val NOFLAGS = 0

    // worker using REQ socket to do LRU routing
    val NBR_CLIENTS = 1
    val NBR_WORKERS = 1

    val context  = ZMQ.context(1)
    val frontend = context.socket(ZMQ.ROUTER)
    val backend  = context.socket(ZMQ.ROUTER)

    frontend.bind("tcp://*:5555")
    backend.bind("tcp://*:5556")

    val clients = (1 to NBR_CLIENTS).toList.map{ i => new Thread(new ClientTask(s"CLIENT$i"))}
    val workers = (1 to NBR_CLIENTS).toList.map{ i => new Thread(new WorkerTask(s"WORKER$i"))}

    clients.foreach(_.start)
    workers.foreach(_.start)

    val workerQueue = scala.collection.mutable.Queue[Array[Byte]]()

    val poller = context.poller(2)

    poller.register(backend,  ZMQ.Poller.POLLIN)
    poller.register(frontend, ZMQ.Poller.POLLIN)

    var clientNbr = NBR_CLIENTS

    while(true) {
      println("begin to poll")
      poller.poll()
      println("done polling")

      println("clientNbr:" + clientNbr)
      println("workerQueue.length: " + workerQueue.length)

      if(clientNbr == 0) {
        sys.exit(0)
      }
      else if(poller.pollin(0) && clientNbr > 0) {
        val workerAddr = backend.recv(NOFLAGS)

        val empty                = backend.recv(NOFLAGS)
        val clientAddrOrReadyMsg = backend.recv(NOFLAGS)

        workerQueue.enqueue(workerAddr)

        if(new String(clientAddrOrReadyMsg) == "READY") {
         // nothing to do - worker is letting us know that he's ready to work
        }
        else {
          // retrieve remaining 2 frames of client message
          // [Empty][Client Message  of "HELLO"]
          val empty          = backend.recv(0)
          val workerResponse = backend.recv(0)

          frontend.send(clientAddrOrReadyMsg, ZMQ.SNDMORE)
          frontend.send("".getBytes,          ZMQ.SNDMORE)
          frontend.send(workerResponse,       NOFLAGS)
          clientNbr -= 1
        }
      }
      else if (poller.pollin(1) && workerQueue.nonEmpty) {
        val clientAddr = frontend.recv(0)
        val empty      = frontend.recv(0)
        val clientMsg  = frontend.recv(0)

        backend.send(workerQueue.dequeue(), ZMQ.SNDMORE)
        backend.send("".getBytes, ZMQ.SNDMORE)
        backend.send(clientAddr, ZMQ.SNDMORE)
        backend.send("".getBytes, ZMQ.SNDMORE)
        backend.send(clientMsg, NOFLAGS)
      }
      else {}
    }
  }
}

当我运行上面的代码时,我看到以下输出:

[info] Running net.broker.LruQueue2
[info] begin to poll
[info] done polling
[info] clientNbr:1
[info] workerQueue.length: 0
[info] begin to poll
[info] done polling
[info] clientNbr:1
[info] workerQueue.length: 1
[info] begin to poll
[info] WORKER1: 3-frames to client: CLIENT1
[info] done polling
[info] clientNbr:1
[info] workerQueue.length: 0
[info] begin to poll
[info] CLIENT1 received: WORLD

根据输出的打印语句,它似乎停留在poller.poll()

如何调试此行为?

0 个答案:

没有答案
相关问题