构建具有高可扩展性的RESTful API

huangapple go评论103阅读模式
英文:

Building a RESTful API with high scalability

问题

我正在寻找构建一个RESTful API,该API将负责根据多个移动应用程序发送的数据插入数据(存储在Amazon Redshift数据库中)。

我已经开发了一个API,你可以在这里找到:https://github.com/Noeru14/fms。它使用了Gin:https://github.com/gin-gonic/gin。如果我打开了太多的并行连接,它以前会崩溃/无法正常工作。

我的一个朋友提到可以使用Node,因为它可以实现非常短的客户端-服务器交互。

我想知道在使用Go和Node构建一个能够处理每秒数十万个请求的RESTful API时需要考虑哪些因素。你还知道在Golang中是否可行吗?

非常感谢。

英文:

I'm looking to build a RESTful API that would be in charge of inserting datas based on the data sent by multiple mobile apps (stored in an Amazon redshift database).

I've already developed an API that you can find here: https://github.com/Noeru14/fms. It uses Gin: https://github.com/gin-gonic/gin. If I opened too many parallel connections, it used to crash / not work properly.

A friend of mine has talked about using Node instead as it allows to have really short client-server interaction.

I'd like to know which factors I'd have to take into account to build a RESTful API that could handle up to hundreds of thousands requests per second with Go and Node. Do you also know if it's doable in Golang ?

Thanks a lot.

答案1

得分: 5

这在Go语言中是可行的,在Node.js中也是可行的。在其他语言中,比如Erlang或Python,也是可行的。但既然你问的是Node.js,那我就回答关于Node.js的部分。

在Node.js中,实现高并发的最重要的一点是永远不要阻塞事件循环或进行任何阻塞操作(除非是事件循环的第一个刻度)。这是人们经常犯的错误,破坏并发性能的头号问题,比如偶尔使用一个看似无害的fs.statSync()(在Stack Overflow的这个回答中有一些这样的错误示例)。在第一个刻度之后使用任何阻塞操作(包括长时间运行的forwhile循环)都是错误的,实际上我认为它应该抛出异常。

另一个可能在某些情况下不是明显错误但仍可能影响可扩展性的问题是在应用程序中存储任何状态。如果你需要有任何持久状态(并尽量最小化这种需求),那么你应该使用数据库来存储。对于需要快速共享的数据,比如会话数据,你应该使用像Redis这样的快速数据库,但前提是你不能通过其他方式(比如JWT等)实现相同的功能。

更倾向于水平扩展而不是垂直扩展,因为在某个点上,服务器将不再变得更大,但总是可以增加更多的服务器。

总结一下:

  1. 永远不要阻塞事件循环。
  2. 将所有需要大量计算的操作放在外部进程中进行。
  3. 永远不要阻塞事件循环。
  4. 使用Redis或Memcached来共享状态。
  5. 永远不要阻塞事件循环。
  6. 使用集群来实现水平扩展。
  7. 永远不要阻塞事件循环。

我有提到永远不要阻塞事件循环吗?

英文:

It is doable in Go and it is doable in Node. It is doable in other languages like Erlang or Python as well. But since you're asking about Node then this is what I'll answer about.

The most important thing for high concurrency in Node is to never block the event loop or do any blocking operation ever (unless it's the first tick of the event loop). This is the number one thing that people do and ruin the concurrency - like putting a little innocent-looking fs.statSync() now and then (see this answer for examples of such mistakes right in the answers on Stack Overflow). Using any blocking operation (including long running for or while loop) after the first tick is always a mistake and in fact I think it should throw exceptions.

Another thing that while not being an outright mistake in all situations may still harm the scalability is storing any state in your application. If you need to have any persistent state (and try to minimize that need at all cost) then you should use a database for that. For data that needs to be shared between requests quickly like session data you should use a fast database like Redis, but only if you cannot achieve the same with things like JWT etc.

Prefer horizontal instead of vertical scalability, because at some point there will be no bigger server, but there will always be more servers.

To sum it up:

  1. Never block the event loop
  2. Do all CPU-heavy computations in external processes
  3. Never block the event loop
  4. Use Redis or Memcached for shared state
  5. Never block the event loop
  6. Use clustering for horizontal scalability
  7. Never block the event loop

Did I mention never blocking the event loop?

答案2

得分: 1

首先,使用"net/http"包可以实现一个简单的路由器,甚至可以使用自定义中间件(如身份验证),使用路由框架进行简单路由不是很高效。而且,你可以设计应用程序以支持多个实例在多个服务器上运行。

这是我在Go语言中的一个示例:https://github.com/efimovalex/EventKitAPI/tree/master/consumerapi,它使用了一个内存中的工作池。

英文:

First of all using the "net/http" package has everything you need to impelement a simple router and even custom middlewares (like auth), using routing frameworks for simple routing is not very efficient. And you could design the application to support multiple instances on multiple servers.

Here is an example of mine in Go: https://github.com/efimovalex/EventKitAPI/tree/master/consumerapi that uses an in memory worker pool

huangapple
  • 本文由 发表于 2017年4月4日 18:55:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/43205224.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定