- 浏览: 44287 次
- 性别:
最近访客 更多访客>>
最新评论
-
kellymalue:
额,毕博是真正的外企风范。这句话我貌似做过MSN签名。不过很中 ...
真正的外企风范——毕博 -
哇你长得真高:
我也有个姥爷姓毕
真正的外企风范——毕博 -
lfsfxy9:
怎么说的都有,远近高低各不同~
真正的外企风范——毕博 -
lndalian2000:
谢谢楼主介绍。只做参考。
真正的外企风范——毕博 -
whaosoft:
为什么天津没这样的公司
真正的外企风范——毕博
webMethods IS中负责服务器启动的类有四个:执行入口类com.wm.app.b2b.server.Main、服务器初始化类com.wm.app.b2b.server.Server、以及两个辅助类com.wm.util.UniqueApp、com.wm.util.AppRegistry。
让我们先来看看Main的main以及注释:
看到这里大家可能会产生疑问,这个UniqueApp的实例的ua到底有什么用呢,为什么要在Server初始化之前先start它,初始化之后又quit呢?要解答这些问题让我们先看看这个UniqueApp究竟做了什么事:
UniqueApp类的start方法、send方法和runRegistry方法:
这里可以很清楚的看到,UniqueApp是一个socket的client端,它的作用就是用一些特定的原语连接localhost上的uaport端口,如果这个端口没有响应或者响应的不对,它就“new AppRegistry(iden_, port_)”。
AppRegistry是一个实现了Runnable接口的类,它又做了什么呢?请看:
AppRegistry类的构造方法、run方法、openSocket方法以及解析原语的processLineReceived方法:
由此看出AppRegistry是一个单线程的Socket Server。虽然到了这里我们都知道了UniqueApp和AppRegistry的作用,但是疑惑仍然没有解答,为什么要在服务器启动之前先连接或者启动一个Socket Server呢?
要得到答案,让我们来看看Server初化始化的时候究竟做了些什么:
Server类的start方法:
这里要说明的是Server类是Thread类的子类,它的run方法如下:
上面的代码不用多解释,大家可以看到IS启动做了哪些事情,IS分为哪些模块,以及这些模块的加载顺序。
IS启动的操作很多,启动时间也比较长,而且有“PortManager.init()”、“saveConfigFiles()”这样需要独占运行的端口占用和文件操作,如果是在同一个JVM上我们可以用Synchronized,如果是不到的JVM呢?答案揭晓了,UniqueApp的作用是使用端口占用的方式在IS启动阶段实现互斥,即对于同一个启动文件夹下的配置一台机器只能有一个IS在启动,否则会报出“Server cannot execute. A server with this configuration is already running.”的错误。
让我们先来看看Main的main以及注释:
public static void main(String argv[]) { int port = 0; String serviceName = null; //处理在启动脚本中传入的几个参数 for(int i = 0; i < argv.length; i++) { if(argv[i].equals("-port") && i < argv.length - 1) port = Integer.valueOf(argv[1 + i++]).intValue(); if(argv[i].equals("-home") && i < argv.length - 1) Config.setProperty("watt.server.homeDir", argv[1 + i++]); if(argv[i].equals("-service") && i < argv.length - 1) serviceName = argv[1 + i++]; } if(port != 0) Config.setProperty("watt.server.port", Integer.toString(port)); UniqueApp ua = null; int uaport = 4321; //获得一个叫uaport的端口参数,默认是4321 String uapstr = System.getProperty("watt.server.uaport"); if(uapstr != null) try { uaport = Integer.parseInt(uapstr); } catch(NumberFormatException _ex) { } //用这个uaport创建一个app ua = new UniqueApp(uaport); try { ua.start(); //调用Server这个类的start方法初始化IS Server.start(argv); ua.quit(); if(Server.restart()) { try { if(serviceName != null) { String homepath = System.getProperty("watt.server.homeDir", "."); String cmd = homepath + File.separator + "bin" + File.separator + "RestartService.exe " + serviceName; Runtime.getRuntime().exec(cmd); } } catch(Exception e) { e.printStackTrace(); } System.exit(42); } else { System.exit(0); } } catch(com.wm.util.UniqueApp.DeniedException _ex) { System.out.println("Server cannot execute. A server with this configuration is already running."); System.exit(0); } }
看到这里大家可能会产生疑问,这个UniqueApp的实例的ua到底有什么用呢,为什么要在Server初始化之前先start它,初始化之后又quit呢?要解答这些问题让我们先看看这个UniqueApp究竟做了什么事:
UniqueApp类的start方法、send方法和runRegistry方法:
public void start() throws DeniedException { if(port_ > lastPort_) debugPrint("UNQ ERROR: port_ (" + port_ + ") > lastPort_ (" + lastPort_ + ")"); for(; port_ <= lastPort_; port_++) { debugPrint("UNQ attempting connection on port " + port_); try { debugPrint("UNQ " + iden_ + " sending initial message"); String response = send("init"); debugPrint("UNQ " + iden_ + " got response " + response); if(response == null) { debugPrint("UNQ connected on port " + port_ + ", but no response"); continue; } if(response.equals("DENIED")) throw new DeniedException(); if(response.equals("OK")) { runHeartbeat(); break; } debugPrint("UNQ connected on port " + port_ + ", but incomprehensible response"); continue; } catch(IOException ioe) { if(DEBUG) ioe.printStackTrace(System.out); runRegistry(); } break; } } public String send(String type) throws IOException { Socket socket = new Socket("localhost", port_); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); String msg = type + ": " + iden_; out.println(msg); out.flush(); return in.readLine(); } public void runRegistry() { debugPrint("UNQ " + iden_ + " starting registry on port " + port_); registry_ = new AppRegistry(iden_, port_); }
这里可以很清楚的看到,UniqueApp是一个socket的client端,它的作用就是用一些特定的原语连接localhost上的uaport端口,如果这个端口没有响应或者响应的不对,它就“new AppRegistry(iden_, port_)”。
AppRegistry是一个实现了Runnable接口的类,它又做了什么呢?请看:
AppRegistry类的构造方法、run方法、openSocket方法以及解析原语的processLineReceived方法:
public AppRegistry(String iden, int port) { info_ = new HashMap(); out_ = null; socket_ = null; info_.put(iden, new Long(0x7fffffffffffffffL)); port_ = port; Thread t = new Thread(this); t.setDaemon(true); t.start(); } public void run() { debugPrint("REG running"); openSocket(); if(socket_ == null) debugPrint("REG no socket"); else while(socket_ != null) processConnection(); debugPrint("REG stopped"); } protected void openSocket() { try { debugPrint("REG running socket server on port " + port_); socket_ = new ServerSocket(port_); socket_.setSoTimeout(3000); } catch(IOException ioe) { if(DEBUG) ioe.printStackTrace(System.out); debugPrint("REG failed to open socket"); socket_ = null; } } protected void processLineReceived(String line) { debugPrint("REG processLineReceived(" + line + ")"); int pos = line != null ? line.indexOf(": ") : -1; if(pos != -1) { String type = line.substring(0, pos); String identifier = line.substring(pos + 2); if(type.equals("init")) handleInit(identifier); else if(type.equals("update")) update(identifier); else if(type.equals("quit")) quit(identifier); else debugPrint("REG unknown type: '" + type + "' in line: '" + line + "'"); } }
由此看出AppRegistry是一个单线程的Socket Server。虽然到了这里我们都知道了UniqueApp和AppRegistry的作用,但是疑惑仍然没有解答,为什么要在服务器启动之前先连接或者启动一个Socket Server呢?
要得到答案,让我们来看看Server初化始化的时候究竟做了些什么:
Server类的start方法:
public static void start(String args[]) { gServer = new Server(args); gServer.start(); try { gServer.join(); } catch(Exception _ex) { } }
这里要说明的是Server类是Thread类的子类,它的run方法如下:
public void run() { try { long start = System.currentTimeMillis(); com.wm.util.Config.setProperty("watt.server", "true"); gRestart = false; gInShutdown = false; gListeners = new Values(); gResources = new Resources(System.getProperty("watt.server.homeDir", "."), true); gConfFile = gResources.getConfigFile("server.cnf"); gResources.getLogJobsInDir(); gResources.getLogJobsOutDir(); gResources.getDatastoreDir(); loadConfiguration(); Scheduler.init(); String tmp = com.wm.util.Config.getProperty("false", "watt.server.control.runMemorySensor"); if(Boolean.valueOf(tmp).booleanValue()) MemorySensor.init(ServerController.getInstance()); ThreadPoolSensor.init(ServerController.getInstance()); checkProperties(); com.wm.util.Config.processCmdLine(args); setupLogging(); JournalLog.init(args); JournalLogger.init(JournalLog.newProducer(), JournalLog.getHandler()); JournalLogger.logCritical(1, 25, Build.getVersion(), Build.getBuild()); if(!LicenseManager.init()) { JournalLogger.logCritical(1, 14); return; } RepositoryManager.init(); JDBCConnectionManager.init(); AuditLogManager.init(); setupIPRules(); UserManager.init(); ACLManager.init(); ThreadManager.init(); StateManager.init(); ListenerAdmin.init(); ServiceManager.init(); InvokeManager.init(); Statistics.init(); NetURLConnection.init(); ContentManager.init(); CacheManager.init(); EventManager.init(); boolean dispatcherCorrectlyInit = false; try { DispatchFacade.init(); dispatcherCorrectlyInit = true; } catch(Exception e) { JournalLogger.logCritical(31, 25, e); } WebContainer.init(); ISMonEvtMgr.create(); PackageManager.init(); DependencyManager dm = NSDependencyManager.current(); if(dm == null || !dm.isEnabled()) JournalLogger.logDebugPlus(3, 15, 25); else JournalLogger.logDebugPlus(3, 14, 25); try { if(dispatcherCorrectlyInit) DispatchFacade.start(); } catch(Exception ce) { JournalLogger.logError(35, 25, ce); } PortManager.init(); MimeTypes.init(); HTTPDispatch.init(); ProxyHTTPDispatch.init(); LBHTTPDispatch.init(); CacheManager.startSweeper(); Document.setHostServices(new ServerXmlHostServices()); try { ClusterManager.init(); } catch(Exception e) { JournalLogger.logDebug(103, 33, e.getMessage()); } try { String jobDir = com.wm.util.Config.getProperty("logs/jobsout", "watt.tx.jobdir"); TContext.init(jobDir); } catch(ServiceException e) { JournalLogger.logDebugPlus(3, 9998, 36, e); } if(Config.isSSLPresent()) try { Class c = Class.forName("com.wm.app.b2b.server.ServerTrustDeciderManager"); TrustDeciderManager tdm = (TrustDeciderManager)c.newInstance(); TrustManager.setManager(tdm); } catch(Throwable _ex) { } if(!ListenerAdmin.isReady() && !gCanListen) { JournalLogger.logCritical(4, 14); return; } Scheduler.scheduleTask("Key Update", new KeyUpdate(), 0L, 0x5265c00L); String sc = com.wm.util.Config.getProperty("true", "watt.server.saveConfigFiles"); if((new Boolean(sc)).booleanValue()) saveConfigFiles(); if(Configurator.isBrokerConfigured()) SyncManager.init(); gRunning = true; long startTimeSeconds = (System.currentTimeMillis() - start) / 1000L; JournalLogger.logCritical(2, 14, Long.toString(startTimeSeconds)); synchronized(this) { try { wait(); } catch(Exception e) { e.printStackTrace(); } } } catch(Exception e) { e.printStackTrace(); } JournalLog.unInit(); }
上面的代码不用多解释,大家可以看到IS启动做了哪些事情,IS分为哪些模块,以及这些模块的加载顺序。
IS启动的操作很多,启动时间也比较长,而且有“PortManager.init()”、“saveConfigFiles()”这样需要独占运行的端口占用和文件操作,如果是在同一个JVM上我们可以用Synchronized,如果是不到的JVM呢?答案揭晓了,UniqueApp的作用是使用端口占用的方式在IS启动阶段实现互斥,即对于同一个启动文件夹下的配置一台机器只能有一个IS在启动,否则会报出“Server cannot execute. A server with this configuration is already running.”的错误。
相关推荐
This guide is for the administrator of a webMethods Integration Server. It provides an overview of how the server operates and explains common administrative tasks such as starting and stopping the ...
### webMethods 8.0 Integration Server (IS) 相关知识点 #### 一、概述 - **产品背景**:webMethods 8.0 IS(Integration Server)是Software AG推出的一款集成解决方案平台,主要应用于企业级应用程序集成(EAI...
每次登录前需检查服务器是否已连接,webMethods服务是否已启动。登录界面包括服务器地址和端口号输入,输入正确信息后进入平台。 【webMethods工作界面】 webMethods的主要工作界面通常分为三个部分:左侧栏显示...
webMethods Broker is the primary component in what is referred to as the “message backbone” in a webMethods integration environment. Along with other webMethods components, webMethods Broker ...
webMethods Developer is a graphical development tool that you use to build edit and test integration logic It provides an integrated development environment in which you can develop the logic and ...
- webMethods Developer:是集成开发环境,提供可视化建模、代码编写和部署工具。 - webMethods Glue:用于快速集成遗留系统、Web服务和业务流程。 - webMethods Fabric:是一个集成云服务和内部部署应用程序的平台...
在IT行业的深度探索中,"webmethods SAP Integration best practices"这一主题揭示了在SAP环境下,如何通过webMethods实现高效、稳定的企业级集成的最佳实践。本文将深入剖析这些最佳实践,帮助读者理解如何优化SAP...
### webMethods Adapter Development Kit 安装指南知识点解析 #### 一、概述 《webMethods Adapter Development Kit Installation Guide》是一份详尽的文档,主要针对webMethods Adapter Development Kit 6.5版本...
6. **服务启动与停止**:手册会解释如何启动和停止WebMethods的各种服务,包括Integration Server、Broker服务等,这些操作通常通过命令行或管理界面完成。 7. **故障排查**:安装过程中可能会遇到问题,手册将提供...
1. **WebMethods各个组件的介绍和功能**:手册中提及了webMethods软件套件中的多个组件,如webMethods Administrator(管理员)、webMethods Broker(经纪人)、webMethods Dashboard(仪表盘)、webMethods ...
在WebMethods的产品线中,包括了WebMethods Access、WebMethods Administrator、WebMethods Broker、WebMethods Dashboard、WebMethods Developer、WebMethods Fabric、WebMethods Glue、WebMethods Installer、...
《webMethods Developer Users Guide》是针对webMethods Developer这一强大集成开发环境的一份详细用户指南。webMethods Developer是一款用于构建、测试和部署企业级业务流程集成解决方案的重要工具。它集成了多种...
1. 为企业决策者提供全面、正确、实时的业务信息:webMethods 的业务整合平台,可以轻易的从企业和合作伙伴的不同应用系统中采集丰富、有效、统一、实时的交易信息,通过提供对这些信息的处理,分析,可以为企业决策...
EDI webmethods user Guide Electronic Data Interchange,電子數據交換﹐是一種電子傳輸數據的方法﹐使用這種方法﹐將商業或行政事務處理中的報文數據按照公認的標准﹐形成結構化的報文數據格式﹐進而將這些結構化...
4. 文档中提及的webMethods Administrator、webMethods Broker等,可能是指WebMethods Integration Server中的不同模块或组件,各自承担不同的任务,比如管理、消息传递、用户界面展示等。 5. 文档提到的多个注册...
webMethods Trading Networks also referred to as Trading Networks is a component that runs on the webMethods Integration Server Trading Networks enables your enterprise to link with other companies ...
webMethods 9.0 Mediator是软件AG旗下webMethods开发平台中的一个关键组件,用于实现服务集成和管理。通过本文,我们将详细介绍webMethods Mediator的功能和作用。 首先,webMethods Mediator是什么?webMethods ...
此外,管理员需要熟悉如何在系统启动时改变类路径信息,因为类加载器是根据类路径来定位和加载Java类的。 接下来,webMethods Integration Server 8.2服务器的角色和架构是其核心组成部分。服务器主要负责服务的...
### webMethods基础知识与应用 #### 一、webMethods概述 - **定义**:webMethods是一种企业服务总线(ESB)技术,它提供了一系列工具和服务,用于集成不同的应用程序和服务。这些工具包括集成服务器、业务流程管理...