You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:32:45