# restful-web-service-test **Repository Path**: hel10word/restful-web-service-test ## Basic Information - **Project Name**: restful-web-service-test - **Description**: 简单的 接口测试 demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-06-29 - **Last Updated**: 2021-07-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 任务要求: 使用spring boot开发一个restful web service,这个restful接收传来的数据,每次post的数据量大概是2-4kb左右。做2个以下的场景: 1. 接收到数据后,什么都不做,数据丢弃 2. 接收到数据后,放到一个cache中,LRU清除掉 ## 接口: ### 场景一 ``` /data/sendDataDoNothing ``` > 请求方式:POST > 功能:无 > 参数:(Integer id,String name) > 返回结果:无 ### 场景二 ``` /data/putDateToCache ``` > 请求方式:POST > 功能:将数据存入缓存中,并使用LRU算法淘汰末尾数据 > 参数:(Integer id,String name) > 返回结果:无 ### 查看Cache ``` /data/toString ``` > 请求方式:GET > 功能:查看Cache中的数据 > 参数:无 > 返回结果:Cache.toString(); ## 第一步 设计程序 使其在处理并发请求时能保证线程安全 ### Cache的设计 1. 为了便于数据的拓展与存储,可以使用HashMap来进行存放原始数据 2. 为了让Cache记录数据的顺序与更新数据后插入头部,淘汰尾部,需要实现双向链表结构 3. 由于是高并发的环境,写缓存操作需要加锁来确保数据的安全性,可以根据需求来考虑是否加读锁 ## 第二步 优化程序 使其能发挥出机器的最佳性能 ### 思路一 最简单的方式,当接口收到请求数据后,直接塞入Cache中,不做人任何处理与返回 > Request获取数据->Cache.Put()->获取资源锁->插入数据->释放锁->进行下一个Request - 优点:能通过对Cache的读来实时获取最新结果 - 缺点:若网络延迟、插入数据太大或者设计数据库操作等等,后续的请求需等待前面的请求都结束才能执行,执行效率太慢 ### 思路二 Controller接受到请求后,先存入List队列中,然后迅速返回结果,后台通过多线程去异步的获取List中的数据插入到Cache中 > Request获取数据->存入List->返回结果->处理下一个Request > 异步开启多线程->监听并消耗List->插入Cache->处理完毕释放资源 - 优点:接口能实时的进行响应, 提高了整个系统的并发能力 - 缺点:需要一定的内存的消耗,当对List的消耗结果只能“滞后反馈” ## 第三步 完善程序 当超过机器性能的请求进来时需要进行限流 当前面两步完成后,我们通过压测,基本可以断定我们部署的服务器大概能承受多少的并发,如果此时还有更多的请求进来,服务器是肯定来不及处理的,所以我们需要通过限流,来拒绝掉超出的部分。 - 可以利用 令牌桶算法 来实现限流 通过服务器压测的结果 来配置令牌桶 由于没有后续要求 ,暂且只实现了 思路一 ## 任务测试: 携带 3kb 的字符串,每2秒100线程,循环2000次, 一共是 20W请求 **由于Cache是自定义的 默认大小为10** 相关的JMeter 脚本、Postman 接口测试 等文件 在 `./Result` 中 - 整个测试过程: ![测试过程](README-IMG/测试过程.gif) - Jmeter汇总数据: ![Jmeter汇总数据](README-IMG/Jmeter汇总数据.png) - CPU利用率均值: ![20w请求时的CPU平均利用率](README-IMG/20w请求时的CPU平均利用率.png) 这儿为了单纯测试 Cache 的效率,调用了内部的多线程来测试,由于Cache的读方法没有添加锁,所以当Put方法进行尾节点删除时,可能读到少一条的数据: ![通过接口调用多线程自测](README-IMG/通过接口调用多线程自测.gif)