功能是查询出用户,然后给这些用户发推送,目前推送速率限制是 300/s, 应该单机就能满足需求,能有多机方案也好,不过还是需要清楚单机能不能做到这个速度。
目前的设计方案是单线程作为生产者查询数据库放到 blockqueue,然后多个消费者消费这个 blockqueue,并发送推送,流控用 guava 的 RateLimiter 。生产者单线程查询数据库,一秒查 300 个以上应该是可以的。
问题:
1,消费者单线程能做到 300/s 发送(用 netty 之类的类库可以做到吗?)? Spring 自带的 resttemplate 应该根本不可能满足这个要求吧?
2,如果是多线程,方案是怎么样?一个线程也需要多个消费者?线程的数量要怎么确定比较好(因为国外服务器服务还有其他功能需要使用,如果线程太多会不会影响其他功能?)。
3,300/s,假设每个请求(包括返回) 100kb,那每秒流量就是 30mb,所以应该是单机就能承受的,是这样计算的吗?
感觉提问有点太多啰嗦和细节,大家能给个方向意见也行~
1. RestTemplate 本身只是上层封装,具体性能依赖底层实现
2. 一个线程一个消费者,满足每秒 300 就行
3. 看机器带宽
自己实验自己调整吧
但 restTemplate 的设计好像是单线程单个调用的,上层 API 调用似乎没有能回调、future 之类的单线程并发接口,这种情况下是要怎么实现单线程多并发请求的功能?
我觉得你的理解没什么问题,RestTemplate 确实是同步调用,你可以试试 AsyncRestTemplate 。
消费者多线程应该很容易实现吧。应该随便找个非阻塞的 HttpClient 库就行。我最近用 Vertx 的 WebClient 。1000/s 没问题,不过我的请求没你这么大。 而且它并不需要创建很多线程,实现原理我说不好,你可以看下官方的文档。
jmeter ?
IO 复用,全程异步,比 Spring 高哪里去了
Spring WebClient? 异步非阻塞的
AsyncRestTemplate 似乎已经 deprecated 了,我搜了一下代替的 Spring client,好像符合要求,但我搜了一下没找到这东西的线程模型的解释,如果是用线程池实现的,感觉不如 vertx 那种单线程的 eventloop 。
不错,应该可以单独集成到 spring boot 项目吧,我之后研究一下。
用 Spring WebClient 就可以了, 非阻塞的
更正一下 不是单线程,是少量
jmh 了解一下,你这个只基于数据库和线程,最多结合一下 junit+jmh,本地跑起来评估一下性能。
建议用 netty 自己写或者找个基于 netty 的 client,否则线程和 IO 可能会有问题。