mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2026-02-24 14:15:24 +00:00
1. 缓存优化
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
package cn.qaiu.lz.web.http;
|
||||
|
||||
import cn.qaiu.lz.common.util.URLParamUtil;
|
||||
import cn.qaiu.lz.web.model.CacheLinkInfo;
|
||||
import cn.qaiu.lz.web.service.CacheService;
|
||||
import cn.qaiu.parser.PanDomainTemplate;
|
||||
import cn.qaiu.vx.core.annotaions.RouteHandler;
|
||||
import cn.qaiu.vx.core.annotaions.RouteMapping;
|
||||
import cn.qaiu.vx.core.enums.RouteMethod;
|
||||
@@ -31,8 +31,7 @@ public class ServerApi {
|
||||
Promise<Void> promise = Promise.promise();
|
||||
String url = URLParamUtil.parserParams(request);
|
||||
|
||||
PanDomainTemplate panDomainTemplate = PanDomainTemplate.fromShareUrl(url).setShareLinkInfoPwd(pwd);
|
||||
cacheService.getAndSaveCachedShareLink(panDomainTemplate)
|
||||
cacheService.getCachedByShareUrlAndPwd(url, pwd)
|
||||
.onSuccess(res -> ResponseUtil.redirect(
|
||||
response.putHeader("nfd-cache-hit", res.getCacheHit().toString())
|
||||
.putHeader("nfd-cache-expires", res.getExpires()),
|
||||
@@ -42,39 +41,32 @@ public class ServerApi {
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/json/parser", method = RouteMethod.GET, order = 3)
|
||||
public Future<String> parseJson(HttpServerRequest request, String pwd) {
|
||||
public Future<CacheLinkInfo> parseJson(HttpServerRequest request, String pwd) {
|
||||
String url = URLParamUtil.parserParams(request);
|
||||
return PanDomainTemplate.fromShareUrl(url).setShareLinkInfoPwd(pwd).createTool().parse();
|
||||
return cacheService.getCachedByShareUrlAndPwd(url, pwd);
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/json/:type/:key", method = RouteMethod.GET, order = 2)
|
||||
public Future<String> parseKeyJson(String type, String key) {
|
||||
String code = "";
|
||||
public Future<CacheLinkInfo> parseKeyJson(String type, String key) {
|
||||
String pwd = "";
|
||||
if (key.contains("@")) {
|
||||
String[] keys = key.split("@");
|
||||
key = keys[0];
|
||||
code = keys[1];
|
||||
pwd = keys[1];
|
||||
}
|
||||
return PanDomainTemplate.fromShortName(type)
|
||||
.generateShareLink(key).setShareLinkInfoPwd(code).createTool().parse();
|
||||
return cacheService.getCachedByShareKeyAndPwd(type, key, pwd);
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/:type/:key", method = RouteMethod.GET, order = 1)
|
||||
public Future<Void> parseKey(HttpServerResponse response, String type, String key) {
|
||||
Promise<Void> promise = Promise.promise();
|
||||
String code = "";
|
||||
String pwd = "";
|
||||
if (key.contains("@")) {
|
||||
String[] keys = key.split("@");
|
||||
key = keys[0];
|
||||
code = keys[1];
|
||||
pwd = keys[1];
|
||||
}
|
||||
|
||||
PanDomainTemplate panDomainTemplate = PanDomainTemplate
|
||||
.fromShortName(type)
|
||||
.generateShareLink(key)
|
||||
.setShareLinkInfoPwd(code);
|
||||
|
||||
cacheService.getAndSaveCachedShareLink(panDomainTemplate)
|
||||
cacheService.getCachedByShareKeyAndPwd(type, key, pwd)
|
||||
.onSuccess(res -> ResponseUtil.redirect(
|
||||
response.putHeader("nfd-cache-hit", res.getCacheHit().toString())
|
||||
.putHeader("nfd-cache-expires", res.getExpires()),
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package cn.qaiu.lz.web.model;
|
||||
|
||||
import cn.qaiu.db.ddl.Length;
|
||||
import cn.qaiu.db.ddl.Table;
|
||||
import cn.qaiu.lz.common.ToJson;
|
||||
import io.vertx.codegen.annotations.DataObject;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author <a href="https://qaiu.top">QAIU</a>
|
||||
* @date 2024/9/11 16:06
|
||||
*/
|
||||
@Table(value = "api_statistics_info", keyFields = "share_key")
|
||||
@Data
|
||||
@DataObject
|
||||
@NoArgsConstructor
|
||||
public class ApiStatisticsInfo implements ToJson {
|
||||
|
||||
/**
|
||||
* pan type 单独拿出来便于统计.
|
||||
*/
|
||||
@Length(varcharSize = 4)
|
||||
private String panType;
|
||||
|
||||
/**
|
||||
* 分享key type:key
|
||||
*/
|
||||
@Length(varcharSize = 4096)
|
||||
private String shareKey;
|
||||
|
||||
/**
|
||||
* 命中缓存次数
|
||||
*/
|
||||
private Integer cacheHitTotal;
|
||||
|
||||
/**
|
||||
* api解析次数
|
||||
*/
|
||||
private Integer apiParserTotal;
|
||||
|
||||
/**
|
||||
* 更新时间戳
|
||||
*/
|
||||
private Long updateTs;
|
||||
|
||||
// 使用 JsonObject 构造
|
||||
public ApiStatisticsInfo(JsonObject json) {
|
||||
if (json.containsKey("panType")) {
|
||||
this.setPanType(json.getString("panType"));
|
||||
}
|
||||
if (json.containsKey("shareKey")) {
|
||||
this.setShareKey(json.getString("shareKey"));
|
||||
}
|
||||
if (json.containsKey("cacheHitTotal")) {
|
||||
this.setCacheHitTotal(json.getInteger("cacheHitTotal"));
|
||||
}
|
||||
if (json.containsKey("apiParserTotal")) {
|
||||
this.setApiParserTotal(json.getInteger("apiParserTotal"));
|
||||
}
|
||||
if (json.containsKey("updateTs")) {
|
||||
this.setUpdateTs(json.getLong("updateTs"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import lombok.NoArgsConstructor;
|
||||
public class CacheLinkInfo implements ToJson {
|
||||
|
||||
/**
|
||||
* 缓存key: type@ShareKey; e.g. lz@xxxx
|
||||
* 缓存key: type:ShareKey; e.g. lz:xxxx
|
||||
*/
|
||||
@Length(varcharSize = 4096)
|
||||
private String shareKey;
|
||||
@@ -51,6 +51,20 @@ public class CacheLinkInfo implements ToJson {
|
||||
|
||||
// 使用 JsonObject 构造
|
||||
public CacheLinkInfo(JsonObject json) {
|
||||
CacheLinkInfoConverter.fromJson(json, this);
|
||||
if (json.containsKey("shareKey")) {
|
||||
this.setShareKey(json.getString("shareKey"));
|
||||
}
|
||||
if (json.containsKey("directLink")) {
|
||||
this.setDirectLink(json.getString("directLink"));
|
||||
}
|
||||
if (json.containsKey("expires")) {
|
||||
this.setExpires(json.getString("expires"));
|
||||
}
|
||||
if (json.containsKey("expiration")) {
|
||||
this.setExpiration(json.getLong("expiration"));
|
||||
}
|
||||
this.setCacheHit(json.getBoolean("cacheHit", false));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package cn.qaiu.lz.web.model;
|
||||
|
||||
import io.vertx.core.json.JsonObject;
|
||||
|
||||
// CacheLinkInfoConverter.java
|
||||
public class CacheLinkInfoConverter {
|
||||
|
||||
public static void fromJson(JsonObject json, CacheLinkInfo obj) {
|
||||
if (json.containsKey("shareKey")) {
|
||||
obj.setShareKey(json.getString("shareKey"));
|
||||
}
|
||||
if (json.containsKey("directLink")) {
|
||||
obj.setDirectLink(json.getString("directLink"));
|
||||
}
|
||||
if (json.containsKey("expires")) {
|
||||
obj.setExpires(json.getString("expires"));
|
||||
}
|
||||
if (json.containsKey("expiration")) {
|
||||
obj.setExpiration(json.getLong("expiration"));
|
||||
}
|
||||
obj.setCacheHit(json.getBoolean("cacheHit", false));
|
||||
}
|
||||
}
|
||||
@@ -10,14 +10,14 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
@DataObject
|
||||
public class StatisticsInfo implements ToJson {
|
||||
Integer fail;
|
||||
Integer success;
|
||||
Integer parserTotal;
|
||||
Integer cacheTotal;
|
||||
Integer total;
|
||||
|
||||
|
||||
public StatisticsInfo(JsonObject jsonObject) {
|
||||
this.fail = jsonObject.getInteger("fail");
|
||||
this.success = jsonObject.getInteger("success");
|
||||
this.parserTotal = jsonObject.getInteger("parserTotal");
|
||||
this.cacheTotal = jsonObject.getInteger("cacheTotal");
|
||||
this.total = jsonObject.getInteger("total");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package cn.qaiu.lz.web.service;
|
||||
|
||||
import cn.qaiu.lz.web.model.CacheLinkInfo;
|
||||
import cn.qaiu.parser.PanDomainTemplate;
|
||||
import cn.qaiu.vx.core.base.BaseAsyncService;
|
||||
import io.vertx.codegen.annotations.ProxyGen;
|
||||
import io.vertx.core.Future;
|
||||
@@ -13,5 +12,7 @@ import io.vertx.core.Future;
|
||||
@ProxyGen
|
||||
public interface CacheService extends BaseAsyncService {
|
||||
|
||||
Future<CacheLinkInfo> getAndSaveCachedShareLink(PanDomainTemplate shareLinkInfo);
|
||||
Future<CacheLinkInfo> getCachedByShareKeyAndPwd(String type, String shareKey, String pwd);
|
||||
|
||||
Future<CacheLinkInfo> getCachedByShareUrlAndPwd(String shareUrl, String pwd);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import cn.qaiu.lz.common.cache.CacheConfigLoader;
|
||||
import cn.qaiu.lz.common.cache.CacheManager;
|
||||
import cn.qaiu.lz.web.model.CacheLinkInfo;
|
||||
import cn.qaiu.lz.web.service.CacheService;
|
||||
import cn.qaiu.parser.PanDomainTemplate;
|
||||
import cn.qaiu.parser.ParserCreate;
|
||||
import cn.qaiu.vx.core.annotaions.Service;
|
||||
import io.vertx.core.Future;
|
||||
import io.vertx.core.Promise;
|
||||
@@ -19,21 +19,22 @@ public class CacheServiceImpl implements CacheService {
|
||||
|
||||
private final CacheManager cacheManager = new CacheManager();
|
||||
|
||||
@Override
|
||||
public Future<CacheLinkInfo> getAndSaveCachedShareLink(PanDomainTemplate template) {
|
||||
private Future<CacheLinkInfo> getAndSaveCachedShareLink(ParserCreate parserCreate) {
|
||||
Promise<CacheLinkInfo> promise = Promise.promise();
|
||||
|
||||
// 构建组合的缓存key
|
||||
ShareLinkInfo shareLinkInfo = template.getShareLinkInfo();
|
||||
ShareLinkInfo shareLinkInfo = parserCreate.getShareLinkInfo();
|
||||
String cacheKey = generateCacheKey(shareLinkInfo.getType(), shareLinkInfo.getShareKey());
|
||||
// 尝试从缓存中获取
|
||||
cacheManager.get(cacheKey).onSuccess(result -> {
|
||||
// 判断是否已过期
|
||||
// 未命中或者过期
|
||||
if (!result.getCacheHit() || result.getExpiration() < System.currentTimeMillis()) {
|
||||
template.createTool().parse().onSuccess(redirectUrl -> {
|
||||
// parse
|
||||
result.setCacheHit(false);
|
||||
result.setExpiration(0L);
|
||||
parserCreate.createTool().parse().onSuccess(redirectUrl -> {
|
||||
long expires = System.currentTimeMillis() +
|
||||
CacheConfigLoader.getDuration(shareLinkInfo.getType()) * 60 * 1000;
|
||||
CacheConfigLoader.getDuration(shareLinkInfo.getType()) * 60 * 1000L;
|
||||
result.setDirectLink(redirectUrl);
|
||||
// result.setExpires(generateDate(expires));
|
||||
promise.complete(result);
|
||||
@@ -45,10 +46,12 @@ public class CacheServiceImpl implements CacheService {
|
||||
"shareKey", cacheKey
|
||||
));
|
||||
cacheManager.cacheShareLink(cacheLinkInfo).onFailure(Throwable::printStackTrace);
|
||||
cacheManager.updateTotalByParser(cacheKey).onFailure(Throwable::printStackTrace);
|
||||
}).onFailure(promise::fail);
|
||||
} else {
|
||||
result.setExpires(generateDate(result.getExpiration()));
|
||||
promise.complete(result);
|
||||
cacheManager.updateTotalByCached(cacheKey).onFailure(Throwable::printStackTrace);
|
||||
}
|
||||
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
|
||||
return promise.future();
|
||||
@@ -62,4 +65,16 @@ public class CacheServiceImpl implements CacheService {
|
||||
private String generateDate(Long ts) {
|
||||
return DateFormatUtils.format(new Date(ts), "yyyy-MM-dd hh:mm:ss");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<CacheLinkInfo> getCachedByShareKeyAndPwd(String type, String shareKey, String pwd) {
|
||||
ParserCreate parserCreate = ParserCreate.fromType(type).shareKey(shareKey).setShareLinkInfoPwd(pwd);
|
||||
return getAndSaveCachedShareLink(parserCreate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<CacheLinkInfo> getCachedByShareUrlAndPwd(String shareUrl, String pwd) {
|
||||
ParserCreate parserCreate = ParserCreate.fromShareUrl(shareUrl).setShareLinkInfoPwd(pwd);
|
||||
return getAndSaveCachedShareLink(parserCreate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,10 +48,9 @@ public class DbServiceImpl implements DbService {
|
||||
JDBCPool client = JDBCPoolInit.instance().getPool();
|
||||
Promise<StatisticsInfo> promise = Promise.promise();
|
||||
String sql = """
|
||||
select COUNT(CASE "code" WHEN 500 THEN "code" END ) "fail",
|
||||
COUNT(CASE "code" WHEN 200 THEN "code" END ) "success",
|
||||
count(1) "total"
|
||||
from "t_parser_log_info"
|
||||
select sum(api_parser_total) parserTotal,sum("cache_hit_total") cacheTotal,
|
||||
sum(api_parser_total) + sum("cache_hit_total") total
|
||||
from "api_statistics_info";
|
||||
""";
|
||||
SqlTemplate.forQuery(client, sql).mapTo(StatisticsInfo.class).execute(new HashMap<>()).onSuccess(row -> {
|
||||
StatisticsInfo info;
|
||||
|
||||
Reference in New Issue
Block a user