亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Java后臺服務程序設計

2019-11-18 14:09:22
字體:
來源:轉載
供稿:網友

  內容:

為什么需要后臺服務程序?
通用服務器框架
服務與監聽
服務控制
服務器實現和運行
參考資源
作者簡介

何千軍 (heqianjun@163.net)
軟件工程師,獨立顧問和自由撰稿人

在很多大型軟件項目中,都有一些極為重要的后臺服務程序,它們并不處理具體的系統業務邏輯,但對整個系統資源和服務的協調治理卻是不可或缺。本文討論如何完整地編寫一個后臺服務治理程序,并通過一個具體的后臺服務治理例子來說明這一技術實現的技巧。
為什么需要后臺服務程序?
在許多大型軟件項目中,后臺服務程序都扮演著極為重要的角色。它們無處不在,例如操作系統的內核程序處理各種對操作系統的內部調用;數據庫系統的核心治理進程處理各種對數據庫的讀寫操作和進程、資源的治理;大型ERP軟件的內核治理程序要完成各種應用模塊的資源、通訊治理等等。它們使系統的各種服務、資源與應用的表示之間形成了一個松耦合關系,這樣就極大地增加了軟件系統的穩定性和伸縮性。后臺服務程序也就是相當于軟件系統的治理調度中心,它是軟件系統的中心處理器,是保證應用高效運行的內核程序。

在不同的軟件系統中,由于軟件的復雜程度和功能的不同使得各種軟件系統的后臺服務程序都有存在較大的差異。但是后臺服務程序還是有很多共同的特點,一個基本的后臺服務程序大概可以由四個部分構成:通用服務器框架、服務與監聽、服務控制、服務器實現。下面我們就使用具體的代碼來實現一個基本的后臺服務器程序。

通用服務器框架
在開發后臺服務程序中,我們首先實現一個通用服務器框架類,它能在多個端口提供多線程的服務(由多個Service對象定義),并且能夠在系統運行時動態地調用和實例化Service類并加載新的服務或卸除已加載的服務。

清單 1顯示了如何編制一個通用服務器框架類文件。

【清單 1:通用服務器框架類文件Server.java

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

public class Server {

PRotected Map services;
Set connections;
int maxConnections;
int freeConn;

ThreadGroup threadGroup;
private int currentConn;
private PrintWriter log = new PrintWriter(System.out, true);
public boolean connected = false;
public Properties proPort, proNum;

public synchronized void setControlFlag() {
connected = true;
}

public synchronized void removeControlFlag() {
connected = false;
}

public void setProperty(Properties proPort, Properties proNum) {
this.proPort = proPort;
this.proNum = proNum;
}

public Server(int maxConn) {
this.maxConnections = maxConn;
this.freeConn=maxConnections;
this.threadGroup = new ThreadGroup(Server.class.getName());
currentConn = 0;
this.services = new HashMap();
this.connections = new HashSet(maxConnections);
}

public synchronized void addService(Service service,int port, int maxConn) throws IOException {
String servicename = service.getClass().getName();
Integer key = new Integer(port);
if (services.get(key) != null) throw new IllegalArgumentException("端口:" + port + " 已經被占用!");
if (getfreeConnections(maxConn)>=0) {
Listener listener = new Listener(this, port, service, maxConn);
services.put(key,listener);
log.println("啟動" + servicename + "服務在" + port +"端口上");
listener.start();
} else {
System.err.println("系統并發連接限制已經達到最大值!");
System.err.println("服務" + servicename + " 啟動失敗!");
}
}


public synchronized void addService(Service service,int port) throws IOException {
this.addService(service,port,10);
}

public synchronized boolean removeService(int port) {
Integer key = new Integer(port);
int maxConn =10;
final Listener listener = (Listener) services.get(key);
if (listener == null) {
log.println("Service " + " isn′t started on port " + port);
return false;
}

services.remove(key);
listener.pleaseStop();
freeConn+=listener.maxConn;
log.println("Close " + listener.service + " on port " + port);
return true;
}

public synchronized void displayStatus(PrintWriter out) {
Iterator keys = services.keySet().iterator();
while (keys.hasNext()) {
Integer port = (Integer) keys.next();
Listener listener = (Listener) services.get(port);
out.println("服務" + listener.service + "運行" + port + " ");
}

out.println("連接限制為" + maxConnections);

Iterator conns = connections.iterator();
while (conns.hasNext()) {
Socket s = (Socket) conns.next();
int sport = s.getLocalPort();
Listener listen = (Listener) services.get(new Integer(sport));
String servicename = listen.service;
out.println(servicename + "響應請求在" + s.getInetAddress().getHostAddress() + "的" + sport + "端口上");
}

out.println("當前連接數為" + currentConn);
out.println("當前系統空閑連接數為" + freeConn);
}

private synchronized int getfreeConnections(int maxConn) {
int num = -1;
if (freeConn >= maxConn) {
freeConn-=maxConn;
num = freeConn;
}
return num;
}

public synchronized int getConnections() {
return currentConn;
}

public synchronized int addConnections(Socket s) {
connections.add(s);
return currentConn++;
}

public synchronized int removeConnections(Socket s) {
connections.remove(s);
try {
s.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return currentConn--;
}

public synchronized int getConnections(int connections) {
int num = 0;
if ((num=freeConn-connections) >= 0) {
freeConn = num;
} else num = -1;
return num;
}

private synchronized int getFreeConn() {
return freeConn;
}
}






如上所述可知,服務器框架類Server主要是通過端口到監聽器影射的散列表services來治理服務對象,Server類的幾個主要方法說明如下:

addService方法:此方法能夠在特定的端口上創建新的服務,即在指定端口上運行指定的Service對象。

removeService方法:此方法使服務器停止指定端口上的服務,并不終止連接,僅使服務器停止接受新的連接。

displayStatus方法:此方法用于打印指定流上服務器的狀態信息。

服務與監聽
每個服務都對應著一個監聽對象,監聽指定端口的連接并在獲得連接請求時調用addConnection(Socket s, Service service)方法來取得(釋放)一個連接。清單 2顯示了如何編制一個監聽類文件。
【清單 2:Listener.java的一個簡單實現】

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

public class Listener extends Thread {
private ServerSocket listener;
private int port;
String service;
Set connections;
private Service runService;
private boolean stop_flag = false;
int maxConn;
private PrintWriter log = new PrintWriter(System.err, true);
private ThreadGroup group;
private int currentConnections = 0;
Server server;
Socket client = null;

public Listener(Server server, int port, Service service, int maxConn, boolean bl) throws IOException {

this.server = server;
this.port = port;
this.service = service.getClass().getName();
this.maxConn = maxConn;
this.group = server.threadGroup;
this.connections = server.connections;
listener = new ServerSocket(this.port);
if (bl == false) listener.setSoTimeout(600000);
this.runService = service;
if (!stop_flag) {
for (int i=0;i<this.maxConn;i++) {
ConnectionHandler currentThread = new ConnectionHandler(server,logStream);
new Thread(this.group, currentThread, this.service+this.port+i).start();
this.logStream.realLog("向線程組" + group.toString() + "添加一個線程" + this.service+this.port+i);
}
} else throw new IllegalArgumentException("系統并發連接限制已經超過最大值!!");
}

public Listener(Server server, int port, Service service, int maxConn) throws IOException {
this(server, port, service, maxConn, false);
}


public void pleaseStop() {
this.stop_flag = true;

try {
listener.close();
} catch (Exception e) {
}
this.interrupt();
}

public void run() {

while(!stop_flag) {
try {
client = listener.accept();
addConnection(client,runService);
} catch (Exception e) {}
}

try {
client.close();
} catch (IOException e) {}
}

private synchronized void addConnection(Socket s, Service service) {
ConnectionHandler.requestToHandler(s, service);
}

}


在實際處理過程中,Listener對象通過在指定端口上與指定服務的綁定實現監聽過程,主要的幾個方法說明如下:
pleaseStop:以禮貌的方法停止接受連接。
addConnection:把指定要處理的服務放到線程池中,以等待空閑的線程處理服務。
監聽對象通過傳遞一個Service對象并喚醒它的serve()方法才真正提供了服務。下面我們就來實現一個具體的服務:

服務接口Service只有一個抽象方法serve(InputStream in, OutputStream out),它所有服務實現所必須重寫的一個方法,Listing 3顯示了一個Service接口的定義。 【清單 3:定義一個Service接口】

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

public interface Service {
public void serve(InputStream in, OutputStream out) throws IOException;
}




編寫一個簡單的顯示時間服務類:見清單 4。 【清單 4:一個顯示系統當前時間的服務類Timer.java】

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

public class Timer implements Service {

public Timer() {

}

public void serve(InputStream in, OutputStream out) throws IOException {
String timeFormat = "yyyy-MM-dd hh:mm:ss";
SimpleDateFormat timeFormatter = new SimpleDateFormat(timeFormat);
BufferedReader from_client = new BufferedReader(new InputStreamReader(in));
PrintWriter outPrint = new PrintWriter(out);
String sDate = timeFormatter.format(new Date());

outPrint.println("當前時間是:" + sDate);
outPrint.flush();
try {
from_client.close();
outPrint.close();
}catch (Exception e){}
}
}



通過實現Service接口可以編寫很多的服務實現提供各種不同的服務,讀者有愛好也可自己編寫一個服務來測試一下。

服務控制
服務控制是在服務器運行時動態地操作控制服務器,如系統運行時,動態地裝載(卸載)服務,顯示服務器的狀態信息等等。為了簡化基本后臺服務系統的復雜程度,我們采用創建一個ControlService服務實例來在運行時治理服務器。ControlService實現了基于命令的協議,可用密碼保護操縱服務器,代碼如清單 5所示:

【清單 5:服務控制類文件ControlService.java】
import java.io.*;
import java.util.*;
import java.net.*;

import dvb.kuanshi.kssms.util.*;
import dvb.kuanshi.kssms.server.Server;

public class ControlService implements Service {
Server server;
String passWord;

public ControlService(Server server, String password) {
this.server = server;
this.password = password;
}

public void serve(InputStream in, OutputStream out) throws IOException {

boolean authorized = false;
BufferedReader from_client = new BufferedReader(new InputStreamReader(in));
PrintWriter to_console = new PrintWriter(System.out, true);
to_console.println("后臺治理服務響應請求! ");
PrintWriter to_client = new PrintWriter(out);
synchronized (this) {
if(server.connected) {
to_client.println("已經有用戶連接,本服務僅答應一個連接! ");
to_client.close();
return;
} else server.setControlFlag();
}

to_client.println("Remote Console>");
to_client.flush();

String line;

while ((line=from_client.readLine())!=null) {

int len = line.indexOf("Remote Console>");
line = line.substring(len+1,line.length());
String printStr;
try {
StringTokenizer st = new StringTokenizer(line);
int count = st.countTokens();
if (!st.hasMoreElements()) continue;

String first = st.nextToken().toLowerCase();
if (first.equals("password")) {
String pwd = st.nextToken();
if (pwd.equals(this.password)) {
to_client.println("OK");
authorized = true;
} else to_client.println("密碼無效,請重試! ");

} else if (first.equals("add")) {
if(!authorized) to_client.println("請登陸! ");
else {
count--;
String servicename;
int Port;
boolean flag = true;
if (count>0) {
servicename = st.nextToken();
Port = Integer.parseInt(st.nextToken());
server.addService(loadClass(servicename1), Port);
to_client.println("服務" + servicename + "已經加載 ");
flag = false;
}
if (flag) to_client.println("系統不能啟動非法服務:" + servicename);
else {to_client.println("請輸入服務名! ");}
}
} else if (first.equals("remove")) {
if(!authorized) to_client.println("請登陸! ");
else {
count--;
if (count>0) {
int port = Integer.parseInt(st.nextToken());
boolean bl = server.removeService(port);
if (bl) to_client.println("端口: " + port +"上的服務已經卸載 ");
else to_client.println("端口: "+ port +"上無任何服務運行,卸載操作失敗! ");
} else to_client.println("請輸入端口名! ");
}
} else if(first.equals("status")) {
if(!authorized) to_client.println("請登陸! ");
else server.displayStatus(to_client);
} else if(first.equals("help")) {
if(!authorized) to_client.println("請登陸! ");
else printHelp(to_client);
} else if(first.equals("quit")) break;
else to_client.println("命令不能識別! ");
} catch(Exception e) {to_client.println("系統后臺出錯" + e.getMessage() +" ");
printHelp(to_client);
}
to_client.println("Remote Console>");
to_client.flush();
}
to_client.flush();
authorized = false;
server.removeControlFlag();
to_client.close();
from_client.close();
}

private void printHelp(PrintWriter out) {
out.println("COMMANDS:" +
" password <password> " +
" add <servicename> <port> " +
" remove <port> " +
" status " +
" help " +
" quit ");
}

protected Service loadClass(String servicename) {
Service s = null;

try {
Class serviceClass = Class.forName(servicename);
s = (Service) serviceClass.newInstance();
} catch (Exception e) {
}

return s;
}
}



服務器實現和運行
服務器實現主要完成服務器的初始化,啟動服務控制實例等工作,代碼如清單 6所示:


【清單 6:runServer.java的一個簡單實現】
import java.util.*;

public class runServer {
public runServer() {
}

public static void main(String[] args) {
try {
int argLen = args.length;
System.out.println("正在初始化系統請等待......");
System.out.println("");
int maxConn = 30;

Server server = new Server(maxConn);

System.out.println("################################################################");
System.out.println("# #");
System.out.println("# 后臺服務治理系統 #");
System.out.println("# #");
System.out.println("################################################################");
System.out.println();
if (argLen>2) {
for (int i = 0;i<argLen;i++) {
if (args[i].equals("-s")) {
i++;
String password = args[i];
i++;
int port = Integer.parseInt(args[i]);
server.addService(new ControlService(server,password), port, 2);
} else {
String servicename = args[i];
i++;
int port = Integer.parseInt(args[i]);
server.addService(loadClass(servicename), port);
}
}

} else throw new IllegalArgumentException("參數數目不正確!");
System.out.println("系統啟動,進入監聽服務模式......");
} catch (Exception e) {
throw new IllegalArgumentException(e.getMessage());
}
}

protected static Service loadClass(String servicename) {
Service s = null;
try {
Class serviceClass = Class.forName(servicename);
s = (Service) serviceClass.newInstance();
} catch (Exception e) {
}
return s;
}
}


 
下面我們就可以啟動示例程序來測試一下了。

如清單 7所示,以密碼保護方式(密碼為test)啟動后臺服務,在6809啟動服務控制實例,在6810端口啟動。

【清單 7:啟動后臺服務程序】
% java runServer -s test 6809 Timer 6810





在另外一個窗口,執行如下命令,將顯示當前系統的時間。

% java clientConnect 6810



在另外一個窗口,執行如下命令,你將能查看系統服務狀態信息,并動態地裝載你寫的服務對象,你可以測試一下。

% java clientConnect 6809



現在,一個基本的后臺服務程序即編制完成了。實際上,一個大型軟件的后臺服務程序是非常復雜的,上面的例子希望能起到拋磚引玉的效果。要寫出性能良好的后臺服務程序還有很多工作要做。

參考資源

要了解更多的 Java信息,請閱讀 java.sun.com的 主頁。
下載后臺服務程序示例全部代碼:code.zip

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美在线视频导航| 欧美—级a级欧美特级ar全黄| 欧美福利视频在线| 欧日韩不卡在线视频| 国产亚洲精品久久久久动| 久久躁狠狠躁夜夜爽| 亚洲女人天堂成人av在线| 一区二区三区四区在线观看视频| 日韩一区二区在线视频| 欧美理论电影网| 欧美激情乱人伦一区| 日韩最新中文字幕电影免费看| 日韩精品欧美国产精品忘忧草| 亚洲第一福利网站| 日韩欧美一区二区三区久久| 国产精品你懂得| 欧美成人精品在线| 亚洲美女又黄又爽在线观看| 日韩在线欧美在线国产在线| 97av在线视频| 色偷偷偷亚洲综合网另类| 高清在线视频日韩欧美| 久久99久久亚洲国产| 亚洲国产精品久久久久秋霞蜜臀| 国产欧美日韩中文字幕| 欧美成人精品三级在线观看| 欧美综合在线第二页| 日韩精品在线免费播放| 久久99久久99精品免观看粉嫩| 国产aⅴ夜夜欢一区二区三区| 精品偷拍各种wc美女嘘嘘| 国产精品高精视频免费| 欧美理论电影在线播放| 亚洲精品自产拍| 欧美激情亚洲自拍| 日本在线观看天堂男亚洲| 国产一区二区三区欧美| 国外日韩电影在线观看| 欧美亚洲另类激情另类| 亚洲人成电影网站色| 深夜福利国产精品| 亚洲xxxxx性| 国产成人精品视频| 亚洲综合小说区| 高清视频欧美一级| 欧美在线观看一区二区三区| 亚洲欧美激情一区| 欧美电影在线观看高清| 亚洲另类欧美自拍| 国产欧美日韩免费看aⅴ视频| 国产婷婷97碰碰久久人人蜜臀| 亚洲第一免费网站| 欧美一级淫片videoshd| 日韩欧美在线免费| 精品国偷自产在线视频99| 欧美小视频在线| 欧美一级淫片videoshd| 亚洲欧洲视频在线| 精品亚洲男同gayvideo网站| 国产精品福利小视频| 2021久久精品国产99国产精品| 亚洲xxxxx性| 国产精品日韩欧美大师| 97热在线精品视频在线观看| 亚洲美女在线观看| 午夜精品在线视频| 亚洲欧美日韩另类| 精品国内自产拍在线观看| 国产精品成人aaaaa网站| 国产一区二区三区在线播放免费观看| 国产一区二区三区在线视频| 亚洲精品v欧美精品v日韩精品| 91精品国产成人| 色樱桃影院亚洲精品影院| 亚洲精品大尺度| 在线观看国产成人av片| 国产91对白在线播放| 欧美电影免费在线观看| 欧美成人一区二区三区电影| 日韩在线免费高清视频| 亚洲色无码播放| 精品久久久久久国产91| 欧美一区二区三区……| 国产精品视频男人的天堂| 亚洲成年人在线播放| 日韩h在线观看| 欧美精品久久久久久久免费观看| 久久精品免费电影| 欧美激情精品久久久久久蜜臀| 久久久精品久久久久| 日韩久久午夜影院| 欧美与欧洲交xxxx免费观看| 91欧美精品午夜性色福利在线| 欧美大肥婆大肥bbbbb| 久久久噜久噜久久综合| 国产精品久久久久久久久久尿| 一区二区中文字幕| 亚洲天堂av电影| 欧美另类暴力丝袜| 日韩精品在线影院| 亚洲成人av片| 91免费欧美精品| 欧洲美女7788成人免费视频| 欧美午夜精品久久久久久浪潮| 国产精品成人v| 欧美精品激情在线| 国产97在线亚洲| 92看片淫黄大片看国产片| 色综合伊人色综合网| 麻豆国产va免费精品高清在线| 日韩激情av在线播放| 中文字幕国产亚洲| 亚洲欧美成人一区二区在线电影| 亚洲免费福利视频| 亚洲人成免费电影| 97视频在线免费观看| 欧美成人精品在线播放| 久久99国产综合精品女同| 欧美国产视频日韩| 亚洲欧美在线磁力| 国产精品影院在线观看| 亚洲综合精品一区二区| 色悠久久久久综合先锋影音下载| 亚洲一区二区三区乱码aⅴ蜜桃女| 操人视频在线观看欧美| 91视频国产高清| 亚洲xxxxx性| 高清一区二区三区日本久| 国产精品视频不卡| 91精品国产91久久久久久不卡| 日韩精品久久久久久久玫瑰园| 日韩在线国产精品| 91爱视频在线| 亚洲国产成人久久综合一区| 亚洲福利在线播放| 97超碰国产精品女人人人爽| 日韩欧美一区二区三区| 亚洲视频一区二区三区| 欧美精品18videosex性欧美| 国产亚洲美女精品久久久| 欧美专区在线播放| 成人天堂噜噜噜| 国产啪精品视频网站| 欧美多人爱爱视频网站| 欧美日韩国产中文精品字幕自在自线| 日本视频久久久| 51ⅴ精品国产91久久久久久| 国产精品一区二区久久精品| 日本成人黄色片| 国产欧美日韩精品在线观看| 亚洲乱码国产乱码精品精| 亚洲欧美日韩中文在线| 日本久久久a级免费| 久久成人18免费网站| 久久中文久久字幕| 亚洲sss综合天堂久久| 国内偷自视频区视频综合| 欧美日韩亚洲视频| 亚洲一区第一页| 成人黄色在线播放| 国产精品18久久久久久首页狼| 国产成人精品久久二区二区| 伊人久久免费视频| 45www国产精品网站|