【java】【28】高并发优化,批量请求下游服务

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);
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值