2011-03-28 12 views
8

के साथ अत्यधिक समवर्ती HTTP एक समवर्ती, थ्रेडेड वातावरण के भीतर http अनुरोध करने के लिए मैं example Netty HTTP Client code के माध्यम से काम कर रहा हूं।नेटटी और एनआईओ

हालांकि, मेरी प्रणाली पूरी तरह से कम थ्रूपुट पर पूरी तरह से टूट जाती है (अपवादों के साथ)।

लगभग छद्म कोड में:

ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory()) 
bootstrap.setPipelineFactory(new HttpClientPipelineFactory()); 

ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)); 
Channel channel = future.awaitUninterruptibly().getChannel(); 

HttpRequest request = new DefaultHttpRequest(); 
channel.write(request); 

उदाहरण में, वहाँ से (कुछ हुप्स के माध्यम से) एक अनुरोध मैं एक ClientBootstrap बनाने बनाने के लिए, और एक चैनल HttpRequest लिखने के लिए।

यह सब काम करता है और अच्छा है।

हालांकि, एक समवर्ती स्थिति में, क्या प्रत्येक अनुरोध एक ही हुप्स के माध्यम से जा रहा है? मुझे लगता है कि फिलहाल मेरे लिए चीजें तोड़ रही हैं। क्या मुझे कनेक्शन का पुन: उपयोग करना चाहिए या अपने क्लाइंट को पूरी तरह से अलग तरीके से संरचित करना चाहिए?

इसके अलावा: मैं क्लोजर में ऐसा कर रहा हूं, अगर इससे कोई फर्क पड़ता है।

+0

शायद आपको https://github.com/ztellman/aleph का उपयोग करना चाहिए? – PheliX

+0

क्या आपके पास एलीफ के साथ अनुभव है? मैंने एक और एसिंक क्लोजर http क्लाइंट की कोशिश की है, लेकिन यह थ्रूपुट के स्तर पर काम नहीं करता है जिसे मुझे बनाए रखने की आवश्यकता है। –

उत्तर

7

नहीं, आप सही काम कर रहे हैं। हालांकि, आपको अपने Channel उदाहरण का संदर्भ रखना होगा। एक बार जब आपके पास वह चैनल हो, तब तक जब तक यह खुला हो, आपको एक और बूटस्ट्रैप बनाने की आवश्यकता नहीं है। (है कि आप क्या कर रहे हैं है।)

यह है कि मैं क्या हाल ही में एक परियोजना में इस्तेमाल होता है:

वर्ग ClientConnection(निर्माता)

// Configure the client. 
bootstrap = new ClientBootstrap(
    new NioClientSocketChannelFactory(
     Executors.newCachedThreadPool(), 
     Executors.newCachedThreadPool() 
    ) 
); 

// Set up the pipeline factory. 
bootstrap.setPipelineFactory(
    new ChannelPipelineFactory() { 
     public ChannelPipeline getPipeline() throws Exception { 
      return Channels.pipeline(
       // put your handlers here 
      ); 
     } 
    } 
); 

वर्ग ClientConnection.connect (स्ट्रिंग होस्ट, int पोर्ट)

if (isConnected()) { 
    throw new IllegalStateException("already connected"); 
} 

// Start the connection attempt. 
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)); 

channel = future.awaitUninterruptibly().getChannel(); 

// Wait until the connection is closed or the connection attempt fails. 
channel.getCloseFuture().addListener(new ChannelFutureListener() { 
    @Override 
    public void operationComplete(ChannelFuture future) throws Exception { 
     new Thread(new Runnable() { 
      public void run() { 
       // Shut down thread pools to exit 
       // (cannot be executed in the same thread pool! 
       bootstrap.releaseExternalResources(); 

       LOG.log(Level.INFO, "Shutting down"); 
      } 
     }).start(); 
    } 
}); 

तो, मूल रूप से, मैं केवल bootstrap और channel का संदर्भ रखता हूं, हालांकि पूर्व कोड की इन पंक्तियों के बाहर बहुत अधिक उपयोग नहीं किया जाता है।

नोट: आपको केवल bootstrap.releaseExternalResources(); निष्पादित करना चाहिए, जब एप्लिकेशन बाहर निकल रहा हो। मेरे मामले में, क्लाइंट कुछ फाइल भेजता है, फिर चैनल बंद करें और बाहर निकलें।

एक बार जब आप Channel उदाहरण कनेक्ट कर लेंगे, तो आपको इसे तब तक उपयोग करने की आवश्यकता होगी जब तक कि आप इसे फिर से बंद न करें। एक बार यह बंद होने के बाद, आप को फिर से नया Channel बनाने के लिए याद कर सकते हैं।

व्यक्तिगत रूप से, मुझे नेटटी को पहले समझने में थोड़ा मुश्किल लगता है, लेकिन एक बार जब आप समझते हैं कि यह कैसे काम करता है, तो यह जावा में सबसे अच्छा एनआईओ ढांचा है। IMO।

+3

'बूटस्ट्रैप' भी उपयोगी होगा यदि आप एक और कनेक्शन बनाना चाहते हैं और मौजूदा मशीनरी (अंतर्निहित नेटटी एनआईओ कार्यकर्ता धागे) का उपयोग करना चाहते हैं। –

संबंधित मुद्दे