1

背景

我们正在使用 Memcached 云在 Heroku 中使用 1 个 dyno 开发 Java 服务。

问题

同时我们正在开发和测试它,它工作正常。但是,当我们决定在真实环境中对其进行测试时,它开始返回以下错误:

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: Unable to create new native thread,但这不是我们的问题。我们检查了他们在那里所说的属性,但我们有很好的价值。但是,我可以看到每次初始化 memcached 时,它都会创建一个新线程,但是当服务停止时该线程不会被删除。有问题。

4

0 回答 0