0

我开发了一个nameko http微服务,它可以运行良好,但是如果我将文件myhttp.py替换为一个名为myhttp.py的cyphon编译文件,我会得到[curl: (7) Failed to connect to localhost port 8000:连接被拒绝],请帮助我。

第 1 步:使用以下 3 个文件(build.bat、setup.py、myhttp.py)生成 myhttp.pyd

构建.bat

python setup.py build_ext --inplace

安装程序.py

from setuptools import setup
from Cython.Build import cythonize

setup(
    name = 'myapp',
    ext_modules=cythonize("myhttp.py"),
    zip_safe=False,
)

我的http.py

from nameko.web.handlers import http
import json
class MyHttpService:
    name = 'my_http_service'
    
    @http('POST','/hello')  #curl -i -d "world" localhost:8000/hello
    def hello(self, request):
        return "Hello, {}!".format(request.get_data(as_text=True))
    
    

第2步:使用下面3个文件(installer.bat、namekorun.py、namekorun.spec)和刚才生成的myhttp.pyd生成namekorun.exe

安装程序.bat

pyinstaller --noconfirm namekorun.spec

名称korun.py

import eventlet; 
eventlet.monkey_patch()
from nameko.runners import ServiceRunner
import myhttp
import signal


runner = ServiceRunner(config={'WEB_SERVER_ADDRESS': '0.0.0.0:8000'})
runner.add_service(myhttp.MyHttpService)


def shutdown(signum, frame):
    # signal handlers are run by the MAINLOOP and cannot use eventlet
    # primitives, so we have to call `stop` in a greenlet
    eventlet.spawn_n(runner.stop)

signal.signal(signal.SIGTERM, shutdown)
runner.start()
runnlet = eventlet.spawn(runner.wait)
while True:
    try:
        runnlet.wait()
    except OSError as exc:
        if exc.errno == errno.EINTR:
            # this is the OSError(4) caused by the signalhandler.
            # ignore and go back to waiting on the runner
            continue
        raise
    except KeyboardInterrupt:
        print()  # looks nicer with the ^C e.g. bash prints in the terminal
        try:
            runner.stop()
        except KeyboardInterrupt:
            print()  # as above
            runner.kill()
    else:
        # runner.wait completed
        break
    
    
    

名称korun.spec

   # -*- mode: python ; coding: utf-8 -*-
    
    
    block_cipher = None
    
    
    partylibs = ['nameko.constants','nameko.containers','nameko.contextdata','nameko.dependency_providers','nameko.events','nameko.exceptions','nameko.extensions','nameko.log_helpers','nameko.messaging','nameko.rpc','nameko.runners','nameko.serialization','nameko.timer','nameko.amqp.publish','nameko.cli.actions','nameko.cli.backdoor','nameko.cli.code','nameko.cli.commands','nameko.cli.main','nameko.cli.run','nameko.cli.shell','nameko.cli.show_config','nameko.standalone.events','nameko.standalone.rpc','nameko.testing.pytest','nameko.testing.rabbit','nameko.testing.services','nameko.testing.utils','nameko.testing.waiting','nameko.testing.websocket','nameko.utils.retry','nameko.utils.concurrency','nameko.web.handlers','nameko.web.server','nameko.web.websocket']
    
    partylibs += ['eventlet','eventlet.hubs.epolls','eventlet.hubs.kqueue','eventlet.hubs.selects']
    partylibs += ['dns','dns.dnssec','dns.e164','dns.hash','dns.namedict','dns.tsigkeyring','dns.update','dns.version','dns.zone']
    
    a = Analysis(['namekorun.py'],
                 pathex=[],
                 binaries=[],
                 datas=[],
                 hiddenimports=partylibs,
                 hookspath=[],
                 hooksconfig={},
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher,
                 noarchive=False)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)
    
    exe = EXE(pyz,
              a.scripts, 
              [],
              exclude_binaries=True,
              name='namekorun',
              debug=False,
              bootloader_ignore_signals=False,
              strip=False,
              upx=True,
              console=True,
              disable_windowed_traceback=False,
              target_arch=None,
              codesign_identity=None,
              entitlements_file=None )
    coll = COLLECT(exe,
                   a.binaries,
                   a.zipfiles,
                   a.datas, 
                   strip=False,
                   upx=True,
                   upx_exclude=[],
                   name='namekorun')
           

第三步:启动dist/namekorun/namekorun.exe,然后在命令窗口输入 curl -i -d "world" localhost:8000/hello ,得到 curl: (7) Failed to connect to localhost port 8000: Connection refused ,如果用 myhttp.py 替换 myhttp.pyd,它运行良好

我的包如下并使用vs2015

包裹 版本
Python 3.6.8
赛通 3.0.0a9
装饰师 4.4.2
小事件 0.25.1
海带 4.6.8
名子 2.12.0
安装程序 4.7
pyinstaller-hooks-contrib 2021.4
4

1 回答 1

1

追踪 的定义nameko.web.handlers.http

setattr(fn, ENTRYPOINT_EXTENSIONS_ATTR, descriptors)

本质上,它试图在函数对象上设置属性。Cython 函数是与常规 Python 函数不同的类,并且该类没有实例字典,因此setattr会失败(我有点惊讶你没有得到明显的错误)。

因此,我不希望使用 Cython 编译此代码。

于 2022-01-05T18:30:20.377 回答