Я пробую gRPC в качестве альтернативы JNI, и идея состоит в том, чтобы служба gRPC была на стороне C++, а клиент подключен на стороне Java/Android. Чтобы добиться наилучшей производительности, я бы предпочел использовать внутрипроцессный канал (открыт для ваших предложений).
Как я могу подключиться к серверу C++ gRPC с помощью InProcessChannel() ? Проблема в том, что мне нужно сдать name для Java InProcessServerBuilder.
В тестах C++ gRPC (например, здесь) я не могу найти его набор, и это заставляет меня думать, что InProcessChannel можно использовать только на чистом C++ (и сервер, и клиент на C++). Возможно ли это для службы С++ и клиента Java?
PS. Я смог сделать это для Java-сервера + Java-клиента.
ППС. Я нашел пару похожих QnAs , например. здесь , но мне интересно, есть ли еще способ заставить его работать вместе (вероятно, с помощью какого-то стороннего канала). Может ли он работать через сокеты домена Unix?
«Внутрипроцессные» транспорты C++ и Java не были названы надлежащим образом для случаев, когда несколько языков находятся в одном процессе. Внутрипроцессные транспорты работают только на каждом отдельном языке; внутрипроцессные транспорты C++ и Java не могут взаимодействовать.
Вы должны использовать обычный клиент/сервер HTTP/2.
Хотя что-то вроде того, что вы хотите, может существовать, например, транспорт с «разделяемой памятью», это значительный объем работы, и он будет относительно мало использоваться для обслуживания.
«обычный клиент/сервер HTTP/2» примерно в 100 раз медленнее (Socket по сравнению с InProcess)
Netty плохо оптимизирована для Android, и, хотя она может работать, gRPC официально не поддерживает ее, поскольку мы не думаем, что она оправдает наши ожидания. Обычно я бы не рекомендовал пытаться заставить netty-transport-native-epoll работать на Android (но, похоже, вы это сделали!). В Android есть LocalSocket, для которого требуется адаптер перед передачей в OkHttpChannelBuilder.socketFactory(). Это может немного раздражать, но я обычно рекомендую использовать этот путь для UDS.
InProcess
в Java отчасти очень быстр, потому что ему не нужно сериализовать сообщения protobuf, и он может сделать некоторые сокращения с помощью многопоточности. Обе эти оптимизации доступны только для RPC Java-to-Java. Таким образом, его текущая производительность не соответствует производительности, которую вы могли бы увидеть при «межъязыковом внутрипроцессном транспорте». Мы ожидаем лишь незначительного увеличения скорости такого транспорта, в основном связанного с уменьшением на 1-2 memcpy()
s.
Я попробую OkHttpChannelBuilder.socketFactory()
Я реализовал это с помощью .socketFactory(), хотя выглядит это странно. Любой лучший способ передать путь к сокету unix (я сделал это очень странным способом - прямо в SocketFactory). Любые предложения по производительности в целом?
Я думаю, что в настоящее время уместно передать путь сокета unix напрямую к SocketFactory. Да, это странно. У меня есть идеи о том, как мы могли бы улучшить это, добавив поддержку непосредственно в gRPC, но на данный момент хак необходим.
Я принял ответ Эрика Андерсона как правильный. Однако может быть полезно узнать, как я работал с сокетами домена Unix.
Пришлось пропатчить netty для Android и использовать . Обратите внимание на некоторые примечания к разрешениям для Android.
Кажется, Unix Domain Socket должен работать. Сообщается, что он поддерживается gRPC C++ и должен быть выполним на Java согласно вашему ответу. Верно? Текущая проблема заключается в том, что требуются общие библиотеки Android, а netty-transport-native-epoll не готов для Android afaik.