Summary of the first project

Source: Internet
Author: User

1 Project Architecture

Basic framework of 5 servers:

2 Game Dress Threads

Main-server and Logic Server configuration


Executorservice Bossexecutor =Executors.newcachedthreadpool (); Executorservice Workerexecutor=Executors.newcachedthreadpool (); ChannelFactory ChannelFactory=Newnioserversocketchannelfactory (Bossexecutor, workerexecutor); Serverbootstrap Bootstrap=NewServerbootstrap (ChannelFactory); Executionhandler Executionhandler=NewExecutionhandler (NewOrderedmemoryawarethreadpoolexecutor (0, 0, Timeunit.minutes,Newthreadfactory () {PrivateAtomicinteger count =NewAtomicinteger (0); @Override Publicthread Newthread (Runnable r) {thread T=NewThread (R, "server-biz-pool-" + count.getandadd (1)); returnT; }                }));//Define nameBootstrap.setpipelinefactory (NewGameserverpipelinefactory (Listenercon, Executionhandler));//gameserverpipelinefactory load the prescribed handler. and will add Executionhandler after Lengthfielddecoder//Disable the Nagle algorithm for highly interactive clientsBootstrap.setoption ("Child.tcpnodelay",true); //Set KeepAliveBootstrap.setoption ("Child.keepalive", Listenerconfiguration.iskeepalive ()); Bootstrap.bind (NewInetsocketaddress (Listenerconfiguration.getip (), Listenerconfiguration.getport ()));

Logic-server two types connection[for Mainserve], 8 for each type. 16 Connections in total

push[responsible for message push]

logic[responsible for business processing]

The pipelinefactory is configured with the appropriate filter and Handler:

The handler of the project have these several:

executionhandler[executes  channelhandler   work

Therefore, in order to increase the number of concurrent, generally through the Executionhandler Line pool asynchronous processing Channelhandler chain (worker The thread ends after executionhandler , and it is ChannelFactory by the worker Collected by the thread pool). ]

requesthandler[Client passes the action is a string, back to Filter,like is login, through the specified bean name and method with invoke execution, request num use Atominteger Record.]


For the thread pool model that Executionhandler needs,Netty provides two options:

1) memoryawarethreadpoolexecutor controls the use of thread pool memory to control Executor The upper limit of the task to be processed (when the upper limit is exceeded, subsequent tasks will be blocked), and can control the upper limit of the single Channel Backlog, and prevent memory overflow error;

2) orderedmemoryawarethreadpoolexecutor is memoryawarethreadpoolexecutor Sub-class. In addition to the functionality of Memoryawarethreadpoolexecutor , it also guarantees the sequence of event streams processed in the same Channel, This is primarily the sequence of events that control the errors that may occur in an event in asynchronous processing mode, but it does not guarantee that events in the same Channel are executed in one thread (often not necessary).

For example:

Thread X:---Channel A (Event A1)--. .--Channel B (event B2)---Channel B (event B3)--->

\ /


/ \

Thread Y:---channel B (event B1)--"channel A (event A2)---channel A (event A3)--->

There are several meanings to be expressed:

(1) for the entire thread pool, events that deal with the same Channel must be handled in order. For example, channel A (event A1) must be processed before channel a (event A2),Channel A (event A3) is processed .

(2) multiple events of the same Channel are distributed to multiple threads in the thread pool to be processed.

(3) different Channel events can be processed at the same time (sharing multiple threads) without affecting each other.

The Orderedmemoryawarethreadpoolexecutor of this sort of event handling is meaningful because, typically, the request sender expects the server to be able to process its own requests in order, especially the application layer protocol, which requires multiple handshakes. For example:XMPP protocol.

(Executionhandler reference:

// used in the project New Executionhandler (new memoryawarethreadpoolexecutor (8, 0, 0));

3 Project Message Queuing

Push queue

Principle: Put the required push information in the appropriate queue of Redis according to priority, and then take out the priority level.

  //Asynchronous Message Processing//Main thread  Private voidcommandprocess () {Try {       while(true) {        FinalCommand command = Commanddao.get (Priority.high, Priority.normal, Priority.lower, priority.message);//Blocking        if(Command! =NULL) {          FinalCommandHandler CommandHandler =commandhandlerfactory.getinstance (). GetHandler (Command.getcommand ()); Runnable Task=NewRunnable () {@Override Public voidrun () {commandhandler.handle (command);//transfer the processed messages through the push connection above            }          }; Gametaskprocessor.ins (). General (Task);//thread pool exec        } Else {           Break; }      }    } Catch(Exception e) {log.error (E.getmessage (), E); Try{Thread.Sleep (1000 * 5); } Catch(Interruptedexception ex) {Log.error (Ex.getmessage (), ex); }    }  }//Cache handler. You can also use Spring getbeanbyname instead. Public classCommandhandlerfactory {Private Static FinalLogger LOG = Loggerfactory.getlogger (commandhandlerfactory.class); PrivateMap<integer, commandhandler> commandhandlermap =NewHashmap<integer, commandhandler>(); Private StaticCommandhandlerfactory instance =NULL; Privatecommandhandlerfactory () {} Public Staticcommandhandlerfactory getinstance () {if(Instance = =NULL) {instance=Newcommandhandlerfactory (); }        returninstance; }     Public voidRegisterintcommand, CommandHandler handler) {//when spring instantiates the corresponding handler, the Init method invokes ("command handler register.command[" + COMMAND + "]");    Commandhandlermap.put (command, handler); }     PublicCommandHandler GetHandler (intcommand) {        intKey = command/10000; if(Commandhandlermap.containskey (key)) {returnCommandhandlermap.get (key); } Else{Log.warn ("The command processor does not exist. command[" + Command + "], key[" + key + "]"); }        return NULL; }}//put/get Command Public classCommanddaoredisimplImplementsCommanddao {Private Static Final intTime_out = 2; PrivateString GetKey (intPriority ) {        returnRediskey.getcommandkey (priority); } @Override Public BooleanAdd (Command command) {String key=GetKey (Command.getpriority ());        Jedisutils.pushmsg (Key, Json.tojson (command)); return true; } @Override PublicCommand Get (Integer ... proritys) {string[] keys=NewString[proritys.length];  for(inti = 0; i < proritys.length; i++) {String key=GetKey (Proritys[i]); Keys[i]=key; } String JSON= Jedisutils.blockpopmsg (time_out, keys);//Blocking Methods        if(JSON! =NULL) {            returnJson.toobject (JSON, Command.)class); }        return NULL; }}

Finally, using the push connection random a connection, handed to Netty processing.

Logic queue

Use Netty Channel Link+java reflection.

Summary of the first project

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.