Authored by hugufei

Merge branch 'master' into 6.2

... ... @@ -32,6 +32,10 @@ public class PersionalRateLimitAspect {
@Around("@annotation(com.yoho.search.common.downgrade.persional.PersionalRateLimit)")
public Object persionalRateLimit(ProceedingJoinPoint pjp) throws Throwable {
try {
//限流是否打开
if(!searchDynamicConfigService.isPersionalRateLimitOpen()){
return pjp.proceed();
}
MethodSignature signature = (MethodSignature) pjp.getSignature();
PersionalRateLimit rersionalRateLimit = signature.getMethod().getAnnotation(PersionalRateLimit.class);
String rateLimitName = this.getPersionalRateLimitName(rersionalRateLimit, pjp);
... ... @@ -78,7 +82,6 @@ public class PersionalRateLimitAspect {
}
PersionalRateLimitConfig limitConfig = searchDynamicConfigService.getPersionalRateLimitConfig(rateLimitName,rateLimit);
if (persionalRateLimitService.isPersionalRateLimit(rateLimitName, limitConfig)) {
DOWNGRADE.error("PersionalRateLimit happen ,rateLimitName is [{}],rateLimit is [{}]", rateLimitName, limitConfig.toLogInfo());
yohoHttpServletRequestWrapper.addParams("uid", new String[] { "0" });
return true;
}
... ... @@ -100,7 +103,6 @@ public class PersionalRateLimitAspect {
}
PersionalRateLimitConfig limitConfig = searchDynamicConfigService.getPersionalRateLimitConfig(rateLimitName,rateLimit);
if (persionalRateLimitService.isPersionalRateLimit(rateLimitName, limitConfig)) {
DOWNGRADE.error("PersionalRateLimit happen ,rateLimitName is [{}],rateLimit is [{}]", rateLimitName, limitConfig.toLogInfo());
map.put("uid", 0);
return true;
}
... ...
... ... @@ -2,6 +2,8 @@ package com.yoho.search.common.downgrade.persional;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
... ... @@ -11,6 +13,8 @@ import com.yoho.search.service.base.SearchDynamicConfigService;
@Service
public class PersionalRateLimitService {
private static final Logger DOWNGRADE = LoggerFactory.getLogger("DOWNGRADE");
@Autowired
private SearchRedis searchRedis;
@Autowired
... ... @@ -22,14 +26,25 @@ public class PersionalRateLimitService {
private boolean isRateLimit(String rateLimitName, PersionalRateLimitConfig limitConfig) {
String redisKey = "yohosearch:rateLimit:" + rateLimitName;
if (!searchRedis.searchRedisTemplate.hasKey(redisKey)) {
// 如果已经被初始化过, 则不用再初始化, 因为其他线程可能已经进行了 increase, 所以必须使用 setIfAbsent
searchRedis.searchValueOperations.setIfAbsent(redisKey, "0");
// 设置有效期, redis所有的key, 必须设置有效期
searchRedis.searchRedisTemplate.longExpire(redisKey, limitConfig.getSecond(), TimeUnit.SECONDS);
try {
long count = searchRedis.searchValueOperations.increment(redisKey, 1).intValue();
// 第一次得到1时,设置过期时间
if (count == 1) {
searchRedis.searchRedisTemplate.longExpire(redisKey, limitConfig.getSecond(), TimeUnit.SECONDS);
}
if(count > limitConfig.getLimit()){
DOWNGRADE.error("PersionalRateLimit happen ,rateLimitName is [{}], redisKey is [{}] ,count is[{}], limitConfig is [{}]", rateLimitName, redisKey, count, limitConfig.toLogInfo());
return true;
}
return false;
} catch (Exception e) {
DOWNGRADE.error(e.getMessage(), e);
try {
searchRedis.searchRedisTemplate.delete(redisKey);
} catch (Exception e2) {
DOWNGRADE.error(e2.getMessage(), e2);
}
return false;
}
// 原子性对值修改delta数值
return searchRedis.searchValueOperations.increment(redisKey, 1).intValue() > limitConfig.getLimit();
}
}
... ...
... ... @@ -199,10 +199,15 @@ public class SearchDynamicConfigService {
return configReader.getBoolean("search.sortpage.recall.use_global_brand", false);
}
/**
* 个性化限流开关
*/
public boolean isPersionalRateLimitOpen() {
return configReader.getBoolean("search.persional.rateLimit.open", true);
}
/**
* 个性化降级配置
* 个性化限流配置
*/
public PersionalRateLimitConfig getPersionalRateLimitConfig(String rateLimitName,PersionalRateLimit persionalRateLimit){
try {
... ... @@ -215,4 +220,6 @@ public class SearchDynamicConfigService {
return new PersionalRateLimitConfig(200,10);
}
}
}
... ...
... ... @@ -134,6 +134,7 @@ public class SortRecallSceneService extends AbstractRecallService {
// 3)填充变价计划,并做品牌打散
begin = System.currentTimeMillis();
List<Map<String, Object>> product_list = productIndexBaseService.getProductListWithPricePlan(recallProductInfoList.getProductInfoList());
product_list = productListSortService.sortProductList(product_list, paramMap);
super.doLogInfo("[func8=getProductListWithPricePlan][cost={}ms]", System.currentTimeMillis() - begin);
// 4)构造返回结果
... ... @@ -232,7 +233,7 @@ public class SortRecallSceneService extends AbstractRecallService {
// 3、构造sort
List<SortBuilder<?>> sortBuilders = new ArrayList<SortBuilder<?>>();
sortBuilders.add(SortBuilders.fieldSort(ProductIndexEsField.salesNum).order(SortOrder.DESC));
sortBuilders.add(SortBuilders.fieldSort(ProductIndexEsField.sevendayMoney).order(SortOrder.DESC));
sortBuilders.add(SortBuilders.fieldSort(ProductIndexEsField.id).order(SortOrder.DESC));
searchParam.setSortBuilders(sortBuilders);
... ... @@ -354,12 +355,12 @@ public class SortRecallSceneService extends AbstractRecallService {
long begin = System.currentTimeMillis();
if (searchDynamicConfigService.isSortPageRecallUseGlobalBrand()) {
brandIds = this.getUserGlobalBrandIds(paramMap);
super.doLogInfo("[func0=getUserGlobalBrandIds][cost={}ms],brandIds is [{}] ]", System.currentTimeMillis() - begin, brandIds);
super.doLogInfo("[func0=getUserGlobalBrandIds][cost={}ms],brandIds is {}]", System.currentTimeMillis() - begin, JSON.toJSONString(brandIds));
} else {
brandIds = this.getUserLikeBrandIds(paramMap);
super.doLogInfo("[func0=getUserLikeBrandIds][cost={}ms],brandIds is [{}] ]", System.currentTimeMillis() - begin, brandIds);
super.doLogInfo("[func0=getUserLikeBrandIds][cost={}ms],brandIds is {}]", System.currentTimeMillis() - begin, JSON.toJSONString(brandIds));
}
// 1、支持firstProductSkn的召回
recallStrategy.add(new FirstProductSknStrategy(1, this.getFirstProductSkns(paramMap)));
// 2、支持直通车的召回-随机召回
... ... @@ -369,11 +370,11 @@ public class SortRecallSceneService extends AbstractRecallService {
// 4、新开店铺商品召回-随机召回
recallStrategy.add(new NewShopStrategy(2));
// 5、支持新上架的召回-有new标签的
recallStrategy.add(new NewShelveStrategy(brandIds, 10));
recallStrategy.add(new NewShelveStrategy(brandIds, 20));
// 6、支持新降价的召回-两天内实际降过价的
recallStrategy.add(new NewReducePriceStrategy(brandIds, 10));
recallStrategy.add(new NewReducePriceStrategy(brandIds, 20));
// 7、支持新开促销的召回-5种促销类型
recallStrategy.add(new NewPromotionStrategy(brandIds, 10));
recallStrategy.add(new NewPromotionStrategy(brandIds, 20));
// 8、支持兜底的召回-人气排序
recallStrategy.add(new CommonStrategy(pageSize));
return recallStrategy;
... ... @@ -412,14 +413,24 @@ public class SortRecallSceneService extends AbstractRecallService {
@Override
protected RecallResult doCarefulRank(Map<String, String> paramMap, RecallResult recallResult) {
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
// 1、获取productList
List<Map<String, Object>> productList = recallResult.getProductList();
// 2、精排
Collections.shuffle(productList);
// 3、TODO 品牌打散
// 2、各召回策略随机打散【除兜底的】
Iterator<Map<String, Object>> iterator = productList.iterator();
while (iterator.hasNext()) {
Map<String, Object> product = iterator.next();
if (!product.get("recallType").equals(RecallType.COMMON)) {
results.add(product);
iterator.remove();
}
}
Collections.shuffle(results);
// 3、加入剩余商品
results.addAll(productList);
// 4、回设productList
recallResult.setProductList(productList);
recallResult.setProductList(results);
return recallResult;
}
... ...
... ... @@ -38,42 +38,44 @@ search.suggestion.tips.conversion.open=true
#recall
search.sortpage.recall.open=true
search.sortpage.recall.use_global_brand=false
search.sortpage.recall.uid.mantissa=5
search.sortpage.recall.uid.mantissa=0,1,2,3,4,5,6,7,8,9
#rateLimit
search.persional.rateLimit.brand.productList=100:2
search.persional.rateLimit.open=true
search.persional.rateLimit.brand.productList=200:2
search.persional.rateLimit.brand.aggregations=100:2
search.persional.rateLimit.breakSize.productList=100:2
search.persional.rateLimit.breakSize.productList=200:2
search.persional.rateLimit.breakSize.aggregations=100:2
search.persional.rateLimit.common.productList=100:2
search.persional.rateLimit.common.productList=200:2
search.persional.rateLimit.common.aggregations=100:2
search.persional.rateLimit.coupon.productList=100:2
search.persional.rateLimit.coupon.productList=200:2
search.persional.rateLimit.coupon.aggregations=100:2
search.persional.rateLimit.fuzzy.productList=100:2
search.persional.rateLimit.fuzzy.productList=200:2
search.persional.rateLimit.fuzzy.aggregations=100:2
search.persional.rateLimit.newArrival.productList=100:2
search.persional.rateLimit.newArrival.productList=200:2
search.persional.rateLimit.newArrival.aggregations=100:2
search.persional.rateLimit.pool.productList=100:2
search.persional.rateLimit.pool.productList=200:2
search.persional.rateLimit.pool.aggregations=100:2
search.persional.rateLimit.promotion.productList=100:2
search.persional.rateLimit.promotion.productList=200:2
search.persional.rateLimit.promotion.aggregations=100:2
search.persional.rateLimit.reducePrice.productList=100:2
search.persional.rateLimit.reducePrice.productList=200:2
search.persional.rateLimit.shop.productList=100:2
search.persional.rateLimit.shop.productList=200:2
search.persional.rateLimit.shop.aggregations=100:2
search.persional.rateLimit.sort.productList=100:2
search.persional.rateLimit.sort.productList=200:2
search.persional.rateLimit.sort.aggregations=100:2
search.persional.rateLimit.zq.productList=100:2
search.persional.rateLimit.zq.productList=200:2
search.persional.rateLimit.zq.aggregations=100:2
search.persional.rateLimit.group_brands=100:2
... ...