最近项目中用到微信推送模板消息给用户,刚开始没有做优化,全部发完大概6分钟左右,加上多线程之后大概1分钟左右就能完成
- runnable类
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
/**
* @author bangthestars
* @date 2020/5/29
*/
@Slf4j
@Data
public class SendMessageRunnable implements Runnable {
/**
* 发送模版消息的url https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s
*/
private String url;
/**
* post请求头
*/
private Map<String,Object> map;
/**
* 模版消息的json数据
*/
private JSONObject jsonObject;
/**
* 异步辅助类 根据业务判断是否需要
*/
private CountDownLatch latch;
/**
* 用户openId
*/
private String openId;
public SendMessageRunnable(String url, Map<String, Object> map, JSONObject jsonObject, CountDownLatch latch, String openId) {
this.url = url;
this.map = map;
this.jsonObject = jsonObject;
this.latch = latch;
this.openId = openId;
}
@Override
public void run() {
try {
sendMessage(openId);
} catch (Exception e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}
private void sendMessage(String openId) {
jsonObject.put("touser", openId);
String postJsonWithHeader = HttpClientUtil.postJsonWithHeader(url, map, jsonObject.toJSONString());
log.info("result:{}", postJsonWithHeader);
}
}
post请求
public static String postJsonWithHeader(String url, Map<String, Object> headerMap, String contentJson) {
String result = null;
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
try {
// 循环增加header
Iterator headerIterator = headerMap.entrySet().iterator();
while (headerIterator.hasNext()) {
Map.Entry<String, String> elem = (Map.Entry<String, String>) headerIterator.next();
post.addHeader(elem.getKey(), elem.getValue());
}
if (contentJson.length() > 0) {
// 解决中文乱码问题
StringEntity se = new StringEntity(contentJson, "utf-8");
se.setContentType("text/json");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
}
// 发送请求并接收返回数据
response = httpClient.execute(post);
if (response != null && response.getStatusLine().getStatusCode() == 200) {
// 获取response的body部分
HttpEntity entity = response.getEntity();
// 读取reponse的body部分并转化成字符串
result = EntityUtils.toString(entity);
}
return result;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
发送模版消息
private final static ExecutorService MANAGER_PROFILE_DATA_EXECUTOR = new ThreadPoolExecutor(9, 100, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue());
9个核心线程,最大100个,等待时间60秒
List<String> openIdList = patientsUserEntities.stream().map(PatientsUserEntity::getOpenId).collect(Collectors.toList());
final CountDownLatch latch = new CountDownLatch(openIdList.size());
// 多线程
Map map = new HashMap();
for (String openId : openIdList) {
SendMessageRunnable sendMessageRunnable = new SendMessageRunnable(url, map, jsonObject, latch, openId);
MANAGER_PROFILE_DATA_EXECUTOR.execute(sendMessageRunnable);
}
// 每个线程执行完,都执行countDown()方法,计时器为0的时候才会继续执行wait后面的代码。这里可以根据业务需要判断是不是需要wait
// latch.await();