gRPC
gRPCはHTTP/2通信でRPC(remote procedure callができるフレームワークです。.protoファイルというインタフェースを定義をサーバとクライアントで共有して、フレームワークがパラメータのチェックなどしてくれます。
他の言語だとOpenAPI/Swaggerのようにコード生成が必要ですが、node.jsではコード生成が不要で、さらにNode-REDを使えばほとんど設定だけで簡単に実装できます。開発中のソフトのエミュレータやテストスタブ/ドライバとして便利に使うことができます。
gRPCはバイナリを送ることやストリーム通信も可能であるなどのメリットがあるのですが、普通の通信でもHTTP/2によって早くなっているはずです。使い慣れたNode-REDがどのくらい早くなるか気になったので、速度を測定してみました。
評価方法
今回はhttpのPOSTとの比較を1000回呼び出しを10セット行って処理時間を比較しました。
なお、今回はWSL(V1)のNode-RED内のローカル通信で行いました。「こんなものかな」という雰囲気をお楽しみください。環境だけでなく、パラメータのデータ形式や通信方式など、評価としては不十分な点も多々ありますので、気になる方はフローを修正してご自身で試していただけたらと思います。
結果:
3倍弱の速度が出ているようです。
HTTP | gRPC | |
---|---|---|
1回目 | 6523 | 2640 |
2回目 | 5987 | 2133 |
3回目 | 5716 | 2168 |
4回目 | 5870 | 1852 |
5回目 | 5987 | 1784 |
6回目 | 5614 | 1763 |
7回目 | 5396 | 1745 |
8回目 | 5441 | 1889 |
9回目 | 5500 | 1775 |
10回目 | 5858 | 1827 |
平均(秒) | 5.7892 | 1.9576 |
フロー
コード
読み込んで使ってください
[{"id":"f6d68618250ca67f","type":"tab","label":"HTTPとgRPC","disabled":false,"info":"","env":[]},{"id":"e95f41214660dee0","type":"inject","z":"f6d68618250ca67f","name":"","props":[{"p":"payload"},{"p":"topic","v":"","vt":"date"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"id\":123456,\"name\":\"test\"}","payloadType":"json","x":130,"y":80,"wires":[["0d5edbe239b1896a"]]},{"id":"f81476510ec5f8e4","type":"debug","z":"f6d68618250ca67f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":660,"y":220,"wires":[]},{"id":"5fb1c2df8eae1e12","type":"http in","z":"f6d68618250ca67f","name":"","url":"/http","method":"post","upload":false,"swaggerDoc":"","x":170,"y":300,"wires":[["37be881fb460ae59"]]},{"id":"0e9cc56c988dc971","type":"http response","z":"f6d68618250ca67f","name":"","statusCode":"","headers":{"Content-Type":"application/json"},"x":620,"y":300,"wires":[]},{"id":"b1f8b6a64988d025","type":"http request","z":"f6d68618250ca67f","name":"","method":"POST","ret":"obj","paytoqs":"ignore","url":"http://localhost:1880/http","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":450,"y":140,"wires":[["4e87001263af2e43"]]},{"id":"a71e4f38fcaca3d3","type":"change","z":"f6d68618250ca67f","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"id\":123456,\"name\":\"test\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":250,"y":140,"wires":[["b1f8b6a64988d025"]]},{"id":"4e87001263af2e43","type":"function","z":"f6d68618250ca67f","name":"","func":"msg.counter = msg.counter+1\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":140,"wires":[["6c52fd1ba44a5aef"]]},{"id":"6c52fd1ba44a5aef","type":"switch","z":"f6d68618250ca67f","name":"","property":"counter","propertyType":"msg","rules":[{"t":"lt","v":"1000","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":310,"y":220,"wires":[["a71e4f38fcaca3d3"],["c4a1a4474f7478bf"]]},{"id":"1f023ef9fb240d3f","type":"debug","z":"f6d68618250ca67f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":660,"y":540,"wires":[]},{"id":"88a6762b8302f60f","type":"change","z":"f6d68618250ca67f","name":"","rules":[{"t":"set","p":"counter","pt":"msg","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":400,"wires":[["d3739dc3caf9689f"]]},{"id":"0b16db712fc56de0","type":"function","z":"f6d68618250ca67f","name":"","func":"msg.counter = msg.counter+1\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":460,"wires":[["90cd9e63946ba227"]]},{"id":"90cd9e63946ba227","type":"switch","z":"f6d68618250ca67f","name":"","property":"counter","propertyType":"msg","rules":[{"t":"lt","v":"1000","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":290,"y":540,"wires":[["d3739dc3caf9689f"],["0709b9bb353b5616"]]},{"id":"0699e370b014662e","type":"grpc-response","z":"f6d68618250ca67f","name":"","x":610,"y":620,"wires":[]},{"id":"f130b9ebdb4402b9","type":"grpc-register-function","z":"f6d68618250ca67f","name":"","server":"8cb71b4d968ba4f2","service":"Greeter","method":"SayHello","x":180,"y":620,"wires":[["a57a172ef664a814"]]},{"id":"d3739dc3caf9689f","type":"grpc-call","z":"f6d68618250ca67f","name":"","server":"8cb71b4d968ba4f2","service":"Greeter","method":"SayHello","chain":"","key":"","x":230,"y":460,"wires":[["0b16db712fc56de0"]]},{"id":"2e42051c498d3367","type":"inject","z":"f6d68618250ca67f","name":"","props":[{"p":"payload"},{"p":"topic","v":"","vt":"date"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"id\":123456,\"name\":\"test\"}","payloadType":"json","x":140,"y":400,"wires":[["88a6762b8302f60f"]]},{"id":"37be881fb460ae59","type":"change","z":"f6d68618250ca67f","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"message\":\"OK!\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":300,"wires":[["0e9cc56c988dc971"]]},{"id":"a57a172ef664a814","type":"change","z":"f6d68618250ca67f","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"message\":\"OK!\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":620,"wires":[["0699e370b014662e"]]},{"id":"c4a1a4474f7478bf","type":"function","z":"f6d68618250ca67f","name":"","func":"msg.payload = Date.now() -msg.topic;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":220,"wires":[["f81476510ec5f8e4"]]},{"id":"0709b9bb353b5616","type":"function","z":"f6d68618250ca67f","name":"","func":"msg.payload = Date.now() -msg.topic;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":460,"y":540,"wires":[["1f023ef9fb240d3f"]]},{"id":"0d5edbe239b1896a","type":"change","z":"f6d68618250ca67f","name":"","rules":[{"t":"set","p":"counter","pt":"msg","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":290,"y":80,"wires":[["a71e4f38fcaca3d3"]]},{"id":"cb132ac35c2e449c","type":"comment","z":"f6d68618250ca67f","name":"HTTP呼出し1000回","info":"","x":140,"y":40,"wires":[]},{"id":"bdc6dfb867aa2128","type":"comment","z":"f6d68618250ca67f","name":"HTTPサーバ","info":"","x":110,"y":260,"wires":[]},{"id":"58d487f0614a7632","type":"comment","z":"f6d68618250ca67f","name":"GRPC呼出し1000回","info":"","x":140,"y":360,"wires":[]},{"id":"a7711b6a35746825","type":"comment","z":"f6d68618250ca67f","name":"GRPCサーバ","info":"","x":120,"y":580,"wires":[]},{"id":"8cb71b4d968ba4f2","type":"grpc-server","port":"5001","name":"","server":"localhost","protoFile":"syntax = \"proto3\";\npackage hello;\n \nservice Greeter {\n rpc SayHello(HelloRequest) returns (HelloReply) {}\n}\n \nmessage HelloRequest {\n int32 id = 1;\n string name = 2;\n}\n \nmessage HelloReply {\n string message = 1;\n}","ca":"","chain":"","key":"","mutualTls":false,"localServer":true}]
参考文献
参考にさせていただきました。ありがとうございます。
おまけ
設定の方法がわからない方は以下をご覧ください。
Node-REDでgRPC:はじめ方