【问题标题】:how to create a connection pool/only once for a third party Application?如何为第三方应用程序创建一个连接池/只创建一次?
【发布时间】:2019-03-19 08:11:17
【问题描述】:

我正在使用 JAVA/Spring MVC,我需要在我的应用程序中为第三方应用程序集成创建一个连接池,因为当我尝试多次连接它时,我的应用程序和服务器系统会占用 100% 的 RAM。

这里我有一个问题,当用户开始多次点击特定方法(callGenerationService())时,我的堆内存(RAM 空间)增加并变为 100%,应用程序会因为连接第三方应用程序而变慢次?在这里我只需要创建一个connection 并多次获取它。我的联系方式,

public class ClickToCallServiceImpl implements ClickToCallServiceInterface {
Client client = null;
@Override
public ClickToCall callGenerationService(ClickToCall clickToCall) {
     client = new Client();
     client.connect("127.0.0.1", 8021 , "password", 10); //Every time Connection Connect.
     client.setEventSubscriptions("plain", "all");
     // client.sendSyncApiCommand("",""); //here i run command on every hit like.
    client.sendSyncApiCommand(clickToCall.command1, clickToCall.command2);
    client.close();
}
}

这里的 'ClickToCall' 是一个带有变量 setter 和 getter 的 @Component Bean/POJO 类。

在那里,我们如何为上述连接创建一个connection (either pool or only once connect),我只连接一次并多次点击clickToCall.Command1 and clickToCall.Command2并使用更少的RAM?提前致谢。

【问题讨论】:

  • 客户端是任何库类还是你自己的?
  • 这是属于Freeswitch ESL技术的库类
  • 是 org.freeswitch.esl.client.inbound.Client 吗?
  • 是的,它是 org.freeswitch.esl.client-0.9.2.jar
  • 您可以使用commons pool 来创建自己的池here 您可以找到一些示例。无论如何,您确定在发送命令后关闭并释放资源?

标签: java spring spring-mvc connection-pooling


【解决方案1】:

请注意,我不是 freeswitch esl 专家,因此您必须正确检查代码。无论如何,这就是我会做的。

首先我为客户创建一个工厂

public class FreeSwitchEslClientFactory extends BasePooledObjectFactory<Client> {

    @Override
    public Client create() throws Exception {
        //Create and connect: NOTE I'M NOT AN EXPERT OF ESL FREESWITCH SO YOU MUST CHECK IT PROPERLY
        Client client = new Client();
        client.connect("127.0.0.1", 8021 , "password", 10);
        client.setEventSubscriptions("plain", "all");
        return client;
    }

    @Override
    public PooledObject<Client> wrap(Client obj) {

        return new DefaultPooledObject<Client>(obj);
    }
}

然后我创建一个可共享的GenericObjectPool

@Configuration
@ComponentScan(basePackages= {"it.olgna.spring.pool"})
public class CommonPoolConfig {

    @Bean("clientPool")
    public GenericObjectPool<Client> clientPool(){
        GenericObjectPool<Client> result = new GenericObjectPool<Client>(new FreeSwitchEslClientFactory());
        //Pool config e.g. max pool dimension
        result.setMaxTotal(20);
        return result;
    }
}

最后我使用创建的池来获取客户端 obj:

@Component
public class FreeSwitchEslCommandSender {

    @Autowired
    @Qualifier("clientPool")
    private GenericObjectPool<Client> pool;

    public void sendCommand(String command, String param) throws Exception{
        Client client = null;
        try {
            client = pool.borrowObject();
            client.sendSyncApiCommand(command, param);
        } finally {
            if( client != null ) {
                client.close();
            }
            pool.returnObject(client);
        }
    }
}

我没有测试(也因为我不能),但它应该可以工作。无论如何,我祈祷您正确检查配置。我不知道总是创建一个 Client 对象并连接是否可以,或者当你想发送命令时连接是否更好

希望对你有用

编辑信息

对不起,我早早犯了错误。您必须将客户端返回到池中 我更新了我的 FreeSwitchEslCommandSender 类

安杰洛

【讨论】:

  • 您好,@AngeloImmedia 感谢分享这个游泳池概念,它对我来说很好,也清楚了我关于游泳池的概念。非常感谢..
  • 你能在这里解释一下吗pool.returnObject(client);?谢谢。
  • 基本上它将客户端实例返回到池中,以便此实例可用于其他调用。 commons.apache.org/proper/commons-pool/apidocs/org/apache/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
相关资源
最近更新 更多