跳到主要内容

消息服务

Solace PubSub+ Python消息API提供了MessagingService类,该类处理与Solace PubSub+事件代理交互的所有功能。要创建MessagingService实例,您必须首先使用所需信息配置属性字典,以建立与事件代理的连接,包括主机详细信息和认证方案。

创建属性字典

要连接到事件代理,您需要在字典中配置服务属性。属性字典可以有多个属性,但必须包含hostvpn-name键。将代理属性字典传递给MessagingServiceClientBuilder以配置与事件代理的连接。可以在代理属性字典中配置五类属性:

  • solace.messaging.config.solace_properties.service_propertiesvpn-name属性所需)
  • solace.messaging.config.solace_properties.transport_layer_propertieshost属性所需)
  • solace.messaging.config.solace_properties.authentication_properties
  • solace.messaging.config.solace_properties.client_properties
  • solace.messaging.config.solace_properties.transport_layer_security_properties

有关详细信息,请参阅Solace PubSub+ Python消息API参考。

以下代码示例展示了用于使用基本认证建立与事件代理连接的代理属性字典:

from solace.messaging.config.solace_properties import transport_layer_properties, service_properties, authentication_properties
# ...
broker_props = {
transport_layer_properties.HOST: "tcps://messaging.solace.cloud:55443",
service_properties.VPN_NAME: "my_VPN",
authentication_properties.SCHEME_BASIC_USER_NAME: "my_username",
authentication_properties.SCHEME_BASIC_PASSWORD: "my_password",
}

或者,如果您正在运行示例,可以通过JSON文件将您想要使用的配置传递给客户端应用程序。以下示例代码展示了如何使用json.loads()函数解析JSON数据,并用它来创建代理属性字典:

import json
# ...
# 读取JSON文件
with open('/path/to/config.json') as file:
json_data = file.read()

# 将JSON反序列化为字典
configDict = json.loads(json_data)

# 使用from_properties(configDict)在创建MessagingService实例时使用JSON数据
messaging_service = MessagingService.builder().from_properties(configDict).build()

有关更详细的示例,请参阅Solace GitHub仓库中的read_config()函数。

端到端负载压缩

Solace PubSub+ Python API可以执行端到端负载压缩,以实现:

  • 更快的消息吞吐量
  • 减少带宽使用
  • 提高应用程序的性能

虽然端到端负载压缩会为单个Solace PubSub+ API增加更多工作,但它可以实现更快的消息发布和接收聚合速率。Solace PubSub+事件代理提供传输消息压缩,可以压缩整个消息,详情请参阅流式压缩连接。然而,当您发送和接收大消息时,压缩整个消息会使事件代理承担大量工作,这可能会导致吞吐量变慢。如果您的应用程序需要发送和接收大消息,我们建议您使用端到端负载压缩以提高性能。

压缩消息负载时的注意事项

以下部分解释了在使用Solace PubSub+消息API压缩消息负载时您应该了解的内容。

仅使用一种消息压缩形式

我们建议您仅使用一种压缩形式,无论是通过事件代理的流式压缩连接还是通过API的端到端负载压缩。多次压缩同一消息可能会浪费资源,通常不会导致消息大小变小。

不要使用端到端负载压缩绕过事件代理支持的最大消息大小

不要传递超过事件代理支持的最大消息大小的负载。我们建议您在使用负载压缩之前将负载大小减小,以确保其小于事件代理支持的最大消息大小。有关最大消息大小的详细信息,请参阅发送大于事件代理最大消息大小的消息。

不要对小消息使用端到端负载压缩

端到端负载压缩最适合几兆字节大小的消息。Solace不建议对小消息使用消息负载压缩,因为端到端负载压缩实际上可能会增加小消息的大小。

升级您的发布者和接收者应用程序

只有当API支持消息负载压缩并且更新到最低支持版本时,接收者应用程序才会自动解压缩任何压缩的消息负载。如果您的接收者应用程序不支持消息负载压缩,这可能会导致潜在的错误或异常。请确保您将发布者和接收者应用程序都升级到负载压缩的最低支持版本。有关版本支持信息,请参阅Solace PubSub+消息API中的功能支持。

端到端负载压缩限制

端到端负载压缩目前不支持Solace PubSub+缓存。

端到端负载压缩与以下内容不兼容:

  • SolCache

  • 非SMF协议,如AMQP、HTTP、Kafka和MQTT

如果您的应用程序使用了上述任何内容,我们建议您不要使用端到端负载压缩。

在Solace PubSub+ Python API中压缩消息负载

您的发布者应用程序可以在发布消息之前压缩任何消息的负载。要压缩消息负载,您必须设置PAYLOAD_COMPRESSION_LEVEL,这告诉API您希望启用端到端负载压缩。负载压缩级别属性可以设置为0到9之间的整数:

  • 0—禁用负载压缩。这是默认设置。

  • 1 - 9—启用负载压缩。1是最低压缩级别,数据吞吐量最快,9是最高压缩级别,数据吞吐量最慢。

您应该根据网络和性能需求调整负载压缩级别。以下代码片段展示了如何在代理属性字典中设置PAYLOAD_COMPRESSION_LEVEL

from solace.messaging.config.solace_properties import service_properties
# ...
service_props = {
# ...
service_properties.PAYLOAD_COMPRESSION_LEVEL: 9
}

建立与事件代理的连接

MessagingService对象允许API建立与事件代理的连接。要创建MessagingService对象,请执行以下操作:

  1. 调用MessagingService类的builder()函数以返回MessagingServiceClientBuilder对象。

  2. MessagingServiceClientBuilder对象为您提供了一系列函数,允许您自定义MessagingService对象。这些包括以下内容:

    • from_properties(configuration: dict)—将必要的代理属性字典传递给MessagingServiceClientBuilder
    • with_authentication_strategy(authentication_strategy: AuthenticationStrategy)
    • with_transport_security_strategy(transport_layer_security_strategy: TransportSecurityStrategy)
    • with_reconnection_retry_strategy(strategy: RetryStrategy)
  3. MessagingServiceClientBuilder对象上调用build()函数以返回MessagingService对象。

  4. 在您的MessagingService对象上调用connect()函数以连接到事件代理。

有关详细信息,请参阅Solace PubSub+ Python消息API参考。

以下示例代码展示了如何创建简单的MessagingService实例并将其连接到事件代理:

# 构建一个具有20次重试和3秒间隔的重新连接策略的消息服务
messaging_service = MessagingService.builder().from_properties(broker_props)\
.with_reconnection_retry_strategy(RetryStrategy.parametrized_retry(20, 3)) \
.with_authentication_strategy(BasicUserNamePassword.of("my_username", "my_password")) \
.build()

# 阻塞连接线程
messaging_service.connect()

要断开MessagingService对象与事件代理的连接,请在其上调用disconnect()。这也会使MessagingService对象符合垃圾回收的条件。

在Python API中通过代理连接到主机事件代理

您可以使用HTTP或SOCKS5代理连接到您私有网络中的事件代理。与其要求每个客户端都通过防火墙,您只需要为外部代理服务器设置一个防火墙例外,该代理服务器将客户端认证到代理。您可能需要使用代理来满足安全要求。Solace在大多数情况下都支持代理。

要设置主机,请使用:

transport_layer_properties.HOST

要通过HTTP或SOCKS协议版本5代理服务器连接到事件代理,配置的主机设置必须包括标准直接连接到事件代理所需的所有参数,但它还必须包括代理服务字符串:

[Protocol:]Host[:Port][%ProxyService]

其中:

ProxyService—用于连接到事件代理的代理服务器。代理服务字符串格式指定为:

[ProxyProtocol]://[username:password@]proxyHost[:proxyPort]

其中:

  • ProxyProtocol—用于与代理服务器通信的协议。有效值为:

    • socks5—使用SOCKS协议版本5(RFC 1928,IETF标准跟踪文件)连接到服务器。
    • httpc—使用HTTP连接协议(RFC 2817,IETF标准跟踪文件)连接到服务器。
  • username:password@—如果代理服务器需要认证,则可以在代理主机之前指定用户名和密码。

  • proxyHost—代理服务器的IP地址(或主机名)。

  • proxyPort—用于建立连接的端口。如果未指定端口号,则SOCKS5的默认端口为1080,HTTP连接的默认端口为3128。

示例:

以下示例展示了如何通过代理服务器连接到事件代理。

  • 192.168.160.28%socks5://192.168.1.1—通过位于192.168.1.1的SOCKS5代理服务器连接到位于192.168.160.28的事件代理。
  • 192.168.160.28%httpc://192.168.1.1—通过位于192.168.1.1的HTTP-Connect代理服务器连接到位于192.168.160.28的事件代理。
  • tcps:solace.company.com%socks5://User:PassWord@proxy.company.com:13128—通过位于proxy.company.com的SOCKS5代理服务器,使用SSL/TCP连接到solace.company.com的事件代理,端口为13128。使用用户名User和密码PassWord对代理服务器进行认证。
  • http://192.168.160.28:44444%httpc://proxy.company.com:11050—使用HTTP连接到位于192.168.160.28的事件代理,端口为44444。通过位于proxy.company.com的代理服务器,端口为11050。

使用传输层安全

传输层安全(TLS)允许在Solace PubSub+ Python API和Solace PubSub+事件代理之间进行加密认证和数据传输。Solace PubSub+ Python API支持TLS 1.1到1.3版本。TLS 1.3需要Solace PubSub+ Python API版本1.10或更高版本。建议使用最新的TLS版本。您可以使用MINIMUM_PROTOCOLMAXIMUM_PROTOCOL服务属性来控制TLS版本,其中默认最小值为TLSv1.2,默认最大值由TLS库自动确定。当您使用TLS时,您必须在transport_layer_properties.HOST属性中使用安全TCP协议(tcpshttps)。以下示例展示了如何配置TLS协议版本和安全主机连接:

broker_props = {
solace.messaging.config.solace_properties.transport_layer_security_properties.MINIMUM_PROTOCOL: TLSv1_2,
solace.messaging.config.solace_properties.transport_layer_security_properties.MAXIMUM_PROTOCOL: TLSv1_3,
solace.messaging.config.solace_properties.transport_layer_properties.HOST: "tcps://messaging.solace.cloud:55443",
# ...
}

with_transport_security_strategy()函数位于config包中,允许您配置TLS连接属性或禁用证书验证。我们建议在配置消息服务时使用证书验证。Solace PubSub+ Python API的config模块提供了以下函数用于配置证书验证:

我们建议在配置消息服务时使用证书验证。Python API的config模块提供了以下函数用于配置证书验证:

  • with_certificate_validation(ignore_expiration: bool, validate_server_name: bool, trust_store_file_path: str, trusted_common_name_list: str)

    • ignore_expiration—当设置为true时,接受过期证书。这不推荐,因为它存在安全风险。
    • validate_server_name—当设置为true时,这是默认设置,不接受与主机不匹配的证书。
    • trust_store_file_path—信任库文件的位置。如果传递空字符串,则不会设置文件路径。
    • trusted_common_name_list—一个逗号分隔的可接受通用名称列表,用于与服务器证书匹配。空字符串将不匹配任何名称。 现代TLS实现确认服务器证书中的主题备用名称,因此通常不需要设置此参数。如果您的服务器证书无法适当升级,您可以使用trusted_common_name_list对服务器证书进行额外验证。

以下示例代码展示了使用TLS时客户端应用程序的推荐安全设置:

# 创建一个具有证书验证的传输安全策略,排除过时的TLS/SSL协议
transport_security = TLS.create().with_certificate_validation(True, False, "./trusted-store", "") \
.with_excluded_protocols(TLS.SecureProtocols.TLSv1,
TLS.SecureProtocols.TLSv1_1,
TLS.SecureProtocols.SSLv3)

# 构建一个消息服务
messaging_service = MessagingService.builder().from_properties(broker_props)\
.with_authentication_strategy(BasicUserNamePassword.of("username", "password")) \
.with_transport_security_strategy(transport_security) \
.build()
  • without_certificate_validation()—此函数配置您的TLS连接不验证服务器证书。

仅在开发环境中使用without_certificate_validation()。我们建议您永远不要在生产环境中使用此函数,因为它会创建安全漏洞。

以下示例代码展示了如何使用without_certificate_validation()函数:

# 创建一个不验证证书的传输安全策略
transport_security = TLS.create().without_certificate_validation()

# 构建一个消息服务
messaging_service = MessagingService.builder().from_properties(broker_props)\
.with_authentication_strategy(BasicUserNamePassword.of("username", "password")) \
.with_transport_security_strategy(transport_security) \
.build()

您还可以使用属性字典中的transport_layer_security_properties配置TLS连接的各个方面。可以使用solace.messaging.config.solace_properties.transport_layer_security_properties中找到的各种字段配置TLS连接。我们建议您使用默认设置(设置为true并启用),以确保以下属性的安全连接:

  • solace.messaging.config.solace_properties.transport_layer_security_properties.CERT_REJECT_EXPIRED
  • solace.messaging.config.solace_properties.transport_layer_security_properties.CERT_VALIDATE_SERVERNAME
  • solace.messaging.config.solace_properties.transport_layer_security_properties.CERT_VALIDATED

有关详细信息,请参阅Solace PubSub+ Python消息API参考。

认证

Solace PubSub+消息API for Python支持多种认证方案(或策略),您可以从中选择。您选择的方案可能取决于连接客户端需要提供的凭据。您可以使用以下认证方案之一:

  • 基本认证
  • Kerberos认证
  • 客户端证书认证
  • OAuth 2.0认证

基本认证

基本认证是默认的客户端认证方案,允许客户端使用客户端用户名和密码对事件代理进行认证。要指定基本认证,请创建一个MessagingService实例,并将以下内容作为with_authentication_strategy()函数的参数指定:

  • BasicUserNamePassword.of(username: str, password: str)
    • username—用于创建BasicUserNamePassword对象的用户名。
    • password—用于创建BasicUserNamePassword对象的密码。

有关详细信息,请参阅Solace PubSub+ Python消息API参考。

以下示例代码展示了如何使用基本认证:

# 构建一个消息服务
messaging_service = MessagingService.builder().from_properties(broker_props)\
.with_authentication_strategy(BasicUserNamePassword.of("username", "password")) \
.build()

Kerberos认证

Python API提供了对Kerberos认证的支持。使用此函数连接需要您在代理上加载Kerberos密钥表(参见管理事件代理文件),并且必须为Kerberos认证客户端连接到的任何消息VPN配置并启用Kerberos认证。

. 调用with_authentication_strategy()函数,并将以下内容作为参数传递:

  • Kerberos.of(service_name: str)
    • service_name—一个有效的Kerberos服务名称。

有关详细信息,请参阅Solace PubSub+ Python消息API参考。

以下示例代码展示了如何使用Kerberos进行认证:

# 构建一个消息服务
messaging_service = MessagingService.builder().from_properties(broker_props)\
.with_authentication_strategy(Kerberos.of("client_kerberos_service_name")) \
.build()

客户端证书认证

要使用客户端证书认证方案,需要执行以下步骤:

  1. 配置主机事件代理使用TLS连接(参见使用传输层安全)。

  2. 您的应用程序必须使用TLS连接到代理。

  3. 在应用程序用于连接的消息VPN上启用客户端证书验证。

  4. 客户端证书必须存在于密钥库文件中,并使用以下内容配置:

    • ClientCertificateAuthentication.of(certificate_file: str, key_file: str, key_password: str)

      • certificate_file—包含客户端证书或客户端证书链的文件。
      • key_file—包含客户端私钥的文件。
      • key_password—如果私钥(key_file)受密码保护,则为密码。

有关详细信息,请参阅Solace PubSub+ Python消息API参考。

以下示例代码展示了如何配置客户端证书认证:

# 构建一个消息服务
messaging_service = MessagingService.builder().from_properties(broker_props)\
.with_authentication_strategy(ClientCertificateAuthentication.of(certificate_file,
key_file,
key_password)) \
.build()

OAuth 2.0认证

OAuth 2.0是一种开放标准,用于访问委托和授权。它通常用作允许网站或应用程序访问用户在其他网站上的信息的机制,而无需提供敏感凭据。OAuth认证方案允许通过授权服务器向第三方客户端颁发的令牌访问PubSub+事件代理上的消息VPN。要使用OAuth 2.0认证,请配置主机事件代理使用TLS连接(参见使用传输层安全),并确保您的应用程序使用TLS连接到事件代理。有关详细信息,请参阅OAuth认证。

Python API支持可以发送到事件代理的不同字段:

  • access_token—一个String,用于应用程序请求数据访问。

和/或

oidc_id_token—一个String,用于Open ID Connect(OIDC)连接。

  • issuer_identifier—(可选)一个String,用于标识适当的OAuth配置文件。

OAuth认证需要使用此函数启用access_tokenoidc_id_token或两者:

  • OAuth2.of(access_token: str, oidc_id_token: str, issuer_identifier: str)
    • 必须提供access_tokenoidc_id_token之一。可选地,可以提供issuer_identifier。如果任何参数不需要,可以传递None

有关详细信息,请参阅Solace PubSub+ Python消息API参考。

以下示例代码展示了如何使用OpenID Connect(OIDC)的OAuth认证:

# 配置服务访问以使用Open ID连接认证,使用ID令牌和可选的访问令牌
messaging_service = MessagingService.builder().from_properties(broker_props)\
.with_authentication_strategy(OAuth2.of("my_access_token",
"my_oidc_token",
None)) \
.with_transport_security_strategy(transport_security) \
.build()
# 配置服务访问以使用OAuth 2认证,使用访问令牌和可选的颁发者标识符
messaging_service = MessagingService.builder().from_properties(broker_props)\
.with_authentication_strategy(OAuth2.of("my_access_token",
None,
"my_issuer_identifier")) \
.with_transport_security_strategy(transport_security) \
.build()

必需的事件代理配置

要使客户端应用程序使用OAuth认证方案,必须为宿主事件代理配置消息VPN OAuth配置文件,并为客户端连接到的任何消息VPN配置并启用OAuth认证。有关详细信息,请参阅OAuth认证。

刷新过期的OAuth令牌

默认情况下,事件代理会在令牌过期时断开客户端连接(参见在令牌过期时断开连接)。当客户端会话断开时,客户端应用程序会根据RECONNECTION_ATTEMPTS属性,使用相同的OAuth令牌尝试重新连接一定次数。如果超过了重新连接尝试次数,则无法重新建立连接,客户端应用程序必须重新创建带有所有订阅的会话。

为了避免需要销毁并重新创建会话,客户端应在令牌过期之前或在重新连接期间更新OAuth令牌。要更新OAuth令牌,请使用update_property(name: str, value: Any)函数,它允许您在创建MessagingService对象后设置可修改的服务属性。第一个参数是以下字符串之一,第二个参数是令牌:

  • messaging_service.update_property(authentication_properties.SCHEME_OAUTH2_ACCESS_TOKEN, new_access_token)用于更新过期的访问令牌
  • messaging_service.update_property(authentication_properties.SCHEME_OAUTH2_OIDC_ID_TOKEN, new_id_token)用于更新过期的ID令牌

可修改的服务属性可能不会立即更新,可能需要下一次重新连接尝试才能更新。

在以下情况下刷新过期的令牌:

  • 客户端应用程序已连接。在这种情况下,客户端联系认证服务器刷新令牌,并在下次API连接到事件代理时修改会话以使用更新后的令牌。

  • 客户端应用程序正在重新连接。重新连接事件包括一个诊断子代码。如果此子代码为Login Failure,这可能表明您的令牌已过期。在这种情况下,API尝试使用过期的令牌重新连接。然后客户端联系认证服务器刷新令牌,并在下次API尝试重新连接到事件代理时修改会话以使用更新后的令牌。

一般来说,如果客户端应用程序能够意识到潜在的令牌过期,并在令牌过期之前刷新它,这是更好的。

当客户端应用程序的会话重新连接时,Python API会重新应用客户端应用程序的直接订阅。如果由于刷新的令牌导致ACL发生变化,事件代理可能会拒绝订阅。