Sistema distribuído inspirado em plataformas de streaming de música (Spotify, Deezer), implementado como projeto final da disciplina de Sistemas Distribuídos. O sistema demonstra comunicação interprocessos, invocação remota (RPC), comunicação indireta e assíncrona via RabbitMQ.
O sistema é composto pelos seguintes componentes:
Envia requisições ao gateway, simulando interações de usuários com a plataforma (busca de músicas, criação de playlists, consulta de histórico).
Middleware que atua como ponto único de entrada do sistema. Recebe requisições do cliente e coordena a comunicação com os serviços distribuídos através de RPC.
Cada serviço executa em processo separado e implementa funcionalidades específicas:
- Catalog Service (
catalog_service.py): Gerencia o catálogo de músicas, permitindo busca e listagem. - Playlist Service (
playlist_service.py): Gerencia playlists de usuários, permitindo criação, adição de músicas e consulta. - User Service (
user_service.py): Gerencia usuários e histórico de reprodução, além de publicar eventos assíncronos.
Fornece abstrações para comunicação via RabbitMQ:
- Funções para publicação de mensagens assíncronas
- Cliente RPC para invocação remota síncrona
Responsável pela comunicação indireta e assíncrona entre os componentes.
O sistema demonstra dois tipos de comunicação:
- Cliente → Gateway → Serviços: Requisições que necessitam resposta imediata
- Usado para: busca de músicas, criação de playlists, consulta de histórico
- Eventos publicados sem esperar resposta imediata
- Usado para: registro de eventos de reprodução (filas de eventos)
- Python 3.10+
- RabbitMQ Server
- Ambiente virtual Python (venv recomendado)
Ubuntu/Debian:
sudo apt update
sudo apt install rabbitmq-serverFedora:
sudo dnf install rabbitmq-servermacOS:
brew install rabbitmqApós instalar, inicie o serviço:
# Linux (systemd)
sudo systemctl start rabbitmq-server
# macOS
brew services start rabbitmq# Navegar para o diretório do projeto
cd /home/vash/distributed_music
# Criar ambiente virtual
python3 -m venv venv
# Ativar ambiente virtual
source venv/bin/activate
# Instalar dependências
pip install -r requirements.txtO sistema precisa de 5 terminais separados rodando simultaneamente. Cada componente deve estar em execução antes do próximo.
- RabbitMQ (deve estar rodando)
- Catalog Service
- Playlist Service
- User Service
- Gateway
- Cliente (executa as operações e encerra)
Verificar se está rodando:
sudo systemctl status rabbitmq-server
# ou
rabbitmqctl statusSe não estiver rodando, apenas INICIE o serviço:
# Linux
sudo systemctl start rabbitmq-server
# macOS
brew services start rabbitmqNota: Se você ainda não instalou o RabbitMQ, volte à seção de Instalação acima.
Abra 4 terminais separados e execute cada serviço na ordem especificada:
Terminal 1 - Catalog Service:
cd /home/vash/distributed_music
source venv/bin/activate
python services/catalog_service.pySaída esperada: 🎵 Catalog Service (Top BR) rodando...
Terminal 2 - Playlist Service:
cd /home/vash/distributed_music
source venv/bin/activate
python services/playlist_service.pySaída esperada: 📂 Serviço de playlists ativo...
Terminal 3 - User Service:
cd /home/vash/distributed_music
source venv/bin/activate
python services/user_service.pySaída esperada: 👤 Serviço de usuários ativo...
Terminal 4 - Gateway:
cd /home/vash/distributed_music
source venv/bin/activate
python gateway.pySaída esperada: 🚪 Gateway aguardando requisições...
Terminal 5 - Cliente:
cd /home/vash/distributed_music
source venv/bin/activate
python client.pyO cliente executará automaticamente todas as operações:
- Busca de músicas
- Listagem de catálogo
- Criação de playlists
- Adição de músicas às playlists
- Consulta de histórico
- Registro de reproduções
Para encerrar o sistema, pressione Ctrl+C em cada terminal na ordem inversa:
- Cliente (se ainda estiver rodando)
- Gateway
- User Service
- Playlist Service
- Catalog Service
Verificar filas no RabbitMQ:
rabbitmqctl list_queuesVocê deve ver as seguintes filas quando os serviços estiverem rodando:
gateway_rpccatalog_rpcplaylist_rpcuser_rpcplay_history_events(quando houver eventos)
Solução: Certifique-se de que o ambiente virtual está ativado e instale as dependências:
source venv/bin/activate
pip install -r requirements.txtSolução: Inicie o RabbitMQ:
sudo systemctl start rabbitmq-server
# ou
sudo systemctl restart rabbitmq-serverSolução: Certifique-se de que todos os serviços estão rodando na ordem correta:
- Catalog Service
- Playlist Service
- User Service
- Gateway
- Cliente
Solução: Verifique se o RabbitMQ está rodando e se todas as conexões estão ativas:
rabbitmqctl list_connectionssearch_music: Busca músicas por título, artista ou gênerolist_all: Lista todas as músicas do catálogoget_song_by_id: Obtém detalhes de uma música específica
create_playlist: Cria uma nova playlist para um usuárioadd_song_to_playlist: Adiciona uma música a uma playlistget_playlist: Obtém detalhes de uma playlistlist_user_playlists: Lista todas as playlists de um usuário
get_user_history: Obtém histórico de reprodução de um usuárioget_user_info: Obtém informações de um usuárioregister_play: Registra uma reprodução de música (também publica evento assíncrono)
Cliente → Gateway (RPC) → Serviço Específico → Gateway → Cliente
↓
Evento Assíncrono (RabbitMQ)
- Cliente envia requisição RPC ao Gateway
- Gateway identifica ação
search_musice encaminha ao Catalog Service - Catalog Service processa a busca e retorna resultados
- Gateway retorna resposta ao Cliente
- Cliente exibe resultados
- Cliente envia requisição RPC ao Gateway
- Gateway encaminha ao User Service
- User Service registra a reprodução
- User Service publica evento assíncrono na fila
play_history_events - Gateway retorna confirmação ao Cliente
{
"action": "search_music",
"query": "Funk"
}{
"result": [
{
"id": 1,
"title": "Tá OK",
"artist": "DENNIS & Kevin O Chris",
"genre": "Funk"
}
]
}{
"user_id": 1,
"song_title": "Tá OK",
"type": "song_played"
}from messaging import RpcClient
rpc = RpcClient()
response = rpc.call('gateway_rpc', {
'action': 'search_music',
'query': 'Sertanejo'
})
print(response)response = rpc.call('gateway_rpc', {
'action': 'create_playlist',
'playlist_name': 'Minhas Favoritas',
'user_id': 1
})
playlist_id = response.get('playlist_id')from messaging import publish
publish('play_history_events', {
'user_id': 1,
'song_title': 'Tá OK',
'type': 'song_played'
})distributed_music/
├── client.py # Cliente do sistema
├── gateway.py # Gateway/Middleware
├── messaging.py # Módulo de comunicação
├── requirements.txt # Dependências Python
├── .gitignore # Arquivos ignorados pelo Git
├── README.md # Este arquivo
└── services/
├── catalog_service.py # Serviço de catálogo
├── playlist_service.py # Serviço de playlists
└── user_service.py # Serviço de usuários
- Comunicação Interprocessos: Componentes comunicam-se via RabbitMQ
- Invocação Remota (RPC): Comunicação síncrona cliente-servidor
- Comunicação Indireta: Via broker de mensagens (RabbitMQ)
- Comunicação Assíncrona: Eventos publicados sem bloqueio
- Middleware (Gateway): Ponto único de entrada e coordenação
- Serviços Distribuídos: Processos separados com responsabilidades específicas
- Ordem é importante: Os serviços devem ser iniciados na ordem especificada
- Mantenha todos os terminais abertos: Cada serviço precisa estar rodando simultaneamente
- Dados em memória: Os dados são armazenados em memória e serão perdidos ao reiniciar os serviços
- Timeout: O sistema tem timeout padrão de 30 segundos para requisições RPC
- Tratamento de erros: Tratamento de erros básico está implementado
Projeto desenvolvido para a disciplina de Sistemas Distribuídos - 2025-2
Este projeto foi desenvolvido para fins educacionais.