同一Docker网络中,如何识别Flask服务间请求的来源服务?
识别Docker网络中Flask请求的来源服务
要解决这个问题,你可以用以下几种实用方法:
方法1:自定义请求头(最简单直接)
在发送请求时添加自定义请求头标识发送方服务名,接收方直接从请求头读取即可。
发送方示例(以login服务调用jobs为例):
import requests import json import os headers = { 'Content-Type': 'application/json', # 自定义头标识服务名 'X-Service-Name': 'login' } data = {"key": "value"} response = requests.post( 'http://jobs:5001/some/api', data=json.dumps(data), headers=headers )
接收方示例(jobs服务接口):
from flask import Flask, request import logging app = Flask(__name__) @app.route('/some/api', methods=['POST']) def execute_task(): try: origin_service = request.headers.get('X-Service-Name', 'unknown') origin_ip = request.environ['REMOTE_ADDR'] origin_port = request.environ['REMOTE_PORT'] logging.warning(f"请求来源:服务名={origin_service},IP={origin_ip}:{origin_port}") # 后续业务逻辑 return "success", 200 except Exception as ex: logging.exception(ex) return "error", 500
方法2:Docker DNS反向解析
Docker自定义网络会为每个服务注册DNS,可通过请求的REMOTE_ADDR反向解析出对应服务名。
接收方代码修改:
from flask import Flask, request import logging import socket app = Flask(__name__) @app.route('/some/api', methods=['POST']) def execute_task(): try: origin_ip = request.environ['REMOTE_ADDR'] origin_port = request.environ['REMOTE_PORT'] # 反向解析IP到服务名 try: origin_service = socket.gethostbyaddr(origin_ip)[0].split('.')[0] except socket.herror: origin_service = 'unknown' logging.warning(f"请求来源:服务名={origin_service},IP={origin_ip}:{origin_port}") return "success", 200 except Exception as ex: logging.exception(ex) return "error", 500
注意:该方法依赖Docker DNS服务,若网络配置变动可能解析失败,需添加异常处理。
方法3:环境变量注入服务名(更灵活)
在docker-compose中给每个服务注入自身服务名的环境变量,发送方读取变量后添加到请求头,避免硬编码。
修改docker-compose.yml(所有服务同理):
version: '3' services: login: build: context: ./repo_login dockerfile: Development.Dockerfile volumes: - ./repo_login:/home/app ports: - "5007:5001" restart: unless-stopped environment: ENV: 'development' # 注入服务名环境变量 SERVICE_NAME: 'login' networks: - qa_network jobs: # ... 原有配置 environment: PYTHONUNBUFFERED: 1 ENV: 'development' SERVICE_NAME: 'jobs' # ... 其他配置 sla: # ... 原有配置 environment: ENV: 'development' SERVICE_NAME: 'sla' # ... 其他配置
发送方代码:
import requests import json import os headers = { 'Content-Type': 'application/json', # 从环境变量读取服务名 'X-Service-Name': os.getenv('SERVICE_NAME', 'unknown') } data = {"key": "value"} response = requests.post( 'http://jobs:5001/some/api', data=json.dumps(data), headers=headers )
接收方代码同方法1,读取X-Service-Name即可。
内容的提问来源于stack exchange,提问作者Miguel Robledo
相关产品推荐
相关产品推荐

