明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

怎么規(guī)劃您的大型JAVA多并發(fā)服務器程序

[摘要]作者: 陳林茂 JAVA 自從問世以來,越來越多的大型服務器程序都采用它進行開發(fā),主要是看中它的穩(wěn)定性及安全性,但對于一個新手來說,您又如何開發(fā)您的JAVA 應用服務器,同時又如何規(guī)劃您的JA...
作者: 陳林茂  

  JAVA 自從問世以來,越來越多的大型服務器程序都采用它進行開發(fā),主要是看中

它的穩(wěn)定性及安全性,但對于一個新手來說,您又如何開發(fā)您的JAVA 應用服務器,

同時又如何規(guī)劃您的JAVA服務器程序,并且很好的控制您的應用服務器開發(fā)的進度,

最后,您又如何發(fā)布您的JAVA 應用服務器呢?(由于很多前輩已有不錯的著作,我

只能在這里畫畫瓢,不足指出,請多來信指正,晚輩將虛心接受!本人的聯(lián)系方式:

linmaochen@sohu.com)


廢話少說,下面轉(zhuǎn)入正題:

本文將分以下幾個部分來闡述我的方法:

  1、 怎樣分析服務器的需求?
  
  2、 怎樣規(guī)劃服務器的架構?

  3、 怎樣規(guī)劃服務器的目錄及命名規(guī)范、開發(fā)代號?

  4、 原型的開發(fā)(-):  怎樣設計服務器的代碼骨架?

  5、 原型的開發(fā)(二): 怎樣測試您的代碼骨架?

  6、 詳細的編碼?

  7、 如何發(fā)布您的JAVA 服務器產(chǎn)品?


一、 如何分析服務器的需求?

   我的觀點是:
   
   1。服務器就像一臺軋汁機,進去的是一根根的甘蔗,出來的是一杯杯的甘蔗汁;

   也就是說,在開發(fā)服務器之前,先要明白,服務器的請求是什么?原始數(shù)據(jù)是什么?

   接下來要弄明白,希望得到的結果是什么? 結果數(shù)據(jù)應該怎樣來表述?

   其實要考慮的很多,無法一一列出(略)。


二、如何規(guī)劃服務器的架構?

   首先問大家一個小小的問題:在上海的大都市里,公路上的公交客車大致可以分為以下兩類:

   空調(diào)客車,票價一般為兩塊,上車不需要排隊,能否坐上座位,就要看個人的綜合能力;

   無人售票車,票價一般1 塊和一塊五毛,上車前需要規(guī)規(guī)矩矩排隊,當然,座位是每個人都有的。

   那么,我的問題是,哪類車的秩序好呢?而且上下車的速度快呢?答案是肯定的: 無人售票車。


   所以,我一般設計服務器的架構主要為:

      首先需要有一個請求隊列,負責接收客戶端的請求,同時它也應有一個請求處理機制,說到實際
    
     上,應有一個處理的接口;

      其次應該有一個輸出隊列,負責收集已處理好的請求,并準備好對應的回答;當然,它也有一個

     回答機制,即如何將結果信息發(fā)送給客戶端;


      大家都知道,服務器程序沒有日志是不行的,那么,服務器同時需要有一個日志隊列,負責整個服

     務器的日志信息收集和處理;


     最后說一點,上公交車是需要有鈔票的,所以,服務器同樣需要有一個驗證機制。

      ...(要說的東西實在太多,只好略)


三、 怎樣規(guī)劃服務器的目錄及命名規(guī)范、開發(fā)代號

    對于一般的大型服務器程序,應該有下面幾個目錄:

    bin :  主要存放服務器的可執(zhí)行二進制文件;
    
    common: 存放JAVA程序執(zhí)行需要的支持類庫;

    conf  : 存放服務器程序的配置文件信息;

    logs  : 存放服務器的日志信息;

    temp  : 存放服務器運行當中產(chǎn)生的一些臨時文件信息;

    cache : 存放服務器運行當中產(chǎn)生的一些緩沖文件;

    src   : 當然是存放服務器的JAVA源程序啦。

    ......(其他的設定,根據(jù)具體需求。)
  

四、原型的開發(fā)(-):  怎樣設計服務器的代碼骨架?


    1。首先服務器程序需要有一個啟動類,我們不妨以服務器的名字命名:(ServerName).class    

    2。服務器需要有一個掌控全局的線程,姑且以:(MainThread.class)命名;

    3。注意不論是短連接和長連接,每一個客戶端需要有一個線程給看著,以 ClientThread.class 命名

    4。請求隊列同樣需要以線程的方式來表現(xiàn): (InputQuene.Class),對應的線程處理類以InputProcessThread.class

       命名;

    5。輸出隊列也需要一個線程:(OutputQuene.Class),對應的處理機制以OutputProcessThread.class 命名;

    6。日志隊列也是需要一個線程的,我們以 logQuene.class,logQueneThread.Class 來命名;

    7。緩沖區(qū)的清理同樣需要定時工作的,我們以CacheThread.Class 來命名;

    8. 如果您的參數(shù)信息是以XML的方式來表達的話,那么我也建議用一個單獨的類來管理這些參數(shù)信息:

      Config.Class

    9. 當然,如果您想做得更細一點的話,不妨將客戶端客服務器端的通訊部分也以接口的形式做出來:
   
       CommInterface.Class

    ......(太多,只能有空再說!)     


五、 原型的開發(fā)(二): 怎樣測試您的代碼骨架?

     下面為原型的骨架代碼,希望大家多多提點意見!謝啦!

/* 服務器描述 : 服務器主控線程
1。讀取組態(tài)文件信息
2。建立需求輸入隊列
3。建立需求處理輸出隊列
4。建立需求處理線程
5。建立輸出預處理線程,進行需求處理結果的預處理
6. 建立緩沖區(qū)管理線程,開始對緩沖取進行管理
7。建立服務連接套捷字,接受客戶的連接請求,并建立客戶連接處理線程
*/

import java.io.*;
import java.net.*;
import java.util.*;


public class mainThread extends Thread {

  
  private ServerSocket serverSocket=null;

  /*當前服務器監(jiān)聽的端口*/
  private int serverPort;

  public mainThread(String ConfUrl) {
   try{
      
      /*建立服務器監(jiān)聽套接字*/
      this.serverSocket =new ServerSocket(serverPort);

    }catch(Exception e){
      //
      System.out.println(e.getMessage());
    }

  }

  /*線程的執(zhí)行緒*/
  public synchronized void run(){

    while(listening){
      try{

         Socket sersocket =this.serverSocket.accept();
         
         ClientThread _clientThread=
                            new ClientThread([ParamList]);

         _clientThread.start();
        
        
       }catch(Exception e){

       }

    }

   /*退出系統(tǒng)*/
   System.exit(0);
}


/*
  1。完成客戶的連接請求,并驗證用戶口令
  2。接受用戶的請求,并將請求信息壓入堆棧;
  3。從結果輸出隊列中搜尋對應的結果信息,并將結果信息發(fā)送給客戶;
  4。處理需求處理過程中出現(xiàn)的異常,并將日志信息發(fā)送給日志服務器。
*/

import java.io.*;
import java.net.*;

public class ClientThread extends Thread {

   public ClientThread([ParamList]){

  }
   
  public void synchronized run(){

  }
}
  

/*
  請求隊列:
  1. 將客戶的需求壓入隊列
  2。將客戶的需求彈出隊列
*/


import java.util.*;

public  class InputQuene {

  private Vector InputTeam;

  public InputQuene() {

    /*初始化隊列容量*/
    InputTeam=new Vector(100);

  }

  /*需求進隊函數(shù)*/
  public synchronized void enQuene(Request request){
     InputTeam.add(request);
  }

  /*將一個請求出隊*/
  public synchronized void deQuene(int index){
    this.InputTeam.remove(index);
  }

}




/*
請求隊列處理線程
1。按先進先出的算法從需求隊列中依次取出每一個請求,并進行處理
2。更新請求的處理狀態(tài)
3。清理已經(jīng)處理過的請求
*/


import java.io.*;
import java.util.*;


public class InputProcessThread extends Thread{

  

  private InputQuene _InQuene;

  public InputProcessThread(){
  }
  
  public void run(){
  }

}


/*
  結果輸出隊列:
  1。完成輸出結果的進隊
  2。完成輸出結果的出隊
*/

import java.util.*;
import java.io.*;

public  class OutputQuene {

  //結果輸出隊列容器
  private Vector outputTeam;

  public OutputQuene() {

    //初始化結果輸出隊列
    outputTeam=new Vector(100);
  }

  //進隊函數(shù)
  public synchronized void enQuene(Result result){
    outputTeam.add(result);
  }
  
  
  /*出隊函數(shù)*/
  public synchronized void deQuene(int index){
    outputTeam.remove(index);
  }

}


/*
  結果處理線程:
  1。完成輸出結果的確認
  2。完成輸出結果文件流的生成
  3。完成文件流的壓縮處理
*/
import java.io.*;

public class OutputProcessThread extends Thread{

  
  private OutputQuene _outputQuene;

  public OutputProcessThread([ParamList]) {
    //todo
  }

  /*線程的執(zhí)行緒*/
  public void run(){
    while(doing){
      try{

           /*處理輸出隊列*/
           ProcessQuene();

        }catch(Exception e){
          e.printStackTrace();
        }

    }

  }

}


/*
  日志信息處理線程:
  功能說明:
  1。完成服務器日志信息的保存
  2。根據(jù)設定的規(guī)則進行日志信息的清理

  期望的目標:
    目前日志信息的保存在一個文件當中,以后要自動控制文件的大小。
*/


import java.io.*;
import java.util.*;

public class LogThread extends Thread{
  private LogQuene logquene;
  
  public LogThread([ParamList]){
    //todo
  }

  /*處理日志信息*/
  public void run(){
    while(doing){
     this.processLog();
     try{
       this.sleep(100);
     }catch(Exception e){
     }
    }
   }
}  



/* 功能描述:
   管理緩沖區(qū)中的文件信息,將文件所有的大小控制在系統(tǒng)設定的范圍之內(nèi)
*/
import java.io.*;
import java.lang.*;
import java.util.*;
import java.text.*;
import java.math.*;


public class CacheThread  extends Thread{
  
  private String CachePath;
  
  /*類的建構式 : 參數(shù):URL 緩沖區(qū)目錄的路徑信息*/
  public CacheThread(String Url) {
    this.CachePath =Url;

    /*創(chuàng)建文件搜索類*/
    try{
      this.CacheDir =new File(this.CachePath);
    }catch(Exception e){
      e.printStackTrace();
    }

  }

  //線程的執(zhí)行緒
  public void run(){
    //定時清理緩沖區(qū)中的文件
  }

  ......

}