Python使用kombu连接信息中包含#号问题排查方式

 更新时间:2024年12月24日 09:31:39   作者:Chengdu.S  
文章描述了在部署Python项目到生产环境时遇到的一个错误,即端口号无法正确转换为整数值,该错误在测试环境和本地调试中没有出现,但在生产环境中才出现,通过分析错误信息和代码,作者发现问题出在URL解析过程中,特别是在处理包含特殊字符(如#号)的URL时

python 项目部署生产环境遇到一个错误问题:

raise ValueError(f"Port could not be cast to integer value as {port!r}") ValueError: Port could not be cast to integer value as 'guest

测试环境和本地调试都没有问题,但是到生产之后就有问题,本章复现有问题的mq连接配置的导致的错误信息,记录问题排查过程

版本信息

框架版本
python3.11.7
kombu5.3.4

环境搭建

python 虚拟环境

Python 虚拟环境(Virtual Environment)是一个隔离的 Python 解释器环境,它允许你为每个 Python 项目安装其特定的依赖包,而不会干扰到全局 Python 环境或其他项目。

这样,你可以确保每个项目都有其独立的、一致的依赖环境,避免了版本冲突和依赖混乱的问题。

Python 中有几个流行的工具用于创建和管理虚拟环境,其中最常用的是 venv 和 virtualenv

venv 创建 python 虚拟环境

python -m venv .venv

执行该命令之后,会创建一个虚拟的环境,产生 .venv文件夹, 目录结构如下

激活虚拟环境

.venv\Scripts\activate

激活虚拟环境之后,文件夹前面会有括号显示虚拟环境的名称

退出虚拟环境

deactivate

虚拟环境下查看python、pip版本

查询pip 配置信息

(.venv) F:\Python\mq>pip config list
global.index-url='http://mirrors.aliyun.com/pypi/simple/'
install.trusted-host='mirrors.aliyun.com'

安装依赖

编写 requirements.txt

kombu==5.3.4

在虚拟环境里面安装依赖

pip install -r requirements.txt

问题复现以及问题排查

1.消息发布端 hello_publisher.py

from __future__ import annotations

import datetime

from kombu import Connection

with Connection('amqp://guest:guest#2024@localhost:5672//') as conn:
    simple_queue = conn.SimpleQueue('simple_queue')
    message = f'helloworld, sent at {datetime.datetime.today()}'
    simple_queue.put(message)
    print(f'Sent: {message}')
    simple_queue.close()

2.在虚拟环境运行代码

出现如下报错信息

(.venv) F:\Python\mq>python hello_publisher.py
Traceback (most recent call last):
  File "F:\Python\mq\hello_publisher.py", line 7, in <module>
    with Connection('amqp://guest:guest#2024@localhost:5672//') as conn:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "F:\Python\mq\.venv\Lib\site-packages\kombu\connection.py", line 203, in __init__
    url_params = parse_url(hostname)
                 ^^^^^^^^^^^^^^^^^^^
  File "F:\Python\mq\.venv\Lib\site-packages\kombu\utils\url.py", line 38, in parse_url
    scheme, host, port, user, password, path, query = _parse_url(url)
                                                      ^^^^^^^^^^^^^^^
  File "F:\Python\mq\.venv\Lib\site-packages\kombu\utils\url.py", line 70, in url_to_parts
    parts.port,
    ^^^^^^^^^^
  File "E:\Anaconda\Lib\urllib\parse.py", line 182, in port
    raise ValueError(f"Port could not be cast to integer value as {port!r}")
ValueError: Port could not be cast to integer value as 'guest'

看到报错的堆栈信息,首先定位到代码行

File "F:\Python\mq\.venv\Lib\site-packages\kombu\utils\url.py", line 70 

在此处加一个断点,调试一下(生产服务不能调试就print输出一下信息)

3.调试出问题的代码

报错的代码方法如下

def url_to_parts(url):
    # type: (str) -> urlparts
    """Parse URL into :class:`urlparts` tuple of components."""
    scheme = urlparse(url).scheme
    schemeless = url[len(scheme) + 3:]
    # parse with HTTP URL semantics
    parts = urlparse('http://' + schemeless)
    path = parts.path or ''
    path = path[1:] if path and path[0] == '/' else path
    return urlparts(
        scheme,
        unquote(parts.hostname or '') or None,
        parts.port,
        unquote(parts.username or '') or None,
        unquote(parts.password or '') or None,
        unquote(path or '') or None,
        dict(parse_qsl(parts.query)),
    )

parts.port 获取的值从 urlparse 方法中解析出来的

执行完 urlparse 方法之后获取到的数值如下

port 的解析在 urlparse 这一步出了问题,重点来看看这个方法的逻辑

经过调试发现问题出在切割方法里面 urllib.parse.urlsplit,具体处理出问题代码在如下片段

链接中有 # 号导致切割之后端口号错位未获取到

去除链接中的#号的正常解析的数据如下

链接中没有 # 号之后,端口可以正常解析了

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • python日志通过不同的等级打印不同的颜色(示例代码)

    python日志通过不同的等级打印不同的颜色(示例代码)

    这篇文章主要介绍了python日志通过不同的等级打印不同的颜色,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • 用python读写excel的方法

    用python读写excel的方法

    这篇文章主要介绍了用python读写excel的方法,涉及xlrd模块与xlwt模块的应用,具有一定的学习借鉴价值,需要的朋友可以参考下
    2014-11-11
  • Pytorch中关于inplace的操作

    Pytorch中关于inplace的操作

    这篇文章主要介绍了Pytorch中关于inplace的操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • python使用pynput库操作、监控你的鼠标和键盘

    python使用pynput库操作、监控你的鼠标和键盘

    这篇文章主要介绍了python使用pynput库操作、监控你的鼠标和键盘,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下
    2021-03-03
  • 一篇文章带你了解python字典基础

    一篇文章带你了解python字典基础

    这篇文章主要介绍了Python字典及字典基本操作方法,结合实例形式详细分析了Python字典的概念、创建、格式化及常用操作方法与相关注意事项,需要的朋友可以参考下
    2021-08-08
  • 简单的Apache+FastCGI+Django配置指南

    简单的Apache+FastCGI+Django配置指南

    这篇文章主要介绍了简单的Apache+FastCGI+Django配置指南,这也是Python上最流行的web框架Django的最流行搭配环境:)需要的朋友可以参考下
    2015-07-07
  • python之PyQt按钮右键菜单功能的实现代码

    python之PyQt按钮右键菜单功能的实现代码

    这篇文章主要介绍了python PyQt按钮右键菜单功能的实现代码,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • python使用心得之获得github代码库列表

    python使用心得之获得github代码库列表

    最近接了个项目,要求获得github的repo的api,度娘了一下,有不少文章介绍,总结了本文,分享给大家并附上代码
    2014-06-06
  • Python如何导出导入所有依赖包详解

    Python如何导出导入所有依赖包详解

    在Python中我们在项目中会用到各种库,自带的自然不必再说,这篇文章主要给大家介绍了关于Python如何导出导入所有依赖包的相关资料,需要的朋友可以参考下
    2021-06-06
  • python dict remove数组删除(del,pop)

    python dict remove数组删除(del,pop)

    我们在用数组列表做删除的时候,可能选择2个方法,一个是del,一个是pop方法
    2013-03-03

最新评论