奥尔良 - 自定义TCP套接字连接

3

如何连接Orleans服务器?

假设我有一个移动应用程序,我想要连接到Orleans服务器。

我应该直接连接到Orleans还是使用一些前端服务器(为什么)?

如果直接连接,我应该使用Orleans Streams还是自定义Socket连接。如果不能使用Orleans客户端(和流),那么如何实现接受Socket连接的Grain?当Grain不被使用时,会从内存中清除吗?

如果通过前端连接,那么该前端是否需要成为一个Grain本身?

3个回答

9
您有多种选项来使用自定义TCP套接字将移动应用程序连接到Orleans集群。使用Orleans构建系统的方法有很多,但为了简单起见,在这里我将提供三个模型:
Orleans系统的核心部分是Orleans集群。集群包含许多Orleans silo,它们是进程,在生产环境中,您将至少有三个silos,每个silos在不同的主机上运行。集群中的silos将相互通信以调用谷物方法并维护集群,并且由于它们在不同的主机上,因此通信将通过网络进行。
第一个连接移动应用程序的选项是创建一组单独的前端主机,其中执行您的自定义TCP套接字服务。当套接字服务接收到请求时,它使用Orleans grain client与Orleans集群通信。谷物方法调用的代码看起来像一个简单的方法调用,但实际上该调用是从前端发送到Orleans集群的网络调用。
如果您想要从套接字服务器向移动应用程序推送消息,还需要能够从Orleans集群向前端推送消息。有两种方法可以做到这一点:

我认为在某些情况下,流比观察者更受青睐,但我不认为这还是现在的情况。总体而言,观察者稍微更容易使用,但观察者方面的错误不会向集群传播,因此它本质上是一种“发出并忘记”的机制,而流则能够传播错误。

前端和集群在同一个进程中

当前端与 Orleans 集群分开托管时,您可以获得一些安全性,因为 Orleans silo 主机不直接暴露于互联网。然而,每个请求或推送消息都需要额外的网络跳跃。为了避免这种情况,您可以将一个 silo 与一个 socket 服务组合成一个单独的进程,而不是拥有单独的前端和 silo 主机,现在您只有一个集群,它同时操作 socket 服务和 Orleans。

然而,您必须克服一个问题。即使呼叫来自与谷粒相同的进程,您也不能调用谷粒,除非使用谷粒客户端。幸运的是,现在存在一个托管的客户端,允许您在同一进程中但在Silo之外进行谷粒调用,而无需使用通过网络发送数据的完整谷粒客户端。这是一个相当新的功能,我还没有看到任何关于如何使用它的文档
作为Socket服务的Silo
您可以在聚合群集中托管整个套接字服务,而不是使用谷粒客户端调用Orleans群集并使用观察者/流将消息发送出群集。您需要实现能够充当自定义TCP套接字服务器的谷粒。要启动此服务器,您需要使用一个启动任务,该任务将调用RunAsync()方法(或其他方法)以启动套接字服务器。
您可能希望每个silo中都有这个grain的实例处于活动状态。有多种方法可以实现这一点。您可以使用无状态工作进程,也可以使用放置策略来确保套接字服务器grain位于执行启动任务的silo中。基本思想是当新的silo启动时,启动任务会执行,并确保所需的grain在silo中激活。Orleans将删除不活动的grains,因此您还必须确保套接字服务器grains永远不会停用。您可以在配置中或通过延迟grain内部的停用来实现此目的。
由于套接字服务器位于grain内部,因此您可以自由调用其他grain方法,而无需通过单独的grain客户端,而是可以使用套接字服务器grain的GrainFactory属性。如果您的套接字服务器要求您启动将使用GrainFactory的独立任务,则必须注意grains and tasks的规则。
如果您的“自定义TCP套接字”是Web套接字,并且您可以使用.NET Core构建系统,我建议您使用带有web sockets middleware(而不是SignalR)的ASP.NET Core,并使用单独的前端主机或通过使用Orleans托管的客户端在前端和Orleans集群之间共享主机。
如果您正在构建完整的自定义TCP套接字解决方案,则可能需要处理加密和身份验证。当使用Web框架和HTTPS时,您会得到这个开箱即用的功能。Orleans可以帮助您管理加密密钥等状态,并且这是可行的,但需要一些努力。我从实际经验中知道这一点。

2
当你无法完全控制客户端设备的安全性时,例如移动应用程序,最好通过可安全的前端(例如RESTful API)使任何请求通过Orleans,并使客户端对后端技术毫不知情。
原因是Orleans消息系统不满足用户身份验证和授权要求。任何Orleans集群客户端都可以随时为任何原因调用任何grain。如果您将其向组织外部的未受控制的通信开放,则会打开Orleans集群进行安全攻击。
Orleans集群作为一个有围墙的花园效果最佳-让所有东西在内部流动,阻止所有东西在外部。
上述并不意味着API必须在不同的进程中实现。Orleans可以与同一进程中的ASP.NET Core Kestrel服务器很好地共存。这就是托管客户端功能的作用,它允许进程内代码使用silo本身,就像它是Orleans客户端一样,而不需要额外的配置。
但是,当涉及到向外界打开端口时,请将Orleans置于有围墙的花园后面,同时打开API端口并在那里应用用户身份验证和授权规则。
将Orleans集群抽象化到API后面还有其他额外好处,例如版本化的端点、实现灵活性等,但那是另一个故事。

虽然我理解并同意你的担忧,但我认为几乎不可能创建一个系统,在该系统中谷物客户端在移动设备上执行,并直接通过互联网调用Orleans集群。客户端与集群紧密耦合,根据集群状态存储方式的不同,客户端将访问此存储以了解有关矽仓库(如其IP地址等)的信息。要能够做到这一点,需要在客户端上进行额外的努力,该客户端还应该使用.NET构建。您必须非常努力才能走出“围墙花园”。 - Martin Liversage

0
通常建议使用某种API(例如REST,GRPC等)连接客户端与silo。因此,您的手机应用程序访问API,然后使用客户端访问orleans集群。
但是,也有托管客户端,但到目前为止我找不到更多关于此选项的信息。但我在最新RC的发布说明中看到了它:
“启用了托管客户端,可有效地在silo进程内托管前端代码。”

https://github.com/dotnet/orleans/releases

更新: 我认为这是实现此功能的拉取请求: https://github.com/dotnet/orleans/pull/3362

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接