因此,您的分布式体系结构如下图所示,您刚刚从企业那里收到了一项要求,以确保生产者发送并随后传输到下游系统(消费者)的消息的SLA必须快且永远不会慢于此。 400毫秒。
要求说:
从生产者发送到任何消费者的消息的延迟绝不应慢于400毫秒。
听起来很熟悉? 对我来说,经验告诉我,如果将来我想保护SLA,则还需要使测试自动化,以免引入瓶颈,而这会增加消息的延迟。 但是怎么做呢? 生产者和使用者位于不同的机器中,并且某些使用者不是用Java编写的。 另外,在生产者和消费者之间有一个队列(或Web服务或RMI或ESB或其他组件或其他任何东西),因此测试起来并不容易。 好吧,所有组件都以类似的方式写入日志,那么为什么不使用日志作为测试数据呢?
例如,这些是2个示例日志,一个来自生产者发出消息(id 1546366),另一个来自接收消息的使用者之一(id 1546366):
生产者日志
2013-02-19 10:09:05,795 INFO [org.grep4j.demo.input.core.InputCoreMessageSender] (pool-19-thread-9) Input::MessageSender::Message(1546366) Sent Successfully
消费者日志
2013-02-19 10:09:06,161 INFO [org.grep4j.demo.handler.bean.mdb.SingleDestPacketHandler] (Thread-62314 (HornetQ-client-global-threads-989457197)) Handler::Packet::Message(1546366) Received::PacketId(982336426)::State(NORMAL)::Dest(CONSUMER4, 1)::DataLevel(EVENT, 7)::Op(CREATE, C)::GlobalId(1546366)::Priority(1)::Src(GUI, 1::Ids(EventId=1546366,SFBId=1546366,isBirType=false,inBir=false))
这就是我使用Grep4j进行自动性能测试的样子:
package com.gdg.grep4j.demo;
import static com.gdg.grep4j.demo.profiles.Profiles.consumer1;
import static com.gdg.grep4j.demo.profiles.Profiles.consumer2;
import static com.gdg.grep4j.demo.profiles.Profiles.consumer3;
import static com.gdg.grep4j.demo.profiles.Profiles.producer;
import static com.gdg.grep4j.demo.services.TimeService.extractTime;
import static org.grep4j.core.Grep4j.constantExpression;
import static org.grep4j.core.Grep4j.grep;
import static org.grep4j.core.fluent.Dictionary.on;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.number.OrderingComparison.lessThan;
import static org.junit.Assert.assertThat;
import org.grep4j.core.result.GrepResults;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
@Test
public class MessageDistributionPerformanceTest {private static final long MAX_ACCETABLE_LATENCY = 400L;private long producerTime = 0;private GrepResults consumersResults;@BeforeTestpublic void triggerMessageDispatcher() {System.out.println('Producing and firing a Message(1546366) to downstream systems...');}@BeforeTestpublic void extractProducerTime() {GrepResults producerResult = grep(constantExpression('Message(1546366) Sent Successfully'), on(producer));producerTime = extractTime(producerResult.toString());}@BeforeTestpublic void grepConsumerLogs() {consumersResults = grep(constantExpression('Message(1546366) Received'),on(consumer1, consumer2, consumer3));}public void testConsumer1Latency() {long consumer1Time = extractTime(consumersResults.filterOnProfile(consumer1).toString());assertThat((consumer1Time - producerTime),is(lessThan(MAX_ACCETABLE_LATENCY)));}public void testConsumer2Latency() {long consumer2Time = extractTime(consumersResults.filterOnProfile(consumer2).toString());assertThat((consumer2Time - producerTime),is(lessThan(MAX_ACCETABLE_LATENCY)));}public void testConsumer3Latency() {long consumer3Time = extractTime(consumersResults.filterOnProfile(consumer3).toString());assertThat((consumer3Time - producerTime),is(lessThan(MAX_ACCETABLE_LATENCY)));}
}
配置文件是grep目标上下文,在我的情况下,所有配置文件都是远程计算机(要更好地了解配置文件,请参阅Grep4j页面 )。
TimeService只是一个简单的服务类,用于提取日志中的时间。
package com.gdg.grep4j.demo.services;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TimeService {private static final Pattern timePattern = Pattern.compile('([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9]) ([0-9][0-9]|2[0-3]):([0-9][0-9]):([0-9][0-9]),([0-9][0-9][0-9])');public static long extractTime(String text) {Matcher lm = timePattern.matcher(text);if (lm.find()) {SimpleDateFormat sdf = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss,SSS');sdf.setTimeZone(TimeZone.getTimeZone('UTC'));String inputString = lm.group();Date date = null;try {date = sdf.parse(inputString);} catch (ParseException e) {e.printStackTrace();}return date.getTime();} else {throw new IllegalArgumentException('timePattern not found');}}
}
在几行简单的代码中,我进行了非常灵活的测试(我可以测试日志中生成的任何内容)。 对于完整的代码: https : //github.com/marcocast/grep4j-gdg.git
参考:通过我们的JCG合作伙伴 Marco Castigliego的grep4j ,可以在“ 删除重复和修复不良名称”博客上轻松测试分布式组件上的SLA 。
翻译自: https://www.javacodegeeks.com/2013/02/easy-testing-slas-on-distributed-components-with-grep4j.html