记一次python在代理环境中使用requests请求服务遇到的坑

背景

新建了一个python3环境镜像,在打镜像时将网络代理url以环境变量的形式存入镜像的环境中;代理url:http_proxy=‘http://10.223.94.15:8089’
新建的镜像起容器后,需要在容器中用python3以get方式访问一个http服务;服务地址:‘http://10.238.3.142:5006/trans_cls’
已知:
容器所在物理机与服务提供服务器端口畅通
网络代理的服务器10.223.94.15与服务提供服务器10.238.3.142端口不通

现象

在容器中使用requests的get方法访问http服务后,较长时间后得到response[503];反馈结果表明,容器请求服务没有得到响应

分析

从debug内容中查看到,由于容器环境变量中配置了代理信息,连接信息connection的代理池会默认获取到代理url从而通过代理去访问目的服务;由于代理服务器与服务提供服务不通,所以response为503也是合情合理
记一次python在代理环境中使用requests请求服务遇到的坑_第1张图片
下面源码则记录了使用代理url构建服务请求ProxyManager对象的过程

class ProxyManager(PoolManager):
    """
    Behaves just like :class:`PoolManager`, but sends all requests through
    the defined proxy, using the CONNECT method for HTTPS URLs.

    :param proxy_url:
        The URL of the proxy to be used.

    :param proxy_headers:
        A dictionary containing headers that will be sent to the proxy. In case
        of HTTP they are being sent with each request, while in the
        HTTPS/CONNECT case they are sent only once. Could be used for proxy
        authentication.

    Example:
        >>> proxy = urllib3.ProxyManager('http://localhost:3128/')
        >>> r1 = proxy.request('GET', 'http://google.com/')
        >>> r2 = proxy.request('GET', 'http://httpbin.org/')
        >>> len(proxy.pools)
        1
        >>> r3 = proxy.request('GET', 'https://httpbin.org/')
        >>> r4 = proxy.request('GET', 'https://twitter.com/')
        >>> len(proxy.pools)
        3

    """

    def __init__(
        self,
        proxy_url,
        num_pools=10,
        headers=None,
        proxy_headers=None,
        **connection_pool_kw
    ):

        if isinstance(proxy_url, HTTPConnectionPool):
            proxy_url = "%s://%s:%i" % (
                proxy_url.scheme,
                proxy_url.host,
                proxy_url.port,
            )
        proxy = parse_url(proxy_url)
        if not proxy.port:
            port = port_by_scheme.get(proxy.scheme, 80)
            proxy = proxy._replace(port=port)

        if proxy.scheme not in ("http", "https"):
            raise ProxySchemeUnknown(proxy.scheme)

        self.proxy = proxy
        self.proxy_headers = proxy_headers or {}

总结

打镜像时应考虑代理与访问服务之间的关系,防止出现意外的使用代理访问服务的情况。

你可能感兴趣的:(python,http)