| src/main/java/com/nq/service/impl/PriceServicesImpl.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/nq/service/impl/StockServiceImpl.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/nq/utils/redis/RedisKeyUtil.java | ●●●●● patch | view | raw | blame | history |
src/main/java/com/nq/service/impl/PriceServicesImpl.java
@@ -110,24 +110,52 @@ } } public String doPost(String pid) { // 从配置中获取 API URL,并拼接 key private static String lastResult = null; private static long lastExecuteTime = 0; private static final long MIN_INTERVAL_MS = 3000; private static final Object cacheLock = new Object(); public static String doPost(String pid) { long currentTime = System.currentTimeMillis(); // 第一次快速检查(不加锁) if (lastResult != null && (currentTime - lastExecuteTime) < MIN_INTERVAL_MS) { return lastResult; } // 同步块内再次检查并执行 synchronized (cacheLock) { currentTime = System.currentTimeMillis(); if (lastResult != null && (currentTime - lastExecuteTime) < MIN_INTERVAL_MS) { return lastResult; } // 执行POST请求 String newResult = doActualPost(pid); // 更新缓存 lastResult = newResult; lastExecuteTime = System.currentTimeMillis(); return newResult; } } private static String doActualPost(String pid) { String apiUrl = PropertiesUtil.getProperty("JS_IN_HTTP_URL") + "stock?key=" + PropertiesUtil.getProperty("JS_IN_KEY"); String result = null; try { URL url = new URL(apiUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 设置请求方法为 POST connection.setRequestMethod("POST"); // 设置请求头 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setDoOutput(true); // 允许向连接输出 connection.setDoOutput(true); connection.setConnectTimeout(5000); connection.setReadTimeout(10000); // 构建 POST 数据 String postData = "pid=" + pid; // 发送 POST 请求 try (OutputStream os = connection.getOutputStream()) { byte[] input = postData.getBytes("utf-8"); os.write(input, 0, input.length); @@ -136,20 +164,24 @@ // 读取响应 BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); StringBuilder response = new StringBuilder(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); result = response.toString(); return response.toString(); } catch (Exception e) { e.printStackTrace(); // 返回缓存或错误信息 if (lastResult != null) { return lastResult; } return "{\"error\":\"请求失败:" + e.getMessage() + "\"}"; } return result; } @Override public boolean isLimitUpBuy(String stockCode) { src/main/java/com/nq/service/impl/StockServiceImpl.java
@@ -40,6 +40,7 @@ import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.locks.ReentrantLock; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -432,9 +433,41 @@ } /*股票日线-K线*/ // 只需要缓存一个最近返回的Object private static Object lastResult = null; private static long lastExecuteTime = 0; private static final long MIN_INTERVAL_MS = 3000; private static final Object cacheLock = new Object(); @Override public Object getKData(String pid, String interval, String stockType) { long currentTime = System.currentTimeMillis(); // 第一次快速检查(不加锁) if (lastResult != null && (currentTime - lastExecuteTime) < MIN_INTERVAL_MS) { return lastResult; } // 同步块内再次检查并更新 synchronized (cacheLock) { currentTime = System.currentTimeMillis(); if (lastResult != null && (currentTime - lastExecuteTime) < MIN_INTERVAL_MS) { return lastResult; } // 获取新数据 Object newResult = doGetKData(pid, interval, stockType); // 更新缓存 lastResult = newResult; lastExecuteTime = System.currentTimeMillis(); return newResult; } } private Object doGetKData(String pid, String interval, String stockType) { EStockType eStockType = EStockType.getEStockTypeByCode(stockType); Object object = HttpUtil.get(eStockType.stockUrl + "kline?pid=" + pid + "&interval=" + interval + "&key=" + eStockType.stockKey); Gson gson = new Gson(); @@ -444,12 +477,13 @@ BigDecimal nowPrice = iPriceServices.getNowPrice(stock.getStockCode()); Map singleStock = getSingleStock(stock.getStockCode()); StockVO stockVO = (StockVO)singleStock.get("stock"); // 修改 List 中的最后一条数据 kData lastData = dataList.get(dataList.size() - 1); lastData.setC(nowPrice.toString()); lastData.setO(stockVO.getOpen_px()); lastData.setH(stockVO.getToday_max()); lastData.setL(stockVO.getToday_min()); return gson.toJson(dataList); } src/main/java/com/nq/utils/redis/RedisKeyUtil.java
@@ -21,6 +21,7 @@ import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; public class RedisKeyUtil { @@ -89,43 +90,78 @@ } } private static final ReentrantLock lock = new ReentrantLock(); private static String lastResult = null; private static long lastExecuteTime = 0; private static final long MIN_INTERVAL_MS = 3000; public static String doPost(String pid) { // 从配置中获取 API URL,并拼接 key String apiUrl = PropertiesUtil.getProperty("JS_IN_HTTP_URL") + "stock?key=" + PropertiesUtil.getProperty("JS_IN_KEY"); String result = null; try { URL url = new URL(apiUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 设置请求方法为 POST connection.setRequestMethod("POST"); // 设置请求头 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setDoOutput(true); // 允许向连接输出 // 构建 POST 数据 String postData = "pid=" + pid; // 发送 POST 请求 try (OutputStream os = connection.getOutputStream()) { byte[] input = postData.getBytes("utf-8"); os.write(input, 0, input.length); } // 读取响应 BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); result = response.toString(); } catch (Exception e) { e.printStackTrace(); // 快速检查缓存 long currentTime = System.currentTimeMillis(); if (lastResult != null && (currentTime - lastExecuteTime) < MIN_INTERVAL_MS) { return lastResult; } return result; // 需要获取锁执行新请求 return executeWithLock(pid); } private static String executeWithLock(String pid) { String apiUrl = PropertiesUtil.getProperty("JS_IN_HTTP_URL") + "stock?key=" + PropertiesUtil.getProperty("JS_IN_KEY"); lock.lock(); try { // 双检锁:再次检查缓存 long currentTime = System.currentTimeMillis(); if (lastResult != null && (currentTime - lastExecuteTime) < MIN_INTERVAL_MS) { return lastResult; } // 执行POST请求 String result = null; try { URL url = new URL(apiUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setDoOutput(true); String postData = "pid=" + pid; try (OutputStream os = connection.getOutputStream()) { byte[] input = postData.getBytes("utf-8"); os.write(input, 0, input.length); } BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuilder response = new StringBuilder(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); result = response.toString(); // 更新缓存 lastResult = result; lastExecuteTime = System.currentTimeMillis(); } catch (Exception e) { e.printStackTrace(); // 请求失败时返回缓存 if (lastResult != null) { return lastResult; } } return result; } finally { lock.unlock(); } }