MockServer 支持非常高的请求吞吐量,但是如果需要更高的每秒请求速率,则可以将 MockServer 集群化,以便所有节点共享期望。
image.pngMockServer 的构建是为了支持单个实例的大规模:
- Apache Benchmark 测试了多达 6,000 个并行客户端,显示 MockServer 平均为 1.58 毫秒,p99 为 4 毫秒,150 个并行客户端每秒发送 95,228 个请求
- Locust 测试了多达 3,000 个并行客户端,并显示 MockServer 对 150 个并行客户端的 p99 为 4 毫秒
以下框架和技术用于最大化可扩展性:
- Netty 一个异步事件驱动的网络应用框架,最大化 HTTP 和 TLS 的可扩展性
- LMAX Disruptor 是一个高性能的线程间消息传递库,可最大限度地提高记录事件(即状态)和日志记录的可扩展性
- ScheduledThreadPoolExecutor 一个可以调度延迟任务的线程池,用于执行延迟响应,避免阻塞线程
性能测试
MockServer 已经使用 Apache Benchmark 和 Locust 在以下场景中进行了性能测试:
- 四个基本期望,包括方法、路径和标头
- 基本 GET 请求匹配第三个期望(即每个请求尝试三个匹配)
在测试期间,MockServer 在 Java 13 JVM 上运行,使用以下命令:
<pre class="prettyprint hljs gradle" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">java -Xmx500m -Dmockserver.logLevel=WARN -Dmockserver.disableLogging=true -jar ~/.m2/repository/org/mock-server/mockserver-netty/5.14.0/mockserver-netty-5.14.0-shaded.jar -serverPort 1080</pre>
下图显示了 p99 如何随着并行客户端数量的增加而增加。
image.pngApache Bench 性能测试结果
Apache Benchmark 执行如下:
<pre class="prettyprint hljs swift" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">ab -k -n 10000000 -c <parallel clients> http://127.0.0.1:1080/simple</pre>
测试结果如下:
image.pngLocust 性能测试结果
执行
<pre class="prettyprint hljs groovy" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">locust --loglevel=WARNING --headless --only-summary -u <parallel clients> -r 100 -t 180 --host=http://127.0.0.1:1080</pre>
测试结果如下:
image.png使用下面的脚本
<pre class="prettyprint hljs python" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import locust.stats
from locust import task, between
locust.stats.CONSOLE_STATS_INTERVAL_SEC = 60
from locust.contrib.fasthttp import FastHttpLocust
class UserBehavior(FastHttpUser):
wait_time = between(1, 1)
@task
def request(self):
self.client.get("/simple", verify=False)</pre>
尽管期望是集群的,但目前不支持集群 MockServer 日志,因此请求验证仅适用于接收请求的节点。
要创建 MockServer 集群,所有实例都需要:
- 共享一个读写文件系统,即相同的物理/虚拟机、NFS、AWS EFS、Azure 文件等
- 配置相同的期望初始化器和期望持久化
- 绑定到一个空闲端口,即如果在同一物理/虚拟机上,则为单独的端口
每个节点可以配置如下(根据需要调整端口):
<pre class="prettyprint hljs livescript" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">MOCKSERVER_WATCH_INITIALIZATION_JSON=true
MOCKSERVER_INITIALIZATION_JSON_PATH=mockserverInitialization.json
MOCKSERVER_PERSIST_EXPECTATIONS=true
MOCKSERVER_PERSISTED_EXPECTATIONS_PATH=mockserverInitialization.json
java -jar ~/Downloads/mockserver-netty-5.14.0-shaded.jar -serverPort 1080 -logLevel INFO</pre>
或者
<pre class="prettyprint hljs livescript" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">java
-Dmockserver.watchInitializatinotallow=true
-Dmockserver.initializatinotallow=mockserverInitialization.json
-Dmockserver.persistExpectatinotallow=true
-Dmockserver.persistedExpectatinotallow=mockserverInitialization.json
-jar ~/Downloads/mockserver-netty-5.14.0-shaded.jar -serverPort 1080 -logLevel INFO</pre>
网友评论