grpclb
grpc load balancer integrated with etcd for Node.js
Install
npm i grpclb grpc
grpclb
lists grpc
as its peerDependency
not dependency
because here
Server side
import { register } from 'grpclb';
const revoke = await register({
server,
etcdKV: { key, value },
ttl: 10,
etcdHosts: hosts,
});
revoke();
server.tryShutdown(() => {});
Client side
- client-side load balancing with
round-robin strategy
We can't register custom service resolver util the C
library exposes the api.
So we can implement client-side load-balancing on the other way: javascript Proxy
import { createGrpcProxy } from 'grpclb';
import { loadSync } from '@grpc/proto-loader';
import { loadPackageDefinition } from 'grpc';
const packageDefinition = loadSync(PROTO_PATH);
const pkgDef = loadPackageDefinition(packageDefinition);
const proxy = await createGrpcProxy({
etcdHosts: hosts,
target: pkgDef.helloworld,
parseKV,
});
const servant = proxy.Greeter;
servant.sayHello({ name }, (error, response) => {});
For static generated grpc javascript codes
The Proxy
way is not convenient. So grpclb
also provides another api to do the load balancing:
import { createClientPool } from 'grpclb';
import { GreeterClient } from 'helloworld/static_codegen/helloworld_grpc_pb';
import { HelloRequest } from 'helloworld/static_codegen/helloworld_pb';
const pool = await createClientPool({
Client: GreeterClient,
parseKV,
etcdHosts: hosts,
});
const servant = pool.get();
servant.sayHello(new HelloRequest(), (error, response) => {});
Notes
grpc
as peerDependency, not dependency
Image you have two copies of grpc
, it would look like:
├── node_modules
│ ├── grpclb
│ │ └── node_modules
│ │ └── grpc
│ └── grpc
└── src
└── static_codegen
├── helloworld_grpc_pb.js
├── helloworld_pb.d.ts
└── helloworld_pb.js
require('grpc')
in src directory, no matter dynamic generated gRPC javascript code or static generated, would resolve to node_modules/grpc
require('grpc')
in grpclb
package would resolve to node_modules/grpclb/node_modules/grpc
Then initialization would throw error
TypeError: Channel's second argument must be a ChannelCredentials
. See details for this issue
List grpc
as peerDependency can avoid this situation.