├── .gitignore ├── README.md ├── pom.xml ├── servlet-async-io ├── README.md ├── benchmark.jmx ├── pom.xml ├── src │ └── main │ │ ├── java │ │ └── me │ │ │ └── chanjar │ │ │ └── learning │ │ │ ├── AsyncReadServlet.java │ │ │ ├── AsyncWriteServlet.java │ │ │ └── Main.java │ │ └── resources │ │ └── bigfile └── user.properties ├── servlet-async-processing ├── README.md ├── benchmark.jmx ├── pom.xml └── src │ └── main │ └── java │ └── me │ └── chanjar │ └── learning │ ├── AsyncServlet1.java │ ├── AsyncServlet2.java │ ├── Main.java │ ├── SlowJob.java │ ├── SlowJobRunner.java │ └── SyncServlet.java ├── spring-mvc-async-io ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── me │ │ └── chanjar │ │ └── learning │ │ ├── Application.java │ │ ├── AsyncReadController.java │ │ ├── AsyncWriteController.java │ │ ├── CallableTraceController.java │ │ ├── config │ │ └── AsyncInterceptorConfiguration.java │ │ └── slowjob │ │ └── SlowJob.java │ └── resources │ └── application.properties ├── spring-mvc-async-processing ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── me │ └── chanjar │ └── learning │ ├── Application.java │ ├── CallableController.java │ ├── CompletionFutureController.java │ ├── DeferredResultController.java │ ├── ListenableFutureController.java │ ├── ResponseBodyEmitterController.java │ ├── SseEmitterController.java │ ├── StreamingResponseBodyController.java │ ├── config │ ├── ExecutorServiceConfiguration.java │ └── MvcAsyncTaskExecutorConfigurer.java │ └── slowjob │ └── SlowJob.java └── tomcat-start ├── pom.xml └── src └── main └── java └── me └── chanjar └── learning └── TomcatStart.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | 24 | # Idea files 25 | *.iml 26 | .idea 27 | 28 | # Eclipse files 29 | .project 30 | .classpath 31 | .settings 32 | 33 | target 34 | rebel.xml 35 | jmeter.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Web Async Learning 2 | 3 | Java web开发async机制学习 4 | 5 | 1. [Servlet 3.0 Async Processing](servlet-async-processing/README.md) 6 | 1. [Servlet 3.0 Async IO](servlet-async-io/README.md) 7 | 1. [Spring MVC Async Processing](spring-mvc-async-processing/README.md) 8 | 1. [Spring MVC Async IO](spring-mvc-async-io/README.md) 9 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | me.chanjar.learning 7 | web-async-learn-aggregator 8 | 1.0-SNAPSHOT 9 | pom 10 | 11 | 12 | 1.8 13 | 1.8 14 | 15 | 16 | 17 | tomcat-start 18 | servlet-async-io 19 | servlet-async-processing 20 | spring-mvc-async-processing 21 | spring-mvc-async-io 22 | 23 | 24 | 25 | 26 | 27 | javax.servlet 28 | javax.servlet-api 29 | 3.1.0 30 | 31 | 32 | org.apache.commons 33 | commons-lang3 34 | 3.6 35 | 36 | 37 | commons-io 38 | commons-io 39 | 2.5 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /servlet-async-io/README.md: -------------------------------------------------------------------------------- 1 | # Servlet 3.1 Async IO 2 | 3 | Servlet Async Processing提供了一种异步请求处理的手段,能够让你将Http thread从慢速处理中释放出来出来其他请求,提高系统的响应度。 4 | 5 | 但是光有Async Processing是不够的,因为整个请求-响应过程的速度快慢还牵涉到了客户端的网络情况,如果客户端网络情况糟糕,其上传和下载速度都很慢,那么同样也会长时间占用Http Thread使其不能被释放出来。 6 | 7 | 于是Servlet 3.1提供了Async IO机制,使得从Request中读、往Response里写变成异步动作。 8 | 9 | ## Async Read 10 | 11 | 我们先来一段客户端上传速度慢的例子,[AsyncReadServlet.java][src-AsyncReadServlet]: 12 | 13 | ```java 14 | @WebServlet(value = "/async-read", asyncSupported = true) 15 | public class AsyncReadServlet extends HttpServlet { 16 | 17 | @Override 18 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 19 | 20 | System.out.println("Servlet thread: " + Thread.currentThread().getName()); 21 | AsyncContext asyncCtx = req.startAsync(); 22 | ServletInputStream is = req.getInputStream(); 23 | is.setReadListener(new ReadListener() { 24 | private int totalReadBytes = 0; 25 | 26 | @Override 27 | public void onDataAvailable() { 28 | System.out.println("ReadListener thread: " + Thread.currentThread().getName()); 29 | 30 | try { 31 | byte buffer[] = new byte[1 * 1024]; 32 | int readBytes = 0; 33 | while (is.isReady() && !is.isFinished()) { 34 | int length = is.read(buffer); 35 | if (length == -1 && is.isFinished()) { 36 | asyncCtx.complete(); 37 | System.out.println("Read: " + readBytes + " bytes"); 38 | System.out.println("Total Read: " + totalReadBytes + " bytes"); 39 | return; 40 | } 41 | readBytes += length; 42 | totalReadBytes += length; 43 | 44 | } 45 | System.out.println("Read: " + readBytes + " bytes"); 46 | 47 | } catch (IOException ex) { 48 | ex.printStackTrace(); 49 | asyncCtx.complete(); 50 | } 51 | } 52 | 53 | @Override 54 | public void onAllDataRead() { 55 | try { 56 | System.out.println("Total Read: " + totalReadBytes + " bytes"); 57 | asyncCtx.getResponse().getWriter().println("Finished"); 58 | } catch (IOException ex) { 59 | ex.printStackTrace(); 60 | } 61 | asyncCtx.complete(); 62 | } 63 | 64 | @Override 65 | public void onError(Throwable t) { 66 | System.out.println(ExceptionUtils.getStackTrace(t)); 67 | asyncCtx.complete(); 68 | } 69 | }); 70 | 71 | } 72 | 73 | } 74 | ``` 75 | 76 | 我们利用`curl`的`--limit-rate`选项来模拟慢速上传``curl -X POST -F "bigfile=@src/main/resources/bigfile" --limit-rate 5k http://localhost:8080/async-read`` 77 | 78 | 然后观察服务端的打印输出: 79 | 80 | ``` 81 | Servlet thread: http-nio-8080-exec-3 82 | ReadListener thread: http-nio-8080-exec-3 83 | Read: 16538 bytes 84 | ReadListener thread: http-nio-8080-exec-4 85 | Read: 16384 bytes 86 | ReadListener thread: http-nio-8080-exec-5 87 | Read: 16384 bytes 88 | ReadListener thread: http-nio-8080-exec-7 89 | Read: 16384 bytes 90 | ReadListener thread: http-nio-8080-exec-6 91 | Read: 16384 bytes 92 | ReadListener thread: http-nio-8080-exec-8 93 | Read: 16384 bytes 94 | ReadListener thread: http-nio-8080-exec-9 95 | Read: 16384 bytes 96 | ReadListener thread: http-nio-8080-exec-10 97 | Read: 2312 bytes 98 | ReadListener thread: http-nio-8080-exec-1 99 | Read: 48 bytes 100 | Total Read: 117202 bytes 101 | ``` 102 | 103 | 可以从输出看到除了doGet和第一次进入onDataAvailable是同一个Http thread之外,后面的read动作都发生在另外的Http thread里。 104 | 这是因为客户端的数据推送速度太慢了,容器先将Http thread收回,当容器发现可以读取到新数据的时候,再分配一个Http thread去读InputStream,如此循环直到全部读完为止。 105 | 106 | 注意:`HttpServletRequest.getInputStream()`和`getParameter*()`不能同时使用。 107 | 108 | ## Async Write 109 | 110 | 再来一段客户端下载慢的例子,[AsyncWriteServlet.java][src-AsyncWriteServlet]: 111 | 112 | ```java 113 | @WebServlet(value = "/async-write", asyncSupported = true) 114 | public class AsyncWriteServlet extends HttpServlet { 115 | 116 | @Override 117 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 118 | 119 | System.out.println("Servlet thread: " + Thread.currentThread().getName()); 120 | AsyncContext asyncCtx = req.startAsync(); 121 | ServletOutputStream os = resp.getOutputStream(); 122 | InputStream bigfileInputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("bigfile"); 123 | 124 | os.setWriteListener(new WriteListener() { 125 | 126 | @Override 127 | public void onWritePossible() throws IOException { 128 | 129 | int loopCount = 0; 130 | System.out.println("WriteListener thread: " + Thread.currentThread().getName()); 131 | while (os.isReady()) { 132 | loopCount++; 133 | System.out.println("Loop Count: " + loopCount); 134 | byte[] bytes = readContent(); 135 | if (bytes != null) { 136 | os.write(bytes); 137 | } else { 138 | closeInputStream(); 139 | asyncCtx.complete(); 140 | break; 141 | } 142 | } 143 | } 144 | 145 | @Override 146 | public void onError(Throwable t) { 147 | 148 | try { 149 | os.print("Error happened"); 150 | os.print(ExceptionUtils.getStackTrace(t)); 151 | } catch (IOException e) { 152 | e.printStackTrace(); 153 | } finally { 154 | closeInputStream(); 155 | asyncCtx.complete(); 156 | } 157 | 158 | } 159 | 160 | private byte[] readContent() throws IOException { 161 | byte[] bytes = new byte[1024]; 162 | int readLength = IOUtils.read(bigfileInputStream, bytes); 163 | if (readLength <= 0) { 164 | return null; 165 | } 166 | return bytes; 167 | } 168 | 169 | private void closeInputStream() { 170 | IOUtils.closeQuietly(bigfileInputStream); 171 | } 172 | }); 173 | 174 | } 175 | 176 | } 177 | ``` 178 | 179 | 同样利用`curl`做慢速下载,``curl --limit-rate 5k http://localhost:8080/async-write`` 180 | 181 | 接下来看以下服务端打印输出: 182 | 183 | ``` 184 | Servlet thread: http-nio-8080-exec-1 185 | WriteListener thread: http-nio-8080-exec-1 186 | Write bytes: 8192 187 | WriteListener thread: http-nio-8080-exec-2 188 | Write bytes: 8192 189 | WriteListener thread: http-nio-8080-exec-3 190 | Write bytes: 8192 191 | WriteListener thread: http-nio-8080-exec-4 192 | Write bytes: 8192 193 | WriteListener thread: http-nio-8080-exec-5 194 | Write bytes: 8192 195 | WriteListener thread: http-nio-8080-exec-6 196 | Write bytes: 8192 197 | WriteListener thread: http-nio-8080-exec-7 198 | Write bytes: 8192 199 | WriteListener thread: http-nio-8080-exec-8 200 | Write bytes: 8192 201 | WriteListener thread: http-nio-8080-exec-9 202 | Write bytes: 8192 203 | WriteListener thread: http-nio-8080-exec-10 204 | Write bytes: 8192 205 | WriteListener thread: http-nio-8080-exec-1 206 | Write bytes: 8192 207 | WriteListener thread: http-nio-8080-exec-2 208 | Write bytes: 8192 209 | WriteListener thread: http-nio-8080-exec-3 210 | Write bytes: 8192 211 | WriteListener thread: http-nio-8080-exec-4 212 | Write bytes: 8192 213 | WriteListener thread: http-nio-8080-exec-5 214 | Write bytes: 2312 215 | ``` 216 | 217 | PS. 后发现即使没有添加`--limit-rate`参数,也会出现类似于上面的结果。 218 | 219 | ## Jmeter 220 | 221 | 上面两个例子使用的是`curl`来模拟,我们也提供了Jmeter的benchmark。 222 | 223 | 需要注意的是,必须在user.properties文件所在目录启动Jmeter,因为这个文件里提供了模拟慢速连接的参数`httpclient.socket.http.cps=5120`。然后利用Jmeter打开benchmark.xml。 224 | 225 | 226 | ## 相关资料 227 | 228 | * [Java EE 7 Tutorial: Java Servlet Technology - Nonblocking I/O][ref-1] 229 | * [Slides - Servlet 3.1 Async IO][ref-2] 230 | * [Non-blocking I/O using Servlet 3.1: Scalable applications using Java EE 7][ref-3] 231 | * [How to simulate network bandwidth in JMeter?][ref-4] 232 | * [Configuring JMeter][ref-5] 233 | * [Servlet 3.1 Asynchronous IO and Jetty-9.1][ref-6] 234 | 235 | [ref-1]: https://docs.oracle.com/javaee/7/tutorial/servlets013.htm 236 | [ref-2]: https://www.slideshare.net/SimoneBordet/servlet-31-async-io 237 | [ref-3]: https://blogs.oracle.com/arungupta/non-blocking-io-using-servlet-31:-scalable-applications-using-java-ee-7-totd-188 238 | [ref-4]: https://wiki.apache.org/jmeter/Controlling%20Bandwidth%20in%20JMeter%20to%20simulate%20different%20networks 239 | [ref-5]: http://jmeter.apache.org/usermanual/get-started.html#configuring_jmeter 240 | [ref-6]: https://webtide.com/servlet-3-1-async-io-and-jetty/ 241 | [src-AsyncReadServlet]: src/main/java/me/chanjar/learning/AsyncReadServlet.java 242 | [src-AsyncWriteServlet]: src/main/java/me/chanjar/learning/AsyncWriteServlet.java 243 | -------------------------------------------------------------------------------- /servlet-async-io/benchmark.jmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | false 7 | true 8 | 9 | 10 | 11 | iteration 12 | 3 13 | = 14 | 15 | 16 | users 17 | 400 18 | = 19 | 20 | 21 | rampup 22 | 0 23 | = 24 | 25 | 26 | 27 | 28 | true 29 | 30 | 31 | 32 | 33 | 34 | 35 | localhost 36 | 8080 37 | 38 | 39 | 40 | 41 | 42 | HttpClient4 43 | 6 44 | 45 | 46 | 47 | continue 48 | 49 | false 50 | ${iteration} 51 | 52 | ${users} 53 | ${rampup} 54 | 1512530334000 55 | 1512530334000 56 | false 57 | 58 | 59 | true 60 | 61 | 62 | 63 | 64 | 65 | 66 | src/main/resources/bigfile 67 | bigfile 68 | plain/text 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | /async-read 82 | POST 83 | true 84 | false 85 | true 86 | false 87 | false 88 | 89 | 90 | 91 | 92 | 93 | continue 94 | 95 | false 96 | ${iteration} 97 | 98 | ${users} 99 | ${rampup} 100 | 1512530334000 101 | 1512530334000 102 | false 103 | 104 | 105 | true 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | /async-write 119 | GET 120 | true 121 | false 122 | true 123 | false 124 | false 125 | 126 | 127 | 128 | 129 | 130 | false 131 | 132 | saveConfig 133 | 134 | 135 | true 136 | true 137 | true 138 | 139 | true 140 | true 141 | true 142 | true 143 | false 144 | true 145 | true 146 | false 147 | false 148 | false 149 | true 150 | false 151 | false 152 | false 153 | true 154 | 0 155 | true 156 | true 157 | true 158 | true 159 | true 160 | 161 | 162 | 163 | 164 | 165 | 166 | true 167 | 168 | saveConfig 169 | 170 | 171 | true 172 | true 173 | true 174 | 175 | true 176 | true 177 | true 178 | true 179 | false 180 | true 181 | true 182 | false 183 | false 184 | false 185 | true 186 | false 187 | false 188 | false 189 | true 190 | 0 191 | true 192 | true 193 | true 194 | true 195 | true 196 | 197 | 198 | 199 | 200 | 201 | 202 | false 203 | 204 | saveConfig 205 | 206 | 207 | true 208 | true 209 | true 210 | 211 | true 212 | true 213 | true 214 | true 215 | false 216 | true 217 | true 218 | false 219 | false 220 | false 221 | true 222 | false 223 | false 224 | false 225 | true 226 | 0 227 | true 228 | true 229 | true 230 | true 231 | true 232 | 233 | 234 | 235 | 500 236 | false 237 | 238 | 239 | 240 | 241 | false 242 | false 243 | true 244 | 245 | 246 | 247 | false 248 | 249 | saveConfig 250 | 251 | 252 | true 253 | true 254 | true 255 | 256 | true 257 | true 258 | true 259 | true 260 | false 261 | true 262 | true 263 | false 264 | false 265 | false 266 | true 267 | false 268 | false 269 | false 270 | true 271 | 0 272 | true 273 | true 274 | true 275 | true 276 | true 277 | 278 | 279 | 280 | 1000 281 | false 282 | 283 | 284 | 285 | 286 | false 287 | false 288 | true 289 | 290 | 291 | 292 | 293 | 294 | -------------------------------------------------------------------------------- /servlet-async-io/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | me.chanjar.learning 7 | web-async-learn-aggregator 8 | 1.0-SNAPSHOT 9 | 10 | 11 | me.chanjar.learning 12 | servlet-async-io 13 | war 14 | 15 | 16 | 17 | 18 | 19 | me.chanjar.learning 20 | tomcat-start 21 | ${project.version} 22 | 23 | 24 | 25 | javax.servlet 26 | javax.servlet-api 27 | runtime 28 | 29 | 30 | 31 | org.apache.commons 32 | commons-lang3 33 | 34 | 35 | 36 | commons-io 37 | commons-io 38 | 39 | 40 | 41 | junit 42 | junit 43 | 3.8.1 44 | test 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /servlet-async-io/src/main/java/me/chanjar/learning/AsyncReadServlet.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import org.apache.commons.lang3.exception.ExceptionUtils; 4 | 5 | import javax.servlet.AsyncContext; 6 | import javax.servlet.ReadListener; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.ServletInputStream; 9 | import javax.servlet.annotation.WebServlet; 10 | import javax.servlet.http.HttpServlet; 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpServletResponse; 13 | import java.io.IOException; 14 | 15 | @WebServlet(value = "/async-read", asyncSupported = true) 16 | public class AsyncReadServlet extends HttpServlet { 17 | 18 | @Override 19 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 20 | 21 | System.out.println("Servlet thread: " + Thread.currentThread().getName()); 22 | AsyncContext asyncCtx = req.startAsync(); 23 | ServletInputStream is = req.getInputStream(); 24 | is.setReadListener(new ReadListener() { 25 | private int totalReadBytes = 0; 26 | 27 | @Override 28 | public void onDataAvailable() { 29 | System.out.println("ReadListener thread: " + Thread.currentThread().getName()); 30 | 31 | try { 32 | byte buffer[] = new byte[1 * 1024]; 33 | int readBytes = 0; 34 | while (is.isReady() && !is.isFinished()) { 35 | int length = is.read(buffer); 36 | if (length == -1 && is.isFinished()) { 37 | asyncCtx.complete(); 38 | System.out.println("Read: " + readBytes + " bytes"); 39 | System.out.println("Total Read: " + totalReadBytes + " bytes"); 40 | return; 41 | } 42 | readBytes += length; 43 | totalReadBytes += length; 44 | 45 | } 46 | System.out.println("Read: " + readBytes + " bytes"); 47 | 48 | } catch (IOException ex) { 49 | ex.printStackTrace(); 50 | asyncCtx.complete(); 51 | } 52 | } 53 | 54 | @Override 55 | public void onAllDataRead() { 56 | try { 57 | System.out.println("Total Read: " + totalReadBytes + " bytes"); 58 | asyncCtx.getResponse().getWriter().println("Finished"); 59 | } catch (IOException ex) { 60 | ex.printStackTrace(); 61 | } 62 | asyncCtx.complete(); 63 | } 64 | 65 | @Override 66 | public void onError(Throwable t) { 67 | System.out.println(ExceptionUtils.getStackTrace(t)); 68 | asyncCtx.complete(); 69 | } 70 | }); 71 | 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /servlet-async-io/src/main/java/me/chanjar/learning/AsyncWriteServlet.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import org.apache.commons.io.IOUtils; 4 | import org.apache.commons.lang3.exception.ExceptionUtils; 5 | 6 | import javax.servlet.AsyncContext; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.ServletOutputStream; 9 | import javax.servlet.WriteListener; 10 | import javax.servlet.annotation.WebServlet; 11 | import javax.servlet.http.HttpServlet; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.io.IOException; 15 | import java.io.InputStream; 16 | 17 | @WebServlet(value = "/async-write", asyncSupported = true) 18 | public class AsyncWriteServlet extends HttpServlet { 19 | 20 | @Override 21 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 22 | 23 | System.out.println("Servlet thread: " + Thread.currentThread().getName()); 24 | AsyncContext asyncCtx = req.startAsync(); 25 | ServletOutputStream os = resp.getOutputStream(); 26 | InputStream bigfileInputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("bigfile"); 27 | 28 | os.setWriteListener(new WriteListener() { 29 | 30 | @Override 31 | public void onWritePossible() throws IOException { 32 | 33 | int writeBytes = 0; 34 | System.out.println("WriteListener thread: " + Thread.currentThread().getName()); 35 | while (os.isReady()) { 36 | byte[] bytes = new byte[1024]; 37 | int readBytes = readContent(bytes); 38 | if (readBytes > 0) { 39 | os.write(bytes); 40 | writeBytes += readBytes; 41 | } else { 42 | closeInputStream(); 43 | asyncCtx.complete(); 44 | break; 45 | } 46 | } 47 | System.out.println("Write bytes: " + writeBytes); 48 | 49 | } 50 | 51 | @Override 52 | public void onError(Throwable t) { 53 | 54 | try { 55 | os.print("Error happened"); 56 | os.print(ExceptionUtils.getStackTrace(t)); 57 | } catch (IOException e) { 58 | e.printStackTrace(); 59 | } finally { 60 | closeInputStream(); 61 | asyncCtx.complete(); 62 | } 63 | 64 | } 65 | 66 | private int readContent(byte[] buffer) throws IOException { 67 | int readLength = IOUtils.read(bigfileInputStream, buffer); 68 | return readLength; 69 | } 70 | 71 | private void closeInputStream() { 72 | IOUtils.closeQuietly(bigfileInputStream); 73 | } 74 | }); 75 | 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /servlet-async-io/src/main/java/me/chanjar/learning/Main.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) throws Exception { 6 | 7 | TomcatStart.start(); 8 | 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /servlet-async-io/src/main/resources/bigfile: -------------------------------------------------------------------------------- 1 | 00001: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 2 | 00002: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 3 | 00003: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 4 | 00004: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 5 | 00005: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 6 | 00006: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 7 | 00007: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 8 | 00008: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 9 | 00009: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 10 | 00010: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 11 | 00011: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 12 | 00012: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 13 | 00013: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 14 | 00014: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 15 | 00015: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 16 | 00016: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 17 | 00017: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 18 | 00018: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 19 | 00019: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 20 | 00020: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 21 | 00021: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 22 | 00022: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 23 | 00023: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 24 | 00024: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 25 | 00025: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 26 | 00026: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 27 | 00027: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 28 | 00028: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 29 | 00029: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 30 | 00030: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 31 | 00031: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 32 | 00032: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 33 | 00033: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 34 | 00034: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 35 | 00035: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 36 | 00036: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 37 | 00037: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 38 | 00038: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 39 | 00039: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 40 | 00040: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 41 | 00041: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 42 | 00042: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 43 | 00043: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 44 | 00044: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 45 | 00045: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 46 | 00046: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 47 | 00047: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 48 | 00048: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 49 | 00049: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 50 | 00050: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 51 | 00051: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 52 | 00052: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 53 | 00053: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 54 | 00054: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 55 | 00055: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 56 | 00056: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 57 | 00057: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 58 | 00058: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 59 | 00059: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 60 | 00060: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 61 | 00061: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 62 | 00062: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 63 | 00063: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 64 | 00064: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 65 | 00065: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 66 | 00066: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 67 | 00067: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 68 | 00068: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 69 | 00069: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 70 | 00070: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 71 | 00071: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 72 | 00072: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 73 | 00073: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 74 | 00074: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 75 | 00075: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 76 | 00076: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 77 | 00077: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 78 | 00078: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 79 | 00079: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 80 | 00080: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 81 | 00081: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 82 | 00082: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 83 | 00083: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 84 | 00084: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 85 | 00085: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 86 | 00086: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 87 | 00087: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 88 | 00088: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 89 | 00089: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 90 | 00090: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 91 | 00091: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 92 | 00092: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 93 | 00093: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 94 | 00094: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 95 | 00095: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 96 | 00096: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 97 | 00097: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 98 | 00098: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 99 | 00099: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 100 | 00100: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 101 | 00101: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 102 | 00102: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 103 | 00103: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 104 | 00104: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 105 | 00105: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 106 | 00106: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 107 | 00107: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 108 | 00108: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 109 | 00109: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 110 | 00110: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 111 | 00111: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 112 | 00112: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 113 | 00113: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 114 | 00114: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 115 | 00115: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 116 | 00116: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 117 | 00117: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 118 | 00118: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 119 | 00119: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 120 | 00120: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 121 | 00121: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 122 | 00122: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 123 | 00123: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 124 | 00124: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 125 | 00125: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 126 | 00126: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 127 | 00127: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 128 | 00128: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 129 | 00129: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 130 | 00130: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 131 | 00131: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 132 | 00132: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 133 | 00133: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 134 | 00134: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 135 | 00135: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 136 | 00136: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 137 | 00137: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 138 | 00138: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 139 | 00139: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 140 | 00140: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 141 | 00141: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 142 | 00142: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 143 | 00143: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 144 | 00144: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 145 | 00145: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 146 | 00146: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 147 | 00147: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 148 | 00148: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 149 | 00149: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 150 | 00150: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 151 | 00151: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 152 | 00152: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 153 | 00153: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 154 | 00154: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 155 | 00155: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 156 | 00156: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 157 | 00157: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 158 | 00158: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 159 | 00159: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 160 | 00160: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 161 | 00161: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 162 | 00162: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 163 | 00163: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 164 | 00164: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 165 | 00165: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 166 | 00166: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 167 | 00167: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 168 | 00168: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 169 | 00169: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 170 | 00170: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 171 | 00171: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 172 | 00172: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 173 | 00173: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 174 | 00174: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 175 | 00175: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 176 | 00176: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 177 | 00177: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 178 | 00178: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 179 | 00179: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 180 | 00180: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 181 | 00181: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 182 | 00182: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 183 | 00183: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 184 | 00184: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 185 | 00185: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 186 | 00186: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 187 | 00187: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 188 | 00188: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 189 | 00189: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 190 | 00190: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 191 | 00191: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 192 | 00192: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 193 | 00193: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 194 | 00194: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 195 | 00195: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 196 | 00196: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 197 | 00197: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 198 | 00198: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 199 | 00199: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 200 | 00200: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 201 | 00201: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 202 | 00202: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 203 | 00203: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 204 | 00204: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 205 | 00205: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 206 | 00206: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 207 | 00207: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 208 | 00208: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 209 | 00209: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 210 | 00210: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 211 | 00211: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 212 | 00212: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 213 | 00213: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 214 | 00214: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 215 | 00215: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 216 | 00216: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 217 | 00217: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 218 | 00218: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 219 | 00219: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 220 | 00220: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 221 | 00221: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 222 | 00222: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 223 | 00223: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 224 | 00224: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 225 | 00225: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 226 | 00226: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 227 | 00227: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 228 | 00228: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 229 | 00229: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 230 | 00230: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 231 | 00231: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 232 | 00232: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 233 | 00233: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 234 | 00234: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 235 | 00235: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 236 | 00236: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 237 | 00237: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 238 | 00238: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 239 | 00239: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 240 | 00240: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 241 | 00241: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 242 | 00242: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 243 | 00243: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 244 | 00244: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 245 | 00245: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 246 | 00246: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 247 | 00247: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 248 | 00248: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 249 | 00249: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 250 | 00250: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 251 | 00251: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 252 | 00252: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 253 | 00253: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 254 | 00254: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 255 | 00255: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 256 | 00256: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 257 | 00257: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 258 | 00258: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 259 | 00259: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 260 | 00260: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 261 | 00261: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 262 | 00262: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 263 | 00263: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 264 | 00264: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 265 | 00265: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 266 | 00266: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 267 | 00267: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 268 | 00268: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 269 | 00269: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 270 | 00270: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 271 | 00271: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 272 | 00272: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 273 | 00273: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 274 | 00274: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 275 | 00275: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 276 | 00276: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 277 | 00277: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 278 | 00278: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 279 | 00279: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 280 | 00280: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 281 | 00281: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 282 | 00282: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 283 | 00283: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 284 | 00284: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 285 | 00285: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 286 | 00286: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 287 | 00287: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 288 | 00288: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 289 | 00289: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 290 | 00290: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 291 | 00291: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 292 | 00292: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 293 | 00293: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 294 | 00294: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 295 | 00295: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 296 | 00296: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 297 | 00297: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 298 | 00298: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 299 | 00299: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 300 | 00300: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 301 | 00301: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 302 | 00302: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 303 | 00303: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 304 | 00304: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 305 | 00305: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 306 | 00306: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 307 | 00307: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 308 | 00308: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 309 | 00309: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 310 | 00310: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 311 | 00311: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 312 | 00312: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 313 | 00313: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 314 | 00314: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 315 | 00315: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 316 | 00316: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 317 | 00317: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 318 | 00318: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 319 | 00319: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 320 | 00320: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 321 | 00321: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 322 | 00322: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 323 | 00323: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 324 | 00324: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 325 | 00325: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 326 | 00326: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 327 | 00327: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 328 | 00328: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 329 | 00329: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 330 | 00330: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 331 | 00331: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 332 | 00332: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 333 | 00333: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 334 | 00334: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 335 | 00335: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 336 | 00336: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 337 | 00337: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 338 | 00338: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 339 | 00339: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 340 | 00340: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 341 | 00341: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 342 | 00342: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 343 | 00343: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 344 | 00344: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 345 | 00345: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 346 | 00346: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 347 | 00347: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 348 | 00348: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 349 | 00349: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 350 | 00350: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 351 | 00351: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 352 | 00352: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 353 | 00353: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 354 | 00354: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 355 | 00355: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 356 | 00356: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 357 | 00357: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 358 | 00358: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 359 | 00359: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 360 | 00360: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 361 | 00361: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 362 | 00362: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 363 | 00363: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 364 | 00364: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 365 | 00365: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 366 | 00366: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 367 | 00367: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 368 | 00368: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 369 | 00369: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 370 | 00370: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 371 | 00371: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 372 | 00372: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 373 | 00373: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 374 | 00374: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 375 | 00375: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 376 | 00376: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 377 | 00377: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 378 | 00378: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 379 | 00379: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 380 | 00380: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 381 | 00381: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 382 | 00382: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 383 | 00383: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 384 | 00384: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 385 | 00385: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 386 | 00386: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 387 | 00387: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 388 | 00388: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 389 | 00389: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 390 | 00390: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 391 | 00391: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 392 | 00392: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 393 | 00393: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 394 | 00394: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 395 | 00395: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 396 | 00396: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 397 | 00397: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 398 | 00398: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 399 | 00399: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 400 | 00400: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 401 | 00401: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 402 | 00402: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 403 | 00403: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 404 | 00404: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 405 | 00405: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 406 | 00406: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 407 | 00407: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 408 | 00408: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 409 | 00409: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 410 | 00410: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 411 | 00411: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 412 | 00412: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 413 | 00413: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 414 | 00414: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 415 | 00415: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 416 | 00416: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 417 | 00417: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 418 | 00418: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 419 | 00419: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 420 | 00420: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 421 | 00421: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 422 | 00422: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 423 | 00423: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 424 | 00424: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 425 | 00425: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 426 | 00426: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 427 | 00427: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 428 | 00428: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 429 | 00429: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 430 | 00430: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 431 | 00431: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 432 | 00432: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 433 | 00433: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 434 | 00434: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 435 | 00435: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 436 | 00436: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 437 | 00437: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 438 | 00438: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 439 | 00439: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 440 | 00440: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 441 | 00441: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 442 | 00442: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 443 | 00443: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 444 | 00444: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 445 | 00445: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 446 | 00446: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 447 | 00447: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 448 | 00448: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 449 | 00449: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 450 | 00450: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 451 | 00451: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 452 | 00452: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 453 | 00453: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 454 | 00454: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 455 | 00455: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 456 | 00456: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 457 | 00457: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 458 | 00458: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 459 | 00459: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 460 | 00460: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 461 | 00461: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 462 | 00462: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 463 | 00463: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 464 | 00464: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 465 | 00465: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 466 | 00466: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 467 | 00467: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 468 | 00468: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 469 | 00469: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 470 | 00470: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 471 | 00471: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 472 | 00472: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 473 | 00473: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 474 | 00474: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 475 | 00475: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 476 | 00476: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 477 | 00477: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 478 | 00478: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 479 | 00479: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 480 | 00480: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 481 | 00481: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 482 | 00482: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 483 | 00483: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 484 | 00484: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 485 | 00485: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 486 | 00486: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 487 | 00487: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 488 | 00488: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 489 | 00489: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 490 | 00490: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 491 | 00491: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 492 | 00492: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 493 | 00493: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 494 | 00494: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 495 | 00495: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 496 | 00496: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 497 | 00497: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 498 | 00498: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 499 | 00499: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 500 | 00500: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 501 | 00501: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 502 | 00502: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 503 | 00503: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 504 | 00504: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 505 | 00505: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 506 | 00506: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 507 | 00507: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 508 | 00508: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 509 | 00509: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 510 | 00510: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 511 | 00511: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 512 | 00512: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 513 | 00513: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 514 | 00514: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 515 | 00515: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 516 | 00516: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 517 | 00517: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 518 | 00518: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 519 | 00519: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 520 | 00520: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 521 | 00521: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 522 | 00522: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 523 | 00523: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 524 | 00524: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 525 | 00525: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 526 | 00526: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 527 | 00527: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 528 | 00528: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 529 | 00529: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 530 | 00530: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 531 | 00531: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 532 | 00532: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 533 | 00533: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 534 | 00534: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 535 | 00535: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 536 | 00536: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 537 | 00537: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 538 | 00538: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 539 | 00539: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 540 | 00540: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 541 | 00541: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 542 | 00542: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 543 | 00543: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 544 | 00544: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 545 | 00545: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 546 | 00546: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 547 | 00547: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 548 | 00548: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 549 | 00549: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 550 | 00550: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 551 | 00551: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 552 | 00552: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 553 | 00553: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 554 | 00554: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 555 | 00555: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 556 | 00556: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 557 | 00557: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 558 | 00558: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 559 | 00559: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 560 | 00560: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 561 | 00561: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 562 | 00562: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 563 | 00563: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 564 | 00564: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 565 | 00565: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 566 | 00566: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 567 | 00567: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 568 | 00568: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 569 | 00569: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 570 | 00570: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 571 | 00571: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 572 | 00572: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 573 | 00573: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 574 | 00574: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 575 | 00575: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 576 | 00576: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 577 | 00577: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 578 | 00578: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 579 | 00579: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 580 | 00580: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 581 | 00581: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 582 | 00582: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 583 | 00583: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 584 | 00584: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 585 | 00585: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 586 | 00586: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 587 | 00587: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 588 | 00588: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 589 | 00589: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 590 | 00590: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 591 | 00591: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 592 | 00592: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 593 | 00593: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 594 | 00594: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 595 | 00595: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 596 | 00596: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 597 | 00597: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 598 | 00598: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 599 | 00599: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 600 | 00600: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 601 | 00601: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 602 | 00602: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 603 | 00603: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 604 | 00604: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 605 | 00605: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 606 | 00606: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 607 | 00607: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 608 | 00608: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 609 | 00609: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 610 | 00610: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 611 | 00611: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 612 | 00612: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 613 | 00613: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 614 | 00614: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 615 | 00615: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 616 | 00616: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 617 | 00617: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 618 | 00618: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 619 | 00619: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 620 | 00620: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 621 | 00621: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 622 | 00622: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 623 | 00623: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 624 | 00624: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 625 | 00625: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 626 | 00626: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 627 | 00627: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 628 | 00628: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 629 | 00629: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 630 | 00630: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 631 | 00631: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 632 | 00632: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 633 | 00633: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 634 | 00634: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 635 | 00635: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 636 | 00636: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 637 | 00637: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 638 | 00638: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 639 | 00639: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 640 | 00640: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 641 | 00641: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 642 | 00642: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 643 | 00643: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 644 | 00644: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 645 | 00645: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 646 | 00646: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 647 | 00647: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 648 | 00648: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 649 | 00649: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 650 | 00650: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 651 | 00651: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 652 | 00652: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 653 | 00653: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 654 | 00654: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 655 | 00655: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 656 | 00656: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 657 | 00657: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 658 | 00658: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 659 | 00659: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 660 | 00660: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 661 | 00661: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 662 | 00662: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 663 | 00663: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 664 | 00664: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 665 | 00665: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 666 | 00666: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 667 | 00667: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 668 | 00668: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 669 | 00669: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 670 | 00670: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 671 | 00671: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 672 | 00672: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 673 | 00673: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 674 | 00674: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 675 | 00675: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 676 | 00676: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 677 | 00677: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 678 | 00678: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 679 | 00679: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 680 | 00680: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 681 | 00681: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 682 | 00682: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 683 | 00683: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 684 | 00684: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 685 | 00685: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 686 | 00686: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 687 | 00687: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 688 | 00688: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 689 | 00689: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 690 | 00690: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 691 | 00691: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 692 | 00692: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 693 | 00693: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 694 | 00694: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 695 | 00695: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 696 | 00696: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 697 | 00697: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 698 | 00698: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 699 | 00699: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 700 | 00700: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 701 | 00701: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 702 | 00702: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 703 | 00703: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 704 | 00704: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 705 | 00705: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 706 | 00706: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 707 | 00707: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 708 | 00708: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 709 | 00709: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 710 | 00710: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 711 | 00711: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 712 | 00712: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 713 | 00713: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 714 | 00714: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 715 | 00715: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 716 | 00716: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 717 | 00717: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 718 | 00718: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 719 | 00719: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 720 | 00720: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 721 | 00721: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 722 | 00722: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 723 | 00723: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 724 | 00724: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 725 | 00725: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 726 | 00726: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 727 | 00727: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 728 | 00728: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 729 | 00729: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 730 | 00730: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 731 | 00731: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 732 | 00732: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 733 | 00733: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 734 | 00734: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 735 | 00735: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 736 | 00736: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 737 | 00737: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 738 | 00738: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 739 | 00739: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 740 | 00740: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 741 | 00741: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 742 | 00742: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 743 | 00743: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 744 | 00744: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 745 | 00745: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 746 | 00746: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 747 | 00747: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 748 | 00748: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 749 | 00749: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 750 | 00750: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 751 | 00751: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 752 | 00752: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 753 | 00753: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 754 | 00754: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 755 | 00755: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 756 | 00756: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 757 | 00757: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 758 | 00758: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 759 | 00759: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 760 | 00760: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 761 | 00761: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 762 | 00762: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 763 | 00763: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 764 | 00764: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 765 | 00765: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 766 | 00766: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 767 | 00767: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 768 | 00768: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 769 | 00769: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 770 | 00770: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 771 | 00771: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 772 | 00772: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 773 | 00773: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 774 | 00774: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 775 | 00775: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 776 | 00776: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 777 | 00777: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 778 | 00778: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 779 | 00779: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 780 | 00780: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 781 | 00781: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 782 | 00782: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 783 | 00783: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 784 | 00784: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 785 | 00785: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 786 | 00786: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 787 | 00787: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 788 | 00788: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 789 | 00789: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 790 | 00790: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 791 | 00791: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 792 | 00792: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 793 | 00793: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 794 | 00794: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 795 | 00795: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 796 | 00796: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 797 | 00797: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 798 | 00798: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 799 | 00799: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 800 | 00800: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 801 | 00801: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 802 | 00802: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 803 | 00803: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 804 | 00804: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 805 | 00805: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 806 | 00806: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 807 | 00807: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 808 | 00808: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 809 | 00809: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 810 | 00810: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 811 | 00811: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 812 | 00812: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 813 | 00813: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 814 | 00814: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 815 | 00815: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 816 | 00816: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 817 | 00817: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 818 | 00818: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 819 | 00819: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 820 | 00820: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 821 | 00821: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 822 | 00822: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 823 | 00823: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 824 | 00824: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 825 | 00825: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 826 | 00826: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 827 | 00827: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 828 | 00828: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 829 | 00829: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 830 | 00830: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 831 | 00831: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 832 | 00832: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 833 | 00833: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 834 | 00834: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 835 | 00835: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 836 | 00836: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 837 | 00837: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 838 | 00838: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 839 | 00839: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 840 | 00840: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 841 | 00841: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 842 | 00842: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 843 | 00843: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 844 | 00844: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 845 | 00845: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 846 | 00846: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 847 | 00847: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 848 | 00848: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 849 | 00849: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 850 | 00850: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 851 | 00851: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 852 | 00852: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 853 | 00853: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 854 | 00854: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 855 | 00855: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 856 | 00856: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 857 | 00857: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 858 | 00858: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 859 | 00859: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 860 | 00860: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 861 | 00861: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 862 | 00862: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 863 | 00863: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 864 | 00864: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 865 | 00865: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 866 | 00866: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 867 | 00867: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 868 | 00868: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 869 | 00869: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 870 | 00870: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 871 | 00871: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 872 | 00872: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 873 | 00873: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 874 | 00874: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 875 | 00875: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 876 | 00876: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 877 | 00877: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 878 | 00878: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 879 | 00879: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 880 | 00880: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 881 | 00881: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 882 | 00882: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 883 | 00883: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 884 | 00884: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 885 | 00885: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 886 | 00886: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 887 | 00887: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 888 | 00888: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 889 | 00889: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 890 | 00890: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 891 | 00891: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 892 | 00892: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 893 | 00893: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 894 | 00894: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 895 | 00895: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 896 | 00896: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 897 | 00897: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 898 | 00898: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 899 | 00899: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 900 | 00900: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 901 | 00901: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 902 | 00902: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 903 | 00903: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 904 | 00904: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 905 | 00905: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 906 | 00906: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 907 | 00907: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 908 | 00908: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 909 | 00909: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 910 | 00910: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 911 | 00911: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 912 | 00912: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 913 | 00913: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 914 | 00914: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 915 | 00915: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 916 | 00916: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 917 | 00917: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 918 | 00918: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 919 | 00919: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 920 | 00920: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 921 | 00921: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 922 | 00922: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 923 | 00923: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 924 | 00924: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 925 | 00925: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 926 | 00926: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 927 | 00927: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 928 | 00928: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 929 | 00929: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 930 | 00930: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 931 | 00931: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 932 | 00932: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 933 | 00933: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 934 | 00934: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 935 | 00935: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 936 | 00936: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 937 | 00937: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 938 | 00938: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 939 | 00939: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 940 | 00940: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 941 | 00941: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 942 | 00942: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 943 | 00943: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 944 | 00944: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 945 | 00945: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 946 | 00946: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 947 | 00947: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 948 | 00948: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 949 | 00949: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 950 | 00950: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 951 | 00951: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 952 | 00952: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 953 | 00953: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 954 | 00954: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 955 | 00955: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 956 | 00956: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 957 | 00957: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 958 | 00958: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 959 | 00959: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 960 | 00960: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 961 | 00961: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 962 | 00962: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 963 | 00963: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 964 | 00964: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 965 | 00965: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 966 | 00966: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 967 | 00967: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 968 | 00968: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 969 | 00969: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 970 | 00970: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 971 | 00971: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 972 | 00972: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 973 | 00973: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 974 | 00974: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 975 | 00975: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 976 | 00976: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 977 | 00977: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 978 | 00978: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 979 | 00979: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 980 | 00980: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 981 | 00981: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 982 | 00982: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 983 | 00983: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 984 | 00984: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 985 | 00985: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 986 | 00986: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 987 | 00987: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 988 | 00988: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 989 | 00989: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 990 | 00990: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 991 | 00991: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 992 | 00992: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 993 | 00993: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 994 | 00994: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 995 | 00995: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 996 | 00996: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 997 | 00997: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 998 | 00998: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 999 | 00999: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 1000 | 01000: 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 1001 | -------------------------------------------------------------------------------- /servlet-async-io/user.properties: -------------------------------------------------------------------------------- 1 | # Define characters per second > 0 to emulate slow connections 2 | httpclient.socket.http.cps=5120 3 | -------------------------------------------------------------------------------- /servlet-async-processing/README.md: -------------------------------------------------------------------------------- 1 | # Servlet 3.0 Async Processing 2 | 3 | Servlet 3.0 开始提供了AsyncContext用来支持异步处理请求,那么异步处理请求到底能够带来哪些好处? 4 | 5 | Web容器一般来说处理请求的方式是:为每个request分配一个thread。我们都知道thread的创建不是没有代价的,Web容器的thread pool都是有上限的。 6 | 那么一个很容易预见的问题就是,在高负载情况下,thread pool都被占着了,那么后续的request就只能等待,如果运气不好客户端会报等待超时的错误。 7 | 在AsyncContext出现之前,解决这个问题的唯一办法就是扩充Web容器的thread pool。 8 | 9 | 但是这样依然有一个问题,考虑以下场景: 10 | 11 | 有一个web容器,线程池大小200。有一个web app,它有两个servlet,Servlet-A处理单个请求的时间是10s,Servlet-B处理单个请求的时间是1s。 12 | 现在遇到了高负载,有超过200个request到Servlet-A,如果这个时候请求Servlet-B就会等待,因为所有HTTP thread都已经被Servlet-A占用了。 13 | 这个时候工程师发现了问题,扩展了线程池大小到400,但是负载依然持续走高,现在有400个request到Servlet-A,Servlet-B依然无法响应。 14 | 15 | 看到问题了没有,因为**HTTP thread和Worker thread耦合在了一起(就是同一个thread)**,所以导致了当大量request到一个耗时操作时,就会将HTTP thread占满,导致整个Web容器就会无法响应。 16 | 17 | 但是如果使用AsyncContext,我们就可以将耗时的操作交给另一个thread去做,这样HTTP thread就被释放出来了,可以去处理其他请求了。 18 | 19 | > 注意,只有使用AsyncContext才能够达到上面所讲的效果,如果直接new Thread()或者类似的方式的,HTTP thread并不会归还到容器。 20 | 21 | 下面是一个官方的例子: 22 | 23 | ```java 24 | @WebServlet(urlPatterns={"/asyncservlet"}, asyncSupported=true) 25 | public class AsyncServlet extends HttpServlet { 26 | /* ... Same variables and init method as in SyncServlet ... */ 27 | 28 | @Override 29 | public void doGet(HttpServletRequest request, 30 | HttpServletResponse response) { 31 | response.setContentType("text/html;charset=UTF-8"); 32 | final AsyncContext acontext = request.startAsync(); 33 | acontext.start(new Runnable() { 34 | public void run() { 35 | String param = acontext.getRequest().getParameter("param"); 36 | String result = resource.process(param); 37 | HttpServletResponse response = acontext.getResponse(); 38 | /* ... print to the response ... */ 39 | acontext.complete(); 40 | } 41 | }); 42 | } 43 | } 44 | ``` 45 | 46 | ## 陷阱 47 | 48 | 在这个官方例子里,每个HTTP thread都会开启另一个Worker thread来处理请求,然后把HTTP thread就归还给Web容器。但是看`AsyncContext.start()`方法的javadoc: 49 | 50 | > Causes the container to dispatch a thread, possibly from a managed thread pool, to run the specified Runnable. 51 | 52 | 实际上这里并没有规定Worker thread到底从哪里来,也许是HTTP thread pool之外的另一个thread pool?还是说就是HTTP thread pool? 53 | 54 | [The Limited Usefulness of AsyncContext.start()][4]文章里写道:不同的Web容器对此有不同的实现,不过Tomcat实际上是利用HTTP thread pool来处理`AsyncContext.start()`的(见[AsyncStateMachine.java#L429][AsyncStateMachine.java_L429])。 55 | 56 | 这也就是说,我们原本是想释放HTTP thread的,但实际上并没有,因为有HTTP thread依然被用作Worker thread,只不过这个thread和接收请求的HTTP thread不是同一个而已。 57 | 58 | 这个结论我们也可以通过[AsyncServlet1][src-AsyncServlet1]和[SyncServlet][src-SyncServlet]的Jmeter benchmark看出来,两者的throughput结果差不多。启动方法:启动[Main][src-Main],然后利用Jmeter启动[benchmark.jmx][src-benchmark.jmx](Tomcat默认配置下HTTP thread pool=200)。 59 | 60 | ## 使用ExecutorService 61 | 62 | 前面看到了Tomcat并没有单独维护Worker thread pool,那么我们就得自己想办法搞一个,见[AsyncServlet2][src-AsyncServlet2],它使用了一个带Thread pool的ExecutorService来处理AsyncContext。 63 | 64 | ## 其他方式 65 | 66 | 所以对于AsyncContext的使用并没有固定的方式,你可以根据实际需要去采用不同的方式来处理,为此你需要一点Java concurrent programming的知识。 67 | 68 | ## 对于性能的误解 69 | 70 | AsyncContext的目的并不是为了**提高性能**,也并不直接提供性能提升,它提供了把HTTP thread和Worker thread解藕的机制,从而提高Web容器的**响应能力**。 71 | 72 | 不过AsyncContext在某些时候的确能够提高性能,但这个取决于你的代码是怎么写的。 73 | 比如:Web容器的HTTP thread pool数量200,某个Servlet使用一个300的Worker thread pool来处理AsyncContext。 74 | 相比Sync方式Worker thread pool=HTTP thread pool=200,在这种情况下我们有了300的Worker thread pool,所以肯定能够带来一些性能上的提升(毕竟干活的人多了)。 75 | 76 | 相反,如果当Worker thread的数量<=HTTP thread数量的时候,那么就不会得到性能提升,因为此时处理请求的瓶颈在Worker thread。 77 | 你可以修改[AsyncServlet2][src-AsyncServlet2]的线程池大小,把它和[SyncServlet][src-SyncServlet]比较benchmark结果来验证这一结论。 78 | 79 | **一定不要认为Worker thread pool必须比HTTP thread pool大**,理由如下: 80 | 81 | 1. 两者职责不同,一个是Web容器用来接收外来请求,一个是处理业务逻辑 82 | 1. thread的创建是有代价的,如果HTTP thread pool已经很大了再搞一个更大的Worker thread pool反而会造成过多的Context switch和内存开销 83 | 1. AsyncContext的目的是将HTTP thread释放出来,避免被操作长期占用进而导致Web容器无法响应 84 | 85 | 所以在更多时候,Worker thread pool不会很大,而且会根据不同业务构建不同的Worker thread pool。 86 | 比如:Web容器thread pool大小200,一个慢速Servlet的Worker thread pool大小10,这样一来,无论有多少请求到慢速操作,它都不会将HTTP thread占满导致其他请求无法处理。 87 | 88 | 89 | ## 相关资料 90 | 91 | * [Java EE 7 Tutorial: Java Servlet Technology - Asynchronous Processing](https://docs.oracle.com/javaee/7/tutorial/servlets012.htm) 92 | * [The Limited Usefulness of AsyncContext.start()][4] 93 | 94 | [4]: https://dzone.com/articles/limited-usefulness 95 | [src-Main]: src/main/java/me/chanjar/learning/Main.java 96 | [src-SyncServlet]: src/main/java/me/chanjar/learning/SyncServlet.java 97 | [src-AsyncServlet1]: src/main/java/me/chanjar/learning/AsyncServlet1.java 98 | [src-AsyncServlet2]: src/main/java/me/chanjar/learning/AsyncServlet2.java 99 | [src-benchmark.jmx]: benchmark.jmx 100 | [AsyncStateMachine.java_L429]: https://github.com/apache/tomcat85/blob/TOMCAT_8_5_23/java/org/apache/coyote/AsyncStateMachine.java#L429 101 | -------------------------------------------------------------------------------- /servlet-async-processing/benchmark.jmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | false 7 | true 8 | 9 | 10 | 11 | iteration 12 | 5 13 | = 14 | 15 | 16 | users 17 | 400 18 | = 19 | 20 | 21 | rampup 22 | 0 23 | = 24 | 25 | 26 | 27 | 28 | true 29 | 30 | 31 | 32 | 33 | 34 | 35 | localhost 36 | 8080 37 | 38 | 39 | 40 | 41 | 42 | HttpClient4 43 | 6 44 | 45 | 46 | 47 | continue 48 | 49 | false 50 | ${iteration} 51 | 52 | ${users} 53 | ${rampup} 54 | 1512530334000 55 | 1512530334000 56 | false 57 | 58 | 59 | true 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | /sync-servlet 73 | GET 74 | true 75 | false 76 | true 77 | false 78 | false 79 | 80 | 81 | 82 | 83 | 84 | continue 85 | 86 | false 87 | ${iteration} 88 | 89 | ${users} 90 | ${rampup} 91 | 1512530334000 92 | 1512530334000 93 | false 94 | 95 | 96 | true 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | /async-servlet-1 110 | GET 111 | true 112 | false 113 | true 114 | false 115 | false 116 | 117 | 118 | 119 | 120 | 121 | continue 122 | 123 | false 124 | ${iteration} 125 | 126 | ${users} 127 | ${rampup} 128 | 1512530334000 129 | 1512530334000 130 | false 131 | 132 | 133 | true 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | /async-servlet-2 147 | GET 148 | true 149 | false 150 | true 151 | false 152 | false 153 | 154 | 155 | 156 | 157 | 158 | false 159 | 160 | saveConfig 161 | 162 | 163 | true 164 | true 165 | true 166 | 167 | true 168 | true 169 | true 170 | true 171 | false 172 | true 173 | true 174 | false 175 | false 176 | false 177 | true 178 | false 179 | false 180 | false 181 | true 182 | 0 183 | true 184 | true 185 | true 186 | true 187 | true 188 | 189 | 190 | 191 | 192 | 193 | 194 | true 195 | 196 | saveConfig 197 | 198 | 199 | true 200 | true 201 | true 202 | 203 | true 204 | true 205 | true 206 | true 207 | false 208 | true 209 | true 210 | false 211 | false 212 | false 213 | true 214 | false 215 | false 216 | false 217 | true 218 | 0 219 | true 220 | true 221 | true 222 | true 223 | true 224 | 225 | 226 | 227 | 228 | 229 | 230 | false 231 | 232 | saveConfig 233 | 234 | 235 | true 236 | true 237 | true 238 | 239 | true 240 | true 241 | true 242 | true 243 | false 244 | true 245 | true 246 | false 247 | false 248 | false 249 | true 250 | false 251 | false 252 | false 253 | true 254 | 0 255 | true 256 | true 257 | true 258 | true 259 | true 260 | 261 | 262 | 263 | 500 264 | false 265 | 266 | 267 | 268 | 269 | false 270 | false 271 | true 272 | 273 | 274 | 275 | false 276 | 277 | saveConfig 278 | 279 | 280 | true 281 | true 282 | true 283 | 284 | true 285 | true 286 | true 287 | true 288 | false 289 | true 290 | true 291 | false 292 | false 293 | false 294 | true 295 | false 296 | false 297 | false 298 | true 299 | 0 300 | true 301 | true 302 | true 303 | true 304 | true 305 | 306 | 307 | 308 | 1000 309 | false 310 | 311 | 312 | 313 | 314 | false 315 | false 316 | true 317 | 318 | 319 | 320 | 321 | 322 | -------------------------------------------------------------------------------- /servlet-async-processing/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | me.chanjar.learning 7 | web-async-learn-aggregator 8 | 1.0-SNAPSHOT 9 | 10 | 11 | me.chanjar.learning 12 | servlet-async-processing 13 | war 14 | 15 | 16 | 17 | 18 | javax.servlet 19 | javax.servlet-api 20 | 21 | 22 | 23 | me.chanjar.learning 24 | tomcat-start 25 | ${project.version} 26 | 27 | 28 | 29 | junit 30 | junit 31 | 3.8.1 32 | test 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /servlet-async-processing/src/main/java/me/chanjar/learning/AsyncServlet1.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import javax.servlet.AsyncContext; 4 | import javax.servlet.ServletException; 5 | import javax.servlet.annotation.WebServlet; 6 | import javax.servlet.http.HttpServlet; 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | import java.io.IOException; 10 | 11 | @WebServlet(value = "/async-servlet-1", asyncSupported = true) 12 | public class AsyncServlet1 extends HttpServlet { 13 | 14 | @Override 15 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 16 | 17 | AsyncContext asyncCtx = req.startAsync(); 18 | asyncCtx.start(new SlowJobRunner(new SlowJob("async servlet1"), asyncCtx)); 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /servlet-async-processing/src/main/java/me/chanjar/learning/AsyncServlet2.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import javax.servlet.AsyncContext; 4 | import javax.servlet.ServletException; 5 | import javax.servlet.annotation.WebServlet; 6 | import javax.servlet.http.HttpServlet; 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | import java.io.IOException; 10 | import java.util.concurrent.ExecutorService; 11 | import java.util.concurrent.Executors; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | @WebServlet(value = "/async-servlet-2", asyncSupported = true) 15 | public class AsyncServlet2 extends HttpServlet { 16 | 17 | private volatile ExecutorService executorService; 18 | 19 | @Override 20 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 21 | 22 | AsyncContext asyncCtx = req.startAsync(); 23 | executorService.submit(new SlowJobRunner(new SlowJob("async servlet2"), asyncCtx)); 24 | 25 | } 26 | 27 | @Override 28 | public void init() throws ServletException { 29 | 30 | super.init(); 31 | executorService = Executors.newFixedThreadPool(400); 32 | } 33 | 34 | @Override 35 | public void destroy() { 36 | 37 | super.destroy(); 38 | executorService.shutdown(); 39 | boolean successfulTerminated = false; 40 | try { 41 | successfulTerminated = executorService.awaitTermination(5, TimeUnit.SECONDS); 42 | } catch (InterruptedException e) { 43 | e.printStackTrace(); 44 | } 45 | if (!successfulTerminated) { 46 | executorService.shutdownNow(); 47 | } 48 | executorService = null; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /servlet-async-processing/src/main/java/me/chanjar/learning/Main.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) throws Exception { 6 | 7 | TomcatStart.start(); 8 | 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /servlet-async-processing/src/main/java/me/chanjar/learning/SlowJob.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | public class SlowJob { 4 | 5 | private final String name; 6 | 7 | public SlowJob(String name) { 8 | this.name = name; 9 | } 10 | 11 | public String doWork() { 12 | try { 13 | Thread.sleep(1000L); 14 | return "Hi from " + name; 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | return null; 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /servlet-async-processing/src/main/java/me/chanjar/learning/SlowJobRunner.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import javax.servlet.AsyncContext; 4 | import java.io.IOException; 5 | import java.io.PrintWriter; 6 | 7 | public class SlowJobRunner implements Runnable { 8 | 9 | private final SlowJob job; 10 | 11 | private final AsyncContext asyncContext; 12 | 13 | public SlowJobRunner(SlowJob job, AsyncContext asyncContext) { 14 | this.job = job; 15 | this.asyncContext = asyncContext; 16 | } 17 | 18 | @Override 19 | public void run() { 20 | 21 | try { 22 | String result = job.doWork(); 23 | PrintWriter writer = asyncContext.getResponse().getWriter(); 24 | writer.println(result); 25 | writer.flush(); 26 | asyncContext.complete(); 27 | } catch (IOException e) { 28 | e.printStackTrace(); 29 | } 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /servlet-async-processing/src/main/java/me/chanjar/learning/SyncServlet.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.annotation.WebServlet; 5 | import javax.servlet.http.HttpServlet; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import java.io.IOException; 9 | import java.io.PrintWriter; 10 | 11 | @WebServlet("/sync-servlet") 12 | public class SyncServlet extends HttpServlet { 13 | 14 | @Override 15 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 16 | 17 | PrintWriter writer = resp.getWriter(); 18 | String result = new SlowJob("sync servlet").doWork(); 19 | writer.println(result); 20 | writer.flush(); 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /spring-mvc-async-io/README.md: -------------------------------------------------------------------------------- 1 | # Spring MVC Async IO 2 | 3 | 在[前一篇文章][ref-spring-mvc-async-proc]里介绍了Spring MVC对于Servlet 3.0 Async Processing的支持。 4 | 同时也提到了Spring MVC并没有提供对Servlet 3.1 Async IO的直接支持,本文介绍一些在Spring MVC中使用到Servlet 3.1 Async Processing的方法。 5 | 6 | 在开始讲解前要先了解Spring MVC是如何做Async Processing的,这里涉及到一个关键类`WebAsyncManager`。 7 | 8 | ## WebAsyncManager 9 | 10 | 在[前一篇文章][ref-spring-mvc-async-proc]里提到过以下几种`AsyncHandlerMethodReturnValueHandler`: 11 | 12 | 1. `CallableMethodReturnValueHandler` 13 | 1. `DeferredResultMethodReturnValueHandler` 14 | 1. `ResponseBodyEmitterReturnValueHandler` 15 | 1. `StreamingResponseBodyReturnValueHandler` 16 | 17 | 仔细看这些Handler的代码会发现最终都使用`WebAsyncManager`执行异步处理。 18 | 19 | `WebAsyncManager`执行的大致动作有这么几个: 20 | 21 | 1. 调用`ServletRequest.startAsync()` 22 | 1. 使用`AsyncTaskExecutor`开启另一个线程执行任务 23 | 1. 调用各种Interceptor的回调方法,比如`CallableProcessingInterceptor`和`DeferredResultProcessingInterceptor` 24 | 25 | 下面以`Callable`为例,详细讲解一下`WebAsyncManager`的执行过程(下面的T-*代表不同的线程): 26 | 27 | 1. T-http-1: `WebAsyncManager.startCallableProcessing` 28 | 1. T-http-1: `CallableInterceptorChain.applyBeforeConcurrentHandling` -> `CallableProcessingInterceptor.beforeConcurrentHandling` 29 | 1. T-http-1: `WebAsyncManager.startAsyncProcessing` -> `AsyncWebRequest.startAsync` -> `ServletRequest.startAsync` 30 | 1. T-http-1: `AsyncTaskExecutor.submit(Callable)` 31 | 1. T-mvc-async: `CallableInterceptorChain.applyPreProcess` -> `CallableProcessingInterceptor.preProcess` 32 | 1. T-mvc-async: `Callable.run`,等待执行完毕 33 | 1. T-mvc-async: `CallableInterceptorChain.applyPostProcess` -> `CallableProcessingInterceptor.postProcess` 34 | 1. T-mvc-async: `WebAsyncManager.setConcurrentResultAndDispatch` -> `AsyncWebRequest.dispatch` -> `ServletRequest.dispatch` 35 | 1. T-http-2: DispatchServlet ... 36 | 1. T-http-2: `AsyncWebRequest.onComplete` -> `CallableInterceptorChain.triggerAfterCompletion` -> `CallableProcessingInterceptor.afterCompletion` 37 | 38 | 上面的结果可以通过观察源代码、访问[http://localhost:8080/callable-trace][url-callable-trace]查看日志,下面是日志样例(注意观察`CallableProcessingLogger`): 39 | 40 | ``` 41 | 2017-12-25 16:58:09.632 DEBUG 19794 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/callable-trace] 42 | 2017-12-25 16:58:09.632 DEBUG 19794 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /callable-trace 43 | 2017-12-25 16:58:09.632 DEBUG 19794 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public java.util.concurrent.Callable me.chanjar.learning.CallableTraceController.hello()] 44 | 2017-12-25 16:58:09.632 DEBUG 19794 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/callable-trace] is: -1 45 | 2017-12-25 16:58:09.633 INFO 19794 --- [nio-8080-exec-1] orConfiguration$CallableProcessingLogger : beforeConcurrentHandling 46 | 2017-12-25 16:58:09.633 DEBUG 19794 --- [nio-8080-exec-1] o.s.w.c.request.async.WebAsyncManager : Concurrent handling starting for GET [/callable-trace] 47 | 2017-12-25 16:58:09.633 DEBUG 19794 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Leaving response open for concurrent processing 48 | 2017-12-25 16:58:09.633 INFO 19794 --- [ my-mvc-async-1] orConfiguration$CallableProcessingLogger : preProcess 49 | 2017-12-25 16:58:10.636 INFO 19794 --- [ my-mvc-async-1] orConfiguration$CallableProcessingLogger : postProcess 50 | 2017-12-25 16:58:10.636 DEBUG 19794 --- [ my-mvc-async-1] o.s.w.c.request.async.WebAsyncManager : Concurrent result value [Hi from CallableTraceController. Current Thread: my-mvc-async-2] - dispatching request to resume processing 51 | 2017-12-25 16:58:10.636 DEBUG 19794 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' resumed processing GET request for [/callable-trace] 52 | 2017-12-25 16:58:10.637 DEBUG 19794 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /callable-trace 53 | 2017-12-25 16:58:10.637 DEBUG 19794 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public java.util.concurrent.Callable me.chanjar.learning.CallableTraceController.hello()] 54 | 2017-12-25 16:58:10.637 DEBUG 19794 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/callable-trace] is: -1 55 | 2017-12-25 16:58:10.637 DEBUG 19794 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerAdapter : Found concurrent result value [Hi from CallableTraceController. Current Thread: my-mvc-async-2] 56 | 2017-12-25 16:58:10.638 DEBUG 19794 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Written [Hi from CallableTraceController. Current Thread: my-mvc-async-2] as "text/plain" using [org.springframework.http.converter.StringHttpMessageConverter@70444987] 57 | 2017-12-25 16:58:10.639 DEBUG 19794 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling 58 | 2017-12-25 16:58:10.639 DEBUG 19794 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Successfully completed request 59 | 2017-12-25 16:58:10.639 INFO 19794 --- [nio-8080-exec-2] orConfiguration$CallableProcessingLogger : afterCompletion 60 | ``` 61 | 62 | ## 将ReadListener加到MVC异步处理过程 63 | 64 | 先来回顾一下使用`ReadListener`的大致步骤: 65 | 66 | ```java 67 | 68 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 69 | 70 | AsyncContext asyncCtx = req.startAsync(); 71 | ServletInputStream is = req.getInputStream(); 72 | is.setReadListener(new ReadListener() { 73 | 74 | @Override 75 | public void onDataAvailable() { 76 | 77 | while (is.isReady() && !is.isFinished()) { 78 | int length = is.read(buffer); 79 | if (length == -1 && is.isFinished()) { 80 | asyncCtx.complete(); 81 | return; 82 | } 83 | // 处理buffer 84 | } 85 | 86 | } 87 | 88 | @Override 89 | public void onAllDataRead() { 90 | // ... 91 | } 92 | 93 | @Override 94 | public void onError(Throwable t) { 95 | // ... 96 | } 97 | }); 98 | 99 | } 100 | ``` 101 | 102 | 所以如果要使用`ReadListener`,那么能够切入的点有两个:第5步和第7步。 103 | 104 | 如果在第5步`CallableProcessingInterceptor.preProcess`里使用`ReadListener`则: 105 | 106 | * 在`ReadListener.onAllDataRead`或者`onError`之前,`Callable`必须阻塞。 107 | * `ReadListener`和`Callable`需要有通信机制。 108 | * `Callable`可以根据不同情况返回不同的结果。 109 | 110 | 如果在第7步`CallableProcessingInterceptor.postProcess`里使用`ReadListener`则: 111 | 112 | * `Callable`事实上变成事先返回结果,而不是等`ReadListener.onAllDataRead`或者`onError`。 113 | * `CallableProcessingInterceptor.postProcess`必须阻塞 114 | * `ReadListener`和`Callable`无法存在通信机制。 115 | 116 | 117 | `spring.http.multipart.resolve-lazily=true`,否则被Multipart***事先消费掉inputStream中的内容。 118 | 119 | curl -X POST -F "bigfile=@src/main/resources/bigfile" --limit-rate 10k http://localhost:8080/async-io-read-hook-pre-process 120 | 121 | 122 | Tomcat 8.5.24及之前存在[BUG 61932][tc-issue-61932],会导致出现。。。。。。TODO。。。。。。 123 | 124 | ## 将WriteListener加到MVC异步处理过程 125 | 126 | TODO 127 | 128 | ## 相关资料 129 | 130 | 131 | * [Is Servlet 3.1 (Read|Write)Listener supported by DeferredResult in Spring 4?][ref-6] 132 | * [Slides - Servlet 3.1 Async IO][ref-2] 133 | * [WebAsyncManager][ref-1] 134 | * [AsyncStateMachine][ref-3] 135 | 136 | [ref-1]: https://docs.spring.io/spring/docs/4.3.x/javadoc-api/org/springframework/web/context/request/async/WebAsyncManager.html 137 | [ref-2]: https://www.slideshare.net/SimoneBordet/servlet-31-async-io 138 | [ref-3]: https://tomcat.apache.org/tomcat-8.5-doc/api/org/apache/coyote/AsyncStateMachine.html 139 | [ref-6]: https://stackoverflow.com/questions/28828355/is-servlet-3-1-readwritelistener-supported-by-deferredresult-in-spring-4 140 | 141 | [url-callable-trace]: http://localhost:8080/callable-trace 142 | [ref-spring-mvc-async-proc]: ../servlet-async-processing/README.md 143 | [tc-issue-61932]: https://bz.apache.org/bugzilla/show_bug.cgi?id=61932 144 | -------------------------------------------------------------------------------- /spring-mvc-async-io/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 1.5.9.RELEASE 9 | 10 | 11 | me.chanjar.learning 12 | spring-mvc-async-io 13 | war 14 | 15 | 16 | 1.8 17 | 1.8 18 | 1.8 19 | 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-thymeleaf 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-devtools 30 | true 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-maven-plugin 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /spring-mvc-async-io/src/main/java/me/chanjar/learning/Application.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 6 | 7 | @SpringBootApplication 8 | @EnableWebMvc 9 | public class Application { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(Application.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /spring-mvc-async-io/src/main/java/me/chanjar/learning/AsyncReadController.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | import org.springframework.web.context.request.NativeWebRequest; 8 | import org.springframework.web.context.request.async.CallableProcessingInterceptorAdapter; 9 | import org.springframework.web.context.request.async.WebAsyncManager; 10 | import org.springframework.web.context.request.async.WebAsyncUtils; 11 | 12 | import javax.servlet.AsyncContext; 13 | import javax.servlet.ReadListener; 14 | import javax.servlet.ServletInputStream; 15 | import javax.servlet.ServletRequest; 16 | import javax.servlet.http.HttpServletRequest; 17 | import java.io.IOException; 18 | import java.util.concurrent.Callable; 19 | 20 | @RestController 21 | public class AsyncReadController { 22 | 23 | private static final Logger LOGGER = LoggerFactory.getLogger(AsyncReadController.class); 24 | 25 | @RequestMapping("async-io-read-hook-pre-process") 26 | public Callable hookPreProcess(ServletRequest request) throws Exception { 27 | 28 | InnerCallable callable = new InnerCallable(); 29 | 30 | WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); 31 | asyncManager.registerCallableInterceptor("some-key", new InnerCallableProcessingInterceptor(callable)); 32 | return callable; 33 | } 34 | 35 | private static class InnerCallable implements Callable { 36 | 37 | private String result; 38 | 39 | private Exception exception; 40 | 41 | @Override 42 | public String call() throws Exception { 43 | synchronized (this) { 44 | this.wait(); 45 | } 46 | if (exception != null) { 47 | throw exception; 48 | } 49 | return result; 50 | } 51 | 52 | public synchronized void onSuccess(String result) { 53 | this.result = result; 54 | this.notify(); 55 | } 56 | 57 | public synchronized void onError(Throwable e) { 58 | if (e instanceof Exception) { 59 | this.exception = (Exception) e; 60 | } else { 61 | this.exception = new RuntimeException(e); 62 | } 63 | this.notify(); 64 | } 65 | } 66 | 67 | private static class InnerCallableProcessingInterceptor extends CallableProcessingInterceptorAdapter { 68 | 69 | private final InnerCallable callable; 70 | 71 | public InnerCallableProcessingInterceptor(InnerCallable callable) { 72 | this.callable = callable; 73 | } 74 | 75 | @Override 76 | public void preProcess(NativeWebRequest request, Callable task) throws Exception { 77 | 78 | HttpServletRequest nativeRequest = (HttpServletRequest) request.getNativeRequest(); 79 | AsyncContext asyncContext = nativeRequest.getAsyncContext(); 80 | ServletInputStream is = nativeRequest.getInputStream(); 81 | is.setReadListener(new ReadListener() { 82 | private int totalReadBytes = 0; 83 | 84 | @Override 85 | public void onDataAvailable() throws IOException { 86 | LOGGER.info("ReadListener onDataAvailable"); 87 | 88 | try { 89 | byte buffer[] = new byte[1 * 1024]; 90 | int readBytes = 0; 91 | while (is.isReady() && !is.isFinished()) { 92 | int length = is.read(buffer); 93 | if (length == -1 && is.isFinished()) { 94 | LOGGER.info("Read: " + readBytes + " bytes"); 95 | LOGGER.info("Total Read: " + totalReadBytes + " bytes"); 96 | return; 97 | } 98 | readBytes += length; 99 | totalReadBytes += length; 100 | 101 | } 102 | LOGGER.info("Read: " + readBytes + " bytes"); 103 | 104 | } catch (IOException ex) { 105 | throw new RuntimeException(ex); 106 | } 107 | } 108 | 109 | @Override 110 | public void onAllDataRead() throws IOException { 111 | LOGGER.info("ReadListener onAllDataRead"); 112 | is.close(); 113 | String msg = "ReadListener thread: " + Thread.currentThread().getName() + " succeeded"; 114 | callable.onSuccess(msg); 115 | } 116 | 117 | @Override 118 | public void onError(Throwable throwable) { 119 | LOGGER.error("ReadListener onError"); 120 | callable.onError(throwable); 121 | } 122 | }); 123 | } 124 | 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /spring-mvc-async-io/src/main/java/me/chanjar/learning/AsyncWriteController.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | public class AsyncWriteController { 4 | } 5 | -------------------------------------------------------------------------------- /spring-mvc-async-io/src/main/java/me/chanjar/learning/CallableTraceController.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import me.chanjar.learning.slowjob.SlowJob; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.util.concurrent.Callable; 8 | 9 | @RestController 10 | public class CallableTraceController { 11 | 12 | @RequestMapping("callable-trace") 13 | public Callable hello() { 14 | return () -> new SlowJob("CallableTraceController").doWork(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /spring-mvc-async-io/src/main/java/me/chanjar/learning/config/AsyncInterceptorConfiguration.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning.config; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 7 | import org.springframework.web.context.request.NativeWebRequest; 8 | import org.springframework.web.context.request.async.CallableProcessingInterceptor; 9 | import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer; 10 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 11 | 12 | import java.util.concurrent.Callable; 13 | 14 | @Configuration 15 | public class AsyncInterceptorConfiguration extends WebMvcConfigurerAdapter { 16 | 17 | @Override 18 | public void configureAsyncSupport(AsyncSupportConfigurer configurer) { 19 | 20 | configurer.setDefaultTimeout(30000L); 21 | ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); 22 | taskExecutor.setThreadNamePrefix("my-mvc-async-"); 23 | taskExecutor.setCorePoolSize(400); 24 | taskExecutor.setMaxPoolSize(400); 25 | taskExecutor.setQueueCapacity(400); 26 | taskExecutor.initialize(); 27 | configurer.setTaskExecutor(taskExecutor); 28 | 29 | configurer.registerCallableInterceptors(new CallableProcessingLogger()); 30 | } 31 | 32 | private static class CallableProcessingLogger implements CallableProcessingInterceptor { 33 | 34 | private static final Logger LOGGER = LoggerFactory.getLogger(CallableProcessingLogger.class); 35 | 36 | @Override 37 | public void beforeConcurrentHandling(NativeWebRequest request, Callable task) throws Exception { 38 | LOGGER.info("beforeConcurrentHandling"); 39 | } 40 | 41 | @Override 42 | public void preProcess(NativeWebRequest request, Callable task) throws Exception { 43 | LOGGER.info("preProcess"); 44 | 45 | } 46 | 47 | @Override 48 | public void postProcess(NativeWebRequest request, Callable task, Object concurrentResult) throws Exception { 49 | LOGGER.info("postProcess"); 50 | } 51 | 52 | @Override 53 | public Object handleTimeout(NativeWebRequest request, Callable task) throws Exception { 54 | LOGGER.info("handleTimeout"); 55 | return null; 56 | } 57 | 58 | @Override 59 | public void afterCompletion(NativeWebRequest request, Callable task) throws Exception { 60 | LOGGER.info("afterCompletion"); 61 | 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /spring-mvc-async-io/src/main/java/me/chanjar/learning/slowjob/SlowJob.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning.slowjob; 2 | 3 | public class SlowJob { 4 | 5 | private final String name; 6 | 7 | public SlowJob(String name) { 8 | this.name = name; 9 | } 10 | 11 | public String doWork() { 12 | try { 13 | Thread.sleep(1000L); 14 | 15 | return "Hi from " + name + ". Current Thread: " + Thread.currentThread().getName() + "\n"; 16 | } catch (InterruptedException e) { 17 | e.printStackTrace(); 18 | } 19 | return null; 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /spring-mvc-async-io/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework.web=DEBUG 2 | spring.http.multipart.resolve-lazily=true 3 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/README.md: -------------------------------------------------------------------------------- 1 | # Spring MVC Async Processing 2 | 3 | 本文讲到的所有特性皆是基于Servlet 3.0 Async Processing的,不是基于Servlet 3.1 Async IO的。 4 | 5 | ## Callable 6 | 7 | > A ``Callable`` can be returned when the application wants to produce the return value asynchronously in a thread managed by Spring MVC. 8 | 9 | 用于异步返回结果,使用的是Spring MVC的``AsyncTaskExecutor``,Spring MVC使用``CallableMethodReturnValueHandler``负责处理它。 10 | 11 | 下面是例子[CallableController][src-CallableController]: 12 | 13 | ```java 14 | @RestController 15 | public class CallableController { 16 | 17 | @RequestMapping("callable-hello") 18 | public Callable hello() { 19 | return () -> new SlowJob("CallableController").doWork(); 20 | } 21 | } 22 | ``` 23 | 24 | 用浏览器访问:[http://localhost:8080/callable-hello][callable-hello] 查看返回结果。 25 | 26 | ## DeferredResult 27 | 28 | > A ``DeferredResult`` can be returned when the application wants to produce the return value from a thread of its own choosing. 29 | 30 | 用于异步返回结果,使用的是client code自己的thread,Spring MVC使用``DeferredResultMethodReturnValueHandler``负责处理它。 31 | 32 | 下面是例子[DeferredResultController][src-DeferredResultController]: 33 | 34 | ```java 35 | @RestController 36 | public class DeferredResultController { 37 | 38 | @Autowired 39 | @Qualifier("customExecutorService") 40 | private ExecutorService executorService; 41 | 42 | @RequestMapping("deferred-result-hello") 43 | public DeferredResult hello() { 44 | DeferredResult deferredResult = new DeferredResult<>(); 45 | executorService.submit(() -> { 46 | try { 47 | deferredResult.setResult(new SlowJob("DeferredResultController").doWork()); 48 | } catch (Exception e) { 49 | deferredResult.setErrorResult(e); 50 | } 51 | 52 | }); 53 | return deferredResult; 54 | } 55 | 56 | } 57 | ``` 58 | 59 | 在这个例子里使用了ExecutorService(见[ExecutorServiceConfiguration][src-ExecutorServiceConfiguration]),你也可以根据实际情况采用别的机制来给``DeferredResult.setResult``。 60 | 61 | 用浏览器访问:[http://localhost:8080/deferred-result-hello][deferred-result-hello] 查看返回结果。 62 | 63 | ## ListenableFuture or CompletableFuture/CompletionStage 64 | 65 | > A ``ListenableFuture`` or ``CompletableFuture``/``CompletionStage`` can be returned when the application wants to produce the value from a thread pool submission. 66 | 67 | 用于异步返回结果,使用client code自己的thread pool,Spring MVC使用``DeferredResultMethodReturnValueHandler``负责处理它。 68 | 69 | 下面是例子[ListenableFutureController][src-ListenableFutureController]: 70 | 71 | ```java 72 | @RestController 73 | public class ListenableFutureController { 74 | 75 | @Autowired 76 | @Qualifier("customExecutorService") 77 | private ExecutorService executorService; 78 | 79 | @RequestMapping("listenable-future-hello") 80 | public ListenableFutureTask hello() { 81 | 82 | ListenableFutureTask listenableFutureTask = new ListenableFutureTask<>( 83 | () -> new SlowJob("ListenableFutureController").doWork()); 84 | executorService.submit(listenableFutureTask); 85 | return listenableFutureTask; 86 | } 87 | 88 | } 89 | ``` 90 | 91 | 用浏览器访问:[http://localhost:8080/listenable-future-hello][listenable-future-hello] 查看返回结果。 92 | 93 | 下面是例子[CompletionFutureController][src-CompletionFutureController] 94 | 95 | ```java 96 | @RestController 97 | public class CompletionFutureController { 98 | 99 | @RequestMapping("completable-future-hello") 100 | public CompletableFuture hello() { 101 | 102 | return CompletableFuture 103 | .supplyAsync(() -> new SlowJob("CompletionFutureController").doWork()); 104 | } 105 | 106 | } 107 | ``` 108 | 109 | 用浏览器访问:[http://localhost:8080/completable-future-hello][completable-future-hello] 查看返回结果。 110 | 111 | ## ResponseBodyEmitter 112 | 113 | > A [ResponseBodyEmitter][ref-7] can be returned to write multiple objects to the response asynchronously; also supported as the body within a ``ResponseEntity``. 114 | 115 | 用于异步的写入多个消息,使用的是client code自己的thread,Spring MVC使用``ResponseBodyEmitterReturnValueHandler``负责处理它。 116 | 117 | 下面是例子[ResponseBodyEmitterController][src-ResponseBodyEmitterController] 118 | 119 | ```java 120 | @RestController 121 | public class ResponseBodyEmitterController { 122 | 123 | @Autowired 124 | @Qualifier("customExecutorService") 125 | private ExecutorService executorService; 126 | 127 | @RequestMapping("response-body-emitter-hello") 128 | public ResponseBodyEmitter hello() { 129 | 130 | ResponseBodyEmitter emitter = new ResponseBodyEmitter(); 131 | executorService.submit(() -> { 132 | try { 133 | for (int i = 0; i < 5; i++) { 134 | 135 | String hello = new SlowJob("ResponseBodyEmitterController").doWork(); 136 | emitter.send("Count: " + (i + 1)); 137 | emitter.send("\n"); 138 | emitter.send(hello); 139 | emitter.send("\n\n"); 140 | } 141 | emitter.complete(); 142 | } catch (Exception e) { 143 | emitter.completeWithError(e); 144 | } 145 | 146 | }); 147 | 148 | return emitter; 149 | } 150 | } 151 | ``` 152 | 153 | 用浏览器访问:[http://localhost:8080/response-body-emitter-hello][response-body-emitter-hello] 查看返回结果。 154 | 155 | ## SseEmitter 156 | 157 | > An [SseEmitter][ref-8] can be returned to write Server-Sent Events to the response asynchronously; also supported as the body within a ``ResponseEntity``. 158 | 159 | 作用和`ResponseBodyEmitter`类似,也是异步的写入多个消息,使用的是client code自己的thread,区别在于它使用的是[Server-Sent Events][w3-1]。Spring MVC使用``ResponseBodyEmitterReturnValueHandler``负责处理它。 160 | 161 | 下面是例子[SseEmitterController][src-SseEmitterController] 162 | 163 | ```java 164 | @RestController 165 | public class SseEmitterController { 166 | 167 | @Autowired 168 | @Qualifier("customExecutorService") 169 | private ExecutorService executorService; 170 | 171 | @RequestMapping("sse-emitter-hello") 172 | public ResponseBodyEmitter hello() { 173 | 174 | SseEmitter emitter = new SseEmitter(); 175 | executorService.submit(() -> { 176 | try { 177 | for (int i = 0; i < 5; i++) { 178 | 179 | String hello = new SlowJob("SseEmitterController").doWork(); 180 | StringBuilder sb = new StringBuilder(); 181 | sb.append("Count: " + (i + 1)).append(". ").append(hello.replace("\n", "")); 182 | emitter.send(sb.toString()); 183 | } 184 | emitter.complete(); 185 | } catch (Exception e) { 186 | emitter.completeWithError(e); 187 | } 188 | 189 | }); 190 | 191 | return emitter; 192 | } 193 | } 194 | ``` 195 | 196 | 用浏览器访问:[http://localhost:8080/sse-emitter-hello][sse-emitter-hello] 查看返回结果。 197 | 198 | ## StreamingResponseBody 199 | 200 | > A [StreamingResponseBody][ref-9] can be returned to write to the response OutputStream asynchronously; also supported as the body within a ``ResponseEntity``. 201 | 202 | 用于异步write outputStream,使用的是Spring MVC的``AsyncTaskExecutor``,Spring MVC使用``StreamingResponseBodyReturnValueHandler``负责处理它。要注意,Spring MVC并没有使用Servlet 3.1 Async IO(\[Read|Write\]Listener)。 203 | 204 | 下面是例子[StreamingResponseBodyController][src-StreamingResponseBodyController] 205 | 206 | ```java 207 | @RestController 208 | public class StreamingResponseBodyController { 209 | 210 | @RequestMapping("streaming-response-body-hello") 211 | public StreamingResponseBody hello() { 212 | 213 | return outputStream -> { 214 | String hello = new SlowJob("CallableController").doWork(); 215 | outputStream.write(hello.getBytes()); 216 | outputStream.flush(); 217 | }; 218 | 219 | } 220 | } 221 | ``` 222 | 223 | 用浏览器访问:[http://localhost:8080/streaming-response-body-hello][streaming-response-body-hello] 查看返回结果。 224 | 225 | 226 | ## 配置MVC Async 227 | 228 | ### AsyncTaskExecutor 229 | 230 | Spring MVC执行异步操作需要用到``AsyncTaskExecutor``,这个可以在用``WebMvcConfigurer.configureAsyncSupport``方法来提供([相关文档][ref-5])。 231 | 如果不提供,则使用``SimpleAsyncTaskExecutor``,``SimpleAsyncTaskExecutor``不使用thread pool,因此推荐提供自定义的``AsyncTaskExecutor``。 232 | 233 | 需要注意的是``@EnableAsync``也需要用到``AsyncTaskExecutor``,不过Spring MVC和它用的不是同一个。 234 | 顺带一提,``EnableAsync``默认也使用``SimpleAsyncTaskExecutor``,可以使用``AsyncConfigurer.getAsyncExecutor``方法来提供一个自定义的``AsyncTaskExecutor``。 235 | 236 | 例子见:[MvcAsyncTaskExecutorConfigurer][src-MvcAsyncTaskExecutorConfigurer]。 237 | 238 | ### Interceptors 239 | 240 | * ``AsyncHandlerInterceptor``,使用``WebMvcConfigurer.addInterceptors``注册 241 | * ``CallableProcessingInterceptor[Adapter]``,使用``WebMvcConfigurer.configureAsyncSupport``注册 242 | * ``DeferredResultProcessingInterceptor[Adapter]``,使用``WebMvcConfigurer.configureAsyncSupport``注册 243 | 244 | 官方文档:[Intercepting Async Requests][ref-6] 245 | 246 | ## WebAsyncManager 247 | 248 | ``WebAsyncManager``是Spring MVC管理async processing的中心类,如果你可以阅读它的源码来更多了解Spring MVC对于async processing的底层机制。 249 | 250 | ## 参考资料 251 | 252 | * [Spring Web MVC Doc - Supported method return values][ref-1] 253 | * [Spring Web MVC Doc - Asynchronous Request Processing][ref-2] 254 | * [Spring Web MVC Doc - Configuring Asynchronous Request Processing][ref-3] 255 | * [Configuring Spring MVC Async Threads][ref-4] 256 | 257 | * [Spring MVC 3.2 Preview: Introducing Servlet 3, Async Support][blog-1] 258 | * [Spring MVC 3.2 Preview: Techniques for Real-time Updates][blog-2] 259 | * [Spring MVC 3.2 Preview: Making a Controller Method Asynchronous][blog-3] 260 | * [Spring MVC 3.2 Preview: Adding Long Polling to an Existing Web Application][blog-4] 261 | * [Spring MVC 3.2 Preview: Chat Sample][blog-5] 262 | 263 | [ref-1]: https://docs.spring.io/spring/docs/4.3.9.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-return-types 264 | [ref-2]: https://docs.spring.io/spring/docs/4.3.9.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-async 265 | [ref-3]: https://docs.spring.io/spring/docs/4.3.9.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-async-configuration 266 | [ref-4]: http://www.clianz.com/2016/02/24/configuring-spring-mvc-async-threads/ 267 | [ref-5]: https://docs.spring.io/spring/docs/4.3.9.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-async-configuration-spring-mvc 268 | [ref-6]: https://docs.spring.io/spring/docs/4.3.9.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-async-interception 269 | [ref-7]: https://docs.spring.io/spring/docs/4.3.9.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-async-http-streaming 270 | [ref-8]: https://docs.spring.io/spring/docs/4.3.9.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-async-sse 271 | [ref-9]: https://docs.spring.io/spring/docs/4.3.9.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-async-output-stream 272 | [w3-1]: https://www.w3.org/TR/eventsource/ 273 | [blog-1]: https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support 274 | [blog-2]: https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates/ 275 | [blog-3]: https://spring.io/blog/2012/05/10/spring-mvc-3-2-preview-making-a-controller-method-asynchronous/ 276 | [blog-4]: https://spring.io/blog/2012/05/14/spring-mvc-3-2-preview-adding-long-polling-to-an-existing-web-application 277 | [blog-5]: https://spring.io/blog/2012/05/16/spring-mvc-3-2-preview-chat-sample/ 278 | [src-MvcAsyncTaskExecutorConfigurer]: src/main/java/me/chanjar/learning/config/MvcAsyncTaskExecutorConfigurer.java 279 | [src-ExecutorServiceConfiguration]: src/main/java/me/chanjar/learning/config/ExecutorServiceConfiguration.java 280 | [src-CallableController]: src/main/java/me/chanjar/learning/CallableController.java 281 | [src-DeferredResultController]: src/main/java/me/chanjar/learning/DeferredResultController.java 282 | [src-ListenableFutureController]: src/main/java/me/chanjar/learning/ListenableFutureController.java 283 | [src-CompletionFutureController]: src/main/java/me/chanjar/learning/CompletionFutureController.java 284 | [src-ResponseBodyEmitterController]: src/main/java/me/chanjar/learning/ResponseBodyEmitterController.java 285 | [src-SseEmitterController]: src/main/java/me/chanjar/learning/SseEmitterController.java 286 | [src-StreamingResponseBodyController]: src/main/java/me/chanjar/learning/StreamingResponseBodyController.java 287 | [callable-hello]: http://localhost:8080/callable-hello 288 | [completable-future-hello]: http://localhost:8080/completable-future-hello 289 | [deferred-result-hello]: http://localhost:8080/deferred-result-hello 290 | [listenable-future-hello]: http://localhost:8080/listenable-future-hello 291 | [sse-emitter-hello]: http://localhost:8080/sse-emitter-hello 292 | [response-body-emitter-hello]: http://localhost:8080/response-body-emitter-hello 293 | [streaming-response-body-hello]: http://localhost:8080/streaming-response-body-hello 294 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 1.5.9.RELEASE 9 | 10 | 11 | me.chanjar.learning 12 | spring-mvc-async-processing 13 | war 14 | 15 | 16 | 1.8 17 | 1.8 18 | 1.8 19 | 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-thymeleaf 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-devtools 30 | true 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-maven-plugin 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/src/main/java/me/chanjar/learning/Application.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 6 | 7 | @SpringBootApplication 8 | @EnableWebMvc 9 | public class Application { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(Application.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/src/main/java/me/chanjar/learning/CallableController.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import me.chanjar.learning.slowjob.SlowJob; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.util.concurrent.Callable; 8 | 9 | @RestController 10 | public class CallableController { 11 | 12 | @RequestMapping("callable-hello") 13 | public Callable hello() { 14 | return () -> new SlowJob("CallableController").doWork(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/src/main/java/me/chanjar/learning/CompletionFutureController.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import me.chanjar.learning.slowjob.SlowJob; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.util.concurrent.CompletableFuture; 8 | 9 | @RestController 10 | public class CompletionFutureController { 11 | 12 | @RequestMapping("completable-future-hello") 13 | public CompletableFuture hello() { 14 | 15 | return CompletableFuture 16 | .supplyAsync(() -> new SlowJob("CompletionFutureController").doWork()); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/src/main/java/me/chanjar/learning/DeferredResultController.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import me.chanjar.learning.slowjob.SlowJob; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.beans.factory.annotation.Qualifier; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import org.springframework.web.context.request.async.DeferredResult; 9 | 10 | import java.util.concurrent.ExecutorService; 11 | 12 | @RestController 13 | public class DeferredResultController { 14 | 15 | @Autowired 16 | @Qualifier("customExecutorService") 17 | private ExecutorService executorService; 18 | 19 | @RequestMapping("deferred-result-hello") 20 | public DeferredResult hello() { 21 | DeferredResult deferredResult = new DeferredResult<>(); 22 | executorService.submit(() -> { 23 | try { 24 | deferredResult.setResult(new SlowJob("DeferredResultController").doWork()); 25 | } catch (Exception e) { 26 | deferredResult.setErrorResult(e); 27 | } 28 | 29 | }); 30 | return deferredResult; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/src/main/java/me/chanjar/learning/ListenableFutureController.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import me.chanjar.learning.slowjob.SlowJob; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.beans.factory.annotation.Qualifier; 6 | import org.springframework.util.concurrent.ListenableFutureTask; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import java.util.concurrent.ExecutorService; 11 | 12 | @RestController 13 | public class ListenableFutureController { 14 | 15 | @Autowired 16 | @Qualifier("customExecutorService") 17 | private ExecutorService executorService; 18 | 19 | @RequestMapping("listenable-future-hello") 20 | public ListenableFutureTask hello() { 21 | 22 | ListenableFutureTask listenableFutureTask = new ListenableFutureTask<>( 23 | () -> new SlowJob("ListenableFutureController").doWork()); 24 | executorService.submit(listenableFutureTask); 25 | return listenableFutureTask; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/src/main/java/me/chanjar/learning/ResponseBodyEmitterController.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import me.chanjar.learning.slowjob.SlowJob; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.beans.factory.annotation.Qualifier; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter; 9 | 10 | import java.util.concurrent.ExecutorService; 11 | 12 | @RestController 13 | public class ResponseBodyEmitterController { 14 | 15 | @Autowired 16 | @Qualifier("customExecutorService") 17 | private ExecutorService executorService; 18 | 19 | @RequestMapping("response-body-emitter-hello") 20 | public ResponseBodyEmitter hello() { 21 | 22 | ResponseBodyEmitter emitter = new ResponseBodyEmitter(); 23 | executorService.submit(() -> { 24 | try { 25 | for (int i = 0; i < 5; i++) { 26 | 27 | String hello = new SlowJob("ResponseBodyEmitterController").doWork(); 28 | emitter.send("Count: " + (i + 1)); 29 | emitter.send("\n"); 30 | emitter.send(hello); 31 | emitter.send("\n\n"); 32 | } 33 | emitter.complete(); 34 | } catch (Exception e) { 35 | emitter.completeWithError(e); 36 | } 37 | 38 | }); 39 | 40 | return emitter; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/src/main/java/me/chanjar/learning/SseEmitterController.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import me.chanjar.learning.slowjob.SlowJob; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.beans.factory.annotation.Qualifier; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter; 9 | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; 10 | 11 | import java.util.concurrent.ExecutorService; 12 | 13 | @RestController 14 | public class SseEmitterController { 15 | 16 | @Autowired 17 | @Qualifier("customExecutorService") 18 | private ExecutorService executorService; 19 | 20 | @RequestMapping("sse-emitter-hello") 21 | public ResponseBodyEmitter hello() { 22 | 23 | SseEmitter emitter = new SseEmitter(); 24 | executorService.submit(() -> { 25 | try { 26 | for (int i = 0; i < 5; i++) { 27 | 28 | String hello = new SlowJob("SseEmitterController").doWork(); 29 | StringBuilder sb = new StringBuilder(); 30 | sb.append("Count: " + (i + 1)).append(". ").append(hello.replace("\n", "")); 31 | emitter.send(sb.toString()); 32 | } 33 | emitter.complete(); 34 | } catch (Exception e) { 35 | emitter.completeWithError(e); 36 | } 37 | 38 | }); 39 | 40 | return emitter; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/src/main/java/me/chanjar/learning/StreamingResponseBodyController.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import me.chanjar.learning.slowjob.SlowJob; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; 7 | 8 | import java.io.IOException; 9 | import java.io.OutputStream; 10 | 11 | @RestController 12 | public class StreamingResponseBodyController { 13 | 14 | @RequestMapping("streaming-response-body-hello") 15 | public StreamingResponseBody hello() { 16 | 17 | return outputStream -> { 18 | String hello = new SlowJob("CallableController").doWork(); 19 | outputStream.write(hello.getBytes()); 20 | outputStream.flush(); 21 | }; 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/src/main/java/me/chanjar/learning/config/ExecutorServiceConfiguration.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning.config; 2 | 3 | import org.springframework.context.Lifecycle; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | import java.util.concurrent.ExecutorService; 8 | import java.util.concurrent.Executors; 9 | import java.util.concurrent.ThreadFactory; 10 | import java.util.concurrent.TimeUnit; 11 | import java.util.concurrent.atomic.AtomicInteger; 12 | 13 | @Configuration 14 | public class ExecutorServiceConfiguration { 15 | 16 | @Bean 17 | public ExecutorService customExecutorService() { 18 | return Executors.newFixedThreadPool(400, new ThreadFactory() { 19 | private final AtomicInteger threadNumber = new AtomicInteger(1); 20 | 21 | @Override 22 | public Thread newThread(Runnable r) { 23 | return new Thread(r, "my-executor-service-" + threadNumber.getAndIncrement()); 24 | } 25 | }); 26 | 27 | } 28 | 29 | @Bean 30 | public Lifecycle customExecutorServiceLifeCycle() { 31 | 32 | final ExecutorService executorService = customExecutorService(); 33 | return new Lifecycle() { 34 | 35 | @Override 36 | public void start() { 37 | 38 | } 39 | 40 | @Override 41 | public void stop() { 42 | 43 | executorService.shutdown(); 44 | boolean successfulTerminated = false; 45 | try { 46 | successfulTerminated = executorService.awaitTermination(5, TimeUnit.SECONDS); 47 | } catch (InterruptedException e) { 48 | e.printStackTrace(); 49 | } 50 | if (!successfulTerminated) { 51 | executorService.shutdownNow(); 52 | } 53 | 54 | } 55 | 56 | @Override 57 | public boolean isRunning() { 58 | return !executorService.isTerminated(); 59 | } 60 | 61 | }; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/src/main/java/me/chanjar/learning/config/MvcAsyncTaskExecutorConfigurer.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 5 | import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer; 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 7 | 8 | @Configuration 9 | public class MvcAsyncTaskExecutorConfigurer extends WebMvcConfigurerAdapter { 10 | 11 | @Override 12 | public void configureAsyncSupport(AsyncSupportConfigurer configurer) { 13 | 14 | configurer.setDefaultTimeout(30000L); 15 | ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); 16 | taskExecutor.setThreadNamePrefix("my-mvc-async-"); 17 | taskExecutor.setCorePoolSize(400); 18 | taskExecutor.setMaxPoolSize(400); 19 | taskExecutor.setQueueCapacity(400); 20 | taskExecutor.initialize(); 21 | configurer.setTaskExecutor(taskExecutor); 22 | 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /spring-mvc-async-processing/src/main/java/me/chanjar/learning/slowjob/SlowJob.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning.slowjob; 2 | 3 | public class SlowJob { 4 | 5 | private final String name; 6 | 7 | public SlowJob(String name) { 8 | this.name = name; 9 | } 10 | 11 | public String doWork() { 12 | try { 13 | Thread.sleep(1000L); 14 | 15 | return "Hi from " + name + ". Current Thread: " + Thread.currentThread().getName() + "\n"; 16 | } catch (InterruptedException e) { 17 | e.printStackTrace(); 18 | } 19 | return null; 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /tomcat-start/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | me.chanjar.learning 7 | web-async-learn-aggregator 8 | 1.0-SNAPSHOT 9 | 10 | 11 | me.chanjar.learning 12 | tomcat-start 13 | jar 14 | 15 | 16 | 8.5.23 17 | 8.5.2 18 | 19 | 20 | 21 | 22 | 23 | 24 | org.apache.tomcat.embed 25 | tomcat-embed-core 26 | ${tomcat.version} 27 | 28 | 29 | org.apache.tomcat.embed 30 | tomcat-embed-logging-juli 31 | ${tomcat-juli.version} 32 | 33 | 34 | org.apache.tomcat.embed 35 | tomcat-embed-jasper 36 | ${tomcat.version} 37 | 38 | 39 | org.apache.tomcat 40 | tomcat-jasper 41 | ${tomcat.version} 42 | 43 | 44 | org.apache.tomcat 45 | tomcat-jasper-el 46 | ${tomcat.version} 47 | 48 | 49 | org.apache.tomcat 50 | tomcat-jsp-api 51 | ${tomcat.version} 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /tomcat-start/src/main/java/me/chanjar/learning/TomcatStart.java: -------------------------------------------------------------------------------- 1 | package me.chanjar.learning; 2 | 3 | import org.apache.catalina.WebResourceRoot; 4 | import org.apache.catalina.core.StandardContext; 5 | import org.apache.catalina.startup.Tomcat; 6 | import org.apache.catalina.webresources.DirResourceSet; 7 | import org.apache.catalina.webresources.StandardRoot; 8 | 9 | import java.io.File; 10 | 11 | /** 12 | * https://devcenter.heroku.com/articles/create-a-java-web-application-using-embedded-tomcat 13 | */ 14 | public class TomcatStart { 15 | 16 | public static void start() throws Exception { 17 | 18 | String webappDirLocation = "src/main/webapp/"; 19 | Tomcat tomcat = new Tomcat(); 20 | 21 | //The port that we should run on can be set into an environment variable 22 | //Look for that variable and default to 8080 if it isn't there. 23 | String webPort = System.getenv("PORT"); 24 | if (webPort == null || webPort.isEmpty()) { 25 | webPort = "8080"; 26 | } 27 | 28 | tomcat.setPort(Integer.valueOf(webPort)); 29 | 30 | StandardContext ctx = (StandardContext) tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath()); 31 | System.out.println("configuring app with basedir: " + new File("./" + webappDirLocation).getAbsolutePath()); 32 | 33 | // Declare an alternative location for your "WEB-INF/classes" dir 34 | // Servlet 3.0 annotation will work 35 | File additionWebInfClasses = new File("target/classes"); 36 | WebResourceRoot resources = new StandardRoot(ctx); 37 | resources.addPreResources(new DirResourceSet(resources, "/WEB-INF/classes", 38 | additionWebInfClasses.getAbsolutePath(), "/")); 39 | ctx.setResources(resources); 40 | 41 | tomcat.start(); 42 | tomcat.getServer().await(); 43 | } 44 | 45 | } 46 | --------------------------------------------------------------------------------