Archived

This forum has been archived. Please start a new discussion on GitHub.

(java client) multiple connection, sequential access

we try to open multiple connections to a single server:

(java client)
Ice.InitializationData id = new Ice.InitializationData();
id.properties = properties; // properties is prepared before
Ice.Communicator m_iceCommunicator = Ice.Util.initialize(id);
Ice.ObjectPrx m_iceObjectPrx = m_iceCommunicator.stringToProxy(searchConnStr);


we have multiple iceCommunicator/iceObjectPrx created

we have multiple threads to use different "connections" (communicator/objectprx), but still, the requests are in "sequential", i.e. one must wait the running request to finish before it can proceed


we want to implement a simple "multiple connection" to increase the concurrency (we are stuck at a stage that we only open one connection, and multiple threads are using the same connection, though it can be "multi-thread", actually requests from different threads are in sequential),
so is there anything i have missed?

(we can't afford to implement something like "ice grid" for the clustering/load balancing solution right now; so any hint to help increase the "performance"/concurrency is very appreciated)

Comments

  • dwayne
    dwayne St. John's, Newfoundland
    Please read this faq.
  • thanks for the faq,

    i should have stated my configs clearly first

    the ice configs are:

    server
    Ice.ThreadPool.Server.Size=20
    Ice.ThreadPool.Server.SizeMax=24
    #Ice.ThreadPool.Server.SizeWarn=10
    Ice.Trace.Network=0
    #Ice.MessageSizeMax limit the max size of each message default = 1024
    Ice.MessageSizeMax=1024


    client
    properties.setProperty("Ice.ThreadPool.Client.Size", "24");
    properties.setProperty("Ice.ThreadPool.Client.SizeMax", "24");
    properties.setProperty("Ice.ThreadPool.Server.Size", "24");
    properties.setProperty("Ice.ThreadPool.Server.SizeMax", "24");
    properties.setProperty("Ice.ACM.Server", "15");
    properties.setProperty("Ice.ACM.Client", "15");


    in fact, we can see the "thread usage warning" on server, i.e. multiple threads are created

    this is the most puzzling part
    we see multi-threading at both clients and server

    but the performance is similar (or even worse if multiple connection) when we use multiple connections (the connections are initiailized at startup, not run time)

    our application running behind ice server is multi-thread-enabled,

    so, we try to see if there is any hint from ice's side
  • dwayne
    dwayne St. John's, Newfoundland
    I expect that you are using the same proxy in each of the threads in your client. Take a look at this thread, which discusses this issue.

    Dwayne
  • thanks

    i have tried to create the proxy with different "connection id":
    Ice.ObjectPrx proxy = ...
    Ice.ObjectPrx proxy1 = proxy.ice_connectionId("id1");

    and have verified:
    - each proxy is different (the hashcode is different)
    - each connection retrieved from the proxy is different (
    the hashcode is different, the "_toString()" method returns different,
    e.g. "local address = ABC:XXX
    remote address = CDE:YYY" , where "XXX" is different for each connection object)


    in fact, i do the above verification again without setting the "connection id", still the same, the connections retrieved are different


    recall that i create each "ice communicator" differently, and so the proxy/connection created are also different?
    <code>
    m_iceCommunicator = Ice.Util.initialize(id);
    m_iceObjectPrx = m_iceCommunicator.stringToProxy(searchConnStr);
    </code>


    does that mean i can have multiple connections shared my multiple threads?
  • dwayne
    dwayne St. John's, Newfoundland
    I missed that you were creating multiple communicators in your client. It is almost never necessary to create more than one communicator, and it should not be in your case.

    Proxies are thread-safe and thus can be used across multiple threads. In your case where you want your client to establish multiple connections to the server you would want to use multiple proxies as I suggested, but not multiple communicators. That would be a waste of resources in your client.

    Having said that, if you were using multiple communicators before and had properly set up the server to have multiple threads, then the requests should have been processed in parallel on the server. A connection cannot be shared between communicators so each should have established it's own connection.

    Perhaps you can post a small complet code example that shows the behavior that you are seeing.

    Dwayne
  • the test case is very simple:

    for (int i = 0; i < 100; i++) {
    create a new thread (every thread will call our ice client's method with the same parameter)
    }

    for (int i = 0; i < 100; i++) {
    start each thread (thread.start)
    }


    and for the "ice client", the initialization of communicator and proxy is done at the start and they are cached,
    then for each ice client method, we just get the created proxy and call the proxy method directly

    no "synchronized" is used throughout the testcase and ice client


    i record each thread's finish time, each thread finish with increasing time,
    e.g.
    Thread 1 use 1 second
    Thread 2 use 1+x second
    Thread 3 use 1+x+y second
    Thread 4 use 1+x+y+... second
    ...


    i try to verify again if there is any problem in our application code at the server, it should be no problem and our code does not have any problemmatic "synchronized" code, and the underlying dependency (i.e.. lucene) is thread-safe/multi-thread-capable as well

    but i find one thing strange,
    if the server response is very "small", then it seems every request is "concurrent" (e.g. each thread's finish time is very similar); but if the server response is "larger", then each thread finish "one by one", i.e. each thread's finish time must be increasing

    would there is a problem when ice send the response back? e.g. ice serialize sending response



    (a side question, if the number of threads is the same, but the number of connections is different, then is it true that the application should perform "better" (or "concurrency" increase) with higher number of conncetion?)
  • dwayne
    dwayne St. John's, Newfoundland
    Ice clients do not serialize requests to the server and Ice servers can process requests concurrently (assuming the thread pool is properly configured).

    Are you using Ice 3.3? If not you should upgrade first and see if you still the same problem.

    Otherwise, as I said previously, it would be be much easier for us to help you if you could provide a self-contained, compilable example that demonstrates the problem.

    Dwayne
  • thanks Dwayne, you already have given me a lot of insights in checking the problems

    sorry that i can't give the sample test cases for demonstration (not because i do not want to share, but it is just too simple so i just write the pesudo code)

    also, i can't afford to upgrade to 3.3.0 ( i am in 3.2.1 now) , so badly i can't ask for further detail/help

    some verifications after the checking:
    - multiple connections are made from clients to servers
    - multiple threads are running at the servers to serve the requests
    - our application code is multi-thread-capable, i.e. multiple threads can call at the same time without performance impact
    - if the response size increases, each concurrent requests will have its corresponding response sending back to client "more slowly" or in sequential


    therefore, i suspect the problem lies at the part of "sending response back from server to client"

    first, i check that the server and client are located at the same LAN connected on 100Mbps, and we have monitored the traffic on the network interface, the traffic is low (under 10% usage)

    so the transport volume between the machines are sufficient

    so i guess if there is any problem in marshalling/demarshalling/serializing/deserializing java objects by ice

    so can i ask some questions for the above?

    1) i have searched the forum, find a post that described ice have problem in "transforming" string at java because java's string is 16bit and ice's is 8bit; as our response mainly consists of strings, does that hurt the performance?

    2) does ice use the "native/original" java object serialization? i.e. no optimization, just use plain jdk support
  • matthew
    matthew NL, Canada
    I'm afraid that pseudo-code doesn't help very much since you have left out many many details on exactly what you are doing. Without a complete self-contained, compilable test case that demonstrates this problem with Ice 3.3 I'm afraid we cannot provide much help. If you would like support for an older version of Ice, then please contact us at sales@zeroc.com in order to subscribe to a support contract.

    With respect to string serialization, if you are sending very long strings it is possible that it could affect performance. However, without knowing what you are doing it is impossible to say.

    Ice for Java, with the exception of the BerkeleyDB component, is pure Java.