1.如何批量请求,并获取处理结果
把请求放到阻塞队列中,启动一个SchedulExecuteService,以固定的频率10ms执行一次批量请求
每个请求封装一个CompletableFeture属性,通过get方法阻塞等待结果
批量请求是一种复用思想,需要给每一个请求指定一个序列号serialNo分用
package com.zhenzhen.demo.user.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhenzhen.demo.user.service.UserService;
import com.zhenzhen.demo.user.util.StringUtils;
@Service
public class UserServiceImpl implements UserService{
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private RestTemplate restTemplate;
@Override
public String getShortUrl(String longUrl) {
//使用redis自增,为每一个长地址生成一个序号
Long shortURLNum = redisTemplate.opsForValue().increment("shortURL", 1);
//直接返回10进制不太好,返回62进制
return StringUtils.get62String(shortURLNum);
}
@Override
public JSONObject getOrder(String userId) {
Map<String,Object> map = new HashMap<>();
map.put("userId", userId);
String result = restTemplate.getForObject("http://ORDER/getOrders", String.class,map);
return JSON.parseObject(result);
}
class Request{
String userId;
String serialNo;
CompletableFuture<Map<String,Object>> completableFuture;
}
LinkedBlockingDeque<Request> linkedBlockingDeque = new LinkedBlockingDeque<Request>();
@Override
public Map<String,Object> getOrderNew(String userId) throws InterruptedException, ExecutionException {
CompletableFuture<Map<String,Object>> completableFuture = new CompletableFuture<Map<String,Object>>();
Request request = new Request();
request.userId = userId;
request.serialNo= UUID.randomUUID().toString();
request.completableFuture = completableFuture;
linkedBlockingDeque.add(request);
return completableFuture.get();
}
@PostConstruct
public void init() {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
int size = linkedBlockingDeque.size();
if(size==0) {
return;
}
List<Map<String,Object>> requetList = new ArrayList<Map<String,Object>>();
List<Request> requests = new ArrayList<>();
for(int i=0;i<size;i++) {
Request request = linkedBlockingDeque.poll();
Map<String,Object> map = new HashMap<>();
map.put("userId", request.userId);
map.put("serialNo", request.serialNo);
map.put("completableFuture", request.completableFuture);
requetList.add(map);
requests.add(request);
}
String resultString = restTemplate.getForObject("http://ORDER/getOrders", String.class, requetList);
JSONObject result = JSON.parseObject(resultString);
List<Map<String,Object>> resultList = (List<Map<String,Object>>)result.get("data");
System.out.println("请求个数"+requests.size());
for(Request request:requests) {
String serialNo = request.serialNo;
for(Map<String,Object> resutl:resultList) {
if(serialNo.equals(resutl.get("serialNo").toString())) {
request.completableFuture.complete(resutl);
break;
}
}
}
}
}, 0, 10, TimeUnit.MILLISECONDS);
}
}