Chunking not functioning as expected

I'm having a hard time getting chunk streams to work. As soon as I moved my service behind traefik the streaming stopped working - now all it does is send the whole response at once.

I've looked into this pretty throughly and tried multiple things:

  • trying it disable buffering by setting: traefik.http.middlewares.limit.buffering.memResponseBodyBytes=0
  • removed the redirect for http to see if it was a TLS issue
  • did a lot more debugging that basically has me fairly confident that traefik is the root cause

For reference my docker-compose:

services:
  api:
    image: ghcr.io/goperigon/pokey:latest
    stop_grace_period: 2m
    healthcheck:
      test: curl http://localhost:8080/ping || exit
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 1m
    command: sh -c "python scripts/init_db.py && fastapi run app/main.py --host 0.0.0.0 --port 8080"
    deploy:
      mode: replicated
      replicas: 2 ### TODO: determine ideal # of replicas under normal load
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        failure_action: pause
        monitor: 20s
        order: start-first
      placement:
        constraints:
          - node.labels.pokey.api.api_node==1
      labels:
        - traefik.enable=true
        - traefik.docker.network=traefik-public
        - traefik.constraint-label=traefik-public

        # - traefik.http.middlewares.pokey-api-https-redirect.redirectscheme.scheme=https
        # - traefik.http.middlewares.pokey-api-https-redirect.redirectscheme.permanent=true

        - traefik.http.middlewares.pokey-api-strip-prefix.stripprefix.prefixes=/pokey

        - traefik.http.routers.pokey-api-public-http.rule=Host(`sys.perigon.io`) && PathPrefix(`/pokey`)
        - traefik.http.routers.pokey-api-public-http.entrypoints=http
        - traefik.http.routers.pokey-api-public-http.middlewares=pokey-api-https-redirect
        - traefik.http.routers.pokey-api-public-http.middlewares=pokey-api-strip-prefix

        - traefik.http.routers.pokey-api-public-https.rule=Host(`sys.perigon.io`) && PathPrefix(`/pokey`)
        - traefik.http.routers.pokey-api-public-https.entrypoints=https
        - traefik.http.routers.pokey-api-public-https.tls=true
        - traefik.http.routers.pokey-api-public-https.tls.certresolver=le
        - traefik.http.routers.pokey-api-public-https.middlewares=pokey-api-strip-prefix
        
        - traefik.http.services.pokey-api-public.loadbalancer.server.port=8080
        # - traefik.http.services.pokey-api-public.loadbalancer.server.scheme=https
        # - traefik.http.services.pokey-api-public.loadbalancer.serverstransport=business-api-secure@file
        - traefik.http.middlewares.limit.buffering.memResponseBodyBytes=0

        - traefik.http.services.pokey-api-public.loadbalancer.healthcheck.path=/ping
        - traefik.http.services.pokey-api-public.loadbalancer.healthcheck.interval=10s
        - traefik.http.services.pokey-api-public.loadbalancer.healthcheck.timeout=5s
    environment:
      - ENV=prod
     
    networks:
      - traefik-public

networks:
  traefik-public:
    external: true

What’s the exact issue? Your target service is sending the response chunked, but Traefik collects all chunks and responds with a single message?

  1. Is the "whole response at once" , is a full response in 100% of times? or sometimes it might be a faulty response with missing parts?
  2. which version of Traefik do you use?

Traefik Version: v2.10.5

Sorry what I meant was normally I have essentially SSE - streaming events over the course of about a minute, new events every second or so. When I put traefik in front of it I get all the events sent at once at the very end, instead of the gradual "chunk-streaming" of the responses.

Here is what I mean in a simple example:

--- normally ---
Events streamed:
0:01: {"msg": "random event"}
0:05: {"msg": "another event"}
0:19: {"msg": "another event"}
1:00: {"msg": "last event"}

--- now (with traefik) ---
0:01:
0:05:
0:19:
1:00: {"msg": "random event"}\n{"msg": "another event"}\n{"msg": "another event"}\n{"msg": "last event"}

At first glance this seems to be some type of buffering that may be happening under the hood? But I'm not quite sure.

Yes that is exactly the issue.

I have seen issue that looked familiar on Github Buffering middleware breaks `chunked` encoded requests · Issue #7930 · traefik/traefik · GitHub

I'm not sure if you use the buffering middleware, but even if not , maybe one of suggestions there might help you.

Also I would try updating to latest Traefik 2 version , since I have seen some PRs that talked about some chunks related functionality that came after version 2.11

1 Like

Finally got it fixed, turns out had an application level middleware saying the content would be gzipped causing traefik to have this behavior

2 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.