Подробное объяснение серии Apache Thrift (1) — обзор и начало работы

задняя часть открытый источник Apache Apache Thrift

предисловие

ThriftЯвляетсялегкий,кросс языкизудаленный сервисный вызовфреймворк, первоначально созданныйFacebookразработка, зайти позжеApacheПроект с открытым исходным кодом. через собственныйIDLПромежуточный язык, а с помощьюмеханизм генерации кодаСоздание различных основных языковRPCСервер/клиенткод шаблона.

ThriftПоддерживает множество различныхЯзык программирования,включаютC++,Java,Python,PHP,Rubyд., эта серия в основном посвященаJavaлингвистическийThriftконфигурации и конкретного использования.

текст

Стек технологий Thrift

Thriftправильнопрограммный стекОпределение очень ясное, так что каждый компонент можетСлабая связь, Для разных сценариев приложений выберите разные способы создания сервисов.

Thriftпрограммный стекСлоистыйснизу вверхОни есть:транспортный уровень(Transport Layer),Уровень протокола(Protocol Layer),слой обработки(Processor Layerсервисный слой(Server Layer).

  • транспортный уровень(Transport Layer): Транспортный уровень отвечает за прямыечитатьинаписатьданные, определяющие конкретныесетевой протокол передачи; НапримерTCP/IPтрансмиссия и т.д.

  • Уровень протокола(Protocol Layer): Уровень протокола определяетформат передачи данных, который отвечает за передачу данных по сетиСериализацияидесериализовать; НапримерJSON,XML,двоичные данныеЖдать.

  • слой обработки(Processor Layer): Слой обработки определяетсяIDL(язык описания интерфейса), который инкапсулирует конкретныйбазовый сетевой транспортиМетод сериализации, и делегирует реализуемому пользователемHandlerдля обработки.

  • сервисный слой(Server Layer): Интегрируйте вышеуказанные компоненты, чтобы обеспечить конкретныеСетевая модель потока/службы ввода-вывода, формируя конечный сервис.

Особенности бережливости

(1) Высокая скорость разработки

написавRPCинтерфейсThrift IDLфайл, использоватьгенератор компиляцииСоздано автоматическиСкелет сервера(Skeletonsклиентская заглушка(Stubs). тем самым спасая разработчиканастроитьиКодек интерфейса обслуживания,передача сообщения,Модель многопоточности сервераи другие основные работы.

  • Сервер: просто следуйтеСервисный скелеткоторыйинтерфейс, напишите конкретнобизнес-обработчик(Handler)которыйКласс реализацииВот и все.
  • Клиент: нужно только скопироватьIDLчетко определенныйклиентская заглушкаисервисный объект, а затем вызовите удаленную службу так же, как вызов метода локального объекта.

(2) Простое обслуживание интерфейса

через техническое обслуживаниеThriftформат IDL (язык описания интерфейса) файл (заметка для написания заметки), его можно использовать какClientИспользуется документация по интерфейсу, а такжеСоздано автоматическиКод интерфейса, всегда согласовывайте код и документацию. иThriftПротокол может гибко поддерживатьсяинтерфейсизМасштабируемость.

(3) Низкая стоимость обучения

потому что это происходит отGoogle Protobufкоманда разработчиков, поэтомуIDLСтиль файла похожGoogle Protobuf, и большеЛегко читать и понимать;особенноRPCсервисный интерфейсСтиль похож на написаниеобъектно-ориентированныйизClassТак же просто.

Начинающим просто нужно обратиться к:thrift.apache.org/, можно понять более чем за часThrift IDLИспользуется синтаксис файла.

(4) Многоязычная/многоязычная поддержка

Thriftслужба поддержкиC++,Java,Python,PHP,Ruby,Erlang,Perl,Haskell,C#,Cocoa,JavaScript,Node.js,Smalltalkи другие языки, вы можете создатьСервис-терминаликлиентская программа.

для нашего часто используемогоJava,PHP,Python,C++Хорошая поддержка, хотя правильнаяiOSотносящийся к окружающей средеObjective-C(Cocoa) поддерживается в меньшей степени, но полностью соответствует нашим требованиям к использованию.

(5) стабильный/широко используемый

ThriftБыло проверено во многих проектах с открытым исходным кодом, чтобы бытьстабильностьиэффективный, НапримерCassandra,Hadoop,HBaseдр.; за границейFacebookОн широко используется в Китае, включая такие компании, как Baidu, Meituan Xiaomi и Ele.me.

Бережливые типы данных

Типы данных, которые могут быть определены сценариями Thrift, включают следующие типы:

  1. основной тип:
    • bool: логическое значение
    • byte: 8-битное целое число со знаком
    • i16: 16-битное целое число со знаком
    • i32: 32-битное целое число со знаком
    • i64: 64-битное целое число со знаком
    • double: 64-битное число с плавающей запятой
    • string: строка в кодировке UTF-8
    • binary: двоичная строка
  2. Тип структуры:
    • struct: объект определенной структуры
  3. Тип контейнера:
    • list: упорядоченный список элементов
    • set: неупорядоченный набор неповторяющихся элементов
    • map: упорядоченный набор ключей/значений
  4. Тип исключения:
    • exception: тип исключения
  5. Тип Обслуживания:
    • service: класс, соответствующий конкретной службе

Бережливый протокол

Thriftпозволяет пользователям выбиратьклиентиСервермеждутранспортный протокол связикатегория, вПротокол передачиВ целом делится натекст(textбинарный(binary) Протокол передачи. заэкономить пропускную способность,Повышение эффективности передачи, обычно используетсябинарныйТип транспортного протокола является большинством, а иногда и основанным натип текстаСоглашение, которое должно быть основано на реальных потребностях в проекте/продукте. Общие протоколы следующие:

  • TBinaryПротокол:бинарныйФормат кодирования для передачи данных
  • Компактный протокол:высокая эффективностьиз,плотныйизбинарныйФормат кодирования для передачи данных
  • TJSONПротокол: использоватьJSONтекстпротокол кодирования данных для передачи данных
  • TSimpleJSONProtocol: предоставляет толькоJSONпросто пишисоглашение, применимое черезРазбор скриптового языка

Транспортный уровень Thrift

Обычно используются следующие транспортные уровни:

  • TSocket: использоватьблокировкаI/Oпередача, которая является наиболее распространенным способом
  • TNonblockingTransport: использоватьнеблокирующий, для строительстваАсинхронный клиент
  • TFrameTransport: использоватьнеблокирующий,в соответствии сразмер блокапередавать, аналогичноJavaсерединаNIO

Тип бережливого сервера

  • TSimpleServer:один потокна стороне сервера, используя стандартныйблокировкаI/O
  • TThreadPoolServer:Многопоточностьна стороне сервера, используя стандартныйблокировкаI/O
  • Неблокирующий сервер:один потоксерверная часть, используйтенеблокирующийI/O
  • THsHaСервер:полусинхронный полуасинхронныйсерверная часть, основанная нанеблокирующийIOчитать и писать иМногопоточностьобработка рабочего задания
  • TThreadedSelectorServer:многопоточный селекторсерверная часть, даTHsHaServerсуществуетасинхронныйIOусовершенствования модели

Пример начала работы с экономией

(1) Запись файла Thrift IDL

а) Скачать0.10.0изThrift IDLКомпилятор, адрес загрузки: http://thrift.apache.org/docs/install. пройти черезгенератор компиляциигенерировать.javaФайл класса для интерфейса.

б) СкачатьWindowsсреда установки.exeфайл, будетthrift.exeПуть добавляется в переменную окружения. существуетIdeaустановить наThriftИзменить плагин.

в) написатьhello.thriftизIDLдокумент:

service HelloWorldService {
  string say(1: string username)
}

г) Используйте инструмент генерации кода для генерации кода и выполните следующие команды:

thrift -gen java hello.thrift

e) Поскольку целевой каталог для генерации кода не указан, сгенерированные файлы классов хранятся в расположении по умолчанию.gen-javaПод содержанием. Создайте здесьHelloWorldService.javaФайл класса, размер файла превышает тысячи строк, часть перехвачена нижеосновной код.

public class HelloWorldService {
    public interface Iface {
        public String say(String username) throws org.apache.thrift.TException;
    }

    public interface AsyncIface {
        public void say(String username, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws org.apache.thrift.TException;
    }

    public static class Client extends org.apache.thrift.TServiceClient implements Iface {
        public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
            public Factory() {
            }

            public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
                return new Client(prot);
            }

            public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
                return new Client(iprot, oprot);
            }
        }

        public Client(org.apache.thrift.protocol.TProtocol prot) {
            super(prot, prot);
        }

        public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
            super(iprot, oprot);
        }

        public String say(String username) throws org.apache.thrift.TException {
            send_say(username);
            return recv_say();
        }
        // 省略.....
    }

    public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
        public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
            private org.apache.thrift.async.TAsyncClientManager clientManager;
            private org.apache.thrift.protocol.TProtocolFactory protocolFactory;

            public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
                this.clientManager = clientManager;
                this.protocolFactory = protocolFactory;
            }

            public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
                return new AsyncClient(protocolFactory, clientManager, transport);
            }
        }

        public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
            super(protocolFactory, clientManager, transport);
        }

        public void say(String username, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws org.apache.thrift.TException {
            checkReady();
            say_call method_call = new say_call(username, resultHandler, this, ___protocolFactory, ___transport);
            this.___currentMethod = method_call;
            ___manager.call(method_call);
        }
        // 省略.....
    }
    // 省略.....
}

Для разработчиков используйте роднойThriftFramework, нужно сосредоточиться только на следующих четырех ядрахВнутренний интерфейс/класс:Iface, AsyncIface, ClientиAsyncClient.

  • Iface:Серверпутем реализацииHelloWorldService.Ifaceинтерфейс, кклиентпредоставить конкретныеСинхронизироватьЛогика бизнеса.
  • AsyncIface:Серверпутем реализацииHelloWorldService.Ifaceинтерфейс, кклиентпредоставить конкретныеасинхронныйЛогика бизнеса.
  • Client:клиентпройти черезHelloWorldService.Clientобъект экземпляра дляСинхронизироватьПутьсервер доступаспособ предоставления услуги.
  • AsyncClient:клиентпройти черезHelloWorldService.AsyncClientобъект экземпляра дляасинхронныйПутьсервер доступаспособ предоставления услуги.

(2) Создайте новый проект Maven

а) Новыйmavenмашиностроение, импортthriftзависимости, вот используемая версия0.10.0.

  <dependency>
      <groupId>org.apache.thrift</groupId>
      <artifactId>libthrift</artifactId>
      <version>0.10.0</version>
  </dependency>

б) создаст классHelloWorldService.javaСкопируйте исходные файлы в каталог исходных файлов проекта и реализуйтеHelloWorldService.Ifaceопределениеsay()метод.

HelloWorldServiceImpl.java

public class HelloWorldServiceImpl implements HelloWorldService.Iface {
    @Override
    public String say(String username) throws TException {
        return "Hello " + username;
    }
}

в) Программирование на стороне сервера:

SimpleServer.java

public class SimpleServer {
    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(ServerConfig.SERVER_PORT);
        TServerSocket serverTransport = new TServerSocket(serverSocket);
        HelloWorldService.Processor processor =
                new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());

        TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory();
        TSimpleServer.Args tArgs = new TSimpleServer.Args(serverTransport);
        tArgs.processor(processor);
        tArgs.protocolFactory(protocolFactory);

        // 简单的单线程服务模型 一般用于测试
        TServer tServer = new TSimpleServer(tArgs);
        System.out.println("Running Simple Server");
        tServer.serve();
    }
}

г) Написание клиентской программы:

SimpleClient.java

public class SimpleClient {
    public static void main(String[] args) {
        TTransport transport = null;
        try {
            transport = new TSocket(ServerConfig.SERVER_IP, ServerConfig.SERVER_PORT, ServerConfig.TIMEOUT);
            TProtocol protocol = new TBinaryProtocol(transport);
            HelloWorldService.Client client = new HelloWorldService.Client(protocol);
            transport.open();

            String result = client.say("Leo");
            System.out.println("Result =: " + result);
        } catch (TException e) {
            e.printStackTrace();
        } finally {
            if (null != transport) {
                transport.close();
            }
        }
    }
}

e) Запустите серверную программу,Серверсуществуетназначенный портмониторклиентиззапрос на подключение, консоль выводит лог запуска:

е) Запустите клиентскую программу,клиентзапрос через сетьHelloWorldServiceизsay()методВыполнение, вывод консоли возвращает результат:

Используемый здесь основан наоднопоточная синхронизацияизПростая модель обслуживания, обычно используется только для вводного обучения и тестирования!

Суммировать

Эта статья оThriftКонцепция соответствующего введения и опытаthriftКак пишутся программы!

Ссылки по теме

  1. Подробное объяснение серии Apache Thrift (1) — обзор и начало работы

  2. Подробное объяснение Apache Thrift Series (2) — Модель сетевых служб

  3. Подробное объяснение серии Apache Thrift (3) — механизм сериализации


Добро пожаловать в технический публичный аккаунт: Zero One Technology Stack

image

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