带有 AMQP 的 Golang 中的 JSON RPC

Posted

技术标签:

【中文标题】带有 AMQP 的 Golang 中的 JSON RPC【英文标题】:JSON RPC in Golang with AMQP 【发布时间】:2019-03-25 02:08:15 【问题描述】:

我使用“github.com/streadway/amqp”通过队列(RabbitMQ)异步处理请求。

并且我使用“github.com/gorilla/rpc”注册我的服务而没有解决方法,但我必须使用丑陋的解决方案将 amqp.Delivery 转换为 http.Request(mux.Server 只能与 http.Request 一起使用) .

我可以为这项任务使用更优雅的解决方案吗?

我找不到 AMQP 的 JSON RPC 路由器。

【问题讨论】:

【参考方案1】:

首先,RPC 和 pub-sub(例如 AMQP)是两个非常不同的野兽;尝试使用一个来实现另一个不一定是错误或坏的,但这绝对是可疑的,并且暗示设计中的某个地方可能存在故障。因此,我强烈建议从您的业务目标开始重新考虑设计,并确保您尝试实现的实际上是实现所需功能的正确方法。

也就是说,您所描述的基本上是可能的,但是您想将抽象提升一个层次。试图通过 AMQP 发送http.Request 正在以一种只会导致更多问题的方式混合协议。实现这种行为的更简洁的方法是拥有一个处理http.Requests(正常)的HTTP处理程序和一个处理amqp.Deliverys(正常)的AMQP处理程序,并让这些处理程序中的每一个都调用一个共享业务仅处理您的域模型的逻辑处理程序。

因此,您的 HTTP 处理程序将解析 HTTP 请求并将其转换为域对象 - 您没有在问题中提供任何具体细节,所以我将发明类似 myapp.UserRegistration 的东西。您的 HTTP 处理程序会将其传递给 myapp.UserService,后者将处理注册用户的实际业务逻辑,它会返回一个结果,然后您将其转换为适当的类型,编组为 JSON,然后发送回客户端一个http.Responsemyapp.UserService 对 HTTP AMQP 一无所知;它在您自己的域类型上运行。

您的 AMQP 处理程序将获取一条消息,将其解析为相同的 myapp.UserRegistration 类型,将其传递给相同的 myapp.UserService 处理程序,并返回相同的响应 - 确保 AMQP 和 HTTP 的业务逻辑符合同样的方法。然后你会得到你的回应,而且……嗯,这是 AMQP,所以你不能向客户端发送回应。我不知道你的设置,也许你有另一个队列可以发送响应,也许你不关心响应并且可以丢弃它。这就是 RPC 和 AMQP 的区别最明显的地方。

这也使您的业务逻辑、HTTP 处理程序和 AMQP 处理程序更易于独立测试,因为您将协议逻辑与业务逻辑分开,即使您不尝试处理多个协议(即,即使您只使用 HTTP,这也不是一个坏主意)

我希望至少可以为您提供足够的信息,让您在实施过程中走上正确的轨道。祝你好运!

【讨论】:

我知道这看起来很疯狂,但我不知道什么是真正的方式。我只是使用这个rabbitmq.com/tutorials/tutorial-six-go.html 示例并尝试为 RPC 创建路由器。我必须识别 2 种类型的实体(学生和主题),将其存储到数据库并返回 ID。我有两种方法 - CreateStudent 和 CreateOrUpdateSubject(例如)。因此,我创建了解决方法来解决方法。也许,真正的方法是对每个任务使用不同的微服务?或者一个 MS 但听 2 个不同的队列。 哦,我想我找到了解决方案。我可以在“routing_key”字段中发送方法名称(本教程rabbitmq.com/tutorials/tutorial-four-go.html) @Adrian 总结得很好。看看 Go kitt 在其设计中的抽象。这与上述内容非常相关:gokit.io/faq/#design-mdash-how-is-a-go-kit-microservice-modeled

以上是关于带有 AMQP 的 Golang 中的 JSON RPC的主要内容,如果未能解决你的问题,请参考以下文章

AMQP Golang优先级不工作

饿了么:基于AMQP实现的golang消息队列MaxQ

golang Amazon S3使用AWS SDK for Go选择带有JSON的示例

无法使用带有 golang 的 mgo 检索“_id”值

并发之消息队列----基于AMQP实现的golang消息队列MaxQ

golang使用rabbitmqhelloworld