java-在Coldfusion 9上使用cflock进行排队

自从ColdFusion 8 Enterprise升级到ColdFusion 9 Enterprise之后,我们一直在处理事件网关问题.

我们有一个事件网关设置,用于建立与第三方的连接.他们至少每10秒(有时是每秒)多次向我们发送更新.

我们将Java类配置为事件网关侦听器,并将事件和数据推送到CFC函数.在该函数中,我们实际上使用了一个名为< cflock>以确保按顺序处理请求,并且请求将在此排队,以具有对命名锁的独占访问权.此锁有30秒的超时时间.

我还对该函数进行了很多调试,并且注意到了一些事情:

> Requetst将在< cflock>之前排队.标签,等待锁,此队列的长度可能超过40个事件
>所有请求在6秒钟内获得锁定后即被处理.从获得锁定到完成处理的平均时间实际上是1.5到2秒

因此,问题在于,我会不时地发生一次锁定超时,并且是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秒钟以模拟实际处理.这种睡眠发生在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与多线程事件网关一起使用!

希望这对遇到此问题的其他人有所帮助.

干杯,Ciaran.

上一篇:python-如何在Oracle上锁定user_tables?


下一篇:如果在TRUNCATE和SELECT INTO之间发送查询,则没有数据.使用MySQL innoDB