赞
踩
网络上相关的资料很少,我又恰好要做这个,索性就把它写出来,我也是在摸索中,理解的不正确的地方这里道个歉,欢迎指正。也算是为amoeba的推广做的一点微不足道的贡献吧!
下图是我的eclipse的Amoeba工程(怎么导入的请看上篇文章)的目录的一部分:
图中的红色标记的就是Amoeba的启动文件。这里需要说明的是,amoeba使用的批处理的方式启动的,批处理里面首先是找到classword,然后加载类,而加载的第一个类就是上述那个类了。
下面打开AmoebaProxyServer.java文件,我为重要的语句加上了注释,请详细查看。
-
- public class AmoebaProxyServer {
- private static Logger log = Logger.getLogger(AmoebaProxyServer.class);
- private static Logger repoterLog = Logger.getLogger("report");
- //定义两个Logger文件,这是Log4j的用法,不是重点
- /** Used to generate "state of server" reports. */
- protected static ArrayList<Reporter> reporters = new ArrayList<Reporter>();
- /** The time at which the server was started. */
- protected static long serverStartTime = System.currentTimeMillis();
-
- /** The last time at which {@link #generateReport} was run. */
- protected static long lastReportStamp = serverStartTime;
-
- public static void registerReporter(Reporter reporter) {
- reporters.add(reporter);
- }
-
- /**
- * Generates a report for all system services registered as a
- * {@link Reporter}.
- */
- public static String generateReport() {
- return generateReport(System.currentTimeMillis(), false);
- }
-
- /**
- * Generates and logs a "state of server" report.
- */
- protected static String generateReport(long now, boolean reset) {
- long sinceLast = now - lastReportStamp;
- long uptime = now - serverStartTime;
- StringBuilder report = new StringBuilder(" State of server report:"+StringUtil.LINE_SEPARATOR);
-
- report.append("- Uptime: ").append(StringUtil.intervalToString(uptime)).append(StringUtil.LINE_SEPARATOR);
- report.append("- Report period: ").append(StringUtil.intervalToString(sinceLast)).append(StringUtil.LINE_SEPARATOR);
-
- // report on the state of memory
- Runtime rt = Runtime.getRuntime();
- long total = rt.totalMemory(), max = rt.maxMemory();
- long used = (total - rt.freeMemory());
- report.append("- Memory: ").append(used / 1024).append("k used, ");
- report.append(total / 1024).append("k total, ");
- report.append(max / 1024).append("k max").append(StringUtil.LINE_SEPARATOR);
-
- for (int ii = 0; ii < reporters.size(); ii++) {
- Reporter rptr = reporters.get(ii);
- try {
- rptr.appendReport(report, now, sinceLast, reset,repoterLog.getLevel());
- } catch (Throwable t) {
- log.error("Reporter choked [rptr=" + rptr + "].", t);
- }
- }
-
- // only reset the last report time if this is a periodic report
- if (reset) {
- lastReportStamp = now;
- }
-
- return report.toString();
- }
-
- protected static void logReport(String report) {
- repoterLog.info(report);
- }
-
- //上面都是与日志文件有关的操作,这些我们可以根据自己的需求进行修改
- /**
- * @param args
- * @throws IOException
- * @throws Exception
- * @throws IllegalAccessException
- * @throws InstantiationException
- */
- //下面进入main开始开始执行
- public static void main(String[] args) throws Exception {
- String level = System.getProperty("benchmark.level", "warn");
- System.setProperty("benchmark.level", level);
- if(args.length>=1){
- ShutdownClient client = new ShutdownClient(MonitorConstant.APPLICATION_NAME);
- /**
- * APPLICATION_NAME是一个常量,这个常量定义在MonitorConstant.java文件中,这个文件在Amoeba/src/java/com/meidusa/amoeba/monitoer中
- * ShutdownClient是一个监视类,由它的run函数负责获取网络数据包并对其进行分析建立连接等。
- * ShutdownClient的对象client在下面的第二个if中调用了run函数,这个run函数执行成功的话,则输出amoeba server is running with ...的信息
- * 这样就是我们看到的amoeba启动时显示的原因了。
- *
- */
- MonitorCommandPacket packet = new MonitorCommandPacket();
- if("start".equalsIgnoreCase(args[0])){
- packet.funType = MonitorCommandPacket.FUN_TYPE_PING;
- if(client.run(packet)){
- /**
- * 根据上一个注释可以知道关键及时这个client的run函数了。
- * 分析run函数之前,先关注它的参数packet,packet的类型是MonitorCommandPacket。
- * 从MonitorCommandPacket.java可以知道这个类继承了AbstractPacket类。
- * AbstractPacket类在src/amoeba/src/java/net/packet中。看它的源码知道,这个类是抽象类
- * Packet的派生类。
- * 进入client的run函数后,请转到run函数继续看分析
- */
- System.out.println("amoeba server is running with port="+client.getPort());
- System.exit(-1);
- }
- }else{
- packet.funType = MonitorCommandPacket.FUN_TYPE_AMOEBA_SHUTDOWN;
- if(client.run(packet)){
- System.out.println("amoeba server shutting down with port="+client.getPort());
- }else{
- System.out.println("amoeba server not running with port="+client.getPort());
- }
- System.exit(0);
- }
- }else{
- System.out.println("amoeba start|stop");
- System.exit(0);
- }
- //执行完上面的if块后到这里继续执行。
- String log4jConf = System.getProperty("log4j.conf","${amoeba.home}/conf/log4j.xml");
- log4jConf = ConfigUtil.filter(log4jConf);
- File logconf = new File(log4jConf);
- if(logconf.exists() && logconf.isFile()){
- DOMConfigurator.configureAndWatch(logconf.getAbsolutePath(), System.getProperties());
- }
-
- final Logger logger = Logger.getLogger(AmoebaProxyServer.class);
- String config = System.getProperty("amoeba.conf","${amoeba.home}/conf/amoeba.xml");
- String contextClass = System.getProperty("amoeba.context.class",ProxyRuntimeContext.class.getName());
-
- if(contextClass != null){
- ProxyRuntimeContext context = (ProxyRuntimeContext)Class.forName(contextClass).newInstance();
- ProxyRuntimeContext.setInstance(context);
- }
-
- config = ConfigUtil.filter(config);
- File configFile = new File(config);
-
- if(config == null || !configFile.exists()){
- logger.error("could not find config file:"+configFile.getAbsolutePath());
- System.exit(-1);
- }else{
- ProxyRuntimeContext.getInstance().init(configFile.getAbsolutePath());
- }
-
- registerReporter(ProxyRuntimeContext.getInstance());
- for(ConnectionManager connMgr :ProxyRuntimeContext.getInstance().getConnectionManagerList().values()){
- registerReporter(connMgr);
- }
-
- Map<String,Object> context = new HashMap<String,Object>();
- context.putAll(ProxyRuntimeContext.getInstance().getConnectionManagerList());
-
- List<BeanObjectEntityConfig> serviceConfigList = ProxyRuntimeContext.getInstance().getConfig().getServiceConfigList();
-
- for(BeanObjectEntityConfig serverConfig : serviceConfigList){
- Service service = (Service)serverConfig.createBeanObject(false,context);
-
- service.init();
- service.start();
- PriorityShutdownHook.addShutdowner(service);
- registerReporter(service);
- }
- //一直到这里进入线程,每六十秒一次循环
- new Thread(){
- {
- this.setDaemon(true);
- this.setName("Amoeba Report Thread");
- }
- public void run(){
- while(true){
- try {
- Thread.sleep(60*1000);
- } catch (InterruptedException e) {
- }
- try{
- logReport(generateReport());
- }catch(Exception e){
- logger.error("report error",e);
- }
- }
- }
- }.start();
- }
- }
- public boolean run(MonitorCommandPacket command) {
- //从AmoebaProxyServer类的main函数转到这里继续执行
- //可以看到正常启动Amoeba的情况下(因为没有连接建立)这个if都能成立的
- if(port <=0){
- socketInfoFile = new File(ConfigUtil.filter("${amoeba.home}"),appplicationName+".shutdown.port");
- if(!socketInfoFile.exists()){
- System.out.println("b");//所以这个输出是可以得到的,然后返回false,又回到main函数中去了
- return false;
- }
- //当有连接建立时,上面的if块就不执行,而是执行下面的块
- try {
- BufferedReader reader = new BufferedReader(new FileReader(socketInfoFile));
- String sport = reader.readLine();
- String tmp[] = StringUtil.split(sport, ":");
- if(tmp.length <=1){
- System.out.println("c");
- return false;
- }
- this.port = Integer.parseInt(tmp[1]);
- this.host = tmp[0];
- reader.close();
- }catch (Exception e) {
- e.printStackTrace();
- System.out.println("d");
- return false;
- }
- }
启动过程中,上面的run函数会返回false,回到main函数中去。根据main的代码知道下面代码:
- if(client.run(packet)){
- /**
- * 根据上一个注释可以知道关键及时这个client的run函数了。
- * 分析run函数之前,先关注它的参数packet,packet的类型是MonitorCommandPacket。
- * 从MonitorCommandPacket.java可以知道这个类继承了AbstractPacket类。
- * AbstractPacket类在src/amoeba/src/java/net/packet中。看它的源码知道,这个类是抽象类
- * Packet的派生类。
- * 进入client的run函数后,请转到run函数继续看分析
- */
- System.out.println("amoeba server is running with port="+client.getPort());
- System.exit(-1);
- }
会跳出这个if,然后跳到main函数的下列代码处执行:
- //执行完上面的if块后到这里继续执行。
- String log4jConf = System.getProperty("log4j.conf","${amoeba.home}/conf/log4j.xml");
- log4jConf = ConfigUtil.filter(log4jConf);
- File logconf = new File(log4jConf);
- if(logconf.exists() && logconf.isFile()){
- DOMConfigurator.configureAndWatch(logconf.getAbsolutePath(), System.getProperties());
- }
-
- final Logger logger = Logge
最后进入while循环,到此amoeba的启动算是完成了,然后就是一直的监听了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。