diff --git a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/ChargingRequestFactory.java b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/ChargingRequestFactory.java index c0e3c1c..90b1d97 100644 --- a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/ChargingRequestFactory.java +++ b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/ChargingRequestFactory.java @@ -9,73 +9,80 @@ 本代码可以从下URL下载: https://github.com/Viscent/javamtp http://www.broadview.com.cn/27006 -*/ + */ package io.github.viscent.mtpattern.ch12.ms.example.testdatagen; -import java.text.DecimalFormat; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.Map; + +public class ChargingRequestFactory extends AbstractRequestFactory { + public ChargingRequestFactory(Map respDelayConf, + int timestampMaxOffset) { + super(respDelayConf, timestampMaxOffset); + } -public class ChargingRequestFactory implements RequestFactory { - private final AtomicInteger seq=new AtomicInteger(0); @Override public SimulatedRequest newRequest() { - return new SimulatedRequest(){ + return new SimulatedRequest() { + + @Override + public void printLogs(Logger logger) { + final int internalDelay = genInternalDelay(); + LogEntry entry = new LogEntry(); + long timeStamp = nextRequestTimestamp(); + entry.timeStamp = timeStamp; + entry.recordType = "request"; + + entry.interfaceType = "SOAP"; + entry.interfaceName = "Chg"; + entry.operationName = "getPrice"; + entry.srcDevice = "OSG"; + entry.dstDevice = "ESB"; + + int traceId = seq.getAndIncrement(); + int originalTId = traceId; + + entry.traceId = "0020" + traceIdFormatter.format(traceId); + + logger.printLog(entry); + + timeStamp += internalDelay; + entry.timeStamp = timeStamp; + + entry.recordType = "request"; + entry.operationName = "getPrice"; + entry.srcDevice = "ESB"; + entry.dstDevice = "BSS"; + traceId = traceId + 1; + entry.traceId = "0021" + traceIdFormatter.format(traceId); + logger.printLog(entry); + + timeStamp += genResponseDelay("BSS"); + entry.timeStamp = timeStamp; + entry.recordType = "response"; + entry.operationName = "getPriceRsp"; + entry.srcDevice = "BSS"; + entry.dstDevice = "ESB"; + traceId = traceId + 3; + entry.traceId = "0021" + traceIdFormatter.format(traceId); + logger.printLog(entry); + + timeStamp += internalDelay; + entry.timeStamp = timeStamp; + entry.recordType = "response"; + entry.operationName = "getLocationRsp"; + entry.srcDevice = "ESB"; + entry.dstDevice = "OSG"; + entry.traceId = "0020" + traceIdFormatter.format(originalTId + 2); + logger.printLog(entry); + + } @Override - public void printLogs(Logger logger) { - LogEntry entry=new LogEntry(); - entry.timeStamp=System.currentTimeMillis(); - entry.recordType="request"; - - entry.interfaceType="SOAP"; - entry.interfaceName="Chg"; - entry.operationName="getPrice"; - entry.srcDevice="OSG"; - entry.dstDevice="ESB"; - DecimalFormat df=new DecimalFormat("0000000"); - - int traceId=seq.getAndIncrement(); - int originalTId=traceId; - - entry.traceId="0020"+df.format(traceId); - - logger.printLog(entry); - - Random rnd = new Random(); - entry.timeStamp+=rnd.nextInt(20); - entry.recordType="request"; - entry.operationName="getPrice"; - entry.srcDevice="ESB"; - entry.dstDevice="BSS"; - traceId=traceId+1; - entry.traceId="0021"+df.format(traceId); - logger.printLog(entry); - - - rnd = new Random(); - entry.timeStamp+=rnd.nextInt(600); - entry.recordType="response"; - entry.operationName="getPriceRsp"; - entry.srcDevice="BSS"; - entry.dstDevice="ESB"; - traceId=traceId+3; - entry.traceId="0021"+df.format(traceId); - logger.printLog(entry); - - rnd = new Random(); - entry.timeStamp+=rnd.nextInt(650); - entry.recordType="response"; - entry.operationName="getLocationRsp"; - entry.srcDevice="ESB"; - entry.dstDevice="OSG"; - entry.traceId="0020"+df.format(originalTId+2); - logger.printLog(entry); - - - } - + public String getInterfaceName() { + return "Charging"; + } + }; } diff --git a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/LocationRequestFactory.java b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/LocationRequestFactory.java index 80fdfac..afe8362 100644 --- a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/LocationRequestFactory.java +++ b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/LocationRequestFactory.java @@ -9,73 +9,80 @@ 本代码可以从下URL下载: https://github.com/Viscent/javamtp http://www.broadview.com.cn/27006 -*/ + */ package io.github.viscent.mtpattern.ch12.ms.example.testdatagen; -import java.text.DecimalFormat; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.Map; + +public class LocationRequestFactory extends AbstractRequestFactory { + + public LocationRequestFactory(Map respDelayConf, + int timestampMaxOffset) { + super(respDelayConf, timestampMaxOffset); + } -public class LocationRequestFactory implements RequestFactory { - private final AtomicInteger seq=new AtomicInteger(0); @Override public SimulatedRequest newRequest() { - // TODO Auto-generated method stub - return new SimulatedRequest(){ + return new SimulatedRequest() { + + @Override + public void printLogs(Logger logger) { + final int internalDelay = genInternalDelay(); + LogEntry entry = new LogEntry(); + long timeStamp = nextRequestTimestamp(); + entry.timeStamp = timeStamp; + entry.recordType = "request"; + + entry.interfaceType = "REST"; + entry.interfaceName = "Location"; + entry.operationName = "getLocation"; + entry.srcDevice = "OSG"; + entry.dstDevice = "ESB"; + + int traceId = seq.getAndIncrement(); + int originalTId = traceId; + + entry.traceId = "0020" + traceIdFormatter.format(traceId); + + logger.printLog(entry); + + timeStamp += internalDelay; + entry.timeStamp = timeStamp; + entry.recordType = "request"; + entry.operationName = "getLocation"; + entry.srcDevice = "ESB"; + entry.dstDevice = "NIG"; + traceId = traceId + 1; + entry.traceId = "0021" + traceIdFormatter.format(traceId); + logger.printLog(entry); + + timeStamp += genResponseDelay("NIG"); + entry.timeStamp = timeStamp; + entry.recordType = "response"; + entry.operationName = "getLocationRsp"; + entry.srcDevice = "NIG"; + entry.dstDevice = "ESB"; + traceId = traceId + 3; + entry.traceId = "0021" + traceIdFormatter.format(traceId); + logger.printLog(entry); + + timeStamp += internalDelay; + entry.timeStamp = timeStamp; + entry.recordType = "response"; + entry.operationName = "getLocationRsp"; + entry.srcDevice = "ESB"; + entry.dstDevice = "OSG"; + entry.traceId = "0020" + traceIdFormatter.format(originalTId + 2); + logger.printLog(entry); + + } @Override - public void printLogs(Logger logger) { - LogEntry entry=new LogEntry(); - entry.timeStamp=System.currentTimeMillis(); - entry.recordType="request"; - - entry.interfaceType="REST"; - entry.interfaceName="Location"; - entry.operationName="getLocation"; - entry.srcDevice="OSG"; - entry.dstDevice="ESB"; - DecimalFormat df=new DecimalFormat("0000000"); - - int traceId=seq.getAndIncrement(); - int originalTId=traceId; - - entry.traceId="0020"+df.format(traceId); - - logger.printLog(entry); - - Random rnd = new Random(); - entry.timeStamp+=rnd.nextInt(20); - entry.recordType="request"; - entry.operationName="getLocation"; - entry.srcDevice="ESB"; - entry.dstDevice="NIG"; - traceId=traceId+1; - entry.traceId="0021"+df.format(traceId); - logger.printLog(entry); - - - rnd = new Random(); - entry.timeStamp+=rnd.nextInt(100); - entry.recordType="response"; - entry.operationName="getLocationRsp"; - entry.srcDevice="NIG"; - entry.dstDevice="ESB"; - traceId=traceId+3; - entry.traceId="0021"+df.format(traceId); - logger.printLog(entry); - - rnd = new Random(); - entry.timeStamp+=rnd.nextInt(150); - entry.recordType="response"; - entry.operationName="getLocationRsp"; - entry.srcDevice="ESB"; - entry.dstDevice="OSG"; - entry.traceId="0020"+df.format(originalTId+2); - logger.printLog(entry); - - } - + public String getInterfaceName() { + return "Location"; + } + }; } diff --git a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/Logger.java b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/Logger.java index 731966c..f679e8c 100644 --- a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/Logger.java +++ b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/Logger.java @@ -9,11 +9,12 @@ 本代码可以从下URL下载: https://github.com/Viscent/javamtp http://www.broadview.com.cn/27006 -*/ + */ package io.github.viscent.mtpattern.ch12.ms.example.testdatagen; -import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -21,21 +22,30 @@ import java.util.concurrent.atomic.AtomicLong; public class Logger { - - //接口日志输出目标目录 + + // 接口日志输出目标目录 private static final String LOG_FILE_BASE_DIR = System .getProperty("java.io.tmpdir") + "/tps/"; private static final String TIME_STAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; private static final String TIME_STAMP_FORMAT1 = "yyyyMMddHHmm"; private int maxLines = 10000; - private AtomicLong linesCount = new AtomicLong(maxLines); - private PrintWriter cachedPwr = null; - public void printLog(LogEntry entry) { - // System.out.println(entry); - // IP address - PrintWriter pwr = this.getWriter(); + private final AtomicLong linesCount = new AtomicLong(0); + private volatile PrintWriter cachedPwr = null; + private volatile long now; + + public Logger() { + now = System.currentTimeMillis(); + try { + cachedPwr = new PrintWriter(new FileWriter(LOG_FILE_BASE_DIR + + retrieveLogFileName(now)), true); + } catch (IOException e) { + e.printStackTrace(); + } + } + public void printLog(LogEntry entry) { + final PrintWriter pwr = cachedPwr; pwr.print(getUTCTimeStamp(Long.valueOf(entry.timeStamp), TIME_STAMP_FORMAT)); pwr.print('|'); @@ -72,26 +82,24 @@ public void printLog(LogEntry entry) { if (count >= maxLines) { pwr.flush(); pwr.close(); - } - } - - private PrintWriter getWriter() { - - if (linesCount.get() >= maxLines) { + linesCount.set(0); try { - cachedPwr = new PrintWriter(LOG_FILE_BASE_DIR + retrieveLogFileName()); - } catch (FileNotFoundException e) { + long newTimeStamp = System.currentTimeMillis(); + if ((newTimeStamp - now) <= 60 * 1000) { + newTimeStamp = now + 60 * 1000; + now = newTimeStamp; + } + cachedPwr = new PrintWriter(new FileWriter(LOG_FILE_BASE_DIR + + retrieveLogFileName(newTimeStamp)), true); + } catch (IOException e) { e.printStackTrace(); } - linesCount.set(0); } - return cachedPwr; } - private String retrieveLogFileName() { + private String retrieveLogFileName(long timeStamp) { - return "ESB_interface_" - + getUTCTimeStamp(System.currentTimeMillis(), TIME_STAMP_FORMAT1) + return "ESB_interface_" + getUTCTimeStamp(timeStamp, TIME_STAMP_FORMAT1) + ".log"; } @@ -104,4 +112,4 @@ private static String getUTCTimeStamp(long timeStamp, String format) { String tempTs = sdf.format(calendar.getTime()); return tempTs; } -} +} \ No newline at end of file diff --git a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/SimulatedRequest.java b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/SimulatedRequest.java index 9103c31..1cfc5d3 100644 --- a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/SimulatedRequest.java +++ b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/SimulatedRequest.java @@ -15,4 +15,5 @@ public interface SimulatedRequest { public void printLogs(Logger logger); + public String getInterfaceName(); } diff --git a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/SmsRequestFactory.java b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/SmsRequestFactory.java index 858c9dc..5b0d37e 100644 --- a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/SmsRequestFactory.java +++ b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/SmsRequestFactory.java @@ -9,76 +9,80 @@ 本代码可以从下URL下载: https://github.com/Viscent/javamtp http://www.broadview.com.cn/27006 -*/ + */ package io.github.viscent.mtpattern.ch12.ms.example.testdatagen; -import java.text.DecimalFormat; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.Map; -public class SmsRequestFactory implements RequestFactory { - private final AtomicInteger seq=new AtomicInteger(0); +public class SmsRequestFactory extends AbstractRequestFactory { + + public SmsRequestFactory(Map respDelayConf, + int timestampMaxOffset) { + super(respDelayConf, timestampMaxOffset); + + } @Override public SimulatedRequest newRequest() { - return new SimulatedRequest(){ + return new SimulatedRequest() { + + @Override + public void printLogs(Logger logger) { + final int internalDelay = genInternalDelay(); + LogEntry entry = new LogEntry(); + long timeStamp = nextRequestTimestamp(); + entry.timeStamp = timeStamp; + entry.recordType = "request"; + + entry.interfaceType = "SOAP"; + entry.interfaceName = "SMS"; + entry.operationName = "sendSms"; + entry.srcDevice = "OSG"; + entry.dstDevice = "ESB"; + + int traceId = seq.getAndIncrement(); + + entry.traceId = "0020" + traceIdFormatter.format(traceId); + + logger.printLog(entry); + + timeStamp += internalDelay; + entry.timeStamp = timeStamp; + entry.recordType = "response"; + entry.operationName = "sendSmsRsp"; + entry.srcDevice = "ESB"; + entry.dstDevice = "OSG"; + logger.printLog(entry); + + timeStamp += internalDelay; + entry.timeStamp = timeStamp; + entry.recordType = "request"; + entry.operationName = "sendSms"; + entry.srcDevice = "ESB"; + entry.dstDevice = "NIG"; + traceId = traceId + 1; + entry.traceId = "0021" + traceIdFormatter.format(traceId); + logger.printLog(entry); + + timeStamp += genResponseDelay("NIG"); + entry.timeStamp = timeStamp; + entry.recordType = "response"; + entry.operationName = "sendSmsRsp"; + entry.srcDevice = "NIG"; + entry.dstDevice = "ESB"; + traceId = traceId + 3; + entry.traceId = "0021" + traceIdFormatter.format(traceId); + logger.printLog(entry); + + } @Override - public void printLogs(Logger logger) { - LogEntry entry=new LogEntry(); - entry.timeStamp=System.currentTimeMillis(); - entry.recordType="request"; - - entry.interfaceType="SOAP"; - entry.interfaceName="SMS"; - entry.operationName="sendSms"; - entry.srcDevice="OSG"; - entry.dstDevice="ESB"; - DecimalFormat df=new DecimalFormat("0000000"); - - int traceId=seq.getAndIncrement(); - - entry.traceId="0020"+df.format(traceId); - - logger.printLog(entry); - - Random rnd = new Random(); - entry.timeStamp+=rnd.nextInt(50); - entry.recordType="response"; - entry.operationName="sendSmsRsp"; - entry.srcDevice="ESB"; - entry.dstDevice="OSG"; - //entry.traceId="2001"+df.format(traceId+1); - logger.printLog(entry); - - - - rnd = new Random(); - entry.timeStamp+=rnd.nextInt(50); - entry.recordType="request"; - entry.operationName="sendSms"; - entry.srcDevice="ESB"; - entry.dstDevice="NIG"; - traceId=traceId+1; - entry.traceId="0021"+df.format(traceId); - logger.printLog(entry); - - - rnd = new Random(); - entry.timeStamp+=rnd.nextInt(300); - entry.recordType="response"; - entry.operationName="sendSmsRsp"; - entry.srcDevice="NIG"; - entry.dstDevice="ESB"; - traceId=traceId+3; - entry.traceId="0021"+df.format(traceId); - logger.printLog(entry); - - - } - + public String getInterfaceName() { + return "SMS"; + } + }; } diff --git a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/TestingDataGen.java b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/TestingDataGen.java index e69f070..c9ff933 100644 --- a/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/TestingDataGen.java +++ b/JavaConcurrencyPatternInAction/src/io/github/viscent/mtpattern/ch12/ms/example/testdatagen/TestingDataGen.java @@ -9,15 +9,16 @@ 本代码可以从下URL下载: https://github.com/Viscent/javamtp http://www.broadview.com.cn/27006 -*/ + */ package io.github.viscent.mtpattern.ch12.ms.example.testdatagen; -import io.github.viscent.mtpattern.ch5.tpt.AbstractTerminatableThread; - +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Map; import java.util.Random; -import java.util.Timer; -import java.util.TimerTask; +import java.util.SimpleTimeZone; +import java.util.concurrent.atomic.AtomicLong; /** * 生成本章实战案例运行时所需的接口日志文件。 @@ -27,70 +28,101 @@ */ public class TestingDataGen { - public static void main(String[] args) { + private static final String TIME_STAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; + private static final SimpleDateFormat SDF_LONG; + private final Logger logger = new Logger(); - final long duration = 5 * 60; // 单位:s + static { + SimpleTimeZone stz = new SimpleTimeZone(0, "UTC"); + SDF_LONG = new SimpleDateFormat(TIME_STAMP_FORMAT); + SDF_LONG.setTimeZone(stz); + } + + public static void main(String[] args) { + TestingDataGen me = new TestingDataGen(); + Map> delayConf = createDefaultConf(); + int argc = args.length; + int duration;// 模拟系统流量的时间跨度(发起请求到停止发起请求的持续时间) + int overrallTPS;// 模拟系统的整体TPS(Transaction per Second) + overrallTPS = (argc >= 1) ? Integer.valueOf(args[0]) : 100 * 3; + duration = (argc >= 2) ? Integer.valueOf(args[1]) : 60; + // 持续时间最短为1分钟(因为日志文件的文件名就是精确到分钟) + me.generate(overrallTPS, duration, delayConf); - // 模拟接口日志文件中的请求速率 - final int tps = 100; - final AbstractTerminatableThread att = new AbstractTerminatableThread() { - final RequestFactory[] factories = new RequestFactory[] { - new SmsRequestFactory(), new ChargingRequestFactory(), - new LocationRequestFactory() }; + } - Logger logger = new Logger(); - int count = 0; + private static Map> createDefaultConf() { + Map> delayConf = new HashMap>(); - @Override - protected void doRun() throws Exception { - RequestFactory rf; - SimulatedRequest req; - Random rnd = new Random(); - int i = 0; + Map smsConf = new HashMap(); + smsConf.put("NIG", 150); + smsConf.put("ESB", 50); + delayConf.put("Sms", smsConf); - i = rnd.nextInt(factories.length); - rf = factories[i]; + Map locationConf = new HashMap(); + locationConf.put("NIG", 500); + locationConf.put("ESB", 20); + delayConf.put("Location", locationConf); - req = rf.newRequest(); + Map chargingConf = new HashMap(); + chargingConf.put("BSS", 1200); + chargingConf.put("ESB", 50); + delayConf.put("Charging", chargingConf); + return delayConf; + } - req.printLogs(logger); + public void generate(int overallTPS, int duration/* minutes */, + Map> respDelayConf) { + if (duration < 1) { + throw new IllegalArgumentException("duration must be greater than 1!"); + } - count++; + doGenerate(overallTPS, duration, respDelayConf); + } - if (0 == (count % tps)) { - System.out.println(count); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - count = 0; - } + public void doGenerate(int overallTPS, int duration/* minutes */, + Map> respDelayConf) { - } + int count = 0; + RequestFactory rf; + SimulatedRequest req; + int factoryIndex = 0; + Random rnd = new Random(); - @Override - protected void doCleanup(Exception cause) { - System.out.println("count:" + count + ",rate:" + (count / duration)); - } + long requestCount = overallTPS * (duration * 60); - }; + final int maxRequestPerTimeslice = (overallTPS / 3) * 10; + final RequestFactory[] factories = new RequestFactory[] { + new SmsRequestFactory(respDelayConf.get("Sms"), maxRequestPerTimeslice), + new ChargingRequestFactory(respDelayConf.get("Charging"), + maxRequestPerTimeslice), + new LocationRequestFactory(respDelayConf.get("Location"), + maxRequestPerTimeslice) }; - att.setDaemon(false); + Map requestCounter = new HashMap(); + AtomicLong reqCount; + for (int i = 0; i < requestCount; i++) { - att.start(); + factoryIndex = rnd.nextInt(factories.length); + rf = factories[factoryIndex]; - final Timer timer = new Timer(true); - timer.schedule(new TimerTask() { + req = rf.newRequest(); - @Override - public void run() { - att.terminate(); + req.printLogs(logger); + reqCount = requestCounter.get(req.getInterfaceName()); + if (null == reqCount) { + reqCount = new AtomicLong(0); + requestCounter.put(req.getInterfaceName(), reqCount); } - }, duration * 1000); + reqCount.incrementAndGet(); + + count++; + } + System.out.println("Total request count:" + count); + System.out.println(requestCounter); } }