Я хотел бы использовать несколько услуг на одном транспорте (Thrift) - PullRequest
7 голосов
/ 02 августа 2011

Я хотел бы создать несколько сервисов и использовать их с разными идентификаторами.Я имею в виду:

У меня есть служба «Пользователи и проекты».Я хочу использовать их одновременно.

Я имею в виду, что я могу добавить больше «сервисов» к «таблице обработчиков» на xmlrpc.

http://ws.apache.org/xmlrpc/server.html

phm.addHandler("Users",
             Users.class); 
phm.addHandler("Projects",
               Projects.class);

Я хотел бы сделать то же самое в Thrift.

Вот простой пример: test.thrift

typedef i64 UserId

struct Bonk
{
  1: string message,
  2: i32 type
}

struct Insanity
{
  1: map<Bonk, UserId> userMap,
  2: list<Bonk> xtructs
}



service ThriftTest
{
  void         testVoid(),
  string       testString(1: string test),
  byte         testByte(1: byte test),
  i32          testI32(1: i32 test),
  i64          testI64(1: i64 test),
  double       testDouble(1: double test),
  list<map<i32,i32>> testMap(1: map<i32,i32> test),
  map<string,string> testStringMap(1: map<string,string> test),
  set<i32>     testSet(1: set<i32> test),
  map<i32,map<i32,i32>> testMapMap(1: i32 test),
  map<UserId, map<i32,Insanity>> testInsanity(1: Insanity argument)
}

Затем я создаю имплементацию, затем добавляю ее в экземпляр TServer.

Users.Processor users_proccesor = new Users.Processor(New UsersImpl());
Projects.Processor project_processor = new Projects.Processors(new ProjectsImp());
// I would like to add Users and Projects  
ThriftTest.Processor prc = new ThriftTest.Processor(new ThiftTestImp());
            TServerTransport serverTransport = new TServerSocket(9090);
            TServer server = new TSimpleServer(new Args(serverTransport).processor( prc ));

И вот моя большая проблема: я не могу добавить несколько экземпляров сервера.

Заранее благодарю за помощь.

Ответы [ 2 ]

7 голосов
/ 18 апреля 2013

Мультиплексные сервисы (по сути, это то, что вы хотите сделать здесь) интегрируются прямо сейчас.Уже есть исправления для ряда доступных языков, либо уже принятых, либо в процессе пересмотра.

https://issues.apache.org/jira/browse/THRIFT-563 - хорошее место для начала.

PS: Рецензенты и статьи приветствуются; -)

4 голосов
/ 31 января 2012

Вызов RPC передается по проводам в структуре TMessage, которая не имеет поля 'targetService'. Так что нет простого способа привязать несколько сервисов к одному порту без добавления этого поля в TMessage и перекомпиляции thrift.

Можно взломать, внедрив собственный TServer, похожий на TSimpleSever (или любой другой TServer).

Сервер должен прочитать целевой сервис в цикле и получить соответствующий процессор:

      ...
      inputProtocol = inputProtocolFactory_.getProtocol(inputTransport);
      outputProtocol = outputProtocolFactory_.getProtocol(outputTransport);
      do {
        String target = inputProtocol.readString();
        processor = processorFactoryMap.get(target).getProcessor(client);
      while (processor.process(inputProtocol, outputProtocol));
      ...

Клиент должен ставить перед каждым сообщением целевую служебную строку. Это можно сделать, обернув TBinaryProtocol в пользовательский протокол:

public void writeMessageBegin(TMessage message) throws TException {
    wrapped.writeString(target);
    wrapped.writeMessageBegin(message);
}

Основным недостатком этого подхода является потеря совместимости с другими клиентами. Поэтому, вероятно, лучше либо запустить два разных TServer на разных портах, либо определить все методы в одном сервисе Thrift, а затем делегировать вызовы соответствующим обработчикам.

...