奥尔良 - 自定义 TCP 套接字连接
Orleans - Custom TCP Socket Connection
连接到 Orleans 服务器的正确方法是什么?
假设我有一个移动应用程序,我想从中连接到奥尔良服务器。
我应该直接连接到 Orleans 还是使用一些前端服务器(为什么?)
如果直接使用 Orleans Streams 或自定义套接字连接。
如果我不能使用 Orleans 客户端(和流),那么应该如何实现 grain 接受套接字连接。是否有可能因为谷物在不使用时会从内存中被逐出?
如果通过前端,前端本身是否需要是 grain?
一般来说,我认为建议使用某种 API(例如 REST、GRPC、..),然后通过客户端连接到筒仓。因此,您的 phone 应用程序访问 api,然后后者使用客户端访问 orleans 集群。
然而,还有一个托管客户端,但到目前为止我找不到有关此选项的更多信息。但是我在最新 RC 的发行说明中看到了它:
Hosted client that enables efficient hosting of frontend code within the silo process is now enabled by default.
https://github.com/dotnet/orleans/releases
更新:
我认为这是此功能的拉取请求:
https://github.com/dotnet/orleans/pull/3362
当您没有对客户端设备(例如移动应用程序)的完全安全控制时,最好通过 securable 前端向 Orleans 发出任何请求,例如 RESTful API,让客户忘记后端技术。
这是因为奥尔良消息系统不满足用户身份验证和授权要求。 Any Orleans 集群客户端可以在 any 时间调用 any grain any原因。如果您将 Orleans 集群开放给组织外部不受控制的通信,这将打开 Orleans 集群以进行安全攻击。
奥尔良集群最适合用作带围墙的花园 - 让一切都在里面流动,把一切都挡在外面。
以上并不意味着 API 必须在不同的进程中实施。 Orleans 可以与同一个进程中的 ASP.NET Core Kestrel 服务器共存。这就是托管客户端功能的用途,它允许进程内代码使用筒仓本身,就好像它是 Orleans 客户端一样,零额外配置。
但是,在向外界开放端口时,请将奥尔良留在围墙花园后面,同时打开 API 端口 和 应用用户身份验证和授权那里有规则。
将您的 Orleans 集群抽象为 API 还有其他好处,例如版本化端点、实施灵活性等,但那是另一回事了。
您有多种选择可以使用自定义 TCP 套接字将您的移动应用程序连接到 Orleans 集群。使用 Orleans 构建系统的方法有很多种,但为了简单起见,我将在此处提供三种模型:
奥尔良系统的中心部分是奥尔良集群。该集群包含许多 Orleans 筒仓,这些筒仓是进程,在生产中,您将在不同的主机上每个 运行 至少有三个筒仓。集群中的筒仓将相互通信以调用 grain 方法并维护集群,并且由于它们位于不同的主机上,因此通信将通过网络进行。
前端集群分离
连接您的移动应用程序的第一个选项是创建一组单独的前端主机,您的自定义 TCP 套接字服务将在其中执行。当套接字服务收到请求时,它使用 Orleans grain client 与 Orleans 集群通信。 grain 方法调用的代码看起来像一个简单的方法调用,但实际上调用是通过网络从前端发送到 Orleans 集群。
如果你想 "push" 从套接字服务器到移动应用程序,你还需要能够将消息从 Orleans 集群推送到前端。有两种方法可以做到这一点:
- 使用 grain observer
- 使用streams
我相信在某些时候流比观察者更受青睐,但我认为情况不再如此。一般来说,观察者稍微更容易使用,但观察者端的错误不会传播回集群,因此它本质上是一种即发即弃机制,而不是能够传播错误的流。
前端和集群同进程
当前端与 Orleans 集群分开托管时,您可以获得一些安全性,因为 Orleans 筒仓主机不会直接暴露在互联网上。但是,每个请求或推送消息都需要一个额外的网络跃点。为避免这种情况,您可以将筒仓与套接字服务组合到一个进程中,而不是拥有单独的前端和筒仓主机,您现在只有一个集群,它同时运行套接字服务和 Orleans。
但是,您必须克服一个问题。除非您使用 grain 客户端,否则您不能调用 grain,即使调用来自与 grain 相同的进程。幸运的是,现在存在一个托管客户端,它允许您从同一个进程但在孤岛之外进行 grain 调用,而无需使用通过网络发送数据的完整 grain 客户端。这是一个相当新的功能,我还没有见过 any documentation about how to use this yet。
筒仓充当套接字服务
无需使用 grain 客户端调用 Orleans 集群和 observers/streams 将消息发送出集群,您可以在集群中的 grain 中托管整个套接字服务。您需要实现一个能够充当自定义 TCP 套接字服务器的 grain。要启动此服务器,您需要使用 startup task 调用 RunAsync()
方法(或其他方法)来启动套接字服务器。
您可能希望这种 grain 的一个实例在每个筒仓中都处于活动状态。有多种方法可以实现这一目标。您可以使用 stateless worker 或者您可以使用放置策略来确保将套接字服务器颗粒放置在执行启动任务的筒仓中。基本思想是,当一个新的 silo 启动时,将执行一个启动任务,该任务确保所需的 grain 在 silo 中被激活。 Orleans 将删除不活动的 grains,因此您还必须确保套接字服务器 grains 永远不会停用。您可以在配置中或通过延迟 grain 内部的停用来执行此操作。
由于套接字服务器在 grain 中,您可以自由调用其他 grain 方法,而不必通过单独的 grain 客户端,而是可以使用 GrainFactory
属性套接字服务器粒度。如果您的套接字服务器要求您启动将使用 GrainFactory
的独立任务,您必须注意有关 grains and tasks.
的规则
如果您的 "custom TCP socket" 是一个网络套接字,并且您可以使用 .NET Core 构建您的系统,我建议您使用 ASP.NET Core 和 web sockets middleware(不是 SignalR)并使用使用Orleans hosted client分离前端主机或在前端和Orleans集群之间共享主机。
如果您要构建完整的自定义 TCP 套接字解决方案,您可能必须处理加密和身份验证。使用 Web 框架和 HTTPS 时,您可以开箱即用。 Orleans 可以帮助您进行加密密钥等的状态管理,这是可行的,但需要一些努力。我从实际经验中知道这一点。
连接到 Orleans 服务器的正确方法是什么?
假设我有一个移动应用程序,我想从中连接到奥尔良服务器。
我应该直接连接到 Orleans 还是使用一些前端服务器(为什么?)
如果直接使用 Orleans Streams 或自定义套接字连接。 如果我不能使用 Orleans 客户端(和流),那么应该如何实现 grain 接受套接字连接。是否有可能因为谷物在不使用时会从内存中被逐出?
如果通过前端,前端本身是否需要是 grain?
一般来说,我认为建议使用某种 API(例如 REST、GRPC、..),然后通过客户端连接到筒仓。因此,您的 phone 应用程序访问 api,然后后者使用客户端访问 orleans 集群。
然而,还有一个托管客户端,但到目前为止我找不到有关此选项的更多信息。但是我在最新 RC 的发行说明中看到了它:
Hosted client that enables efficient hosting of frontend code within the silo process is now enabled by default.
https://github.com/dotnet/orleans/releases
更新: 我认为这是此功能的拉取请求: https://github.com/dotnet/orleans/pull/3362
当您没有对客户端设备(例如移动应用程序)的完全安全控制时,最好通过 securable 前端向 Orleans 发出任何请求,例如 RESTful API,让客户忘记后端技术。
这是因为奥尔良消息系统不满足用户身份验证和授权要求。 Any Orleans 集群客户端可以在 any 时间调用 any grain any原因。如果您将 Orleans 集群开放给组织外部不受控制的通信,这将打开 Orleans 集群以进行安全攻击。
奥尔良集群最适合用作带围墙的花园 - 让一切都在里面流动,把一切都挡在外面。
以上并不意味着 API 必须在不同的进程中实施。 Orleans 可以与同一个进程中的 ASP.NET Core Kestrel 服务器共存。这就是托管客户端功能的用途,它允许进程内代码使用筒仓本身,就好像它是 Orleans 客户端一样,零额外配置。
但是,在向外界开放端口时,请将奥尔良留在围墙花园后面,同时打开 API 端口 和 应用用户身份验证和授权那里有规则。
将您的 Orleans 集群抽象为 API 还有其他好处,例如版本化端点、实施灵活性等,但那是另一回事了。
您有多种选择可以使用自定义 TCP 套接字将您的移动应用程序连接到 Orleans 集群。使用 Orleans 构建系统的方法有很多种,但为了简单起见,我将在此处提供三种模型:
奥尔良系统的中心部分是奥尔良集群。该集群包含许多 Orleans 筒仓,这些筒仓是进程,在生产中,您将在不同的主机上每个 运行 至少有三个筒仓。集群中的筒仓将相互通信以调用 grain 方法并维护集群,并且由于它们位于不同的主机上,因此通信将通过网络进行。
前端集群分离
连接您的移动应用程序的第一个选项是创建一组单独的前端主机,您的自定义 TCP 套接字服务将在其中执行。当套接字服务收到请求时,它使用 Orleans grain client 与 Orleans 集群通信。 grain 方法调用的代码看起来像一个简单的方法调用,但实际上调用是通过网络从前端发送到 Orleans 集群。
如果你想 "push" 从套接字服务器到移动应用程序,你还需要能够将消息从 Orleans 集群推送到前端。有两种方法可以做到这一点:
- 使用 grain observer
- 使用streams
我相信在某些时候流比观察者更受青睐,但我认为情况不再如此。一般来说,观察者稍微更容易使用,但观察者端的错误不会传播回集群,因此它本质上是一种即发即弃机制,而不是能够传播错误的流。
前端和集群同进程
当前端与 Orleans 集群分开托管时,您可以获得一些安全性,因为 Orleans 筒仓主机不会直接暴露在互联网上。但是,每个请求或推送消息都需要一个额外的网络跃点。为避免这种情况,您可以将筒仓与套接字服务组合到一个进程中,而不是拥有单独的前端和筒仓主机,您现在只有一个集群,它同时运行套接字服务和 Orleans。
但是,您必须克服一个问题。除非您使用 grain 客户端,否则您不能调用 grain,即使调用来自与 grain 相同的进程。幸运的是,现在存在一个托管客户端,它允许您从同一个进程但在孤岛之外进行 grain 调用,而无需使用通过网络发送数据的完整 grain 客户端。这是一个相当新的功能,我还没有见过 any documentation about how to use this yet。
筒仓充当套接字服务
无需使用 grain 客户端调用 Orleans 集群和 observers/streams 将消息发送出集群,您可以在集群中的 grain 中托管整个套接字服务。您需要实现一个能够充当自定义 TCP 套接字服务器的 grain。要启动此服务器,您需要使用 startup task 调用 RunAsync()
方法(或其他方法)来启动套接字服务器。
您可能希望这种 grain 的一个实例在每个筒仓中都处于活动状态。有多种方法可以实现这一目标。您可以使用 stateless worker 或者您可以使用放置策略来确保将套接字服务器颗粒放置在执行启动任务的筒仓中。基本思想是,当一个新的 silo 启动时,将执行一个启动任务,该任务确保所需的 grain 在 silo 中被激活。 Orleans 将删除不活动的 grains,因此您还必须确保套接字服务器 grains 永远不会停用。您可以在配置中或通过延迟 grain 内部的停用来执行此操作。
由于套接字服务器在 grain 中,您可以自由调用其他 grain 方法,而不必通过单独的 grain 客户端,而是可以使用 GrainFactory
属性套接字服务器粒度。如果您的套接字服务器要求您启动将使用 GrainFactory
的独立任务,您必须注意有关 grains and tasks.
如果您的 "custom TCP socket" 是一个网络套接字,并且您可以使用 .NET Core 构建您的系统,我建议您使用 ASP.NET Core 和 web sockets middleware(不是 SignalR)并使用使用Orleans hosted client分离前端主机或在前端和Orleans集群之间共享主机。
如果您要构建完整的自定义 TCP 套接字解决方案,您可能必须处理加密和身份验证。使用 Web 框架和 HTTPS 时,您可以开箱即用。 Orleans 可以帮助您进行加密密钥等的状态管理,这是可行的,但需要一些努力。我从实际经验中知道这一点。