0

我们有一个 Java 中的 Web 应用程序,它调用进度过程。Progress 4gl 版本是 10.x,在 AIX 上。

要求是实现以下功能:假设 Web 应用程序调用了一个进度过程。这使得 appserver 事务运行。在事务处理期间,如果用户关闭浏览器窗口,则需要识别 appserver 进程,并应使用其进程 ID 将其终止。进程的终止可以通过调用 shell 脚本来实现。如何识别即将关闭的 Web 应用程序会话的 appserver 进程 ID?

4

3 回答 3

0

你从汤姆和蒂姆那里得到了两个很好的答案。我认为你需要重新考虑你的架构。

但这并不能回答有关获取 PID 的问题。假设您运行某种与 Progress AppServer 的连接,该 AppServer 正在运行一个 .p 程序,并且在该程序中您可以执行以下操作:

FIND FIRST _MyConnection NO-LOCK.
/* You might not want to DISPLAY but rather do something else: */
DISPLAY _MyConnection._MyConn-Pid.

您也可以在操作系统中执行此操作。假设你已经运行了 proenv-script,所以你已经设置了你的环境,你可以这样做:

wtbman -name asXXX -query

(将 asXXX 替换为您的应用服务器的名称 - 默认为 asbroker1)。

输出是这样的:

OpenEdge Release 11.3.1 as of Fri Sep 13 19:00:23 EDT 2013


Connecting to Progress AdminServer using rmi://localhost:xxxx/Chimera (8280)
Searching for asXXX (8288)
Connecting to asXXX  (8276)
Incorrect utility to use for asXXX (15827)

Broker Name                    : asXXX
Operating Mode                 : State-reset
Broker Status                  :  ACTIVE
Broker Port                    : YYYY
Broker PID                     : ZZZZ
Active Servers                 : 2
Busy Servers                   : 0
Locked Servers                 : 0
Available Servers              : 2
Active Clients (now, peak)     : (0, 2)
Client Queue Depth (cur, max)  : (0, 2)
Total Requests                 : 26322
Rq Wait (max, avg)             : (18079 ms, 25 ms)
Rq Duration (max, avg)         : (18079 ms, 25 ms)

PID   State     Port  nRq    nRcvd  nSent  Started          Last Change
16319 AVAILABLE ZZZZZ 001447 001447 001447 Aug 8, 2014 11:50 Aug 14, 2014 13:20
16320 BUSY      ZZZZZ 001385 001385 001385 Aug 8, 2014 11:50 Aug 14, 2014 13:10

查看pid列表。16319 可用且 16320 正忙并且已经持续了 10 分钟(如果现在时间是 13:20)。这告诉我们 PID 16320 很可能是挂起程序。

现在你可以这样做:

asbman -name asxxx -agentdetail 16320

这将为您提供更多信息,例如 PROPATH、堆栈跟踪和连接的数据库。在查找问题时非常有帮助。

于 2014-08-14T11:29:42.227 回答
0

如果 appserver 进程花费的时间足够长以至于这是一个问题,那么你做错了 - 通常对 appserver 的往返调用应该很短,以至于在此期间关闭浏览器并不重要。

其次,如果您正在无状态运行,则无法知道呼叫正在运行哪个 appserver 代理,因为最后一个呼叫可能已路由到多个代理中的任何一个,并且没有与呼叫者握手那是哪一个。

因此,做你正在寻找的唯一合理的方法是

  1. 让浏览器应用程序触发对 Web 基础架构的“取消我的操作”调用并更新数据库字段以指示此请求
  2. 让应用服务器正在运行的程序定期检查数据库表字段以查看它的当前操作是否已被取消,如果已设置该标志则退出处理。
于 2014-08-08T17:51:46.480 回答
0

所以真正的问题是你有长时间运行的任务,用户会因为不耐烦而放弃并重试(可能是由于缺乏对任务进度的反馈)?

您尚未提供有关“Java 中的 Web 应用程序”的任何详细信息,因此我真的不知道您在做什么,也不知道它与 Progress 应用程序服务器会话有何关系。

为了让 Web 应用程序终止远程运行的进程,它需要对该远程进程有某种引用。听起来您当前正在同步调用远程进程并等待响应。您需要做的第一件事是异步调用远程进程(Progress 确实支持异步应用服务器调用。这可能是一个起点。但这取决于“Java 中的 Web 应用程序”的含义。)

如果您可以以某种方式异步调用该进程,那么您应该在启动它时获取 PID(或其他可用于外部参照该进程的唯一标识符)。当您弹出确认警报框以正确输入“kill”命令时,可以使用它。

如果您无法弄清楚如何进行异步应用服务器调用,那么使用同步调用模拟此类事情的粗略方法是通过 db 表编组请求(和响应):

  1. 插入描述请求的记录,提供所有必要的参数和上下文以独立启动请求,然后将请求 ID 返回给调用者。

  2. 然后调用者循环——暂停一段时间并检查请求的状态。这应该是一个非常简单的调用,它只是从数据库中读取请求记录以提取其状态。

  3. 在远程,一个或多个批处理正在循环读取请求表以查找新记录。当他们找到一个时,他们会启动一个进程来执行请求。您可以在这里使用各种控件和负载平衡的东西,或者您可以保持简单和容易。

  4. 执行请求的进程会适当地更新状态记录,以便 Web 浏览器客户端可以看到正在发生的事情。(第2步)

  5. 当请求完成时,结果将反馈给客户端——可能通过数据库表或作为新页面。这取决于应用程序。基本思想是,当第 2 步注意到状态为“完成”时,它会执行任何适当的操作来验证结果。

如果客户端决定终止一个请求,它应该在步骤#1 中接收到足够的信息以将该引用传递给服务器,以便服务器可以对其进行操作。通常,您希望将请求记录的状态更新为“已终止”(或其他),然后允许子进程注意到这一点并自行终止,或者使用操作系统级别的工具来执行实际的“终止”。

顺便说一句——如果您适当地组织了其中的“上下文和参数”部分,您可能能够识别并消除重复的请求,或者至少缓存答案。

于 2014-08-11T16:03:38.290 回答