├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src ├── assembly └── release.xml └── main ├── java └── com │ └── opensource │ └── rpc │ └── benchmark │ ├── AbstractBenchmarkClient.java │ ├── AbstractBoltExchangeRunnable.java │ ├── AbstractClientRunnable.java │ ├── AbstractExchangeRunnable.java │ ├── BoltProxyFactory.java │ ├── ClientRunnable.java │ ├── InvokeOption.java │ ├── ParsedOption.java │ ├── ProxyFactory.java │ └── RpcBenchmarkClient.java └── resources ├── benchmark.sh └── log4j2.xml /.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 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | /.idea/ 25 | /rpc-performance.iml 26 | /target/ 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 支持dubbo框架dubbo协议、sofa rpc中bolt协议rpc性能测试。 2 | 3 | 一. fork压测模板工程 4 | 5 | ```shell 6 | git clone https://github.com/zonghaishang/rpc-performance-test.git 7 | ``` 8 | 9 | 按照[压测模板工程指引](https://github.com/zonghaishang/rpc-performance-test.git),开发待压测的接口。 10 | 11 | 二、执行压测 12 | 13 | ```shell 14 | cd rpc.benchmark 15 | ./benchmark.sh 16 | usage: benchmark.sh [options] 17 | -b,--target target benchmark runnable class 18 | -c,--threads The number of concurrent 19 | -d,--duration benchmark running duration(seconds) 20 | -h,--host server host or address 21 | -p,--port server port 22 | -t,--timeout rpc request timeout(milliseconds) 23 | -tc,--connections The number of tcp connection 24 | -w,--warm-up warm up duration(seconds) 25 | 26 | # 开始压测, 为了测试结果更准确,建议warm up 30秒. 27 | # 压测工具默认会不统计最后调用10秒 28 | # eg: 29 | ./benchmark.sh -b BenchmarkRandom_1k -h 127.0.0.1 -p 20880 -d 300 -w 30 30 | ``` 31 | 32 | 压测执行完后,输出: 33 | 34 | ```shell 35 | ----------Benchmark Statistics-------------- 36 | concurrents: 1 37 | connections: 1 38 | Running: 300s 39 | Benchmark Time: 261s 40 | Requests: 1463862 Success: 100% (1463862) Error: 0% (0) 41 | Avg TPS: 5419 Max TPS: 5827 Min TPS: 4121 42 | Avg RT: 0.184ms 43 | RT <= 0: 0% 0/1463862 44 | RT (0,1]: 99% 1462090/1463862 45 | RT (1,5]: 0% 1709/1463862 46 | RT (5,10]: 0% 34/1463862 47 | RT (10,50]: 0% 27/1463862 48 | RT (50,100]: 0% 1/1463862 49 | RT (100,500]: 0% 1/1463862 50 | RT (500,1000]: 0% 0/1463862 51 | RT > 1000: 0% 0/1463862 52 | ``` 53 | 54 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.opensource.rpc.benchmark 5 | rpc-performance 6 | jar 7 | 1.0.2 8 | rpc-performance 9 | http://maven.apache.org 10 | 11 | 12 | 2.6.5 13 | 5.6.5 14 | 1.4 15 | 2.17.1 16 | 17 | 18 | 19 | 20 | com.alibaba 21 | dubbo 22 | ${dubbo.version} 23 | provided 24 | 25 | 26 | 27 | com.alipay.sofa 28 | sofa-rpc-all 29 | ${sofa.rpc.version} 30 | provided 31 | 32 | 33 | 34 | commons-cli 35 | commons-cli 36 | ${commons.cli.version} 37 | 38 | 39 | 40 | org.apache.logging.log4j 41 | log4j-api 42 | ${log4j.version} 43 | 44 | 45 | org.apache.logging.log4j 46 | log4j-core 47 | ${log4j.version} 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-compiler-plugin 56 | 57 | 1.6 58 | 1.6 59 | UTF-8 60 | 61 | 62 | 63 | maven-assembly-plugin 64 | 2.2.1 65 | 66 | 67 | assembly 68 | package 69 | 70 | single 71 | 72 | 73 | 74 | ${basedir}/src/assembly/release.xml 75 | 76 | false 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/assembly/release.xml: -------------------------------------------------------------------------------- 1 | 2 | dist 3 | 4 | tar.gz 5 | 6 | false 7 | 8 | 9 | src/main/resources 10 | rpc.benchmark 11 | 0755 12 | 13 | 14 | 15 | 16 | rpc.benchmark/lib 17 | true 18 | true 19 | 20 | *:sources 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/com/opensource/rpc/benchmark/AbstractBenchmarkClient.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Apache License 3 | *

4 | * http://code.google.com/p/nfs-rpc (c) 2011 5 | */ 6 | package com.opensource.rpc.benchmark; 7 | 8 | import org.apache.commons.cli.CommandLine; 9 | import org.apache.commons.cli.CommandLineParser; 10 | import org.apache.commons.cli.DefaultParser; 11 | import org.apache.commons.cli.HelpFormatter; 12 | import org.apache.commons.cli.Option; 13 | import org.apache.commons.cli.Options; 14 | import org.apache.commons.cli.ParseException; 15 | 16 | import java.io.BufferedWriter; 17 | import java.io.FileWriter; 18 | import java.text.SimpleDateFormat; 19 | import java.util.ArrayList; 20 | import java.util.Calendar; 21 | import java.util.Date; 22 | import java.util.HashMap; 23 | import java.util.List; 24 | import java.util.Map; 25 | import java.util.concurrent.CountDownLatch; 26 | import java.util.concurrent.CyclicBarrier; 27 | 28 | /** 29 | * @author yiji 30 | * @version : AbstractBenchmarkClient.java, v 0.1 2020年04月09日 4:07 下午 yiji Exp $ 31 | */ 32 | public abstract class AbstractBenchmarkClient { 33 | 34 | private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 35 | 36 | private static long maxTPS = 0; 37 | 38 | private static long minTPS = 0; 39 | 40 | private static long allRequestSum; 41 | 42 | private static long allResponseTimeSum; 43 | 44 | private static long allErrorRequestSum; 45 | 46 | private static long allErrorResponseTimeSum; 47 | 48 | private static int runtimeSeconds; 49 | 50 | // < 0 51 | private static long below0sum; 52 | 53 | // (0,1] 54 | private static long above0sum; 55 | 56 | // (1,5] 57 | private static long above1sum; 58 | 59 | // (5,10] 60 | private static long above5sum; 61 | 62 | // (10,50] 63 | private static long above10sum; 64 | 65 | // (50,100] 66 | private static long above50sum; 67 | 68 | // (100,500] 69 | private static long above100sum; 70 | 71 | // (500,1000] 72 | private static long above500sum; 73 | 74 | // > 1000 75 | private static long above1000sum; 76 | 77 | public void run(String[] args) throws Exception { 78 | 79 | ParsedOption option = parseArguments(args); 80 | 81 | final String serverIP = option.getHost(); 82 | final int serverPort = option.getPort(); 83 | final int threads = option.getThreads(); 84 | final int timeout = option.getTimeout(); 85 | runtimeSeconds = option.getDuration(); 86 | final long endTime = System.nanoTime() / 1000L + runtimeSeconds * 1000 * 1000L; 87 | final int connections = option.getConnections(); 88 | 89 | printStartInfo(serverIP, serverPort, threads, timeout, connections); 90 | 91 | CyclicBarrier barrier = new CyclicBarrier(threads); 92 | CountDownLatch latch = new CountDownLatch(threads); 93 | List clients = new ArrayList(); 94 | 95 | // benchmark start after thirty seconds,let java app warm up 96 | long beginTime = System.nanoTime() / 1000L + option.getWarmUp() * 1000 * 1000L; 97 | for (int i = 0; i < threads; i++) { 98 | clients.add(getClientRunnable( 99 | new InvokeOption(option.getTargetInterface() 100 | , serverIP 101 | , serverPort 102 | , connections 103 | , timeout 104 | , barrier 105 | , latch 106 | , beginTime 107 | , endTime))); 108 | } 109 | 110 | startRunnable(clients); 111 | 112 | // waiting task complete 113 | latch.await(); 114 | 115 | // read results & add all 116 | // key: runtime second range 117 | // value: Long[2] array 118 | // -> Long[0]: execute count 119 | // -> Long[1]: response time sum 120 | Map times = new HashMap(); 121 | Map errorTimes = new HashMap(); 122 | for (ClientRunnable runnable : clients) { 123 | List results = runnable.getResults(); 124 | // response time range count 125 | long[] responseSpreads = results.get(0); 126 | below0sum += responseSpreads[0]; 127 | above0sum += responseSpreads[1]; 128 | above1sum += responseSpreads[2]; 129 | above5sum += responseSpreads[3]; 130 | above10sum += responseSpreads[4]; 131 | above50sum += responseSpreads[5]; 132 | above100sum += responseSpreads[6]; 133 | above500sum += responseSpreads[7]; 134 | above1000sum += responseSpreads[8]; 135 | long[] tps = results.get(1); 136 | long[] responseTimes = results.get(2); 137 | long[] errorTPS = results.get(3); 138 | long[] errorResponseTimes = results.get(4); 139 | for (int i = 0; i < tps.length; i++) { 140 | String key = String.valueOf(i); 141 | if (times.containsKey(key)) { 142 | Long[] successInfos = times.get(key); 143 | Long[] errorInfos = errorTimes.get(key); 144 | successInfos[0] += tps[i]; 145 | successInfos[1] += responseTimes[i]; 146 | errorInfos[0] += errorTPS[i]; 147 | errorInfos[1] += errorResponseTimes[i]; 148 | times.put(key, successInfos); 149 | errorTimes.put(key, errorInfos); 150 | } else { 151 | Long[] successInfos = new Long[2]; 152 | successInfos[0] = tps[i]; 153 | successInfos[1] = responseTimes[i]; 154 | Long[] errorInfos = new Long[2]; 155 | errorInfos[0] = errorTPS[i]; 156 | errorInfos[1] = errorResponseTimes[i]; 157 | times.put(key, successInfos); 158 | errorTimes.put(key, errorInfos); 159 | } 160 | } 161 | } 162 | 163 | long ignoreRequest = 0; 164 | long ignoreErrorRequest = 0; 165 | int maxTimeRange = runtimeSeconds - 30; 166 | // ignore the last 10 second requests, so tps can count more accurate 167 | for (int i = 0; i < 10; i++) { 168 | Long[] values = times.remove(String.valueOf(maxTimeRange - i)); 169 | if (values != null) { 170 | ignoreRequest += values[0]; 171 | } 172 | Long[] errorValues = errorTimes.remove(String.valueOf(maxTimeRange - i)); 173 | if (errorValues != null) { 174 | ignoreErrorRequest += errorValues[0]; 175 | } 176 | } 177 | 178 | for (Map.Entry entry : times.entrySet()) { 179 | long successRequest = entry.getValue()[0]; 180 | long errorRequest = 0; 181 | if (errorTimes.containsKey(entry.getKey())) { 182 | errorRequest = errorTimes.get(entry.getKey())[0]; 183 | } 184 | allRequestSum += successRequest; 185 | allResponseTimeSum += entry.getValue()[1]; 186 | allErrorRequestSum += errorRequest; 187 | if (errorTimes.containsKey(entry.getKey())) { 188 | allErrorResponseTimeSum += errorTimes.get(entry.getKey())[1]; 189 | } 190 | long currentRequest = successRequest + errorRequest; 191 | if (currentRequest > maxTPS) { 192 | maxTPS = currentRequest; 193 | } 194 | if (minTPS == 0 || currentRequest < minTPS) { 195 | minTPS = currentRequest; 196 | } 197 | } 198 | 199 | boolean isWriteResult = Boolean.parseBoolean(System.getProperty("write.statistics", "false")); 200 | if (isWriteResult) { 201 | BufferedWriter writer = new BufferedWriter(new FileWriter("benchmark.all.results")); 202 | for (Map.Entry entry : times.entrySet()) { 203 | writer.write(entry.getKey() + "," + entry.getValue()[0] + "," + entry.getValue()[1] + "\r\n"); 204 | } 205 | writer.close(); 206 | } 207 | 208 | System.out.println("----------Benchmark Statistics--------------"); 209 | System.out.println( 210 | " Running: " + runtimeSeconds + "s" 211 | + (option.getWarmUp() > 0 ? " and warm up for " + option.getWarmUp() + "s" : "") 212 | + " test @ " + option.getTargetInterface()); 213 | 214 | System.out.println(" " + threads + " threads and " + connections + " connections"); 215 | long benchmarkRequest = allRequestSum + allErrorRequestSum; 216 | long allRequest = benchmarkRequest + ignoreRequest + ignoreErrorRequest; 217 | System.out.println(" Requests: " + allRequest + " Success: " + (allRequestSum + ignoreRequest) * 100 218 | / allRequest + "% (" + (allRequestSum + ignoreRequest) + ") Error: " 219 | + (allErrorRequestSum + ignoreErrorRequest) * 100 / allRequest + "% (" 220 | + (allErrorRequestSum + ignoreErrorRequest) + ")"); 221 | System.out.println(" Avg TPS: " + benchmarkRequest / times.keySet().size() + " Max TPS: " + maxTPS 222 | + " Min TPS: " + minTPS); 223 | System.out.println(" Avg RT: " + (allErrorResponseTimeSum + allResponseTimeSum) / benchmarkRequest / 1000f 224 | + "ms"); 225 | System.out.println(" RT <= 0: " + (below0sum * 100 / allRequest) + "% " + below0sum + "/" + allRequest); 226 | System.out.println(" RT (0,1]: " + (above0sum * 100 / allRequest) + "% " + above0sum + "/" + allRequest); 227 | System.out.println(" RT (1,5]: " + (above1sum * 100 / allRequest) + "% " + above1sum + "/" + allRequest); 228 | System.out.println(" RT (5,10]: " + (above5sum * 100 / allRequest) + "% " + above5sum + "/" + allRequest); 229 | System.out.println(" RT (10,50]: " + (above10sum * 100 / allRequest) + "% " + above10sum + "/" + allRequest); 230 | System.out.println(" RT (50,100]: " + (above50sum * 100 / allRequest) + "% " + above50sum + "/" + allRequest); 231 | System.out.println(" RT (100,500]: " + (above100sum * 100 / allRequest) + "% " + above100sum + "/" + allRequest); 232 | System.out.println(" RT (500,1000]: " + (above500sum * 100 / allRequest) + "% " + above500sum + "/" 233 | + allRequest); 234 | System.out.println(" RT > 1000: " + (above1000sum * 100 / allRequest) + "% " + above1000sum + "/" + allRequest); 235 | System.exit(0); 236 | } 237 | 238 | private void printStartInfo(String serverIP, int serverPort, int threads, int timeout, int clientNums) { 239 | // Print start info 240 | Date currentDate = new Date(); 241 | Calendar calendar = Calendar.getInstance(); 242 | calendar.setTime(currentDate); 243 | calendar.add(Calendar.SECOND, runtimeSeconds); 244 | 245 | StringBuilder startInfo = new StringBuilder(); 246 | startInfo.append("ready to start client benchmark: ").append("\n"); 247 | startInfo.append("server is: ").append(serverIP).append(":").append(serverPort).append("\n"); 248 | startInfo.append("concurrent is: ").append(threads).append("\n"); 249 | startInfo.append("connection is: ").append(clientNums).append("\n"); 250 | startInfo.append("timeout is: ").append(timeout).append("ms").append("\n"); 251 | startInfo.append("the benchmark start at:").append(dateFormat.format(currentDate)).append("\n"); 252 | startInfo.append("the benchmark will end at:").append(dateFormat.format(calendar.getTime())); 253 | 254 | System.out.println(startInfo.toString()); 255 | } 256 | 257 | private ParsedOption parseArguments(String[] args) { 258 | ParsedOption option = new ParsedOption(); 259 | 260 | Options options = new Options(); 261 | options.addOption(new Option("b", "target", true, "target benchmark runnable class")); 262 | options.addOption(new Option("h", "host", true, "server host or address")); 263 | options.addOption(new Option("p", "port", true, "server port")); 264 | options.addOption(new Option("t", "timeout", true, "rpc request timeout(milliseconds)")); 265 | options.addOption(new Option("d", "duration", true, "benchmark running duration(seconds)")); 266 | options.addOption(new Option("c", "threads", true, "The number of concurrent")); 267 | options.addOption(new Option("tc", "connections", true, "The number of tcp connection")); 268 | options.addOption(new Option("w", "warm-up", true, "warm up duration(seconds)")); 269 | 270 | HelpFormatter formatter = new HelpFormatter(); 271 | 272 | CommandLineParser parser = new DefaultParser(); 273 | try { 274 | CommandLine cmd = parser.parse(options, args); 275 | 276 | String host = cmd.getOptionValue("h"); 277 | String port = cmd.getOptionValue("p"); 278 | String duration = cmd.getOptionValue("d"); 279 | String target = cmd.getOptionValue("b"); 280 | if (host == null || port == null || duration == null) { 281 | printUsage(options, formatter); 282 | } 283 | 284 | option.setHost(host); 285 | option.setPort(Integer.parseInt(port)); 286 | option.setDuration(Integer.parseInt(duration)); 287 | option.setTargetInterface(target); 288 | 289 | String timeout = cmd.getOptionValue("t"); 290 | String threads = cmd.getOptionValue("c"); 291 | String connections = cmd.getOptionValue("tc"); 292 | String warmUp = cmd.getOptionValue("w"); 293 | if (timeout == null) { timeout = "1000"; } 294 | if (threads == null) { threads = "1"; } 295 | if (connections == null) { connections = "1"; } 296 | 297 | option.setTimeout(Integer.parseInt(timeout)); 298 | option.setThreads(Integer.parseInt(threads)); 299 | option.setConnections(Integer.parseInt(connections)); 300 | 301 | if (warmUp != null) { 302 | option.setWarmUp(Integer.parseInt(warmUp)); 303 | } 304 | 305 | } catch (ParseException e) { 306 | System.err.println("Parsing failed. Reason: " + e.getMessage()); 307 | printUsage(options, formatter); 308 | } 309 | 310 | return option; 311 | } 312 | 313 | private void printUsage(Options options, HelpFormatter formatter) { 314 | // print help usage: 315 | formatter.printHelp("benchmark.sh [options]", options); 316 | System.exit(0); 317 | } 318 | 319 | public abstract ClientRunnable getClientRunnable(InvokeOption option) 320 | throws Exception; 321 | 322 | protected void startRunnable(List runnable) { 323 | for (int i = 0; i < runnable.size(); i++) { 324 | final ClientRunnable execute = runnable.get(i); 325 | Thread thread = new Thread(execute, "benchmark-client-" + i); 326 | thread.start(); 327 | } 328 | } 329 | 330 | } -------------------------------------------------------------------------------- /src/main/java/com/opensource/rpc/benchmark/AbstractBoltExchangeRunnable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Alipay.com Inc. 3 | * Copyright (c) 2004-2020 All Rights Reserved. 4 | */ 5 | package com.opensource.rpc.benchmark; 6 | 7 | /** 8 | * only for sofa rpc benchmark 9 | * 10 | * @author yiji 11 | * @version : AbstractBoltExchangeRunnable.java, v 0.1 2020年04月21日 4:05 下午 yiji Exp $ 12 | */ 13 | public abstract class AbstractBoltExchangeRunnable extends AbstractClientRunnable { 14 | 15 | protected BoltProxyFactory serviceFactory = new BoltProxyFactory(); 16 | 17 | public AbstractBoltExchangeRunnable(InvokeOption option) { 18 | super(option); 19 | this.serviceFactory.setTargetIP(option.targetIP); 20 | this.serviceFactory.setConnections(option.connections); 21 | this.serviceFactory.setTargetPort(option.targetPort); 22 | this.serviceFactory.setTimeout(option.rpcTimeout); 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/com/opensource/rpc/benchmark/AbstractClientRunnable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Apache License 3 | *

4 | * http://code.google.com/p/nfs-rpc (c) 2011 5 | */ 6 | package com.opensource.rpc.benchmark; 7 | 8 | import org.apache.logging.log4j.LogManager; 9 | import org.apache.logging.log4j.Logger; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | import java.util.concurrent.CountDownLatch; 14 | import java.util.concurrent.CyclicBarrier; 15 | import java.util.concurrent.TimeUnit; 16 | 17 | /** 18 | * @author yiji 19 | * @version : AbstractClientRunnable.java, v 0.1 2020年04月09日 6:41 下午 yiji Exp $ 20 | */ 21 | public abstract class AbstractClientRunnable implements ClientRunnable { 22 | 23 | private static final Logger LOGGER = LogManager.getLogger(AbstractClientRunnable.class); 24 | 25 | private CyclicBarrier barrier; 26 | 27 | private CountDownLatch latch; 28 | 29 | private long endTime; 30 | 31 | private boolean running = true; 32 | 33 | // response time spread 34 | private long[] responseSpreads = new long[9]; 35 | 36 | // error request per second 37 | private long[] errorTPS = null; 38 | 39 | // error response times per second 40 | private long[] errorResponseTimes = null; 41 | 42 | // tps per second 43 | private long[] tps = null; 44 | 45 | // response times per second 46 | private long[] responseTimes = null; 47 | 48 | // benchmark startTime 49 | private long startTime; 50 | 51 | // benchmark maxRange 52 | private int maxRange; 53 | 54 | protected InvokeOption option; 55 | 56 | public AbstractClientRunnable(InvokeOption option) { 57 | this.option = option; 58 | this.barrier = this.option.barrier; 59 | this.latch = this.option.latch; 60 | this.startTime = this.option.startTime; 61 | this.endTime = this.option.endTime; 62 | maxRange = (Integer.parseInt(String.valueOf((endTime - startTime))) / 1000000) + 1; 63 | errorTPS = new long[maxRange]; 64 | errorResponseTimes = new long[maxRange]; 65 | tps = new long[maxRange]; 66 | responseTimes = new long[maxRange]; 67 | // init 68 | for (int i = 0; i < maxRange; i++) { 69 | errorTPS[i] = 0; 70 | errorResponseTimes[i] = 0; 71 | tps[i] = 0; 72 | responseTimes[i] = 0; 73 | } 74 | } 75 | 76 | public void run() { 77 | try { 78 | barrier.await(); 79 | } catch (Exception e) { 80 | // IGNORE 81 | } 82 | runJavaAndHessian(); 83 | latch.countDown(); 84 | } 85 | 86 | private void runJavaAndHessian() { 87 | while (running) { 88 | long beginTime = getCurrentTime(); 89 | if (beginTime >= endTime) { 90 | running = false; 91 | break; 92 | } 93 | 94 | try { 95 | Object result = doInvoke(); 96 | long currentTime = getCurrentTime(); 97 | // warm up ?? 98 | if (beginTime <= startTime) { 99 | continue; 100 | } 101 | long consumeTime = currentTime - beginTime; 102 | sumResponseTimeSpread(consumeTime); 103 | int offset = Integer.parseInt(String.valueOf(beginTime - startTime)) / 1000000; 104 | if (offset >= maxRange) { 105 | LOGGER.error("benchmark range exceeds maxRange,range is: " + offset + ",maxRange is: " + maxRange); 106 | continue; 107 | } 108 | 109 | if (result != null) { 110 | tps[offset] = tps[offset] + 1; 111 | responseTimes[offset] = responseTimes[offset] + consumeTime; 112 | } else { 113 | LOGGER.error("server return result is null"); 114 | errorTPS[offset] = errorTPS[offset] + 1; 115 | errorResponseTimes[offset] = errorResponseTimes[offset] + consumeTime; 116 | } 117 | } catch (Exception e) { 118 | LOGGER.error("failed to trigger doInvoke", e); 119 | long currentTime = getCurrentTime(); 120 | // warm up ?? 121 | if (beginTime <= startTime) { 122 | continue; 123 | } 124 | long consumeTime = currentTime - beginTime; 125 | sumResponseTimeSpread(consumeTime); 126 | int offset = Integer.parseInt(String.valueOf(beginTime - startTime)) / 1000000; 127 | if (offset >= maxRange) { 128 | LOGGER.error("benchmark range exceeds maxRange,range is: " + offset + ",maxRange is: " + maxRange); 129 | continue; 130 | } 131 | errorTPS[offset] = errorTPS[offset] + 1; 132 | errorResponseTimes[offset] = errorResponseTimes[offset] + consumeTime; 133 | } 134 | } 135 | } 136 | 137 | private long getCurrentTime() { 138 | return System.nanoTime() / 1000L; 139 | } 140 | 141 | public abstract Object doInvoke(); 142 | 143 | public List getResults() { 144 | List results = new ArrayList(); 145 | results.add(responseSpreads); 146 | results.add(tps); 147 | results.add(responseTimes); 148 | results.add(errorTPS); 149 | results.add(errorResponseTimes); 150 | return results; 151 | } 152 | 153 | private void sumResponseTimeSpread(long responseTime) { 154 | // 更精确统计落在时间range计数 155 | double rt = responseTime; 156 | 157 | if (rt <= 0) { 158 | responseSpreads[0] = responseSpreads[0] + 1; 159 | } else if (rt <= T_1_MICROS) { 160 | responseSpreads[1] = responseSpreads[1] + 1; 161 | } else if (rt <= T_5_MICROS) { 162 | responseSpreads[2] = responseSpreads[2] + 1; 163 | } else if (rt <= T_10_MICROS) { 164 | responseSpreads[3] = responseSpreads[3] + 1; 165 | } else if (rt <= T_50_MICROS) { 166 | responseSpreads[4] = responseSpreads[4] + 1; 167 | } else if (rt <= T_100_MICROS) { 168 | responseSpreads[5] = responseSpreads[5] + 1; 169 | } else if (rt <= T_500_MICROS) { 170 | responseSpreads[6] = responseSpreads[6] + 1; 171 | } else if (rt <= T_1000_MICROS) { 172 | responseSpreads[7] = responseSpreads[7] + 1; 173 | } else { 174 | responseSpreads[8] = responseSpreads[8] + 1; 175 | } 176 | } 177 | 178 | private static final long T_1_MICROS = TimeUnit.MILLISECONDS.toMicros(1); 179 | private static final long T_5_MICROS = TimeUnit.MILLISECONDS.toMicros(5); 180 | private static final long T_10_MICROS = TimeUnit.MILLISECONDS.toMicros(10); 181 | private static final long T_50_MICROS = TimeUnit.MILLISECONDS.toMicros(50); 182 | private static final long T_100_MICROS = TimeUnit.MILLISECONDS.toMicros(100); 183 | private static final long T_500_MICROS = TimeUnit.MILLISECONDS.toMicros(500); 184 | private static final long T_1000_MICROS = TimeUnit.MILLISECONDS.toMicros(1000); 185 | 186 | } -------------------------------------------------------------------------------- /src/main/java/com/opensource/rpc/benchmark/AbstractExchangeRunnable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Apache License 3 | *

4 | * http://code.google.com/p/nfs-rpc (c) 2011 5 | */ 6 | package com.opensource.rpc.benchmark; 7 | 8 | /** 9 | * 10 | * only for dubbo rpc benchmark 11 | * 12 | * @author yiji 13 | * @version : AbstractExchangeClientRunnable.java, v 0.1 2020年04月09日 7:25 下午 yiji Exp $ 14 | */ 15 | public abstract class AbstractExchangeRunnable extends AbstractClientRunnable { 16 | 17 | protected ProxyFactory serviceFactory = new ProxyFactory(); 18 | 19 | public AbstractExchangeRunnable(InvokeOption option) { 20 | super(option); 21 | this.serviceFactory.setTargetIP(option.targetIP); 22 | this.serviceFactory.setConnections(option.connections); 23 | this.serviceFactory.setTargetPort(option.targetPort); 24 | this.serviceFactory.setTimeout(option.rpcTimeout); 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/com/opensource/rpc/benchmark/BoltProxyFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Alipay.com Inc. 3 | * Copyright (c) 2004-2020 All Rights Reserved. 4 | */ 5 | package com.opensource.rpc.benchmark; 6 | 7 | import com.alipay.sofa.rpc.common.RpcConstants; 8 | import com.alipay.sofa.rpc.config.ApplicationConfig; 9 | import com.alipay.sofa.rpc.config.ConsumerConfig; 10 | 11 | /** 12 | * @author yiji 13 | * @version : BoltProxyFactory.java, v 0.1 2020年04月21日 4:06 下午 yiji Exp $ 14 | */ 15 | public class BoltProxyFactory extends ProxyFactory { 16 | 17 | protected T createClient(Class targetInterface, String targetIP, int targetPort, int timeout, int connections) { 18 | ConsumerConfig consumerConfig = new ConsumerConfig(); 19 | consumerConfig.setInterfaceId(targetInterface.getName()); 20 | consumerConfig.setDirectUrl("bolt://" + targetIP + ":" + targetPort); 21 | consumerConfig.setProtocol(RpcConstants.PROTOCOL_TYPE_BOLT); 22 | consumerConfig.setBootstrap("bolt"); 23 | consumerConfig.setApplication(new ApplicationConfig().setAppName("benchmark_client")); 24 | consumerConfig.setReconnectPeriod(1000); 25 | consumerConfig.setTimeout(timeout); 26 | consumerConfig.setConnectionNum(connections); 27 | 28 | return (T) consumerConfig.refer(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/opensource/rpc/benchmark/ClientRunnable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Apache License 3 | *

4 | * http://code.google.com/p/nfs-rpc (c) 2011 5 | */ 6 | package com.opensource.rpc.benchmark; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author yiji 12 | * @version : ClientRunnable.java, v 0.1 2020年04月09日 3:48 下午 yiji Exp $ 13 | */ 14 | public interface ClientRunnable extends Runnable { 15 | 16 | List getResults(); 17 | 18 | } -------------------------------------------------------------------------------- /src/main/java/com/opensource/rpc/benchmark/InvokeOption.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Apache License 3 | *

4 | * http://code.google.com/p/nfs-rpc (c) 2011 5 | */ 6 | package com.opensource.rpc.benchmark; 7 | 8 | import java.util.concurrent.CountDownLatch; 9 | import java.util.concurrent.CyclicBarrier; 10 | 11 | /** 12 | * @author yiji 13 | * @version : ClientOption.java, v 0.1 2020年04月09日 8:02 下午 yiji Exp $ 14 | */ 15 | public class InvokeOption { 16 | 17 | String targetInterface; 18 | String targetIP; 19 | int targetPort; 20 | int connections; 21 | int rpcTimeout; 22 | long startTime; 23 | long endTime; 24 | CyclicBarrier barrier; 25 | CountDownLatch latch; 26 | 27 | public InvokeOption(String targetInterface, String targetIP, int targetPort, int connections, int rpcTimeout, 28 | CyclicBarrier barrier, CountDownLatch latch, long startTime, long endTime) { 29 | this.targetInterface = targetInterface; 30 | this.targetIP = targetIP; 31 | this.targetPort = targetPort; 32 | this.connections = connections; 33 | this.rpcTimeout = rpcTimeout; 34 | this.barrier = barrier; 35 | this.latch = latch; 36 | this.startTime = startTime; 37 | this.endTime = endTime; 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /src/main/java/com/opensource/rpc/benchmark/ParsedOption.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Apache License 3 | *

4 | * http://code.google.com/p/nfs-rpc (c) 2011 5 | */ 6 | package com.opensource.rpc.benchmark; 7 | 8 | /** 9 | * @author yiji 10 | * @version : Options.java, v 0.1 2020年04月09日 4:10 下午 yiji Exp $ 11 | */ 12 | public class ParsedOption { 13 | 14 | /** 15 | * server host or ip 16 | */ 17 | private String host; 18 | 19 | /** 20 | * server port 21 | */ 22 | private int port; 23 | 24 | /** 25 | * request timeout (milliseconds) 26 | */ 27 | private int timeout; 28 | 29 | /** 30 | * benchmark duration (seconds) 31 | */ 32 | private int duration; 33 | 34 | /** 35 | * The number of concurrent 36 | */ 37 | private int threads; 38 | 39 | /** 40 | * The number of tcp connections 41 | */ 42 | private int connections; 43 | 44 | private int warmUp; 45 | 46 | /** 47 | * save detail to benchmark.all.results file ? 48 | */ 49 | private boolean writeStatistics; 50 | 51 | /** 52 | * benchmark target class 53 | */ 54 | private String targetInterface; 55 | 56 | public String getHost() { 57 | return host; 58 | } 59 | 60 | public void setHost(String host) { 61 | this.host = host; 62 | } 63 | 64 | public int getPort() { 65 | return port; 66 | } 67 | 68 | public void setPort(int port) { 69 | this.port = port; 70 | } 71 | 72 | public int getTimeout() { 73 | return timeout; 74 | } 75 | 76 | public void setTimeout(int timeout) { 77 | this.timeout = timeout; 78 | } 79 | 80 | public int getDuration() { 81 | return duration; 82 | } 83 | 84 | public void setDuration(int duration) { 85 | this.duration = duration; 86 | } 87 | 88 | public int getThreads() { 89 | return threads; 90 | } 91 | 92 | public void setThreads(int threads) { 93 | this.threads = threads; 94 | } 95 | 96 | public int getConnections() { 97 | return connections; 98 | } 99 | 100 | public void setConnections(int connections) { 101 | this.connections = connections; 102 | } 103 | 104 | public boolean isWriteStatistics() { 105 | return writeStatistics; 106 | } 107 | 108 | public void setWriteStatistics(boolean writeStatistics) { 109 | this.writeStatistics = writeStatistics; 110 | } 111 | 112 | public String getTargetInterface() { 113 | return targetInterface; 114 | } 115 | 116 | public void setTargetInterface(String targetInterface) { 117 | this.targetInterface = targetInterface; 118 | } 119 | 120 | public int getWarmUp() { 121 | return warmUp; 122 | } 123 | 124 | public void setWarmUp(int warmUp) { 125 | this.warmUp = warmUp; 126 | } 127 | } -------------------------------------------------------------------------------- /src/main/java/com/opensource/rpc/benchmark/ProxyFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Apache License 3 | *

4 | * http://code.google.com/p/nfs-rpc (c) 2011 5 | */ 6 | package com.opensource.rpc.benchmark; 7 | 8 | import com.alibaba.dubbo.config.ApplicationConfig; 9 | import com.alibaba.dubbo.config.ReferenceConfig; 10 | 11 | import java.util.concurrent.ConcurrentHashMap; 12 | 13 | /** 14 | * @author yiji 15 | * @version : ServiceFactory.java, v 0.1 2020年04月09日 6:46 下午 yiji Exp $ 16 | */ 17 | public class ProxyFactory { 18 | 19 | String targetIP = null; 20 | 21 | int targetPort = 0; 22 | 23 | int timeout = 0; 24 | 25 | int connections = 0; 26 | 27 | public String getTargetIP() { 28 | return targetIP; 29 | } 30 | 31 | public void setTargetIP(String targetIP) { 32 | this.targetIP = targetIP; 33 | } 34 | 35 | public int getTargetPort() { 36 | return targetPort; 37 | } 38 | 39 | public void setTargetPort(int targetPort) { 40 | this.targetPort = targetPort; 41 | } 42 | 43 | public int getTimeout() { 44 | return timeout; 45 | } 46 | 47 | public void setTimeout(int timeout) { 48 | this.timeout = timeout; 49 | } 50 | 51 | public int getConnections() { 52 | return connections; 53 | } 54 | 55 | public void setConnections(int connections) { 56 | this.connections = connections; 57 | } 58 | 59 | // Cache ExchangeClient 60 | private static ConcurrentHashMap services = new ConcurrentHashMap(); 61 | 62 | @SuppressWarnings("unchecked") 63 | public T getReference(final Class targetInterface) { 64 | String key = targetInterface.getName(); 65 | 66 | T ref = (T) services.get(key); 67 | if (ref != null) { 68 | return ref; 69 | } 70 | 71 | synchronized (services) { 72 | 73 | ref = (T) services.get(key); 74 | if (ref != null) { 75 | return ref; 76 | } 77 | 78 | ref = createClient(targetInterface, targetIP, targetPort, timeout, connections); 79 | services.put(key, ref); 80 | 81 | return ref; 82 | } 83 | } 84 | 85 | protected T createClient(Class targetInterface, String targetIP, int targetPort, int timeout, int connections) { 86 | ReferenceConfig referenceConfig = new ReferenceConfig(); 87 | referenceConfig.setInterface(targetInterface); 88 | 89 | referenceConfig.setConnections(connections); 90 | 91 | ApplicationConfig application = new ApplicationConfig(); 92 | application.setName("benchmark_client"); 93 | referenceConfig.setApplication(application); 94 | 95 | StringBuilder url = new StringBuilder(); 96 | url.append("dubbo://").append(targetIP).append(":").append(targetPort).append("/").append(targetInterface.getName()); 97 | referenceConfig.setUrl(url.toString()); 98 | 99 | referenceConfig.setTimeout(timeout); 100 | 101 | return referenceConfig.get(); 102 | } 103 | 104 | } -------------------------------------------------------------------------------- /src/main/java/com/opensource/rpc/benchmark/RpcBenchmarkClient.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Apache License 3 | *

4 | * http://code.google.com/p/nfs-rpc (c) 2011 5 | */ 6 | package com.opensource.rpc.benchmark; 7 | 8 | /** 9 | * @author yiji 10 | * @version : RpcBenchmarkClient.java, v 0.1 2020年04月09日 7:58 下午 yiji Exp $ 11 | */ 12 | public class RpcBenchmarkClient extends AbstractBenchmarkClient { 13 | 14 | @Override 15 | public ClientRunnable getClientRunnable(InvokeOption option) 16 | throws Exception { 17 | Class[] parameterTypes = new Class[] {InvokeOption.class}; 18 | Object[] parameters = new Object[] {option}; 19 | return (ClientRunnable) Class.forName(option.targetInterface).getConstructor(parameterTypes).newInstance(parameters); 20 | } 21 | 22 | public static void main(String[] args) throws Exception { 23 | new RpcBenchmarkClient().run(args); 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/resources/benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | java -Xms512m -Xmx512m -Xmn128m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log -Djava.ext.dirs="./lib:./ext:$JAVA_HOME/jre/lib/ext" com.opensource.rpc.benchmark.RpcBenchmarkClient $@ -------------------------------------------------------------------------------- /src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | --------------------------------------------------------------------------------