Параллелизм с EventMachine для высокой производительности - PullRequest
1 голос
/ 18 марта 2012

Мне нужен высокопроизводительный сетевой tcp сервер. Я написал этот код в EventMachine.

class ReactingServer < EventMachine::Connection
  attr_accessor :packet, :packet_class
  @@packet_count = 0

  def initialize(packet_class)
    super
    @packet_class = eval(packet_class)
    @packet = @packet_class.new
    @@packet_count = 0
  end

  def receive_data(data)
    @packet.clear

    operation = proc do
      @packet.read(data)
      @@packet_count = @@packet_count +1
    end

    call_back = proc do
      puts @packet.inspect
      puts "-------------------#{@@packet_count}------------------------\n"
    end
    EventMachine.defer operation, call_back
  end
end

Тогда я написал клиент ruby.

require 'rubygems'
require 'socket'

sock = TCPSocket.new("192.168.15.5", 8181)

500.times do |n|
    packet = "\x00\x01\x1\x0\x1FNazar Hu\x00\x0F\xF\xF\xF\xF\xF\xF"
    sock.send packet, 0
  sleep 0.01
end

Первая проблема, с которой я сталкиваюсь, заключается в том, что, если я удаляю sleep с клиента, многие пакеты не могут быть получены на стороне сервера. Если я отправляю 5 пакетов, в среднем получается 3 пакета. Почему это происходит.

Другой вопрос заключается в том, что моему серверу необходимо было установить соединение с 20K, и в среднем 10 соединений отправляли бы пакеты на сервер в секунду. Способен ли EventMachine справляться с такого рода нагрузками?

Ответы [ 3 ]

1 голос
/ 01 октября 2012

receive_data не вызывается каждый раз, когда кто-то что-то отправляет в сокет, он буферизируется.И размер data может отличаться от нескольких байтов до нескольких килобайт.Вы несете ответственность за правильный анализ данных.Вы можете быть уверены в том, что все отправленные данные будут получены, и порядок будет правильным.

0 голосов
/ 26 ноября 2014

Есть аккуратная статья http://www.slideshare.net/igrigorik/ruby-c10k-high-performance-networking-rubykaigi-09

Я не знаю, как выглядит ваш главный блок, но вы пробовали добавить epoll в начало вашего event_machine :: server?

EM.epoll
trap("TERM") { EM.stop }
trap("INT")  { EM.stop }
EM.run do
  EM.start_server("0.0.0.0", 8181, ReactingServer, "PacketClass") do
    # ...
  end
end

Кроме того, этот eval выглядит немного забавно.Можете ли вы заменить "PacketClass" на :class => PacketClass вместо этого?

Я предполагаю, как выглядит ваш код.

0 голосов
/ 18 марта 2012

Вы проверяли Голиаф ?Он основан на EventMachine и волокнах.Сообщается, что он может обслуживать до 3000 запросов / с.

...