Threads Ошибка Облако Memcached Heroku Java

Фон

Мы разрабатываем сервис Java в Heroku с 1 dyno, который использует облако Memcached.

Проблема

Тем временем мы разрабатывали и тестировали его, он работал нормально. Однако, когда мы решили протестировать его в реальной среде, он начал возвращать следующую ошибку:

java.lang.OutOfMemoryError: unable to create new native thread java.lang.Thread.start0(Native Method) java.lang.Thread.start(Thread.java:717) net.spy.memcached.MemcachedConnection.<init>(MemcachedConnection.java:306) net.spy.memcached.DefaultConnectionFactory.createConnection(DefaultConnectionFactory.java:209) net.spy.memcached.MemcachedClient.<init>(MemcachedClient.java:209) Memcached.<init>(Memcached.java:34) Main.lambda$main$1(Main.java:101) spark.SparkBase$1.handle(SparkBase.java:311) spark.webserver.MatcherFilter.doFilter(MatcherFilter.java:159) spark.webserver.JettyHandler.doHandle(JettyHandler.java:60)
org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:179)
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136) org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) org.eclipse.jetty.server.Server.handle(Server.java:451) org.eclipse.jetty.server.HttpChannel.run(HttpChannel.java:252) org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:266)
org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:240)
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:596)
org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:527) java.lang.Thread.run(Thread.java:748)

У нас не было так много клиентов, чтобы достичь 256 процессов или потоков (ограничение 1 dyno).

Временное решение

Мы еще этого не знаем

Код <!--Main--> //... try { memcached = new Memcached (); } catch (Exception e) { memcached = null; } //...

<!--Memcached-->
public class Memcached {
private MemcachedClient memcachedClient;
private boolean connected;

public Memcached () throws Exception {
    setConnected(true);

    try {
        AuthDescriptor ad = new AuthDescriptor(new String[] { "PLAIN" },
                new PlainCallbackHandler(System.getenv("MEMCACHEDCLOUD_USERNAME"),
                    System.getenv("MEMCACHEDCLOUD_PASSWORD")
                )
        );

        setMemcachedClient(new MemcachedClient(
                new ConnectionFactoryBuilder()
                        .setDaemon(true)
                        .setFailureMode(FailureMode.Retry)
                        .setProtocol(ConnectionFactoryBuilder.Protocol.BINARY) //this is the line 34 
                        .setAuthDescriptor(ad).build(),
                AddrUtil.getAddresses(System.getenv("MEMCACHEDCLOUD_SERVERS"))
        ));
    } catch (Exception ex) {
        // the Memcached client could not be initialized
        setConnected(false);
        throw new Exception ("{\"ErrorCode\":20,\"Portal\":\"Memcached\",\"ResponseCode\":\"\",\"Message\":\""
                + ex.getMessage() + "\"}");
    }
}

public String get (String service, String fromCurrency, String toCurrency) {
    if (!isConnected()) {
        return null;
    }

    try {
        return (String) getMemcachedClient().get(service + ";" + fromCurrency + ";" + toCurrency);
    }
    catch (Exception e) {
        return null;
    }
}

public boolean set (String service, String fromCurrency, String toCurrency, String value) {
    if (!isConnected()) {
        return false;
    }

    try {
        double hour = Double.parseDouble(System.getenv("TIME_CACHE_HOUR"));
        getMemcachedClient().set(service + ";" + fromCurrency + ";" + toCurrency, (int)(60 * 60 * hour), value);

        return true;
    }catch (Exception e) {
        return false;
    }
}

public boolean isConnected () {
    return this.connected;
}

private void setConnected (boolean connected) {
    this.connected = connected;
}

private MemcachedClient getMemcachedClient () {
    return this.memcachedClient;
}

private void setMemcachedClient (MemcachedClient memcachedClient) {
    this.memcachedClient = memcachedClient;
}

Кто-нибудь знает, как мы можем исправить эту ошибку?

РЕДАКТИРОВАТЬ: я прочитал сообщение Java: невозможно создать новый собственный поток, но это не наша проблема. Мы проверили атрибуты, которые они там сказали, но у нас есть хорошие значения. Однако я мог видеть, что каждый раз, когда инициализируется memcached, создается новый поток, но этот поток не удаляется при остановке службы. Вот в чем проблема.


person Manwelanza    schedule 20.02.2018    source источник
comment
Возможный дубликат Java: невозможно создать новый собственный поток   -  person codefinger    schedule 20.02.2018
comment
Как я уже писал в своем EDIT, этот пост не решает нашу проблему. Тем не менее, спасибо, мы могли видеть реальную проблему благодаря этому, но мы не знаем, как это исправить.   -  person Manwelanza    schedule 21.02.2018