Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can a client send a list of IP addresses for load balancing? #1307

Closed
07pia05 opened this issue Mar 19, 2020 · 12 comments
Closed

How can a client send a list of IP addresses for load balancing? #1307

07pia05 opened this issue Mar 19, 2020 · 12 comments

Comments

@07pia05
Copy link

07pia05 commented Mar 19, 2020

const grpcJs = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const proto = protoLoader.loadSync('books.proto', {
    keepCase: true,
    longs: String,
    enums: String,
    defaults: true,
    oneofs: true
  });
const packageGrpcJs = grpcJs.loadPackageDefinition(proto);
const clientGrpcJs = new packageGrpcJs.books.BookService(
    ['127.0.0.1:50051', '127.0.0.1:50052'], 
    grpcJs.credentials.createInsecure()
);

I get the following error

/home/js/grpc/node_modules/@grpc/grpc-js/build/src/resolver.js:51
        if (target.startsWith(prefix)) {
                   ^

TypeError: target.startsWith is not a function
@murgatroid99
Copy link
Member

grpc-js does not currently have a mechanism to do exactly what you're trying to do. The existing name resolution+load balancing functionality can load balance across multiple addresses, when DNS records or hosts file records have multiple entries, but they always use the same port, and there isn't currently a way to load balance to multiple ports on the same address.

@murgatroid99
Copy link
Member

By default, grpc-js only uses one address, so to enable true load balancing you will need to set a default service config (documented here). You can do this by passing the client construction argument 'grpc.service_config' with a value that is a JSON string representation of a service config object. I haven't checked recently, but I think the simplest service config object that enables load balancing is

const serviceConfig = {
  'loadBalancingConfig': [
    { round_robin: {} }
  ]
}

Then you can construct your client like this to enable round robin load balancing:

const client = new Client(address, credentials, { 'grpc.service_config': JSON.stringify(serviceConfig) });

@yunnysunny
Copy link

@murgatroid99 Is the parameter of address is a DNS server's name?

@murgatroid99
Copy link
Member

No, it's the DNS name of the gRPC server.

@yunnysunny
Copy link

yunnysunny commented Aug 25, 2020

I have read the code of grpc-node, and found that we can set the parameter of address to dns://domain-name to find the hosts from DNS server. But it‘s not mentioned on the document.
And the module of resolver(in the code of packages/grpc-js/src/resolve.ts) is not exported to developer, if we wanna implement an instance of custom resolver to resolve the problem of load balancing with different port,we have none method except writing the load balancing code myself. Other grpc drivers , such as golang, has ability of passing custom resolver parameter to the driver's API, so I think it may be good for node too.

@murgatroid99
Copy link
Member

The dns: scheme specifies that the target should be interpreted as a DNS name. This is also the default behavior: if you do not use any scheme, it will use DNS by default. So a target of dns:///example.com will behave the same as example.com.

@yunnysunny
Copy link

Will you consider exporting the packages/grpc-js/src/resolve.ts to developer?

@murgatroid99
Copy link
Member

That API is not currently designed to be part of the public API. It would need to go through an API design process and probably some revisions before we export it like that.

@yunnysunny
Copy link

I'm glade to hear that. Expecting you complete it.

@RebornTong
Copy link

RebornTong commented Jan 11, 2022

const client = new Client(address, credentials, { 'grpc.service_config': JSON.stringify(serviceConfig) });

then, how address can be multi server ip, or how Client can be iniciated with a list of ip addreses?
eg: address="172.0.0.1:9090,192.168.1.2:9090" , is there some like this ?

@murgatroid99
Copy link
Member

Yes, grpc-js now supports the ipv4: and ipv6: schemes in the naming documentation. Those can be used to pass in multiple addresses for the client to load balance over.

@RebornTong
Copy link

thanks, it works!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants