Article From:
## PrefaceEvery language usually behaves differently in some extreme cases. So what happens to the Java language I use, when it has 1 million concurrent connections? It’s a little curious and more anticipative.This time use the often used handy ** netty ** NIThe O framework (netty-3.6.5.Final) is well encapsulated and has a comprehensive interface, just like its current domain name ** **, which focuses on network IO.There is no technical content in the whole process, and it is more boring to have a superficial analysis, ready and hard.Let’s take the scalp.## Test Server ConfigurationRunning in VMWare Workstation 9, 64-bit Centos 6.2 system allocates about 14.9G of memory and 4 cores.Java 7 version is installed:` ` ` `Java VErsion “1.7.0_21″Java (TM) SE Runtime Environment (build 1.7.0_21-b11)Java HotSpot (TM) 64-Bit ServeR VM (build 23.21-b01, mixed mode)` ` ` `Add the following configuration in / etc / sysctl. conf:` ` ` `Fs. file-max = 1048576Net.ipv4. ip_local_port_range = 1024 65535Net. ipv4. tcp_mem = 786432 2097152 3145728Net. ipv4. tcp_rmem = 4096409616777216Net. ipv4. tcp_wmem = 4096 4096 16777216Net. ipv4. tcp_tw_reuse = 1Net.ipv4.tcp_tw_reCycle = 1` ` ` `Add the following configuration in / etc/security/limits.conf:` ` ` `* soft nofile 1048576* hard nofileOne million forty-eight thousand five hundred and seventy-six` ` ` `Test endThe source code of client 5.c and related configuration information can be seen in the first few blogs of the tester, no matter the configuration or the program is the same as before.Server programThis time, it’s very simple, no job.Transaction function, client HTTP request, server output chunked encoding content.Entry HttpChunkedServer. java:` ` ` `Package com. test. server;ImportStatic;Import;Import java.utIl. concurrent. Executors;Import org.jboss.netty.bootstrap.ServerBootstrap;Import org.jboss.netty.chAnnel. Channel Pipeline;Import Factory;Import org.jboss.nettyChannel. socket. nio. NioServerSocket ChannelFactory;Import org.jboss.netty.handler.codec.http.HttpChuNkAggregator;Import org.jboss.netty.handler.codec.http.HttpRequestDecoder;Import org.jboss.netty.hAndler. codec. http. HttpResponseEncoder;Import;Public class Http Chunked Server {Private final port;Public Http Chunked Server (intport){This.port = port;}Public void run () {//Configure the server.Server Bootstrap bootstrap = new Server Bootstrap (New NioServer Socket Channel FactoryExecutors. new CachedThreadPool (),Executors.newCacheDThreadPool ());//Set up the event pipeline factory.Bootstrap. setPipeline Factory(new Channel Pipeline Factory ()Public Channel Pipeline getPipeline () throws Exception {Channel Pipeline pipeline = pipeline ();Pipeline. addLast (“decoder”, ne)W HttpRequestDecoder ());Pipeline. addLast (“aggregator”, new Http Chunk Aggregator (6553)6))Pipeline. addLast (“encoder”, new HttpResponseEncoder ());PipelinE. addLast (“chunkedWriter”, new ChunkedWriteHandler ());Pipeline. addLast (“handler”, n)EW Http Chunked Server Handler ();Return pipeline;}};Bootstrap. setOption (“child. reuse Address”, true);Bootstrap. setOption (“child. tcpNoDelay”, tru)E);Bootstrap. setOption (“child. keepAlive”, true);//Bind and start to accept incomiNg connections.Bootstrap. bind (new InetSocket Address (port));}Public static void MaIn (String[] args) {Int port;If (args. length & gt; 0) {Port = Integer.pArseInt (args[0]);} else {Port = 8080;}System. out. format (“se”Rver start with port% d n “, port);New HttpChunkedServer (port). run ();}}` ` ` `The only selfDefine processor HttpChunkedServerHandler. java:` ` ` `Package com. test. server;Import static org.jboss.netty.hanDler. codec. http. HttpHeaders. Names. CONTENT_TYPE;Import static org.jboss.netty.handler.codec.http.HttPMethod.GET;Import static org.jboss.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;ImportStatic org.jboss.netty.handler.codec.http.HttpResponseStatus.METHOD_NOT_ALLOWED;Import static org.Jboss. netty. handler. codec. http. HttpResponseStatus. OK;Import static org.jboss.netty.handler.codec.htTp. HttpVersion. HTTP_1_1;Import java.util.concurrent.atomic.AtomicInteger;Import org.jboss.netty.buFfer.ChannelBuffer;Import org.jboss.netty.buffer.ChannelBuffers;Import;Import;Import;Import;Import;Import;Import;Import org.jboss.netty.handler.codec.frame.TooLong FrameException;Import org.jboss.Netty. handler. codec. http. DefaultHttpChunk;Import org.jboss.netty.handler.codec.http.DefaultHttpRespOnse;Import org.jboss.netty.handler.codec.http.HttpChunk;Import org.jboss.netty.handler.codec.http.HttpHeaders;Import org.jboss.netty.handler.codec.http.HttpRequest;Import org.jboss.netty.handler.Codec. http. HttpResponse;Import org.jboss.netty.handler.codec.http.HttpResponseStatus;Import org.jbOss.netty.util.CharsetUtil;Public class Http Chunked Server Handler extends SimpleChannel Upstream HandlEr {Private static final Atomic Integer count = new Atomic Integer (0);Private void incremenT () {System. out. format (“online user% d\ n”, count. incrementAndGet ()));}PrivateVoid decrement () {If (count. get () lt; = 0) {System. out. format (“~online user%D\n, “0”;} else {System. out. format (“~online user%d\ n”, count. decrementAndGet (“);}}@OverridePublic void message Received (Channel Handler Contextctx, Mes)SageEvent E)Throws Exception {HttpRequest request = E. getMessage();If (request. getMethod ()!= GET) {SendError (ctx, METHOD_NOT_ALLOWED);Return;}SendPrepare (CTX);Increment ();}@OverRidePublic void channel Disconnected (ChannelHandler Contextctx,Channel State Event) throws Exception {Decrement ();Super. channel Disconnected (ct)X, e);}@OverridePublic void exceptionCaught (Channel Handler Contextctx, ExceptionE)Vent E)Throws Exception {Throwable cause = E. getCause ();If (cause INS)Tance of Too Long Frame Exception {SendError (ctx, BAD_REQUEST);Return;}}Private static void sendError (Channel Handler Context ctx,HttpResponseStatus {HttpResponse response = new Default HttpResponse (HTTP_1_1, status);Response. setHeader (CONTENT_TYPE, text/plain; charset = UTF-8);ResponsE. setContent (Channel Buffers. copied Buffer)”Failure:” status. toString () + “\ r n”, CHarsetUtil.UTF_8);//Close the connection as soon as the error message is sent.Ctx. getChannel (). write (response)AddListener (Channel FutureListener. CLOSE);}Private void sendPrepare (Channel Handler Contextctx) {HttpResponse response = nEW DefaultHttpResponse (HTTP_1_1, OK);Response. setChunked (true);Response.setHeader (HttpHeaders.Names.CONTENT_TYPE,”Text / html; charset = UTF-8″;Response.addHeaDer(HttpHeaders.Names.CONNECTION,HttpHeaders. Values. KEEP_ALIVE;Response.sEtHeader (HttpHeaders. Names. TRANSFER_ENCODING,HttpHeaders. Values. CHUNKED;Channel Chan = ctx. getChannel ();Chan. write (response);// Buffer must be sufficient 256Bytes, the browser can receive the uuuuuuuuuuuuStringBuilder builder = new StringBuilder ();Builder.append (“”);Int leftChars = 256-builder. length ();For (int I = 0; I & lt; leftChars; i++) {Builder.append (“”);}WriteStringChunk (chan, builder. toString ());}Private void write String Chunk (Channel channel, String data) {ChannelBuffer ChUnkContent = ChannelBuffers. dynamicBuffer (channel Buffer)GetConfig (). getBufferFactory ();ChunkContent. writeBytes (data. getBytes ());HttpChunk Chuk = new Default HttpChunk (chu)NkContent);Channel. write (chunk);}}` ` ` `## Start script uuuuuuuuuuuu` ` ` `Set CLASSPATH=.Nohup JAva-server-Xmx6G-Xms6G-Xmn600M-XX: PermSize=50M-XX: MaxPermSize=50M-Xss256K-XX:+DisableExpliciTGC-XX: SurvivorRatio = 1-XX:+UseConcMarkSweepGC-XX:+UseParNewGC-XX:+CMSParallel RemarkEnabled-XX:+UseCMSCompact AtFull Collection-XX: CMSFull GCs BeforeCompaction = 0-XX:+CMSClass Unloading Enabled-XX:LarGePageSizeInBytes = 128M-XX:+UseFast Accessor Methods-XX:+UseCMSInitiating Occupancy Only-XX:CMSInitiatIngOccupancy Fraction = 80-XX: SoftRefLRUPolicyMSPerMB = 0-XX:+PrintClassHistogram-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-XX:+PrintHeapAtGC-Xloggc:gc.log-Djava.ext.dirs=lib com.test.server.HttpChunKedServer 8000 & gt; server. out 2 & gt; & amp; 1 & amp;` ` ` `Some information when # reaches 1 million concurrent connectionsTurn off the test after each server reaches a million concurrent persistent connectionsEnd program, disconnect all connections, until the server log output online user is 0, repeat the above steps again. In this repeated situation, observe some information such as memory. For example, the current system occupancy is set to `list_free_1’when all test terminals are disconnected at one time.):` ` ` `Total used free shared buffers cachedMem:15189 7736 7453 0 18 120-/+buffers/cache: 75977592Swap: 4095 948 3147` ` ` `Through top observation, process-related information` ` ` `PID USERPR NI VIRT RES SHR S%CPU%MEM TIME+COMMAND4925 root 200 8206 m 4.3 g 2776 S 0.3 28.8 50:18.66 Java` ` ` `In the startup script, we set the heap memory to 6G.The ** PS aux | grep Java ** command obtains information:` ` ` `Root 4925 38.028.8 8403444 4484764? Sl 15:2650:18 java-server… Http Chunked Server 8000` ` ` `RSS takes up 44847 memory64K/1024K=4379MThen start the test end again. When the server receives ** online user 1023749 **, the `ps aux | grep java` content is as follows: uuuuuuuuuu` ` ` `Root 4925 43.6 28.4 8403444 4422824? Sl 15:26 62:53 java-server…` ` ` `View current network information statistics` ` ` `SS -sTotal: 1024050 (kernel 1024084)TCP: 1023769 (estab 1023754, closed 2, orphaned 0, synrecv 0, t)Imewait 0/0, ports 12Transport Total IP IPv6*1024084-RAW 0 0 0UDP 7 6 1TCP 102376712One million twenty-three thousand seven hundred and fifty-fiveINET 1023774 18 1023756FRAG 0 000` ` ` `throughLook over top.` ` ` `Top -p 4925Top-17:51:30 up 3:02, 4 users, load average:1.03, 1.80, 1.19TAsks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombieCpu0: 0.9% us, 2.6% sy, 0.0% ni, 52.9% id, 1.0% wa, 13.6% hi, 29.0% si, 0.0% stCpu1: 1.4% us, 4.5% sy, 0.0% ni, 80.1% id, 1.9%Wa, 0.0% hi, 12.0% si, 0.0% stCpu2: 1.5% us, 4.4% sy, 0.0% ni, 80.5% id, 4.3% wa, 0.0% hi, 9.3% sI, 0.0%stCpu3: 1.9% us, 4.4% sy, 0.0% ni, 84.4% id, 3.2% wa, 0.0% hi, 6.2% si, 0.0% stMem:15554336k total, 15268728k used, 285608k free, 3904k buffersSwap: 4194296k total, 1082592K used, 3111704k free, 37968k cachedPID USER PR NI VIRT RES SHR S%CPU%MEM TIME+ COMMAND4925 root 200 8206m 4.2g 2220S 3.3 28.4 62:53.66 Java` ` ` `The four cores are occupied, and each core is not even. This is in the virtual machine.As a result, real servers may be better. Because it is not a CPU intensive application, CPU is not a problem and need not pay more attention.System memory status` ` ` `Free -mTotal usedFree shared buffers cachedMem: 15189 14926 263 0556-/+buffers/cache: 14864 324Swap: 4095 1057Three thousand and thirty-eight` ` ` `Physical memory has been unable to meet the requirements, occupying 1057M virtual memory.Look at heap memory` ` ` `Jmap -heap 4925Attaching to process ID4925, please wait…Debugger attached successfully.Server compiler detected.JVM version is23.21-b01Use parallel threads in the new generation.Use thread-local object allocation.Concurrent Mark-Sweep GCHeap Configuration:MinHeapFreeRatio = 40MaxHeapFreeRatio =SeventyMaxHeapSize = 6442450944 (6144.0MB)NewSize = 629145600 (600.0MB)MaXNewSize = 629145600 (600.0MB)OldSize = 5439488 (5.1875MB)NewRatio= 2SurvivorRatio = 1PermSize = 52428800 (50.0MB)MaxPermSize = 52428800 (50.0MB)G1HeapRegionSize = 0 (0.0MB)Heap Usage:New Generation (Eden+1 Survivor)Space):Capacity = 419430400 (400.0MB)Used = 308798864 (294.49354553222656MB)FREE = 110631536 (105.50645446777344MB)73.62338638305664% usedEden Space:Capacity= 209715200 (200.0MB)Used = 103375232 (98.5863037109375MB)Free = 106339968 (101.4136962890625MB)49.29315185546875% usedFrom Space:Capacity = 209715200 (200.0MB)Used = 205423632 (195.90724182128906MB)Free = 4291568 (4.0927581787109375MB)Ninety-seven95362091064453% usedTo Space:Capacity = 209715200 (200.0MB)Used = 0 (0.0MB)Free = 209715200 (200.0MB)0% usedConcurrent mark-sweep generation:Capacity = 5813305344 (5544.0MB)Used = 4213515472 (4018.321487426758MB)Free = 1599789872 (152)5.6785125732422MB)72.48054631000646% usedPerm Generation:Capacity = 52428800 (50.0MB)Used = 5505696 (5.250640869140625MB)Free = 46923104 (44.749359130859375MB)10.50128173828125% used1439 interned Strings occupying 110936 bytes.` ` ` `The old generation occupies 72% of the memory, which is more reasonable. After all, the system already has.One million connections have been processed.Re-disconnect all test ends to see system memory (free-m)` ` ` `Total used free sharedBuffers cachedMem: 15189 7723 7466 0 13 120/+buffers/cache: 7589 7599Swap: 4095 950 3145` ` ` `Recorded as `list_free_2`.The results of memory comparison between `list_free_1’and `list_free_2′, after two releases, show that the available physical memory of the system has been reduced to 7589M, which was previously 7597M physical memory.In summary, our JAVA test program occupies memoryAs far as it is concerned, the minimum memory requirement is 7589+950=8.6G.GC logWe set a series of parameters at the startup script, whether we achieve the goal or not, we also need to get specific results from the GC log, recommend the use of [GCView]Er] ( of GC events:[! [gc_eventdetails] (] (http://ww)[! [gc_total_1] (] ( [![gc_total_2] (] ( [! [gc_total_3] (http)://] ( short:Full GC was only performed once, which was too expensive and stopped for 12 seconds.- PartNew became a major pauser, causing the entire system to pause for 41 seconds, which was unacceptable.- current JVM tuning hiIt’s a mixed bag, and we have to keep working hard.A brief summary of the Chinese charactersComparing Java with Erlang and C, the more troublesome thing is how much space it needs to prepare its stack at the beginning of the program. In other words, JVM startup parameters set the size of heap memory and set the appropriate garbage return.Receive mechanism. If the program needs more memory later, stop the program, edit the startup parameters, and then start again. In a word, it is trouble. JVM tuning alone requires continuous fine-tuning based on detection, information, logs, etc.- JVM needs to specify heap size ahead of time.Erlang/C, this could be a problem.- GC (garbage collection), relatively troublesome, need to continuously fine-tune JVM parameters according to logs, JVM stack information, runtime situation.- Set a maximum connection target, test multiple times to peak, and then release all connections.Observing memory occupancy repeatedly to get a more appropriate system running memory value- Eclipse Memory Analyzer with jmap export stack DUMP file, analysis of memory leaks, or very convenient- Want to modify runtime content, or heat it upLoad, default impossible- There will be better reflection on real machines.Tucao:JAVA OSGI, as opposed to Erlang, requires people to change their minds. It’s not so native. It’s always a bit awkward. Community or business companies can fix it, but it’s just a way to achieve something.Hot-loaded enterprise features that object-oriented does not have.Test the source code, [Download just_test] (—** No programming, no customer, no case, no learning. Crazy Tourist Circle, a wave of masters are communicating and learning! **** More than 10 in-depth articles in the Netty Death Series of Crazy Creator Circle: [General Entrance of Blog Park] ( circle/p/9904544.html)**]QQ group: 104131248**

Leave a Reply

Your email address will not be published. Required fields are marked *