Open amit034 opened 2 years ago
trying to pipe 4 microservices with more then 50000 messages getting poor results comparing to REST API
I'm trying to learn about gRPC and use its advantages in the stream client & server side capabilities, and compare its performance with REST.
in my POC i have created an application that request for a movie to watch and get a recommendation.
The application, on receiving the request, fetches the list of movies categorized by the genre, then matches it against the user preferences and finally passes it over a recommendation engine to suggest a movie response back to the user.
A total of four microservices will be built for this solution. All interactions between the microservices will be based on gRPC.
the request stream: Movie Finder -> Movie Store -> User Preferences -> Recommender
syntax = "proto3"; enum Genre { COMEDY = 0; ACTION = 1; THRILLER = 2; DRAMA = 3; } message Movie { string title = 1; double rating = 2; Genre genre = 3; string description = 4; } message MovieFinderRequest { int32 user_id = 1; Genre genre = 2; } message MovieFinderResponse { Movie movie = 1; } service MovieFinderService { rpc findMovie(MovieFinderRequest) returns (MovieFinderResponse) {}; } // MovieStoreService message MovieStoreRequest { Genre genre = 1; } message MovieStoreResponse { Movie movie = 1; } service MovieStoreService { // server streaming rpc call to receive a stream of movies rpc getMovies(MovieStoreRequest) returns (stream MovieStoreResponse) {}; } //UserPreferencesService message UserPreferencesRequest { int32 user_id = 1; Movie movie = 2; } message UserPreferencesResponse { Movie movie = 1; } service UserPreferencesService { // Bidirectional streaming rpc call to receive a stream of movies shortlisted based on user preferences rpc getShortlistedMovies(stream UserPreferencesRequest) returns (stream UserPreferencesResponse) {}; } //RecommenderService message RecommenderRequest { Movie movie = 1; } message RecommenderResponse { Movie movie = 1; } service RecommenderService { // client streaming request that receives a stream of movies and recommends one rpc getRecommendedMovie(stream RecommenderRequest) returns (RecommenderResponse) {}; }
pipeline( movieStoreClient.getMovies({genre}), new Transform({ objectMode: true, transform({movie}, encoding, callback) { callback(null, {userId, movie}); } }), userPreferencesClient.getShortlistedMovies(), recommenderClient.getRecommendedMovie((err, recommenderResponse) => { if (err) { console.error(err); return next({message: err.message}) } return res.send(recommenderResponse); }), (err) => { if (err) { next({message: err.message}) } } );
I've assumed the gRPC will beat Rest API due to the streaming and the lightweight payload. but it wasn't the case, the REST API returned back in 600ms and the gRPC in 4s.
I was thinking to use makeGenericClientConstructor to prevent from serialize\deserialize the request and response down the wire to reduce the message data conversation time but unfortunately I need to make manipulations on the data to add user info, so I must deserialize it.
what am I missing ?
here is my POC if someone have the time to look at it. https://github.com/amit034/grpc-node-poc
REST/HTTP 1.1 is like gRPC unary protocol. However, Your many services use stream protocol in request & response. I think you need to use Unary Protocol in all services as a benchmark.
I looked at your POC repository and I can't find the code that actually performs the performance test. Can you point out where that code is so that we can see the usage pattern that resulted in the performance you observed?
I'm facing some similar issue where the REST implementation is faster than the grpc one. My benchmark code is: https://github.com/bmviniciuss/tcc/blob/main/benchmarks/src/create-card/create-card.js
I'm seeing gRPC close to or worst than HTTP. Am I missing something?
The gateway calls either the HTTP or gRPC: HTTP: https://github.com/bmviniciuss/tcc/blob/main/gateway/src/adapters/card/AxiosHttpCardAPI.ts gRPC: https://github.com/bmviniciuss/tcc/blob/main/gateway/src/adapters/card/GRPCCardAPI.ts
Experiencing the same issue. gRPC performance is significantly worse than rest (using "@grpc/grpc-js": "^1.8.15"
with "@nestjs/core": "^9.0.0"
). Downgrading all the way to 1.2.x did nothing.
trying to pipe 4 microservices with more then 50000 messages getting poor results comparing to REST API
I'm trying to learn about gRPC and use its advantages in the stream client & server side capabilities, and compare its performance with REST.
in my POC i have created an application that request for a movie to watch and get a recommendation.
The application, on receiving the request, fetches the list of movies categorized by the genre, then matches it against the user preferences and finally passes it over a recommendation engine to suggest a movie response back to the user.
A total of four microservices will be built for this solution. All interactions between the microservices will be based on gRPC.
the request stream: Movie Finder -> Movie Store -> User Preferences -> Recommender
I've assumed the gRPC will beat Rest API due to the streaming and the lightweight payload. but it wasn't the case, the REST API returned back in 600ms and the gRPC in 4s.
I was thinking to use makeGenericClientConstructor to prevent from serialize\deserialize the request and response down the wire to reduce the message data conversation time but unfortunately I need to make manipulations on the data to add user info, so I must deserialize it.
what am I missing ?
here is my POC if someone have the time to look at it. https://github.com/amit034/grpc-node-poc