Практика фреймворка RPC: Apache Thrift

Java задняя часть сервер Apache Thrift
Практика фреймворка RPC: Apache Thrift

I. Обзор

RPC (удаленный вызов процедур)удаленный вызов процедур, сказано так абстрактно, на самом деле упрощенное понимание заключается в том, как узел запрашивает услуги, предоставляемые другим узлом. в статьеПостроение микросервисного центра отслеживания цепочки вызововЦепочка звонков, смоделированная в статье:ServiceA ---> ServiceB ---> ServiceCЭто пример удаленного звонка, но эта статья черезRestTemplateэтоМетод синхронного вызова, используя протокол HTTP для завершения на прикладном уровне, хотя этот метод работает, но иногда он неэффективен. С другой стороны, RPC не зависит от протокола прикладного уровня и может напрямую совершать удаленные вызовы на основе TCP, а связь может выполняться на транспортном уровне, поэтому он больше подходит для некоторых сценариев, требующих более высокой эффективности. Поскольку метод вызова RPC основан на установлении сокетного соединения между клиентом и сервером для реализации передачи двоичных данных, базовый уровень будет более сложным, поэтому появились некоторые фреймворки RPC для инкапсуляции этой сложности, что позволяет разработчикам сосредоточиться на бизнесе. . . . Общие фреймворки RPC включают: Thrift, gRPC, Finagle, Dubbo и т. д. В начале этой статьи автор выберет некоторые практики. В этой статье в основном описывается процесс практики автора для фреймворка Thrift.

Thrift — это проект Apache, который сочетает в себе мощный программный стек и механизм генерации кода для обеспечения бесперебойной поддержки многих языков.

Лучше действовать!

Примечание:Эта статья была впервые опубликована на моем официальном аккаунтеCodeSheep,МожетНажмитеилисканированиеследующеебудь остороженЗаходи подписывайся ↓ ↓ ↓

CodeSheep · 程序羊


2. Экспериментальная среда

  • Mac OS X 10.13.2
  • SpringBoot 2.0.1
  • Thrift 0.11.0
  • IDE: IntelliJ IDEA 2018.01

Чтобы облегчить понимание читателя, я сначала обобщу следующее содержание, включая 7 пунктов:

  • Бережливая среда сборки
  • Конфигурация плагина Thrift в IDEA
  • Создайте проект Thrift и скомпилируйте (цель: определить интерфейс RPC)
  • Разработать интерфейс Thrift API
  • Разработать RPC-сервер
  • Разработать RPC-клиент
  • Практический эксперимент по коммуникациям RPC

Три, бережливая конструкция окружающей среды

  • **Метод 1: **Собственный метод установки, устанавливайте его шаг за шагом, следуя официальным шагам.

Обратитесь сюда:Официальное руководство по установке Thrift на Mac

  • **Метод 2:**Используйте инструмент для заваривания (рекомендовать)

brew install thrift

brew install thrift


4. Конфигурация плагина Thrift в IDEA

Способ 1: Настройка непосредственно в интерфейсе IDEA

Откройте центр подключаемых модулей IDEA и найдитеThriftготов к установке

利用插件中心安装Thrift

Способ 2. Вручную загрузите плагин Thrift и установите его.

как статьиЭлегантное кодирование SpringBoot: благословение ЛомбокаТак же, как установка плагина Lombok в IDEA в этой статье, иногда из-за сетевых причин плагин не может быть установлен, когда метод не работает.В это время вы можете вручную загрузить плагин и установить его .

Вы можете загрузить подключаемый модуль Thrift по следующему адресу: http://plugins.jetbrains.com/plugin/7331-thrift-support.

手动下载Thrift插件

Тогда иди в ИДЕЮInstall plugin from disk...Выберите загруженный zip-пакет для установки, а затем перезапустите IDE.

Install plugin from disk

Флаг успешного завершения установкиCompilerпоявился вБережливый компилятор! Как показано ниже:

成功安装Thrift插件


5. Создайте проект Thrift и скомпилируйте (укажите интерфейс RPC)

  • Шаг 1: Создайте проект Thrift и настройте его

IDE достаточно умна, чтобыNew ProjectВарианты создания бережливого проекта предоставляются, когда:

Thrift项目创建选项

После создания проекта вProject Settingsустановить вFacetsКонфигурация Thrift, как показано на рисунке ниже, здесь мы добавляемГенератор Java

添加一个Java的Generator

Настраивается во всплывающем диалогеOutput folderпуть, который используется для храненияэкономный файлпревратился висходный файл java:

配置好Output folder

ОК, проект Thrift готов!

  • Шаг 2: Создайте файл интерфейса бережливости

Создайте файл интерфейса бережливости здесь:RPCDateService.thrift

Не буду вдаваться в подробности о способе написания файла thrift, он, как и gRPC, имеет свой синтаксис, пространство имен — это имя пакета окончательно сгенерированного файла интерфейса.

namespace java com.hansonwang99.thrift.interface
service RPCDateService{
    string getDate(1:string userName)
}

В этом интерфейсном файле мы определяемСервис, предоставляющий даты, чтобы клиент мог запросить текущее время сервера через этот интерфейс

  • Шаг 3. Скомпилируйте исходные файлы Thrift для создания классов интерфейса Java.

Щелкните правой кнопкой мыши исходный файл .thrift, щелкнитеRecompile 'xxx.thrift'готов завершитьфайл интерфейса бережливости ---> файл интерфейса javaпреобразование

Recompile 'xxx.thrift'

Выходной файл интерфейса Java создается из приведенной выше конфигурации.outputв, егоСтруктура пакета = пространство имен в файле .thrift выше, а структура его пакета показана на рисунке ниже Этот интерфейс Java очень важен и будет использоваться для реализации вызовов RPC между клиентом и сервером в будущем.

输出的.java文件


6. Разработать интерфейс Thrift API

Создаем Maven-проект:ThriftAPI, который содержит интерфейс Java, созданный пользовательским интерфейсом Thrift выше:RPCDateService.javaфайл, который будет использоваться для реализации кода RPC-сервера и RPC-клиента позади!

  • Добавьте экономные зависимости в pom.xml
    <dependencies>
        <dependency>
            <groupId>org.apache.thrift</groupId>
            <artifactId>libthrift</artifactId>
            <version>0.11.0</version>
        </dependency>
    </dependencies>
  • Добавьте RPCDateService.java

вышесказанноепятый шагЗависит отRPCDateService.thriftСгенерированоRPCDateService.javaПросто скопируйте его в проект Maven как есть Структура кода выглядит следующим образом:

ThriftAPI代码结构

Опять же,Проект ThriftAPIБудет обслуживать RPC-сервер и RPC-клиент, которые будут созданы ниже.


Семь, разработка сервера RPC

Мы используем SpringBoot для реализации RPC-сервера

  • Добавьте зависимости в pom.xml

В дополнение к автоматически добавленным зависимостям SpringBoot необходимо добавить приведенное вышеЗависимости ThriftAPIохватывать

<dependency>
        <groupId>com.hansonwang99</groupId>
        <artifactId>ThriftAPI</artifactId>
         <version>1.0-SNAPSHOT</version>
</dependency>
  • Создать контроллер и реализовать интерфейс RPC
@Controller
public class RPCDateServiceImpl implements RPCDateService.Iface {
    @Override
    public String getDate(String userName) throws TException {
        Date now=new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("今天是"+"yyyy年MM月dd日 E kk点mm分");
        String nowTime = simpleDateFormat.format( now );
        return "Hello " + userName + "\n" + nowTime;
    }
}

Здесь текущее время сервера возвращается вызывающей стороне в виде строки!

  • Напишите RPCThriftServer: используется для запуска сервера RPC.
@Component
public class RPCThriftServer {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Value("${thrift.port}")
    private int port;
    @Value("${thrift.minWorkerThreads}")
    private int minThreads;
    @Value("${thrift.maxWorkerThreads}")
    private int maxThreads;

    private TBinaryProtocol.Factory protocolFactory;
    private TTransportFactory transportFactory;

    @Autowired
    private RPCDateServiceImpl rpcDateService;

    public void init() {
        protocolFactory = new TBinaryProtocol.Factory();
        transportFactory = new TTransportFactory();
    }

    public void start() {
        RPCDateService.Processor processor = new RPCDateService.Processor<RPCDateService.Iface>( rpcDateService );
        init();
        try {
            TServerTransport transport = new TServerSocket(port);
            TThreadPoolServer.Args tArgs = new TThreadPoolServer.Args(transport);
            tArgs.processor(processor);
            tArgs.protocolFactory(protocolFactory);
            tArgs.transportFactory(transportFactory);
            tArgs.minWorkerThreads(minThreads);
            tArgs.maxWorkerThreads(maxThreads);
            TServer server = new TThreadPoolServer(tArgs);
            logger.info("thrift服务启动成功, 端口={}", port);
            server.serve();
        } catch (Exception e) {
            logger.error("thrift服务启动失败", e);
        }
    }
}
  • Создать SpringBoot-приложение
@SpringBootApplication
public class RPCThriftServerApplication {
    private static RPCThriftServer rpcThriftServer;
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(RPCThriftServerApplication.class, args);
        try {
            rpcThriftServer = context.getBean(RPCThriftServer.class);
            rpcThriftServer.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • Добавьте файл конфигурации application.properties
thrift.port=6666
thrift.minWorkerThreads=10
thrift.maxWorkerThreads=100

Давайте запустим комиссионный сервис на порту 6666!

  • Запустите службу сервера RPC

RPC服务端启动成功


Восемь, разработайте RPC-клиент.

Здесь SpringBoot также используется для реализации RPC-клиента!

  • Добавьте зависимости в pom.xml

    Это то же самое, что и зависимость сервера RPC, поэтому я не буду вдаваться в подробности.

  • Написание RPCThriftClient: используется для вызовов RPC

Здесь есть два файла:RPCThriftClient.javaиRPCThriftClientConfig.java

RPCThriftClient.javaследующее:

public class RPCThriftClient {
    private RPCDateService.Client client;
    private TBinaryProtocol protocol;
    private TSocket transport;
    private String host;
    private int port;

    public String getHost() {
        return host;
    }
    public void setHost(String host) {
        this.host = host;
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }

    public void init() {
        transport = new TSocket(host, port);
        protocol = new TBinaryProtocol(transport);
        client = new RPCDateService.Client(protocol);
    }

    public RPCDateService.Client getRPCThriftService() {
        return client;
    }

    public void open() throws TTransportException {
        transport.open();
    }

    public void close() {
        transport.close();
    }
}

иRPCThriftClientConfig.javaэто использовать конфигурацию для генерации bean-компонентов

@Configuration
public class RPCThriftClientConfig {
    @Value("${thrift.host}")
    private String host;
    @Value("${thrift.port}")
    private int port;

    @Bean(initMethod = "init")
    public RPCThriftClient rpcThriftClient() {
        RPCThriftClient rpcThriftClient = new RPCThriftClient();
        rpcThriftClient.setHost(host);
        rpcThriftClient.setPort(port);
        return rpcThriftClient;
    }
}
  • Напишите Restful Controller в качестве записи вызова
@RestController
@RequestMapping("/hansonwang99")
public class RPCThriftContoller {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private RPCThriftClient rpcThriftClient;

    @RequestMapping(value = "/thrift", method = RequestMethod.GET)
    public String thriftTest(HttpServletRequest request, HttpServletResponse response) {
        try {
            rpcThriftClient.open();
            return rpcThriftClient.getRPCThriftService().getDate("hansonwang99");
        } catch (Exception e) {
            logger.error("RPC调用失败", e);
            return "error";
        } finally {
            rpcThriftClient.close();
        }
    }
}
  • Создать SpringBoot-приложение
@SpringBootApplication
public class RPCThriftClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(RPCThriftClientApplication.class, args);
    }
}
  • Добавьте файл конфигурации application.properties
thrift.host=localhost
thrift.port=6666
server.port=9999
  • Запустите клиентскую службу RPC.

RPC客户端启动成功


9. Эксперимент связи RPC

Введите в наш браузер:localhost:9999/hansonwang99/thriftВы можете просмотреть текущее время сервера, полученное клиентом с сервера, что указывает на то, что процесс связи RPC открыт!

客户端成功从服务端取回结果


10. Постскриптум

Экспериментальный код этой статьи находится в открытом доступе.Нажмите, чтобы получить

Дополнительные статьи автора о SpringBt находятся здесь:


Если вам интересно, вы также можете уделить время прочтению некоторых статей автора о контейнеризации и микросервисах:


CodeSheep · 程序羊