Stats: 50.000 calls to a plain Java method: 152199 ms 50.000 calls to a Java method that performs an inline SQL query against a MySQL database: 173.269
And that's still on a local network ... Adam Taft schrieb: > > Not trolling, but why use XmlRpc if this is your targetted I/O rate? > You would likely be much better to implement your own socket protocol > if you're expecting this high of socket connections from the client. > > XmlRpc (being based on HTTP) is a relatively expensive and slow > protocol to begin with. If you're trying to keep real time game state > using XmlRpc, I'm guessing you'll run into other throughput problems > than just what you've described. > > Perhaps you should be looking at using an already existing game engine > that includes sockets. If you don't find anything you like, then > perhaps create a spec and write one for yourself. You might find > other people have a similar problem. > > I understand the usefulness of having XmlRpc on the backend, since the > client can be built on any number of platforms, etc. In fact, I have > a game concept that uses XmlRpc because of the non-proprietary nature > of the protocol. But, it sounds like your client is very specific and > that you're going to distribute it. Therefore, it wouldn't be a > stretch to create your own socket protocol, staying away from the > stateless types like http. Keep your connections open, use a > connection pool, etc. > > I know that doesn't answer your question. It just seems you might > need to step back and rethink your architecture a little. Is XmlRpc > really the right choice for you? Socket programming is not that > difficult. > > > > > Daniel Kastenholz wrote: > >> Hi, >> >> I'm writing an online game based on XML-RPC and am currently doing some >> performance tests. To measure the throughput, I've written a test case >> that attemps to call several remote procedures/methods several thousand >> times and takes the time. Now I've stepped over a problem. Everything is >> fine when this test is run with a Linux-client/Linux-server setup. But >> when I test it with a Windows client, I keep getting BindExceptions >> after a short time. 500 iterations are no problem, but once it goes into >> thousands, every call results in an exceptions and blocking I/O (about >> 10 seconds per call!): >> >> <output> >> [java] Avoiding obscuring previous error by supressing error >> encountered while ending request: >> org.apache.xmlrpc.XmlRpcClientException: Exception closing URLConnection >> [java] java.net.BindException: Address already in use: connect >> </output> >> >> I've searched a little and learned that this problem is kind of >> Windows-homebrewn: >> >> <quote src="http://lists.mysql.com/java/5132"> >> >> [...] Windows XP only will make outbound TCP/IP connections using ports >> 1024-5000, and takes up to 4 minutes to recycle them :( >> Therefore, if you do a lot of connections in a short amount of time, you >> can easily eat that port range up (That 3960 is awful close to 5000 - >> 1024, isn't it :p ). >> >> The range can be adjusted via a registry setting (yes the KB article >> says Windows 2000, but it works on XP as well, I've tested it), see: >> >> http://support.microsoft.com/default.aspx?scid=kb;en-us;196271 >> >> </quote> >> >> But this isn't really an option, because I don't want players to have to >> change their registry settings before being able to play the game >> without a crash every couple of minutes. Changing XMLRPC's >> "setKeepAlive()" option didn't help, either. The Sun people suggest yet >> another workaround: >> >> <quote src="http://java.sun.com/features/2002/08/j2se-network.html"> >> >> With both TCP and UDP, it may be necessary at times to bind more than >> one socket to the same socket address. In J2SE 1.4, the SO_REUSEADDR >> socket option can be enabled or disabled using the >> ServerSocket.setReuseAddress method for TCP sockets and the >> DatagramSocket.setReuseAddress method for UDP sockets. >> >> >> In the case of TCP, when a connection is closed it may remain in a >> timeout state for a short period of time. In such cases, it is not >> possible to bind a socket to the required address if a previous >> connection to the same address is in a timeout state; typically, you get >> an error message "Couldn't bind, address already in use". If you wish to >> allow the socket to be bound even though a previous connection is in a >> timeout state, use setReuseAddress prior to binding (using bind) the >> socket. It's worth noting that when a ServerSocket is created, the >> initial setting of SO_REUSEADDR is not defined. Use getReuseAddress to >> determine the setting of SO_REUSEADDR. Also, after a socket is bound, >> the behavior of SO_REUSEADDR is not defined. >> >> >> In the case of UDP, it may be necessary to bind more than one socket to >> the same socket address for the purpose of receiving multicast packets. >> The SO_REUSEADDR socket option allows multiple sockets to be bound to >> the same socket address if it is enabled prior to binding the socket. >> Unlike with TCP sockets, when a DatagramSocket is created, the initial >> setting of SO_REUSEADDR is disabled; however, after a socket is bound, >> the behavior of SO_REUSEADDR is not defined. >> >> </quote> >> >> Currently, this seems to be the only solution without accessing the >> registry. Unfortunately, I wouldn't know where to set this flag. The >> only connection-related code that I could find in the sources was a >> ".getFile()" call that is made on an URL object. Besides, I wouldn't >> like to hack around in the code of the XMLRPC distribution, as this >> would complicate upgrading. >> >> Any suggestions or workarounds? >> >> >> Thank you very much. >> >> >> Daniel >> >
