我计划提供两项服务。用 Ruby 编写的 HTTP REST 服务用 Go 编写的 JSON RPC 服务Ruby 服务将打开一个到 Go JSON RPC 服务的 TCP 套接字连接。它将为收到的每个传入 HTTP 请求执行此操作。它将通过套接字向 Go 服务发送一些数据,该服务随后将相应的数据发送回套接字。去代码Go 服务 go 看起来像这样(简化):srv := new(service.App) // this would expose a Process methodrpc.Register(srv)listener, err := net.Listen("tcp", ":8080")if err != nil { // handle error}for { conn, err := listener.Accept() if err != nil { // handle error } go jsonrpc.ServeConn(conn)}请注意,我们使用 goroutine 为传入连接提供服务,因此我们可以并发处理请求。红宝石代码下面是一段简单的 Ruby 代码片段,它演示了(理论上)我将数据发送到 Go 服务的方式:require "socket"require "json"socket = TCPSocket.new "localhost", "8080"b = { :method => "App.Process", :params => [{ :Config => JSON.generate({ :foo => :bar }) }], :id => "0"}socket.write(JSON.dump(b))response = JSON.load socket.readline我担心的是:这会是一个安全的事件序列吗?我不是在问这是否是“线程安全的”,因为我不担心跨 go 例程操纵共享内存。我更关心我的 Ruby HTTP 服务是否会取回它期望的数据?如果我有两个并行请求进入我的 HTTP 服务(或者 Ruby 应用程序托管在负载均衡器之后,因此HTTP 服务的不同实例正在处理多个请求),那么我可以让实例 A 将消息 Foo 发送到 Go服务; 而实例 B 发送消息 Bar。Go 服务内部的业务逻辑将根据其输入返回不同的响应,因此我想确保 Ruby 实例 A 为 Foo 返回正确的响应,而 B 为 Bar 返回正确的响应。我假设套接字连接更像是一个队列,因为如果实例 A 先向 Go 服务发出请求,然后B 这样做,但 B 无论出于何种原因响应更快,那么 Go 服务会将 B 的响应写入套接字并且 Ruby 应用程序的实例 A 最终将读取错误的套接字数据(这显然只是一种可能的情况,因为我可能很幸运并且让实例 B 在实例 A 之前读取了套接字数据)。解决方案?我不确定这个问题是否有简单的解决方案。除非我不使用 TCP 套接字或 RPC 而是依赖 Go 服务中的标准 HTTP。但我想要 TCP 的性能和更少的开销。我担心设计可能会变得更加复杂,因为可能必须实现一个外部队列作为与 Ruby 服务同步响应的一种方式。可能是因为我的 Ruby 服务本质上是同步的(HTTP 响应/请求),所以我别无选择,只能为 Go 服务切换到 HTTP。但是我想先与社区进行仔细检查,以防万一我遗漏了一些明显的东西。
- 1 回答
- 0 关注
- 175 浏览
添加回答
举报
0/150
提交
取消
