In gRPC, what does the scheme at the front of a channel target string select, and which port applies when none is given?
answer
- the prefix before the first colon
- chooses a resolver, not a host
- one form skips lookup entirely
- one form points at a local socket
- an unspecified port has a default
basics
~10 sThe scheme selects the name resolver: dns: resolves a name to addresses, ipv4: and ipv6: take literal addresses, unix: points at a local socket. A dns: target that names no port defaults to 443.
solid answer
~40 sA gRPC channel is created from a target, not a URL, and the part before the first colon is a scheme that picks which **name resolver** runs. `dns:[//authority/]host[:port]` looks the name up and can return several addresses; `ipv4:address[:port]` and `ipv6:address[:port]` take literal addresses with no lookup; `unix:path`, `unix:///absolute_path` and `unix-abstract:abstract_path` reach a local socket; `vsock:cid:port` reaches a local hypervisor socket. If a `dns:` target gives no port, the resolver applies its default of **443** — which is almost never what an internal pool listens on, so omitting the port shows up as a connection that never establishes. The resolver also returns more than addresses: it can supply a service config carrying `loadBalancingConfig` and `methodConfig`.
code
pseudocode · 4 lineschannel = create_channel("dns:///matcher.internal:50051") // name lookup, explicit port
channel = create_channel("dns:///matcher.internal") // name lookup, resolver default port 443
channel = create_channel("ipv4:10.0.1.7:50051,10.0.1.8:50051") // literal addresses, no lookup
channel = create_channel("unix:/var/run/matcher.sock") // local socket, no network at allgo deeper
Know that the part before the colon chooses a resolver, and that leaving the port off a name-based target does not mean the client guesses the right one. Write the port.
Be able to explain that the resolver returns both an address list and a service config, and that the config is where the balancing policy and per-method defaults come from.
Show that you know re-resolution is event-driven rather than periodic, and can trace a stale address list back to a channel that has not failed recently enough to refresh.
The lever here is who controls the resolver and the config it serves: that is where balancing policy is distributed to a whole fleet without redeploying a single caller.
## The target is not a URL When an application creates a gRPC channel it hands the client library a **target string**. It looks like a URL and it is not one. Its shape is `scheme:[//authority/]path`, and the scheme does not name a wire protocol — it names a **name resolver**, a pluggable component whose whole job is to turn the rest of the string into something the channel can connect to. This matters because a gRPC channel is not a connection to a host. It is an abstraction over a *set* of endpoints, and the resolver is the thing that produces that set. Everything a client-side balancer later does — opening one connection or several, rotating calls, dropping a failed endpoint — starts from what the resolver handed back. ## The schemes a client typically ships | Scheme | Form | What it produces | |---|---|---| | `dns` | `dns:[//authority/]host[:port]` | one or more addresses from a name lookup, refreshed on re-resolution | | `ipv4` / `ipv6` | `ipv4:address[:port]`, `ipv6:address[:port]` | literal addresses, no lookup at all | | `unix` | `unix:path`, `unix:///absolute_path` | a local socket on the filesystem | | `unix-abstract` | `unix-abstract:abstract_path` | a local socket in the abstract namespace | | `vsock` | `vsock:cid:port` | a socket to a local hypervisor peer | The `//authority/` section of a `dns:` target is optional and names the resolver's own authority — the server to ask — not the service being called. Most targets leave it empty, which is why they are written with three slashes: `dns:///matcher.internal:50051`. ## The port nobody wrote down If a `dns:` target names no port, the resolver supplies a default of **443**. That default exists because a public gRPC endpoint is expected to be reached over TLS on the standard secure-HTTP port. An internal worker pool almost never listens there, so the mistake has a very specific signature: - the name resolves fine, so nothing looks wrong with the lookup; - the connection attempt goes to port 443 and is refused or hangs; - calls fail with an availability error rather than anything that mentions a port; - adding `:50051` to the target fixes it instantly. A literal-address target behaves the same way: leave the port off `ipv4:10.0.1.7` and you get the same default. ## The resolver returns more than addresses The second thing a name resolver produces is a **service config** — a JSON document the channel applies to itself. Two of its fields matter constantly: - `loadBalancingConfig` selects which client-side balancing policy the channel runs across the resolved addresses; - `methodConfig` carries per-method settings, including a `timeout` that applies when the caller sets no deadline of its own. So the resolver answers two questions at once: *where are the endpoints* and *how should this channel treat them*. A client that changes nothing but its target string can therefore end up with a different balancing behaviour, because a different resolver was selected and that resolver supplies a different config — or none, in which case the channel falls back to its default policy. ## Resolution is not a timer One more property surprises people who expect DNS-style refreshing. A gRPC channel does not re-run its resolver on a fixed schedule for the life of the process. Re-resolution is **event-driven**: it happens when the channel is first used, and again when a connection or a subchannel fails and the balancer asks for a fresh answer. Resolvers also rate-limit how often they will actually go and look, so a burst of failures does not become a burst of lookups. The practical consequence is the one every team meets the first time it scales a pool out: a caller whose channel came up an hour ago is working from the address list it got an hour ago, and nothing about adding workers reaches it until something on that channel breaks. ## Where this shows up Picture a pool of workers that match biometric fingerprint templates. The callers are other internal services, each holding one long-lived channel. A deploy renames the pool's service record; the resolver is asked again only when connections start failing, so for a few seconds callers are still dialling addresses that no longer answer — each failure is exactly the event that triggers the re-resolution that fixes it. Understanding that the scheme chose the resolver, and that the resolver runs on events rather than on a clock, is what makes that sequence readable instead of mysterious.
- What does the name resolver hand back besides a list of addresses?A service config. Its `loadBalancingConfig` field selects the client-side balancing policy for the channel, and `methodConfig` carries per-method settings such as a `timeout` that applies when the caller set no deadline. The resolver therefore answers both where the endpoints are and how this channel should treat them.
- Why does a literal-address target still need a balancing policy?Because a literal-address target can list several addresses, and the policy decides what to do with them. Under the default policy the client connects to them in order and uses the first that comes up, so the remaining addresses sit idle as fallbacks rather than sharing the load.
saying these in an interview costs you the question
- Thinks the scheme is a URL scheme like http or https
- Assumes a dns: target with no port falls back to 80
- Believes the resolver always returns exactly one address
- Thinks the target string picks the balancing policy directly
- Assumes the name is resolved once at startup and never again