I. Обзор
RPC (удаленный вызов процедур)удаленный вызов процедур, сказано так абстрактно, на самом деле упрощенное понимание заключается в том, как узел запрашивает услуги, предоставляемые другим узлом. в статьеПостроение микросервисного центра отслеживания цепочки вызововЦепочка звонков, смоделированная в статье:ServiceA ---> ServiceB ---> ServiceCЭто пример удаленного звонка, но эта статья черезRestTemplate
этоМетод синхронного вызова, используя протокол HTTP для завершения на прикладном уровне, хотя этот метод работает, но иногда он неэффективен. С другой стороны, RPC не зависит от протокола прикладного уровня и может напрямую совершать удаленные вызовы на основе TCP, а связь может выполняться на транспортном уровне, поэтому он больше подходит для некоторых сценариев, требующих более высокой эффективности. Поскольку метод вызова RPC основан на установлении сокетного соединения между клиентом и сервером для реализации передачи двоичных данных, базовый уровень будет более сложным, поэтому появились некоторые фреймворки RPC для инкапсуляции этой сложности, что позволяет разработчикам сосредоточиться на бизнесе. . . . Общие фреймворки RPC включают: Thrift, gRPC, Finagle, Dubbo и т. д. В начале этой статьи автор выберет некоторые практики. В этой статье в основном описывается процесс практики автора для фреймворка Thrift.
Thrift — это проект Apache, который сочетает в себе мощный программный стек и механизм генерации кода для обеспечения бесперебойной поддержки многих языков.
Лучше действовать!
Примечание:Эта статья была впервые опубликована на моем официальном аккаунте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
4. Конфигурация плагина Thrift в IDEA
Способ 1: Настройка непосредственно в интерфейсе IDEA
Откройте центр подключаемых модулей IDEA и найдитеThriftготов к установке
Способ 2. Вручную загрузите плагин Thrift и установите его.
как статьиЭлегантное кодирование SpringBoot: благословение ЛомбокаТак же, как установка плагина Lombok в IDEA в этой статье, иногда из-за сетевых причин плагин не может быть установлен, когда метод не работает.В это время вы можете вручную загрузить плагин и установить его .
Вы можете загрузить подключаемый модуль Thrift по следующему адресу: http://plugins.jetbrains.com/plugin/7331-thrift-support.
Тогда иди в ИДЕЮInstall plugin from disk...Выберите загруженный zip-пакет для установки, а затем перезапустите IDE.
Флаг успешного завершения установкиCompilerпоявился вБережливый компилятор! Как показано ниже:
5. Создайте проект Thrift и скомпилируйте (укажите интерфейс RPC)
- Шаг 1: Создайте проект Thrift и настройте его
IDE достаточно умна, чтобыNew ProjectВарианты создания бережливого проекта предоставляются, когда:
После создания проекта вProject Settingsустановить вFacetsКонфигурация Thrift, как показано на рисунке ниже, здесь мы добавляемГенератор Java
Настраивается во всплывающем диалогеOutput folderпуть, который используется для храненияэкономный файлпревратился висходный файл java:
ОК, проект 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преобразование
Выходной файл интерфейса Java создается из приведенной выше конфигурации.outputв, егоСтруктура пакета = пространство имен в файле .thrift выше, а структура его пакета показана на рисунке ниже Этот интерфейс Java очень важен и будет использоваться для реализации вызовов RPC между клиентом и сервером в будущем.
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Будет обслуживать 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-клиент.
Здесь 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.
9. Эксперимент связи RPC
Введите в наш браузер:localhost:9999/hansonwang99/thrift
Вы можете просмотреть текущее время сервера, полученное клиентом с сервера, что указывает на то, что процесс связи RPC открыт!
10. Постскриптум
Экспериментальный код этой статьи находится в открытом доступе.Нажмите, чтобы получить
Дополнительные статьи автора о SpringBt находятся здесь:
- Мониторинг приложений Spring Boot на практике
- Приложения SpringBoot развертываются во внешнем контейнере Tomcat.
- Практика поисковой системы ElasticSearch в SpringBt
- Предварительное изучение совместного программирования Kotlin+SpringBoot
- Практика ведения журнала Spring Boot
- Элегантное кодирование SpringBoot: благословение Ломбока
Если вам интересно, вы также можете уделить время прочтению некоторых статей автора о контейнеризации и микросервисах:
- Используйте стек технологий K8S для создания личного частного облака Серийная статья
- Подробная конфигурация сервера Nginx из списка конфигураций
- Строительство центра мониторинга визуализации контейнеров Docker
- Использование ELK для создания контейнерного центра журналов приложений Docker
- Практика фреймворка RPC: Apache Thrift
- Практика фреймворка RPC: Google gRPC
- Построение микросервисного центра отслеживания цепочки вызовов
- Контейнеры Docker обмениваются данными между хостами
- Предварительное исследование кластера Docker Swarm
- Несколько рекомендаций по эффективному написанию Dockerfile