0

オブジェクトを(正常に)プールに戻す方法について少し混乱しています。私はrabbitmq用のチャネルのプールを作成することをテストしています(これはrabbitmqとは特に関係ありません)。rabbitmq のプロセスは、サーバーへの接続を作成してからチャネルを作成することです。チャネルを作成してプールの一部を使用しようとしていますが、新しいチャネルを作成し続け、古いチャネルを再利用していないようです。これは、rabbit の Web UI を確認すると、キューにアイテムがあるのと同じ数のチャネルがあると表示されますが、アップロード速度は 1 秒あたり約 10,000 メッセージであるため、その範囲のチャネルしかないと予想されるため、そうであると考えています。

プールに正常に戻る方法(またはアイデア)がないため、これが起こっていると確信しています。returnObject を使用していますが、別のプロセスで使用できるようにするために何かする必要がありますか?

MyPooledObject classこれがコードです(コードはたくさんありますが、問題はとの 部分にあると思いますpool.returnObject(obj)

import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;

import java.io.IOException;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;

public class PoolExample {
    public static class MyPooledObject {
        Connection connection;
        public MyPooledObject() throws IOException {
            System.out.println("hello world");
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            connection = factory.newConnection();

        }

        public Channel sing() throws IOException {
            //System.out.println("mary had a little lamb");
            return connection.createChannel();
        }

        public void destroy() {
            System.out.println("goodbye cruel world");

        }
    }

    public static class MyPoolableObjectFactory extends BasePoolableObjectFactory<MyPooledObject> {
        @Override
        public MyPooledObject makeObject() throws Exception {
            return new MyPooledObject();
        }

        @Override
        public void destroyObject(MyPooledObject obj) throws Exception {
            obj.destroy();
        }
        // PoolableObjectFactory has other methods you can override
        // to valdiate, activate, and passivate objects.
    }

    public static void main(String[] args) throws Exception {
        PoolableObjectFactory<MyPooledObject> factory = new MyPoolableObjectFactory();
        ObjectPool<MyPooledObject> pool = new GenericObjectPool<MyPooledObject>(factory);

        // Other ObjectPool implementations with special behaviors are available;
        // see the JavaDoc for details

        try {
            for (int i = 0; i < 500000000; i++) {
                MyPooledObject obj;

                try {
                    obj = pool.borrowObject();
                } catch (Exception e) {
                    // failed to borrow object; you get to decide how to handle this
                    throw e;
                }

                try {
                    // use the pooled object
                    Channel channel = obj.sing();
                    String message = "Mary Had a little lamb";
                    channel.basicPublish( "", "task_queue", 
                            MessageProperties.PERSISTENT_TEXT_PLAIN,
                            message.getBytes());

                } catch (Exception e) {
                    // this object has failed us -- never use it again!
                    pool.invalidateObject(obj);
                    obj = null; // don't return it to the pool

                    // now handle the exception however you want

                } finally {
                    if (obj != null) {
                        pool.returnObject(obj);
                    }
                }
            }
        } finally {
            pool.close();
        }
    }
}
4

1 に答える 1

1

動作は期待どおりです。一度にプール内のオブジェクトを 1 つしか使用しないため、makeObject にブレーク ポイントを設定すると、一度しか使用しないことがわかります。

プール内の複数のオブジェクトを同時に使用すると、プールがいっぱいになり、別のオブジェクトが使用されます。

于 2012-05-01T16:25:08.623 に答える