- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
自从我们从 ColdFusion 8 Enterprise 升级到 ColdFusion 9 Enterprise 以来,我们一直在处理事件网关的问题。
我们有一个事件网关设置来建立与第三方的连接。他们至少每 10 秒向我们更新一次,有时每秒更新多次。
我们将一个 Java 类配置为事件网关监听器,并将事件和数据推送到 CFC 函数。在该函数中,我们实际上使用了一个命名 <cflock>
以确保请求按顺序处理,并且请求将在此时排队以独占访问命名锁。此锁有 30 秒 超时。
我在这个函数中也有很多调试,我注意到了一些事情:
<cflock>
之前排队标记,等待锁定,这个队列可以超过 40 个事件所以问题是,我会时不时地发生锁定超时,而且是在 30 秒之后。首先,如果请求正在等待锁定,我会记录下来。它看起来像这样:
"Information","Thread-23","06/23/10","15:45:18","APP1","F4B42A5A-F34D-C614-DE01B150E6906F78 (1277304318606) : PRE LOCK"
然后在日志的更下方,我看到了相同的请求:
"Error","Thread-23","06/23/10","15:45:48","APP1","F4B42A5A-F34D-C614-DE01B150E6906F78 (1277304348607) : LOCK ERROR: A timeout occurred while attempting to lock lock_ResponseDispatcher."
他们之间有 30 秒的时间。此时,请求和与其关联的任何事件数据都将丢失。对我不好。
所以我想看看队列的处理速度是否足够快。我不确定 <cflock>
事件是如何排队的.有硬性限制吗?
无论如何,在这个特定的运行中,我看到了:
当队列中已经有 6 个请求时,请求进入队列,因此队列中的第 7 个
在接下来的 30 秒内,大约有 17 个请求从队列中移除
大约相同数量的请求被添加到队列中
在此期间,有问题的请求未被处理,并在 30 秒后超时
简直不敢相信自己的眼睛!就好像 <cflock>
队列的处理方式不是先进先出(FIFO),而是先进后出(FILO)!
这样的事情可能吗?还有其他人见过这种行为吗?
非常感谢任何有想法的人。
夏兰
最佳答案
我认为这里的关键是我正在使用 event gateways这是异步的。事实上,在进行实验之后,我的问题的原因似乎非常明显:)
我已经指定了可用于在 CF 管理中处理事件网关请求的线程数(请参阅事件网关 -> 设置)。此设置在 CF Dev Edition 上固定为 1,但在 Enterprise Edition 中可以增加。对于这个实验,我将它增加到 5。只有当它增加时,您才会看到这种奇怪的行为。
所以我的事件网关代码非常简单,它只是创建一个 UUID(因此我可以在我的日志中跟踪请求)然后锁定线程 5 秒以模拟实际处理。此 sleep
发生在 cflock
调用内部,因此一次只能有一个线程进行处理。我们需要这样做来避免在实际代码中处理重复项。
这是完整的 CFC:
component {
public void function onIncomingMessage (required struct msg) {
var sys = createObject("java", "java.lang.System");
var tag = createUUID();
var logFile = "test\gatewaytest";
writelog (file=logFile, text="#tag# - about to queue");
try {
lock name="myTestLock" timeout="120" {
writelog (file=logFile, text="#tag# - got lock");
thread action="sleep" duration="5000"; //ms
}
writelog (file=logFile, text="#tag# - released lock");
} catch (any e) {
writelog (file=logFile, text="#tag# - ERROR - #e.message#");
}
}
}
请注意锁上的超长超时值(2 分钟)。这是为了处理事件网关异步处理带来的问题。
事件网关是一个简单的内置 CFML 类型,其 ID 为“TestGW”,我将其链接到上面的 CFC。
我设置了一个简单的脚本来将事件发送到事件网关,这里是完整的:
<cfset msg = {mymessage = "hello gateway"} />
<cfset sendGatewayMessage("TestGW", msg) />
场景 1 - 单线程:
如果事件网关处理线程的数量设置为 1 并且我敲击网关,我会看到以下日志输出:
"Information","Thread-17","06/25/10","10:32:09",,"50805BB4-1C23-9073-67A70A86CA6F8E54 - about to queue"
"Information","Thread-17","06/25/10","10:32:09",,"50805BB4-1C23-9073-67A70A86CA6F8E54 - got lock"
"Information","Thread-17","06/25/10","10:32:14",,"50805BB4-1C23-9073-67A70A86CA6F8E54 - released lock"
"Information","Thread-17","06/25/10","10:32:14",,"50811F1A-1C23-9073-67AD3E9C0BF2000C - about to queue"
"Information","Thread-17","06/25/10","10:32:14",,"50811F1A-1C23-9073-67AD3E9C0BF2000C - got lock"
"Information","Thread-17","06/25/10","10:32:19",,"50811F1A-1C23-9073-67AD3E9C0BF2000C - released lock"
"Information","Thread-17","06/25/10","10:32:19",,"5081E27F-1C23-9073-67B5D2EF6AED8426 - about to queue"
"Information","Thread-17","06/25/10","10:32:19",,"5081E27F-1C23-9073-67B5D2EF6AED8426 - got lock"
"Information","Thread-17","06/25/10","10:32:24",,"5081E27F-1C23-9073-67B5D2EF6AED8426 - released lock"
"Information","Thread-17","06/25/10","10:32:24",,"5082A5E1-1C23-9073-674E9467F395686F - about to queue"
"Information","Thread-17","06/25/10","10:32:24",,"5082A5E1-1C23-9073-674E9467F395686F - got lock"
"Information","Thread-17","06/25/10","10:32:29",,"5082A5E1-1C23-9073-674E9467F395686F - released lock"
这里要注意的关键是它是单线程的。这一切都是关于一次一个地排队事件,一切都按顺序发生。
场景 2 - 更多线程:
如果事件网关处理线程的数量增加到 5 并且我敲打网关,我会看到以下日志输出:
"Information","Thread-18","06/25/10","11:26:01",,"526CC05B-C9E1-FADE-73CE3426BC0A3F92 - about to queue"
"Information","Thread-18","06/25/10","11:26:01",,"526CC05B-C9E1-FADE-73CE3426BC0A3F92 - got lock"
"Information","Thread-27","06/25/10","11:26:01",,"526CD0EB-049E-D382-2C3A7E3C0DBF8ED3 - about to queue"
"Information","Thread-21","06/25/10","11:26:02",,"526CDEED-C2B3-3C92-0F57CFA317AC02F8 - about to queue"
"Information","Thread-20","06/25/10","11:26:02",,"526CEE25-F25B-890C-F7501B5489C6BB21 - about to queue"
"Information","Thread-25","06/25/10","11:26:02",,"526CFD3C-EAFD-40E7-EBA2BE59B87D5936 - about to queue"
"Information","Thread-24","06/25/10","11:26:03",,"526D0FC5-E5E2-642E-452636C8838ADE33 - about to queue"
"Information","Thread-26","06/25/10","11:26:03",,"526D1096-C82E-535B-36D57D3A431D1436 - about to queue"
"Information","Thread-23","06/25/10","11:26:03",,"526D1F9C-9A9C-FA84-E153A944123E77BE - about to queue"
"Information","Thread-19","06/25/10","11:26:04",,"526D2EDC-EA54-4D83-3F6BB681A5CCAA89 - about to queue"
"Information","Thread-22","06/25/10","11:26:04",,"526D3F09-073F-2B0C-E94652D1C95B09CB - about to queue"
"Information","Thread-18","06/25/10","11:26:06",,"526CC05B-C9E1-FADE-73CE3426BC0A3F92 - released lock"
"Information","Thread-22","06/25/10","11:26:06",,"526D3F09-073F-2B0C-E94652D1C95B09CB - got lock"
"Information","Thread-22","06/25/10","11:26:11",,"526D3F09-073F-2B0C-E94652D1C95B09CB - released lock"
"Information","Thread-27","06/25/10","11:26:11",,"526CD0EB-049E-D382-2C3A7E3C0DBF8ED3 - got lock"
"Information","Thread-27","06/25/10","11:26:16",,"526CD0EB-049E-D382-2C3A7E3C0DBF8ED3 - released lock"
"Information","Thread-19","06/25/10","11:26:16",,"526D2EDC-EA54-4D83-3F6BB681A5CCAA89 - got lock"
"Information","Thread-19","06/25/10","11:26:21",,"526D2EDC-EA54-4D83-3F6BB681A5CCAA89 - released lock"
请特别注意 UUID 为 526D3F09-073F-2B0C-E94652D1C95B09CB
的请求。这是最后一个记录的请求,因此在队列的末尾。然而,一旦锁可用,它就会跳转并获取锁 - 不是那里的 526CD0EB-049E-D382-2C3A7E3C0DBF8ED3
请求第一的。
结论:
因为当我们使用多个线程时,我们无法保证在使用事件网关时等待 cflock
时线程的处理顺序。我们需要确保锁定的超时值足够高,以便在繁忙时段可以在任何请求超过锁定超时之前完整处理事件队列。
我猜这对我们来说可能适合将 cflock
与多线程事件网关一起使用!
我希望这可以帮助遇到此问题的任何其他人。
干杯,夏兰。
关于java - 在 Coldfusion 9 上使用 cflock 排队,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3103572/
我们目前有一系列加载到应用程序范围内的变量,这些变量很少更改。 很少更改,我的意思是它们是电话号码之类的字符串,或者出现在网站上的简单文本值,可能每周或每月更改一次。 由于我们正在读取这些变量并且它们
我想知道在这种情况下是否需要锁定我的表(我使用的是 Coldfusion 和 MySQL): 我有一张 table 叫 wishlists(memberId, gameId, rank, update
我正在编写一些带有 CFLOCK 标签的代码,并且我的代码将返回到 CFLOCK 内的某个地方。例子: ... do some processing ...
我正在尝试在页面 test.cfm 上锁定 block ,下面是在页面上编写的代码。 writeOutput("Before lock at #now()#"); lock name="thread
我知道正确的使用方法 对于 cf 开发人员来说,这是 www 上一个相当大的话题。 当我试图更好地理解它时,我创建了一个简单的 UDF,它接受一个 session 数组,我想知道考虑到它是一个简单的
自从我们从 ColdFusion 8 Enterprise 升级到 ColdFusion 9 Enterprise 以来,我们一直在处理事件网关的问题。 我们有一个事件网关设置来建立与第三方的连接。他
我有一个 ColdFusion 事件网关,有时会在以下行中产生错误(其中 Local.curThread 是数字 1-5): 错误是: Message: timeout value is negat
我是一名优秀的程序员,十分优秀!