- 浏览: 44358 次
- 性别:
最近访客 更多访客>>
最新评论
-
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 Developer:是集成开发环境,提供可视化建模、代码编写和部署工具。 - webMethods Glue:用于快速集成遗留系统、Web服务和业务流程。 - webMethods Fabric:是一个集成云服务和内部部署应用程序的平台...
每次登录前需检查服务器是否已连接,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 ...
在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是一款用于构建、测试和部署企业级业务流程集成解决方案的重要工具。它集成了多种...
4. 文档中提及的webMethods Administrator、webMethods Broker等,可能是指WebMethods Integration Server中的不同模块或组件,各自承担不同的任务,比如管理、消息传递、用户界面展示等。 5. 文档提到的多个注册...
1. 为企业决策者提供全面、正确、实时的业务信息:webMethods 的业务整合平台,可以轻易的从企业和合作伙伴的不同应用系统中采集丰富、有效、统一、实时的交易信息,通过提供对这些信息的处理,分析,可以为企业决策...
EDI webmethods user Guide Electronic Data Interchange,電子數據交換﹐是一種電子傳輸數據的方法﹐使用這種方法﹐將商業或行政事務處理中的報文數據按照公認的標准﹐形成結構化的報文數據格式﹐進而將這些結構化...
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)技术,它提供了一系列工具和服务,用于集成不同的应用程序和服务。这些工具包括集成服务器、业务流程管理...