0

我正在开发一个 RESTful API,并且我已经实现了 OAuth 2.0 授权。

我所有的客户都通过 SSL 发出请求,在 Authorization 标头中传递不记名令牌:

Authorization: Bearer sdflksd3r4823vgbyerge

目前我正在 Postgres 中保存访问令牌和刷新令牌,因此在每个请求中,服务器都必须连接到数据库并执行 SELECT 查询。'tokens' 表包含大约一百万行,所以性能不是很好,即使表被索引......我也认为在每个请求上检查令牌有效性是相当浪费时间的。

我们的令牌现在只是数据的随机字节。我们考虑使用自编码令牌,这样令牌就可以在没有数据库查找的情况下进行解码和验证,但问题是令牌必须可以从用户那里撤销,所以这不是一个解决方案。

我有哪些选择?

我正在考虑使用Redis而不是 Postgres:读取应该快得多。另一种选择可能是检查令牌有效性,将响应缓存在 Memcached 中 15 分钟,因此后续请求不需要数据库查找。

有任何想法吗?

4

2 回答 2

3

我试着轻轻地刺激一些真实的数字。由于您不准备说出您的“ec2 微型实例”在可用的 GHz/RAM/磁盘 I/O 方面实际上有什么,我们将不得不以另一种方式尝试。

CREATE TABLE tokens(tok text, username text);
INSERT INTO tokens SELECT md5(i::text), 'User number ' || i FROM generate_series(1,1000000) i;
SELECT * FROM tokens WHERE username LIKE '%01' LIMIT 19;
-- Now check the timings on some of returned tokens
EXPLAIN ANALYSE SELECT username FROM tokens WHERE tok = '38b3eff8baf56627478ec76a704e9b52';
                                                 QUERY PLAN                                                      
---------------------------------------------------------------------------------------------------------------------
 Index Scan using tokens_pkey on tokens  (cost=0.42..8.44 rows=1 width=18) (actual time=0.099..0.101 rows=1 loops=1)
   Index Cond: (tok = '38b3eff8baf56627478ec76a704e9b52'::text)
 Total runtime: 0.133 ms
(3 rows)

如您所见 - 我的运行速度如此之快,以至于时间可能毫无意义。如果我在乎的话,我会从 10 个并行进程中运行 10000 个,并随机等待。我没有——它不到 1 毫秒,即使在我期望的最慢的虚拟机上也小于 5 毫秒。

那么-您的应用程序有问题吗?不能说 - 你没有提供细节。

是你的框架吗?不能说——你不会说。

是连接时间吗?说不出来...

是查询本身吗?说不出来...

不过,PostgreSQL使用索引从 100 万行的小表中读取单行的任何问题都不是问题。

祝你好运!

于 2013-11-14T18:45:31.487 回答
1

请注意,令牌上应该有一个索引,Richard 的回复省略了该索引。在创建索引之前,我的查询运行时间约为 200 毫秒。创建索引后,它下降到 0.1 毫秒。(对不起,我会直接评论他的帖子,但我没有足够高的分数)。

于 2014-02-11T00:58:01.650 回答