为什么我在这里收到 WinError 10061(连接被拒绝)? [英] Why am I getting WinError 10061 (connection refused) here?

查看:42
本文介绍了为什么我在这里收到 WinError 10061(连接被拒绝)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道对此有几个问题.但我认为这个案例没有被涵盖.

I know there are a few questions about this. But I don't think this case has been covered.

我只是编写了一些代码来安装并启动 W10 Elasticsearch 服务(如果它尚未启动并运行).当我在没有安装 ES 服务的情况下运行它时,我在 requests.get( ...) 处收到一个 ES 内部错误(它会杀死脚本).

I've simply made a bit of code to install and then start a W10 Elasticsearch service if it isn't already up and running. When I run this when the ES service has not been installed I get an ES internal error at requests.get( ...) (and it kills the script).

但如果我再次运行脚本,服务被识别为运行良好,并且 requests.get( ...) 返回 OK,没有抛出内部 ES 错误.这表明该脚本确实安装并启动了服务......但由于某种原因,之后立即发送 URL 请求(相同的运行/进程)会导致问题.

But if I run the script again the service is recognised as running fine, and requests.get( ...) returns OK, with no internal ES error thrown. This shows that the script does indeed both install and start the service... but for some reason sending the URL request immediately afterwards (same run/process) causes a problem.

顺便说一句,如果我只是停止服务,所以它仍然安装,但停止,然后运行脚本,它再次出错(即在简单启动服务后)并发生错误.

Incidentally, if I simply stop the service, so it is still installed, but stopped, and then run the script, again it fouls up (i.e. after simply starting the service) and the error occurs.

此外,我很确定昨天我开始试验时不会发生这种情况.出于这个原因,我在我的 repo 中回到了最简单的实现,希望有人可以解释发生了什么以及如何(是否)解决它.IE.我希望能够在同一个 Python 运行(进程)中安装、启动服务,然后开始使用它.

What's more, I'm pretty sure that this wasn't happening yesterday when I started experimenting with this. For this reason I have gone back in my repo to the simplest implementation, in the hope that someone can explain what's up and how (whether) it can be resolved. I.e. I want to be able to install the service, start it, and then start using it, all from within the same Python run (process).

这是一个 MRE:

import os, sys, io, requests, psutil, elasticsearch

def install_and_start_es_service():
    def get_service(name):
        service = None
        try:
            service = psutil.win_service_get(name)
            service = service.as_dict()
        except Exception as ex:
            print( f'service {name} not yet installed' )
        return service
    try:
        destination_extract_dir = 'D:/apps/ElasticSearch'
        es_bin_dir = destination_extract_dir + '/elasticsearch-7.10.2/bin'
        service = get_service('elasticsearch-service-x64')
        if service and service['status'] == 'running':
            # best case scenario
            return True
        # at this point we will need to try to either start or install the service.
        # to do either of those we need to ensure that the ES bin directory is in place
        if not os.path.isdir( es_bin_dir ):    
            print( 'ES bin dir not found' )
            return False 
        os.chdir( es_bin_dir )
        if not service:
            # can we install the service?
            print( f'before service.bat install...' )
            os.chdir( es_bin_dir )
            os.system( 'elasticsearch-service.bat install' )
            print( f'after service.bat install...' )
        service = get_service('elasticsearch-service-x64')
        if not service:
            print( 'something went wrong trying to install the ES service')
            return False    
        # can we start the service?
        print( f'before service.bat start...' )
        os.chdir( es_bin_dir )
        os.system( 'elasticsearch-service.bat start' )
        print( f'after service.bat start...' )
        service = get_service('elasticsearch-service-x64')
        if service == None or service['status'] != 'running':
            print( 'something went wrong trying to start the ES service')
            return False
    except Exception as e:
        logger.exception( 'unexpected exception thrown while trying to install and start ES service' )
        return False    
    return True
    
es_started = install_and_start_es_service()
print( f'ES started? {es_started}')
if not es_started:
    sys.exit()
r = requests.get('http://localhost:9200')
print( f'type r {type(r)}') # requests.models.Response

这是出现问题时堆栈跟踪的典型结束:

This is a typical end of the stacktrace when things go wrong:

  File "D:\more software projects\python_venv\env\lib\site-packages\requests\adapters.py", line 516, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=9200): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x0000020842FAAD30>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it'))

请注意,这是一个内部 ES 错误...即跟踪并非源自我的一行代码.但是,我可以确定 requests.get( ... 行是导致它.

Note that this is an internal ES error... i.e. the trace does not originate from a line of my code. However, I can work out that the requests.get( ... line is causing it.

编辑

leandrojmp 建议可能需要非零等待期.我应该提到我已经用 time.sleep( 5 ) 尝试过这个.我原以为这应该绰绰有余……但我将沿着这些方向尝试更多的实验……

leandrojmp helpfully suggests a non-zero waiting period might be required. I should have mentioned that I had tried this with time.sleep( 5 ). I'd have thought that should be more than enough... but am going to try a bit more experimentation along those lines...

推荐答案

您得到的错误是来自请求库的错误,因为您的 elasticsearch 实例尚未准备好.

The error you are getting is an error from the request library because your elasticsearch instance was not ready yet.

无法建立连接,因为目标机器主动拒绝

No connection could be made because the target machine actively refused it

这意味着您的 elasticsearch 正在运行,端口已打开,但它还没有准备好响应请求,因为它仍在启动中.

This means that your elasticsearch was running, the port was open, but it wasn't ready to answer to requests yet because it was still starting.

从您在 Windows 机器中启动 Elasticsearch 服务的那一刻到 Elasticsearch 服务真正响应请求的那一刻,可能需要几秒钟,有时几分钟.

From the moment where you start the Elasticsearch service in your windows machine to the moment where the elasticsearch service can really answer to requests, it could take a few seconds, sometimes a few minutes.

启动服务后,您需要等待一段时间才能发出请求,或者实现一些逻辑以继续尝试,直到它可以与您的 elasticsearch 实例通信.

You will need to wait some time to make a request after you start the service, or implement some logic to keep trying until it can talk to your elasticsearch instance.

如果您在启动服务后立即尝试发出请求,您的脚本可能会失败,该服务需要一些时间来启动 JVM 并启动 elasticsearch 应用程序.

If you try to make a request immediately after you start the service, your script will probably fail, the service needs some time to boot up the JVM and start the elasticsearch application.

这篇关于为什么我在这里收到 WinError 10061(连接被拒绝)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆