Service Discovery
Summary and problem description
IPC通道(例如消息队列或UNIX域套接字)上的服务发现是不可执行的,因为传输的数据较大,这可能会导致多个帧的传输。如果发现大量高频服务,例如在启动时,IPC通道可能会成为瓶颈。
Status quo in iceoryx v1.0 (Almond)(iceoryx v1.0的现状(Almond)
Runtime
iox::expected<InstanceContainer, FindServiceError> PoshRuntime::findService(capro::ServiceDescription)
- Sends message over IPC channel
RouDi
-
runtime::IpcMessage{ProcessManager,PortManager}::findService(caper::ServiceDescription)
-
在RouDi收到来自运行时的请求后调用
-
通过IPC通道将应答发送回“PoshRuntime”
-
Requirements
-
用户界面应具有轮询和推送通知界面。
-
请求/响应和发布/订阅主题应由用户发现和区分。
-
必须保证用户不会破坏服务发现
- 通过获取服务发现通信所需的内存块
- 通过发送关于用户创建的服务的虚假服务发现信息
-
应提供C接口
-
内存开销应该最小,以便在各种环境中启用此功能
-
性能应针对默认用例进行优化,在默认用例中,大多数服务都是在启动时创建的,并且在运行时服务发现的变化最小。
-
在不影响系统的情况下,每个应用程序都可以同时使用服务发现。
Static discovery Design Draft(静态发现设计草案)
- 应支持静态发现
- 启动时,RouDi读取一个配置文件,其中包含
- 所有主题(发布/订阅)
- 所有服务(请求/响应)
- 共享内存管理段由RouDi预先配置,并且已经包含所有硬连接的发布者、订阅者、服务器和客户端端口,并且应用程序获取这些预先创建和连接的端口。
- 启动时,RouDi读取一个配置文件,其中包含
- 为
ServiceRegistry创建抽象接口
-
将新类添加到
StaticServiceRegistry::StaticServicesRegistry(std::map<CaproIdString_t,instance_t>map)
-
基于通知的回调只调用一次,并且用户获得完整的服务注册表
-
使用“FindService()”进行轮询将始终返回相同的结果
-
-
另一种选择是在初始化阶段之后使用“finalize()”方法
-
Alternative D: Discovery Class + Listener
在RouDi中创建一个发送“ServiceRegistryTopic”的新发布者。此发布者将用于发出服务注册表中的更改信号,并传输服务发现注册表。完整的旧服务注册表(保存在本地)将与新类中的新服务注册表进行比较,从而扩展公共用户API。
在RouDi中创建一个发送“ServiceRegistryTopic”的新发布者。此发布者将用于发出服务注册表中的更改信号,并传输服务发现注册表。完整的旧服务注册表(保存在本地)将与新类中的新服务注册表进行比较,从而扩展公共用户API。
Pro:
- 用于基于事件和同步请求的简单一致的用户API
- “findService”的筛选可以在新类中完成
- 不需要变化计数器,因为通过POSH机制解决了ABA问题
- 不仅传输服务注册表的增量,还传输完整的服务注册表信息
- 快速数据传输
- 接近DDS机制
- 无法替换“接口端口”
Con:
- New publisher in RouDi needed
- Memory consumption is high through to traditional pub/sub(通过传统的pub/sub,内存消耗很高)
注:
- 为了避免自定义用户配置的内存池出现内存不足问题或访问权限问题,发布者应写入
iceoryx_management
段(内省发布者也是如此)
Alternative E: Introduce new StatusPort/ConfigPort/BroadcastPort
传统的发布者和订阅者没有针对发送不经常或从不更改的数据(例如参数、配置或内省数据)进行优化。在传统的发布者和订阅者被重新用作“StatusPort”的情况下,就像在备选方案D中一样,内存消耗很高,并且在某些情况下很少需要(比如启动)。因此,应引入一类新的端口,称为“StatusPort”。在内部,只能使用两个内存块,类似于“iox::concurrent::TACO”,使用ABA计数器检查作者是否在阅读时进行了写作(弗兰肯斯坦对象)。读者应将ServiceRegistryTopic从共享存储器复制到本地副本。仅支持可复制的琐碎数据。客户端数据不应直接访问,而应通过lambda访问。
Pro:
- “StatusPort”可用于在两个安全域(例如ASIL-B和ASIL-D)之间进行通信,因为订阅者只需要读取访问而不需要写入访问
- 重新使用“StatusPort”进行内省2.0、心跳/保持活动和发送静态配置
- 使用共享内存实现快速数据传输
- 无法替换“接口端口”
- 不仅传输服务注册表的增量,还传输完整的服务注册表信息
- 用于基于事件和同步请求的简单一致的用户API
- “findService”的筛选可以在新类中完成
Con:
- “findService”的筛选可以在新类中完成
- 新类,需要RouDi基础设施集成(例如请求此端口)
- 复制是必要的
- 如果编写器更新太频繁,而读取器从未完成读取,则可能会出现饥饿(这是一个常见的无锁问题,应通过良好的文档进行处理)