六月很快又過了… 呢個月上司返左 UK 2 個weeks, 通常呢, 出事既時候都係相關既人行開左, 係呢段時間非常掛住我呢個上司 🙂 下旬就係production push 既日子, 今次因為唔再係6:00pm 先開始, 所係由 10:00 am – 8:00 pm 順風順水咁搞掂 個 SCBCD 既試, 唉, 有點 shame, 自己其實未讀曬, (懶+考試先黎OT) 只係個 mock 太勁, 91% pass, 個officer 話 well done, 仲問我係咪好努力, 我唯有話 係呀係呀….. 買左 xbox 360, 呢2個weekend 就沈迷左係 Call of duty 4 既世界..
There is insufficient information for AsyncWeb (subproject of Mina) on internet, what I need is simulating a web services that reply in various seconds for load testing. the following code may not be correct, some wiered debug message… and I just depressed it by log4j.properties Mostly follow the lightweight example of AsyncWeb, the eclipse project zip can be obtained here
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
public class Main { private static final int PORT = 80; /** * Main * * @param args * @throws IOException */ public static void main(String[] args) throws IOException { SocketAcceptor acceptor = new NioSocketAcceptor(); acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new HttpCodecFactory())); acceptor.getFilterChain().addLast("executor", new ExecutorFilter(new OrderedThreadPoolExecutor(32))); //Allow the port to be reused even if the socket is in TIME_WAIT state acceptor.setReuseAddress(true); acceptor.getSessionConfig().setReuseAddress(true); acceptor.getSessionConfig().setReceiveBufferSize(1024); acceptor.getSessionConfig().setSendBufferSize(1024); // No Nagle's algorithm acceptor.getSessionConfig().setTcpNoDelay(true); acceptor.getSessionConfig().setSoLinger(-1); acceptor.setBacklog(10240); acceptor.setHandler(new CustomHttpIoHandler()); // customer handler acceptor.bind(new InetSocketAddress(PORT)); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
public class CustomHttpIoHandler implements IoHandler { private final Logger logger = LoggerFactory.getLogger(getClass()); private final Timer timer; private Random random = new Random(System.currentTimeMillis()); private final String SOAPENV_HEAD = ""; public CustomHttpIoHandler(){ timer = new Timer(true); } public void exceptionCaught(IoSession session, Throwable cause) throws Exception { if (!(cause instanceof IOException)) { cause.printStackTrace(); } session.close(true); } public void messageSent(IoSession session, Object message) throws Exception { } public void sessionClosed(IoSession session) throws Exception { } public void sessionCreated(IoSession session) throws Exception { } public void sessionIdle(IoSession session, IdleStatus status) throws Exception { session.close(true); } public void sessionOpened(IoSession session) throws Exception { session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30); } public void messageReceived(IoSession session, Object message) throws Exception { HttpRequest req = (HttpRequest) message; doAsynchronousDelayedResponse(session, req); } /** * business logic for various percentage and behaviour * * @param session mina session * @param req Http request * @throws CharacterCodingException */ private void doAsynchronousDelayedResponse(final IoSession session, final HttpRequest req) throws CharacterCodingException { int delay = 0; Behaviour behaviour; int value = nextRandom(1, 100); if(value < = 50){ // 50% of responses return valid result within 0-3 secs (good response time & good result) delay = nextRandom(10, 3000); behaviour = Behaviour.GOOD_TIME_GOOD_RESULT; }else if(value > 50 && value < =60){ //10% of responses return expected error within 0-3 secs (good response time & expected error result) delay = nextRandom(10, 3000); behaviour = Behaviour.GOOD_TIME_ERROR_RESULT; }else if(value > 60 && value < = 90){ //30% of responses return valid result within 3-15 secs (fair response time & good result) delay = nextRandom(3000, 15000); behaviour = Behaviour.FAIR_TIME_GOOD_RESULT; }else if(value > 90 && value < =95){ //5% of responses return valid result within 15-190 secs (poor response time & good result) delay = nextRandom(15000, 190000); behaviour = Behaviour.POOR_TIME_GOOD_RESULT; }else if(value > 95 && value < =97){ //2.5% of responses return valid result after 190 seconds (bad response time & good result) delay = nextRandom(15000, 190000); behaviour = Behaviour.BAD_TIME_GOOD_RESULT; }else{ //2.5% of responses return 'no content' after 190 seconds (bad response time & bad result) delay = nextRandom(15000, 190000); behaviour = Behaviour.BAD_TIME_BAD_RESULT; } final MutableHttpResponse res = new DefaultHttpResponse(); res.setStatus(HttpResponseStatus.OK); res.setContentType("application/soap+xml; charset=utf-8"); // get corresponding response from behaviour StringBuffer sb = getResponseXML(behaviour); IoBuffer bb = IoBuffer.allocate(1024); bb.setAutoExpand(true); bb.putString(sb.toString(), Charset.forName("UTF-8").newEncoder()); bb.flip(); res.setContent(bb); logger.info("delay:" + delay + " stub:" + behaviour); timer.schedule(new TimerTask() { @Override public void run() { writeResponse(session, req, res); } }, delay); } /** * Write the http response * * @param session mina session * @param req HTTP Request * @param res HTTP Response */ private void writeResponse(IoSession session, HttpRequest req, MutableHttpResponse res) { res.normalize(req); WriteFuture future = session.write(res); if (!HttpHeaderConstants.VALUE_KEEP_ALIVE.equalsIgnoreCase( res.getHeader( HttpHeaderConstants.KEY_CONNECTION))) { future.addListener(IoFutureListener.CLOSE); } } /** * Generate next random number from min(inclusive) to max(inclusive) * @param min minimum number * @param max maximum number * @return random integer */ private int nextRandom(int min, int max){ return random.nextInt(max-min+1)+min; } /** * Indicate what kind of behaviour * * @author SteveChan */ public enum Behaviour{ GOOD_TIME_GOOD_RESULT, //return valid result within 0-3 secs GOOD_TIME_ERROR_RESULT, //return expected error within 0-3 secs FAIR_TIME_GOOD_RESULT, //return valid result within 3-15 secs POOR_TIME_GOOD_RESULT, //return valid result within 15-190 secs ( BAD_TIME_GOOD_RESULT, //return valid result after 190 seconds BAD_TIME_BAD_RESULT //return 'no content' after 190 seconds } /** * * @param stub indicate what Behaviour * @return StringBuffer with return xml content */ private StringBuffer getResponseXML(Behaviour stub){ StringBuffer sb = new StringBuffer(); if(stub.equals(Behaviour.GOOD_TIME_GOOD_RESULT) || stub.equals(Behaviour.FAIR_TIME_GOOD_RESULT) || stub.equals(Behaviour.POOR_TIME_GOOD_RESULT) || stub.equals(Behaviour.BAD_TIME_GOOD_RESULT)){ sb.append(SOAPENV_HEAD) .append("") // some content here .append("") .append(""); }else if(stub.equals(Behaviour.GOOD_TIME_ERROR_RESULT)){ sb.append(SOAPENV_HEAD) .append("") // some content here .append("") .append(""); }else{ //BAD_TIME_BAD_RESULT sb.append(SOAPENV_HEAD) .append("") // some content here .append("") .append(""); } if(logger.isDebugEnabled()){ logger.debug("return stardard soap response xml by " + stub ); logger.debug(sb.toString()); } return sb; } } |
今個月既expenditure 嚴重超支, 下個月又要俾 vehicle registration fee, 雖然 AUD 近日回升得幾勁, 不過我既支出都係 AUD, 物價又唔見得平左…. EB games 出左個 promotion, 當然又俾班同事說我買, 仲專登send 另一個 jb hi-fi deal 俾我 今日走左去 helensvale 問, 冇貨, 哈哈, 都好, 有藉口唔買 ~~~ 之前有個調查話 australia 係最多人買console (inc. xbox/ps3/wii) 既地方, 應該都係, 係屋企打機唔使使咁多錢, 好過出街 🙂 星期五去左另一個同事屋企玩 poker, 第一次去到 palm beach 咁南, burleigh waters 已經夠遠, 要45mins 先返到office, 我就真係唔ok 啦… 不過間屋有泳池 水池, summer 真係幾爽既 前排冇左墨西哥一個大客, 佔收入30-40% 掛, 好在 spot 黎緊會出街, sales team 既人都幾好野, 都未有demo (our system) 都簽都40幾部出去. 老闆仲話要8月前出街….. omg, 呢2個月唔使旨意leave on time 只係hea 左一個week 就冇啦…. 不過上司卻叫我不用埋會, 多數都唔會8月前要起貨, 先做好plan 左既野先 可能係佢已經聽過好多 “urgent” request, 已經知道根本唔urgent :p