Load balancing
gRPC
Available since
- HAProxy 2.0
- HAProxy Enterprise 2.0r1
- HAProxy ALOHA 11.5
gRPC is a remote procedure call framework that allows a client application to invoke an API function on a server as if that function were defined in the client’s own code. It uses Protocol Buffers to serialize messages, which allows clients and servers to exchange messages even when the two are written using different programming languages. gRPC offers bidirectional streaming of messages, meaning that an interaction between the client and server can be initiated from either side and once a connection is established, calls can be streamed continuously, similar to the WebSocket protocol.
The load balancer can act as a Layer 7 proxy for gRPC traffic because gRPC uses HTTP/2 as its transport protocol. This gives you access to fetch methods for inspecting the messages as they pass through the load balancer.
Enable gRPC over HTTP/2 Jump to heading
-
To enable HTTP/2 between clients and the load balancer, configure the
bind
line in afrontend
section as anssl
endpoint. Theproto
parameter announces that the load balancer supports HTTP/2 (h2):haproxyfrontend grpc_servicemode httpbind :3001 proto h2default_backend grpc_servershaproxyfrontend grpc_servicemode httpbind :3001 proto h2default_backend grpc_servers -
Configure TLS connections to the servers in the
backend
section and specify the HTTP/2 protocol:haproxybackend grpc_serversmode httpbalance roundrobinserver s1 192.168.0.10:3000 check proto h2server s2 192.168.0.10:3000 check proto h2haproxybackend grpc_serversmode httpbalance roundrobinserver s1 192.168.0.10:3000 check proto h2server s2 192.168.0.10:3000 check proto h2
Example gRPC application Jump to heading
In this example, you use a gRPC service called RollDiceService that returns a random number between 1 and 6 and a gRPC client that calls the service.
-
Download the client and server binaries.
-
On your load balancer server, start the server binary so that it listens on port 3000:
nixSERVER_ADDRESS=:3000 ./servernixSERVER_ADDRESS=:3000 ./serveroutputtext2020/12/18 17:36:12 Listening on address :3000outputtext2020/12/18 17:36:12 Listening on address :3000 -
Update your configuration to have a
frontend
andbackend
that receives gRPC traffic and forwards it to the server you just started. Addproto h2
to thebind
andserver
lines to use HTTP/2 as the protocol:haproxyfrontend grpc_servicemode httpbind :3001 proto h2default_backend grpc_serversbackend grpc_serversmode httpserver s1 127.0.0.1:3000 check proto h2haproxyfrontend grpc_servicemode httpbind :3001 proto h2default_backend grpc_serversbackend grpc_serversmode httpserver s1 127.0.0.1:3000 check proto h2 -
Either on the load balancer server or another Linux machine on the network, start the client binary to connect to the gRPC service via the load balancer at port 3001. This will show the output of the client calling the RollDice function on the service:
nixSERVER_ADDRESS=localhost:3001 NUMBER_OF_DICE=2 ./clientnixSERVER_ADDRESS=localhost:3001 NUMBER_OF_DICE=2 ./clientoutputtext2020/12/18 18:08:09 Rolling 2 dice...2020/12/18 18:08:09 roll: 42020/12/18 18:08:09 roll: 12020/12/18 18:08:11 Rolling 2 dice...2020/12/18 18:08:11 roll: 22020/12/18 18:08:11 roll: 6outputtext2020/12/18 18:08:09 Rolling 2 dice...2020/12/18 18:08:09 roll: 42020/12/18 18:08:09 roll: 12020/12/18 18:08:11 Rolling 2 dice...2020/12/18 18:08:11 roll: 22020/12/18 18:08:11 roll: 6 -
Follow the access log to see the requests flow through the load balancer:
outputtext127.0.0.1:51780 [18/Dec/2020:18:08:21.722] grpc_service grpc_servers/s1 0/0/0/1/+1 200 +99 - - ---- 1/1/1/0/0 0/0 "POST http: localhost:3001/RollDiceService/RollDice HTTP/2.0"127.0.0.1:51780 [18/Dec/2020:18:08:23.725] grpc_service grpc_servers/s1 0/0/0/1/+1 200 +99 - - ---- 1/1/1/0/0 0/0 "POST http: localhost:3001/RollDiceService/RollDice HTTP/2.0"outputtext127.0.0.1:51780 [18/Dec/2020:18:08:21.722] grpc_service grpc_servers/s1 0/0/0/1/+1 200 +99 - - ---- 1/1/1/0/0 0/0 "POST http: localhost:3001/RollDiceService/RollDice HTTP/2.0"127.0.0.1:51780 [18/Dec/2020:18:08:23.725] grpc_service grpc_servers/s1 0/0/0/1/+1 200 +99 - - ---- 1/1/1/0/0 0/0 "POST http: localhost:3001/RollDiceService/RollDice HTTP/2.0"
The ungrpc converter Jump to heading
gRPC uses Protocol Buffers to serialize messages. Use the ungrpc
converter function to extract information from a gRPC Protocol Buffers message. It takes the ID of the Protocol Buffers field in a message. In the following example, the Protocol Buffers message has a field named numberOfDice that has an ID of 1:
text
message RollDiceRequest {int32 numberOfDice = 1;}
text
message RollDiceRequest {int32 numberOfDice = 1;}
In your configuration, specify this ID and the data type to extract the value. Here, we print the numberOfDice value to the end of the access log:
haproxy
frontend grpc_servicemode httpbind :3001 proto h2default_backend grpc_servers# Store the numberOfDice value in the sess.numberofdice variablehttp-request set-var(sess.numberofdice) req.body,ungrpc(1,int32)# add the variable to the end of the standard HTTP log formatlog-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r Number of dice: %[var(sess.numberofdice)]"
haproxy
frontend grpc_servicemode httpbind :3001 proto h2default_backend grpc_servers# Store the numberOfDice value in the sess.numberofdice variablehttp-request set-var(sess.numberofdice) req.body,ungrpc(1,int32)# add the variable to the end of the standard HTTP log formatlog-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r Number of dice: %[var(sess.numberofdice)]"
Your access log will now include the field’s value:
outputtext
127.0.0.1:51780 [18/Dec/2020:18:08:21.722] grpc_service grpc_servers/s1 0/0/0/1/+1 200 +99 - - ---- 1/1/1/0/0 0/0 "POST http:localhost:3001/RollDiceService/RollDice HTTP/2.0" Number of dice: 2127.0.0.1:51780 [18/Dec/2020:18:08:23.725] grpc_service grpc_servers/s1 0/0/0/1/+1 200 +99 - - ---- 1/1/1/0/0 0/0 "POST http:localhost:3001/RollDiceService/RollDice HTTP/2.0" Number of dice: 2
outputtext
127.0.0.1:51780 [18/Dec/2020:18:08:21.722] grpc_service grpc_servers/s1 0/0/0/1/+1 200 +99 - - ---- 1/1/1/0/0 0/0 "POST http:localhost:3001/RollDiceService/RollDice HTTP/2.0" Number of dice: 2127.0.0.1:51780 [18/Dec/2020:18:08:23.725] grpc_service grpc_servers/s1 0/0/0/1/+1 200 +99 - - ---- 1/1/1/0/0 0/0 "POST http:localhost:3001/RollDiceService/RollDice HTTP/2.0" Number of dice: 2
See also Jump to heading
Do you have any suggestions on how we can improve the content of this page?