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

RabbitMQ management api can't connect #1036

Closed
gentunian opened this issue Oct 30, 2020 · 11 comments
Closed

RabbitMQ management api can't connect #1036

gentunian opened this issue Oct 30, 2020 · 11 comments
Labels

Comments

@gentunian
Copy link

gentunian commented Oct 30, 2020

Describe the bug

When opening the "broker" tab, nothing is shown.

To Reproduce

  1. Use this docker-compose.yml:
version: '3'

services:

  broker:
    image: rabbitmq:3.8-management

  monitor:
    image: mher/flower:0.9.5
    command:  flower --address=0.0.0.0 --port=5555 --broker=$CELERY_BROKER_URL --broker_api=$CELERY_BROKER_API_URL
    environment:
      CELERY_BROKER_URL: amqp://broker:5672
      CELERY_BROKER_API_URL: http://guest:guest@broker:15672/api
    ports:
      - 5555:5555
  1. run it: docker-compose up
  2. Open http:localhost:5555/broker

Expected behavior

Flower showing rabbitmq management api connection.

Actual behavior

broker_1   | {bad_header,<<"GET /api">>}
monitor_1  | [E 201030 16:57:13 broker:84] RabbitMQ management API call failed: [Errno 104] Connection reset by peer
@gentunian gentunian added the bug label Oct 30, 2020
@pinoatrome
Copy link
Contributor

+1

@pinoatrome
Copy link
Contributor

Hi,
I managed to avoid the 'bad_header' error in rabbitMQ changing the name of the BROKER_API_URL on the docker-compose.yml file.

from

CELERY_BROKER_API_URL: http://guest:guest@broker:15672/api

to

FLOWER_BROKER_API_URL: http://guest:guest@broker:15672/api

HTH
GG

@marcelolima
Copy link

@pinoatrome it's just a variable name change, would you mind sharing how it would fix the problem? (the URL is still the same)

@pinoatrome
Copy link
Contributor

pinoatrome commented Jan 21, 2021

@marcelolima
Hi Marcelo,
you are correct: the URL is the same and uses 15672 (management port) instead of 5672 (applicative port), using 'FLOWER_BROKER_API_URL' instead of 'CELERY_BROKER_API_URL' results in a app.options.broker_api being populated (with the management URL passed) instead of building the api_url in RabbitMQ(BrokerBase) constructor with a default format (that is using the applicative port).

This is what I got from a debugging session:

in class BrokerView(BaseHandler) (views/broker.py:14)
in case the transport is 'amqp' (true when RabbitMQ is used as broker) this assignment

http_api = app.options.broker_api

results in a not null value for http_api only if FLOWER_BROKER_API_URL is specified.

This avoids to build a api_url using the default pattern in class RabbitMQ(BrokerBase) (utils/broker.py: 41)
that fails when asking for queues because it is using the port 5672 instead of the management port 15672.

class BrokerView(BaseHandler):
    @web.authenticated
    @gen.coroutine
    def get(self):
        app = self.application
        broker_options = self.capp.conf.BROKER_TRANSPORT_OPTIONS

        http_api = None
        if app.transport == 'amqp' and app.options.broker_api:
            http_api = app.options.broker_api

if Broker is instantiated with a null http_api argument (not specifying FLOWER_BROKER_API_URL) the default value assigned to http_api is used:

'http://guest:guest@localhost:5672/api//' <-- is not using the 'management' port (15672) but the applicative port (5672)

class RabbitMQ(BrokerBase):
        ....
        self.vhost = quote(self.vhost, '') or '/' if self.vhost != '/' else self.vhost
        ....
        if not http_api:
            http_api = "http://{username}:{password}@{host}:{port}/api/{vhost}".format(
                username=self.username, password=self.password,
                host=self.host, port=self.port, vhost=self.vhost
            )

Then in queues this http_api results in url with port 5672 instead of 15672; when invoked generates a HTTPClientError with message:
"RabbitMQ management API call failed: Stream closed"

    @gen.coroutine
    def queues(self, names):
        url = urljoin(self.http_api, 'queues/' + self.vhost)

Hope this Helps
Ciao

@marcelolima
Copy link

thank you, @pinoatrome !
It wasn't the problem I was facing but after checking your response I also went to check the source code and found the reason:

I was passing: http://guest:guest@broker:15672/api instead of http://guest:guest@broker:15672/api/vhost (vhost at the end). That's why I was getting a 404 before.

@eddyojb88
Copy link

eddyojb88 commented Mar 27, 2021

I think that there is a significant series of inconsistencies with using a dockerized flower.

  1. Pointing the command in the docker-compose file to an $env_var seems to command flower to default to Redis

  2. When setting environment variables, there seems to be a random success rate as to whether a celery worker is picked up or not in the Flower UI

  3. There is a random success rate upon first firing up docker-compose and it successfuly calling the API and displaying something in the UI. Refreshing the page results in a stalling of the API.

Can someone point me to a working configuration of django, database, celery, rabbitmq and flower in docker? Flower is looking to be coming out of my stack at this point, having spent a day trying to resolve this one.

@0mars
Copy link

0mars commented Dec 28, 2021

I started seeing all of these issues, since I added a vhost

@JayDarji
Copy link

JayDarji commented Jun 8, 2022

Those who're still wondering and running flower with celery flower command directly, ie like

celery --broker=amqp://guest:guest@localhost:5672// flower -A project_name --basic_auth=guest:guest

and facing this problem that isn't able to get queues in broker tab of flower, can add a little extra argument, and then it'll work.

--broker_api=http://guest:guest@localhost:15672/api/vhost

So now, full command should be:

celery --broker=amqp://guest:guest@localhost:5672// flower -A project_name --basic_auth=guest:guest --broker_api=http://guest:guest@localhost:15672/api/vhost

Here, if your rabbitmq and flower running on same server, you can build urls with localhost in broker and broker_api parameters.
If that is not a case, then you can pass the public ip of the server where rabbitmq is running.

Also, in broker we're passing rabbitmq-server port and in broker_api we're passing rabbitmq management plugins port.
If rabbitmq management plugin is not enabled, please enable that because flower gets queues info from rabbitmq management plugin API.

@adv27
Copy link

adv27 commented Oct 23, 2023

Thank @JayDarji 🙏
The current documentation on the latest(2.0.0) still seems wrong
https://flower.readthedocs.io/en/2.0/config.html#broker-api

$ celery flower broker-api="http://username:password@rabbitmq-server-name:15672/api/"

The correct one should be

$ celery flower --broker_api="http://username:password@rabbitmq-server-name:15672/api/vhost"

@redliu312
Copy link

@JayDarji

wow, you answer really solved my issue.
Thank you

@ismaelzsilva
Copy link

@adv27 answer solved it, thank you!

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

No branches or pull requests

10 participants