3

我正在尝试使用 java 在 twitter4j 之上构建到 twitter 的连接器。Twitte4j 没有处理并希望您处理的问题之一是速率限制问题。

我使用 Twitter4j 充分利用 twitter api 的方法是在其上构建多个线程。我的推文转储只有推文 ID 和用户 ID 的用户在我的数据库中,我需要我的推特线程来查询推特并在新信息流入它们时更新这些表。所以,我构建了两个不同的线程,一个更新用户表,一个更新推文表。用户更新线程相当容易做到,因为 twitter 支持一次查询多达 100 个用户(用户/查找)。但是,推文线程一次只支持一个(推文/节目)。所以,我有我的“推文更新”线程,再启动 5 个线程,其中每个线程去查询 twitter 并一次更新一个帖子。这就是 ratelimit 发挥作用的地方。所以,任何时候,我有 6 个线程正在运行并查询 TwitterService(我的服务类)。这些线程在查询之前总是检查是否达到了速率限制,如果是,它们进入睡眠模式。所以线程调用的服务方法如下所示:

private synchronized void checkRateLimitStatus() {
        if (rateLimitHit) {
            try {
                logger.warn("RateLimit has been reached");
                wait(secondsUntilReset * 1000);
                rateLimitHit = false;
                secondsUntilReset = 0;

            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
            notifyAll();
        }
    }

布尔 rateLimitHit 由 Twitter4J 侦听器设置,它检查剩余的请求数。一旦计数为零,此布尔值设置为真。代码如下所示:

public synchronized void onRateLimitStatus(RateLimitStatusEvent evt) {
                RateLimitStatus status = evt.getRateLimitStatus();
                if (status.getRemainingHits() == 0) {
                    rateLimitHit = true;
                    secondsUntilReset = status.getSecondsUntilReset();
                }

            }

这个问题是,比如说,我还有 3 个查询留给 Twitter,并且方法 checkRateLimitStatus() 将为所有 6 个查询返回 false(因为它尚未设置)。因此,所有线程都开始了,因为计数还不是零。但是,当前 3 个线程使用 Twitter 完成时,计数将达到零,其余三个线程失败。

我该如何解决这个问题?如何使这些线程更可靠?

4

1 回答 1

1

假设获取速率限制状态是基于与其他操作相同的 Twitter 消息传递,那么总会有一个滞后,这使得任何通过检查此状态来带来可靠性的尝试都失败了。除非您以同步方式操作,否则状态总是有可能过时。我建议您尝试在本地计算速率限制状态并使所有线程自恢复以防出错。从浪费 CPU 时间的角度来看,对于任何可重复的操作,使用等待/通知机制也是一个好点。

于 2012-06-09T09:21:59.927 回答