我有以下使用模式,我想知道是否有已知的方法来处理它。
假设我有一个网站,用户可以建立一个查询来运行它对远程数据库。远程数据库是安全的,用户无法访问它。因此,查询将是这样的:SELECT * FROM myTable
将被发送到我们的web服务器,我们的web服务器将查询另一台服务器上的远程DB,接收结果并在HTTP响应中传递它们。所以,流程是:
- Location1 (Europe):用户/浏览器提交包含SQL查询的HTTP POST。
- Location2 (US): HTTP Server收到请求,对数据库运行SQL
- Location3 (Asia):数据库运行查询,返回数据
- Location2 (US): HTTP Server收到SQL resultset返回。发送响应。
- Location2 (US): HTTP Server收到请求,对数据库运行SQL
- Location1 (Europe):用户/浏览器在渲染的网页中接收回数据。
假设我没有控制这三个位置,我们可以看到,如果结果集的大小很大,可能会有很多数据传输延迟。我想知道是否有任何方法可以做像下面这样的事情,如果有的话,它是如何做到的:
- Location1 (Europe):用户/浏览器提交包含SQL查询的HTTP POST。
- Location2 (US): HTTP服务器接收请求,立即返回QueryID,对数据库异步运行SQL。
- Location3 (Asia) Database runs query
- Location2 (US): HTTP服务器接收请求,立即返回QueryID,对数据库异步运行SQL。
- Location1 (Europe):用户/浏览器从数据库接收响应。(如何?它不能直接从DB)
总结一下,如果我们假设结果集的大小为50MB,在第一种情况下,50MB将从:
Asia (DB) -> US (Server) -> Europe (Client)
在第二种情况下,它将从
Asia (DB) -> Europe (Client)
您可以将身份验证与授权解耦,以便在浏览器、HTTP服务器和数据库这三个实体之间建立更灵活的连接。
要使第二个示例工作,您可以这样做:
- HTTP服务器(US)向DB (Asia)异步提交查询,并为其请求一个验证令牌
- 当查询正在运行时,HTTP服务器(美国)将验证令牌发送回浏览器(欧洲)。
- 浏览器(欧洲)现在使用认证令牌发起对数据库(亚洲)的第二次HTTP调用,也可能使用queryID。
- DB可能需要实现一个简单的令牌验证协议。它应该:
- 验证传入的授权令牌
- 检索会话
- 开始将查询结果集流式传输回呼叫方。
对于DB服务器,有很多开箱即用的精简docker映像可以在几秒钟内实现授权服务器,并且可以使用nginx侦听浏览器。
如你所见,架构是可以算出来的。但是,亚洲的DB服务器需要进行改造以实现某种令牌授权。最简单和广泛的策略是使用OAuth2,这是目前最流行的。
基于@TheImpalers的答案:
如何添加另一个表到您的远程数据库,只是为了检索查询结果?
当客户端请求后端服务进行数据库查询时,后端服务将生成一个UUID或其他安全令牌,并告诉DB运行查询并将其存储在给定的UUID下。后端服务还将UUID返回给客户端,然后客户端可以直接从DB检索相关数据。
TLDR:
Europe (Client) -> US (Server) -> Asia (Server) -> Asia (DB)
在亚洲打开一个HTTP服务器(如果没有访问相同的DC/服务器-租一个不同的),然后从HTTP美国重定向请求->HTTP Asia,将连接本地数据库&流化响应。
重定向可以是公共重定向(302)或VPN上的私有代理,如果你关心延迟&有这样的可能性。
前端直接与DB对话并不是一个很好的模式,因为你不能做任何你长期需要的中间件操作(破坏更改,分析,授权,重定向,速率限制,可伸缩性…)
如果你的SQL很重&你不能用长时间的TCP连接同步请求,在websocket服务器上设置流(也在亚洲)。