Protocol support

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

  1. To enable HTTP/2 between clients and the load balancer, configure the bind line in a frontend section as an ssl endpoint. The proto parameter announces that the load balancer supports HTTP/2 (h2):

    haproxy
    frontend grpc_service
    mode http
    bind :3001 proto h2
    default_backend grpc_servers
    haproxy
    frontend grpc_service
    mode http
    bind :3001 proto h2
    default_backend grpc_servers
  2. Configure TLS connections to the servers in the backend section and specify the HTTP/2 protocol:

    haproxy
    backend grpc_servers
    mode http
    balance roundrobin
    server s1 192.168.0.10:3000 check proto h2
    server s2 192.168.0.10:3000 check proto h2
    haproxy
    backend grpc_servers
    mode http
    balance roundrobin
    server s1 192.168.0.10:3000 check proto h2
    server s2 192.168.0.10:3000 check proto h2

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_service
mode http
bind :3001 proto h2
default_backend grpc_servers
# Store the numberOfDice value in the sess.numberofdice variable
http-request set-var(sess.numberofdice) req.body,ungrpc(1,int32)
# add the variable to the end of the standard HTTP log format
log-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_service
mode http
bind :3001 proto h2
default_backend grpc_servers
# Store the numberOfDice value in the sess.numberofdice variable
http-request set-var(sess.numberofdice) req.body,ungrpc(1,int32)
# add the variable to the end of the standard HTTP log format
log-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:

output
text
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: 2
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" Number of dice: 2
output
text
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: 2
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" Number of dice: 2

See also Jump to heading

  • To force a protocol on the bind directive, see bind - proto.
  • To force a protocol on the server directive, see server - proto.
  • To fetch the request body, see req.body.
  • To convert the protocol buffers message field from a gRPC message, see ungrpc.

Do you have any suggestions on how we can improve the content of this page?