运行RPC服务

Nameko提供了一个命令行脚本来负载RPC服务,但是也提供了通过程序启动RPC服务的方式。如之前最小RPC服务一节所示,直接运行nameko run [模块名[:RPC服务类名]]就可以启动一个或者一组RPC服务,如果不指定RPC服务类名,仅指定模块名,Nameko会自动寻找模块中的RPC服务类。

通过程序来启动RPC服务是通过Nameko提供的ServiceContainerServiceRunner类来实现的。ServiceContainer类是Nameko为RPC服务提供包装和依赖注入的工具类,每一个RPC服务都需要在ServiceContainer类实例的支持下运行。在启动RPC服务时,每一个RPC服务都需要一个ServiceContainer类实例来负载。构造一个ServiceContainer至少需要提供RPC服务类和一个配置对象。以下是一个使用ServiceContainer控制RPC服务的示例。

from nameko.containers import ServiceContainer


class Service:
	name = 'rpc_service'


container = ServiceContainer(Service, config={})

# 启动RPC服务
container.start()

# 停止RPC服务
container.stop()

# 强行终止RPC服务
container.kill()

ServiceContainer可以接受以下配置项,这些配置项也可以用于其他需要配置RPC服务的位置。

  • AMQP_URI,AMQP消息队列连接串。
  • WEB_SERVER_ADDRESS,Web服务地址。
  • rpc_exchange,RPC服务消息所使用的消息队列Exchange。
  • serializer,串行化RPC调用传递信息的串行化器。
  • SERIALIZERS,可用的串行化器。
  • ACCEPT,允许使用的内容类型。
  • AMQP_SSL,配置AMQP的SSL连接。
  • max_workers,配置最大允许的Worker数量。

在Nameko的命令行中也可以使用这些配置项,可以将其写入到一个YAML文件中,并使用nameko run --config config.yaml [模块名[:RPC服务类名]]来加载配置并启动RPC服务。

在配置文件中还可以使用自定义的配置项,这些自定义的配置项可以通过nameko.dependency_providers模块中提供的Config类来只读访问。以下是一个使用Config类实例来读取配置项的示例。

from nameko.dependency_providers import Config


class Service:
	name = 'config_test'
	
	config = Config()
	
	@property
	def feature_enabled(self):
		return self.config.get('SOME_FEATURE_ENABLED', False)
	
	@rpc
	def some_method(self):
		pass

ServiceRunner是一个允许托管多个RPC服务的工具类,它会自动对RPC服务使用ServiceContainer进行包装,对加入其中的RPC服务进行统一的管理。Nameko的命令行nameko run也是采用这个工具类来完成RPC服务的运行。以下是ServiceRunner类的使用示例。

from nameko.runners import ServiceRunner


class ServiceA:
	name = 'service_a'


class ServiceB:
	name = 'service_b'


runner = ServiceRunner(config={})
runner.add_service(ServiceA)
runner.add_service(ServiceB)

# 启动所有RPC服务
runner.start()

# 停止所有RPC服务
runner.stop()

# 强行终止所有RPC服务
runner.kill()

除此之外,Nameko还提供了一个run_services()方法来运行RPC服务,这个方法在执行后会自动返回一个ServiceRunner对象用于RPC服务的控制。以下是run_services()方法的使用示例。

from nameko.runners import run_services


with run_services(config, ServiceA, ServiceB) as runner:
	# 执行其他交互操作
# 当离开with的作用域,所有服务自动停止

run_service()方法可以接受一个参数名为kill_on_exit,当给定值为True时,将会使用.kill()来代替.stop()来停止RPC服务。