Нагрузка на LongPoll сервер VK API

338
20 марта 2017, 07:57

Здравствуйте,
из-за большой нагрузки, пару-тройку сотен в минуту, (да-да, она действительно такая и даже больше, в зависимости от времени суток), LongPoll сервер ВК выдает ошибку:

{"failed":1,"ts":<new_ts>}

Означает эта ошибка следующее: —

история событий устарела или была частично утеряна, приложение может получать события далее, используя новое значение ts из ответа.


И дело в том, что бот работает минуты 2-3, и начинает выпадать эта ошибка, причина её в следующем: перед отправкой сообщения, бот проверял (отправляя запрос), состоит ли пользователь в группе, поскольку сообщений было по несколько в секунду, запросов было очень много, и отвечал он на них после того, как обработал ответ на запрос по проверке пользователя, из-за этого "устаревала либо частично терялась" история событий. Потом я убрал эту проверку - бот продержался минут 20, и затем упал по какой-то непонятной причине с кучей строчек:

    at com.vk.api.sdk.httpclient.HttpTransportClient.post(HttpTransportClient.java:170)
    at com.vk.api.sdk.client.ApiRequest.executeAsString(ApiRequest.java:95)
    at com.vk.api.sdk.client.ApiRequest.execute(ApiRequest.java:59)
    at LongPollHandler.run(LongPollHandler.java:180)
Caused by: java.net.SocketTimeoutException: connect timed out
    at java.net.DualStackPlainSocketlmpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketlmpl.socketConnect(Unknown Source)
    at java.net.AbstractPlainSocketlmpl.doConnect(Unknown Source)
    at java.net.AbstractPlainSocketlmpl.connectToAddress(Unknown Source)
    at java.net.AbstractPlainSocketlmpl.connect(Unknown Source)
    at java.net.PlainSocketlmpl.connect(Unknown Source)
    at java.net.SocksSocketlmpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSL ConnectionSocketFactory.java:337)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect (DefaultHttpClientConnectionOperator.java:141)
    ... 15 more
com.vk.api.sdk.exceptions.ClientException: I/O exception
    at com.vk.api.sdk.client.ApiRequest.executeAsString(ApiRequest.java:98)
    at com.vk.api.sdk.client.ApiRequest.execute(ApiRequest.java:59)
    at LongPollHandler.run(LongPollHandler.java:180)

Из строчек моего кода, которые упоминаются в этой ошибке, только LongPollHandler.java:180, в которой лишь содержится следующий запрос:

int album_size = new JSONObject(vk.photos().get().ownerId(id страницы с альбомами).albumId(id альбома).getInt("count");

То есть, мы находим длину альбома по его id. Остальные строчки говорят о чём-то, что я не понимаю. Полный лог ошибки не особо предоставляется возможным получить, ибо опять же, запросов много и он на каждый отвечает ошибкой, уловить кусок, который тоже дается не полностью, не получится.

Вопрос: как ослабить нагрузку? Дело в том, что если перезапустить приложение, бот опять работает, но до новых ошибок. Возможно как-то перераспределить эти запросы? Или что-то ещё сделать, чтобы в таком случае, одну часть получаемых ответов обрабатывало одно приложение или поток, другую часть - другое, и чтобы приложение не падало с непонятными ошибками или из-за нагрузки?
Буду очень благодарен.

UPDATE: Сейчас словил ещё одну ошибку:

java.net.SocketTimeoutException: timeout
        at okio.Okio$4.newTimeoutException(Okio.java:227)
        at okio.AsyncTimeout.exit(AsyncTimeout.java:284)
        at okio.AsyncTimeout$2.read(AsyncTimeout.java:240)
        at okio.RealBufferedSource.indexOf(RealBufferedSource.java:325)
        at okio.RealBufferedSource.indexOf(RealBufferedSource.java:314)
        at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:210)
        at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:185)
        at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:126)
        at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:707)
        at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:81)
        at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:692)
        at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:547)
        at okhttp3.RealCall.getResponse(RealCall.java:242)
        at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:199)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:161)
        at okhttp3.RealCall.execute(RealCall.java:57)
        at Connection.getLongPollResponse(Connection.java:44)
        at LongPoll.getLongPollHistory(LongPoll.java:7)
        at LongPollHandler.run(LongPollHandler.java:92)
Caused by: java.net.SocketTimeoutException: Read timed out
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(Unknown Source)
        at java.net.SocketInputStream.read(Unknown Source)
        at java.net.SocketInputStream.read(Unknown Source)
        at sun.security.ssl.InputRecord.readFully(Unknown Source)
        at sun.security.ssl.InputRecord.read(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
        at sun.security.ssl.AppInputStream.read(Unknown Source)
        at okio.Okio$2.read(Okio.java:138)
        at okio.AsyncTimeout$2.read(AsyncTimeout.java:236)
        ... 16 more
java.lang.NullPointerException
        at java.io.StringReader.<init>(Unknown Source)
        at org.json.JSONTokener.<init>(JSONTokener.java:85)
        at org.json.JSONObject.<init>(JSONObject.java:319)
        at LongPollHandler.run(LongPollHandler.java:92)

LongPollHandler.java:92

JSONObject response = new JSONObject(longPoll.getLongPollHistory(server, key, ts));

Метод VK SDK, аналогичный этому: документация VK. Тут, вроде, можно догадаться, что слишком долго приложение ожидало ответ от LongPoll-сервера. Либо я ошибаюсь. Но та ошибка, что выше, всё равно для меня не понятна.

READ ALSO
Интерфейс CharSequence и его методы

Интерфейс CharSequence и его методы

Имеем interface CharSequenceДанный интерфейс содержит в себе следующие методы:

283
из java/c# в Delphi [требует правки]

из java/c# в Delphi [требует правки]

ПриветЕсть необходимость перевести данный ниже код в Delphi

494
Поиск существующего фрагмента

Поиск существующего фрагмента

В активити создаю фрагменты frag1,frag2Сохраняю идентификатор frag2:

245
Как запускать единственный экземпляр Activity из Fragment?

Как запускать единственный экземпляр Activity из Fragment?

Имеется класс Home extends Activity с NavigationDrawer в нёмЧерез displayView создаю Fragment'ы в зависимости от нажатия элемента

241