Commit 55339a3a authored by 于桐's avatar 于桐

Merge branch 'master' into deprecated-202103

* master:
  调整日志打印,增加耗时区间
  主从库分离时,不能在同一线程内切换,写操作出错
  将容易存在写操作的从库查询服务copy一份
  日志长度还原
  测试腾讯云环境从库查询
  增加返回日志结果长度
  用户分群数据上报
  sonar fix
  sonar fix
parents 2da1fa9c f67547da
......@@ -344,7 +344,7 @@
<dependency>
<groupId>cn.qg.ec.data-stream-sdk</groupId>
<artifactId>data-stream-sdk</artifactId>
<version>1.0.9-SNAPSHOT</version>
<version>1.1.12-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
......
......@@ -60,7 +60,8 @@ public class RedisLockAspect {
} else if (StringUtils.isNotBlank(annotation.key())) {
String keySPEL = annotation.key();
try {
if (keySPEL.startsWith("#this")) {//判断是否是spel表达式
String keyPrefix = "#this";
if (keySPEL.startsWith(keyPrefix)) {//判断是否是spel表达式
Expression expression = new SpelExpressionParser().parseExpression(keySPEL);
String value = expression.getValue(args, String.class);
lockKey = prefix.concat(":").concat(value);
......
......@@ -55,13 +55,23 @@ public class LogCallHttpAspect {
hasException = true;
throw e;
} finally {
Stopwatch stop = stopwatch.stop();
long elapsed = stop.elapsed(TimeUnit.MILLISECONDS);
long elapsed = stopwatch.stop().elapsed(TimeUnit.MILLISECONDS);
String resultStr = result == null ? "" : objectMapper.writeValueAsString(result);
resultStr = resultStr.length() < 500 ? resultStr : resultStr.substring(0, 500);
log.info("[httpRequestLog],url:[{}],remoteIP:[{}],args:[{}],duration:[{}],exception:[{}],result:[{}]",
request.getRequestURL(), remoteIP, args, elapsed, hasException, resultStr);
log.info("[httpRequestLog],url:[{}],duration:[{}],[耗时区间]{},remoteIP:[{}],args:[{}],exception:[{}],result:[{}]",
request.getRequestURL(), elapsed, slowlyTag(elapsed), remoteIP, args, hasException, resultStr);
}
return result;
}
private String slowlyTag(long elapsed) {
Long second = elapsed / 1000L;
String outTimeFormat = "[outTime_%s]";
StringBuffer sb = new StringBuffer();
// 3秒步长
for (int outTime = 3; outTime <= second; outTime ++) {
sb.append(String.format(outTimeFormat, outTime));
}
return sb.toString();
}
}
......@@ -470,7 +470,7 @@ public class UserController implements IBaseController {
result.put("avatar", userAttached.getAvatar());
result.put("nick", userAttached.getNick());
}
UserDetail userDetail = userDetailService.findByUserId(userId);
UserDetail userDetail = userDetailService.findSlaveByUserId(userId);
if (userDetail != null) {
result.put("name", userDetail.getName());
result.put("sex", Optional.ofNullable(userDetail.getGender()).orElse(cn.quantgroup.xyqb.model.Gender.UNKNOWN).ordinal() + "");
......
......@@ -59,6 +59,8 @@ import cn.quantgroup.xyqb.util.PasswordUtil;
import cn.quantgroup.xyqb.util.ValidationUtil;
import cn.quantgroup.xyqb.util.encrypt.Md5Util;
import cn.quantgroup.xyqb.validator.ChineseName;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.common.base.MoreObjects;
......@@ -444,7 +446,7 @@ public class InnerController implements IBaseController {
@RequestMapping("/user_detail/search/phone")
@ApiOperation(httpMethod = "POST", value = "查询用户详情")
public JsonResult findUserDetailByPhone(String phoneNo) {
UserDetail userDetail = userDetailService.findByPhoneNo(phoneNo);
UserDetail userDetail = userDetailService.findSlaveByPhoneNo(phoneNo);
if (userDetail != null) {
return JsonResult.buildSuccessResult(null, UserDetailRet.getUserDetail(userDetail));
}
......@@ -871,6 +873,7 @@ public class InnerController implements IBaseController {
}
Address address = addressService.findByUserId(user.getId());
if (!Objects.isNull(address)) {
log.info("[findUserAssociationModelByUser]获取用户地址address:{}", JSON.toJSONString(address));
bean.putAddressList(Collections.singletonList(address));
}
List<Contact> contacts = contactService.findByUserIdAndBizType(user.getId(), BizType.CASH, true);
......
......@@ -24,8 +24,8 @@ public class BlackHoleRegisteredEventListener implements ApplicationListener<Reg
private String routingKey;
@Resource
private RabbitTemplate registeredNotifyBlackHoleRabbitTemplate;
long [] templateIds = {8l,280l};
long [] templateIds_159913 = {433l,434l}; // 羊小咩小程序的渠道,合同内容不包含现金分期业务,如果这种情况较多可以考虑配置化
private long [] templateIds = {8L,280L};
private long [] templateIds_159913 = {433L,434L}; // 羊小咩小程序的渠道,合同内容不包含现金分期业务,如果这种情况较多可以考虑配置化
private static final Long YXM_CHANNEL = 159913L; // 羊小咩小程序的渠道(小程序_电商,小程序_VCC)
@Override
......@@ -37,7 +37,7 @@ public class BlackHoleRegisteredEventListener implements ApplicationListener<Reg
String dateStr = signDate.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
int day = signDate.getDayOfMonth();
// 信用钱包服务与隐私协议
long[] regTempIds = userRegisterParam.getRegisterFrom().equals(YXM_CHANNEL) ? templateIds_159913 : templateIds;
long[] regTempIds = YXM_CHANNEL.equals(userRegisterParam.getRegisterFrom()) ? templateIds_159913 : templateIds;
for (long id : regTempIds) {
JSONObject fields = new JSONObject();
fields.put("phoneNo", user.getPhoneNo());
......
package cn.quantgroup.xyqb.event;
import java.io.UnsupportedEncodingException;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import com.amazonaws.services.kinesis.producer.UserRecordResult;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import cn.qg.ec.kinesis.EnvironmentConfig;
import cn.qg.ec.kinesis.KinesisProducerClient;
import cn.qg.ec.model.user.base.UserBaseDetailEvent;
import cn.quantgroup.tech.util.TechEnvironment;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.exception.PushUserToLkbException;
import cn.quantgroup.xyqb.model.UserRegisterParam;
import cn.quantgroup.xyqb.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
/**
* 注册成功之后,用户分群数据上报
* http://confluence.quantgroup.cn/pages/viewpage.action?pageId=34832018
* http://confluence.quantgroup.cn/pages/viewpage.action?pageId=41784208
* http://confluence.quantgroup.cn/pages/viewpage.action?pageId=34818640
* @author yutong
*/
@Slf4j
@Component
public class KinesisRegisteredEventListener implements ApplicationListener<RegisterEvent> {
@Override
public void onApplicationEvent(RegisterEvent event) {
UserRegisterParam userRegisterParam = event.getUserRegisterParam();
User user = userRegisterParam.getUser();
log.info("[KinesisRegistered] 用户分群数据上报准备, userId:{}, registeredFrom:{}", user.getId(), user.getRegisteredFrom());
sendRecord(user);
}
private void sendRecord(User user) {
// EnvironmentConfig.DEV 环境变量配置
KinesisProducerClient kinesisProducerClient = new KinesisProducerClient(
TechEnvironment.isPro() ? EnvironmentConfig.PROD : EnvironmentConfig.DEV);
// 用户登录事件发送
// UserBaseDetailEvent regEvent = UserBaseDetailEvent
// .builder()
// .channel(1L)
// .hashPhoneNo("*********")
// .businessEventBaseInfo(BusinessEventBaseInfo
// .builder()
// .channel("***")
// .deviceId("***")
// .ip("***")
// .userUuid("***")
// .build())
// .subEventType(UserBaseDetailEvent.SubEventType.REGISTER)
// .build();
UserBaseDetailEvent regEvent = UserBaseDetailEvent
.builder()
.userId(String.valueOf(user.getId()))
.userUuid(user.getUuid())
.subEventType(UserBaseDetailEvent.SubEventType.REGISTER)
.build();
regEvent.setRegisterChannel(user.getRegisteredFrom().intValue());
regEvent.setRegisterTime(user.getCreatedAt().getTime());
try {
ListenableFuture<UserRecordResult> listenableFuture = kinesisProducerClient.SendRecord(regEvent);
Futures.addCallback(listenableFuture, Callback);
log.info("[KinesisRegistered] 用户分群数据上报发送, regEvent:{}", JsonUtil.toJson(regEvent));
} catch (UnsupportedEncodingException | JsonProcessingException e) {
log.error("[KinesisRegistered]用户分群数据上报出错, e:{}", e);
throw new PushUserToLkbException("用户分群数据上报出错");
}
}
// 异步响应结果 如果发送失败,发送方需要进行重试发送
FutureCallback<UserRecordResult> Callback = new FutureCallback<UserRecordResult>() {
@Override
public void onFailure(Throwable t) {
/* Analyze and respond to the failure */
log.error(t.getMessage(), t);
log.error("[KinesisRegistered] 用户分群数据上报失败, Throwable:{}", ExceptionUtils.getStackTrace(t));
}
@Override
public void onSuccess(UserRecordResult result) {
log.info("[KinesisRegistered] 用户分群数据上报成功, result:{}", result.toString());
}
};
}
......@@ -12,26 +12,18 @@ import cn.quantgroup.tech.util.TechEnvironment;
* @version:
*/
public class KinesisProducerClientFactory {
private KinesisProducerClientFactory() {
}
private KinesisProducerClientFactory() {
}
private static KinesisProducerClient client;
private static class KinesisProducerClientHolder {
private static final KinesisProducerClient client = new KinesisProducerClient(getConfig());
public static KinesisProducerClient getClient() {
if (null == client) {
synchronized (KinesisProducerClient.class) {
if (null == client) {
client = new KinesisProducerClient(getConfig());
}
}
}
return client;
}
private static EnvironmentConfig getConfig() {
return TechEnvironment.isPro() ? EnvironmentConfig.PROD : EnvironmentConfig.DEV;
}
}
private static EnvironmentConfig getConfig() {
if (!TechEnvironment.isPro()) {
return EnvironmentConfig.DEV;
}
return EnvironmentConfig.PROD;
}
}
public static KinesisProducerClient getClient() {
return KinesisProducerClientHolder.client;
}
}
\ No newline at end of file
......@@ -12,11 +12,14 @@ import java.util.List;
*/
public interface IUserDetailService {
UserDetail findByUserId(Long userId);
UserDetail findSlaveByUserId(Long userId);
UserDetail saveUserDetail(UserDetail userDetail) throws DataIntegrityViolationException;
UserDetail findByPhoneNo(String phoneNo);
UserDetail findSlaveByPhoneNo(String phoneNo);
void updateUserQq(Long userId, String qq);
void updateUserEmail(Long userId, String email);
......
......@@ -25,6 +25,8 @@ public interface IUserService {
User findByPhoneInDb(String phone);
User findSlaveByPhoneInDb(String phone);
User findByUuidInDb(String uuid);
/**
......
package cn.quantgroup.xyqb.service.user.impl;
import cn.quantgroup.tech.db.DSType;
import cn.quantgroup.tech.db.TargetDataSource;
import cn.quantgroup.xyqb.entity.UserAttached;
import cn.quantgroup.xyqb.repository.IUserAttachedRepository;
import cn.quantgroup.xyqb.service.user.UserCenterService;
......@@ -28,10 +30,11 @@ public class UserCenterServiceImpl implements UserCenterService {
private IUserAttachedRepository userAttachedRepository;
@Override
@TargetDataSource(type = DSType.SLAVE)//查询从库
// @Cacheable(value = "userAttachedCache", key = "'xyqbUserAttached' + #userId", unless = "#result == null", cacheManager = "cacheManager")
public UserAttached searchUserAttachedByUserId(long userId) {
return userAttachedRepository.findByUserId(userId);
}
}
@Override
public List<UserAttached> searchUserAttachedListByUserId(List<Long> userIds) {
......
package cn.quantgroup.xyqb.service.user.impl;
import cn.quantgroup.tech.db.DSType;
import cn.quantgroup.tech.db.TargetDataSource;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserDetail;
......@@ -59,6 +61,17 @@ public class UserDetailServiceImpl implements IUserDetailService {
userDetail.setEmail(AddressFilter.getEmail(userDetail.getPhoneNo(), userDetail.getEmail()));
return userDetail;
}
@Override
@TargetDataSource(type = DSType.SLAVE)//查询从库
public UserDetail findSlaveByUserId(Long userId) {
UserDetail userDetail = userDetailRepository.findByUserId(userId);
if (null == userDetail) {
return userDetail;
}
userDetail.setEmail(AddressFilter.getEmail(userDetail.getPhoneNo(), userDetail.getEmail()));
return userDetail;
}
@Override
public UserDetail saveUserDetail(UserDetail userDetail) throws DataIntegrityViolationException {
......@@ -77,6 +90,12 @@ public class UserDetailServiceImpl implements IUserDetailService {
return userDetailRepository.findByPhoneNo(phoneNo);
}
@Override
@TargetDataSource(type = DSType.SLAVE)//查询从库
public UserDetail findSlaveByPhoneNo(String phoneNo) {
return userDetailRepository.findByPhoneNo(phoneNo);
}
@Override
public void updateUserQq(Long userId, String qq) {
userDetailRepository.updateUserQq(qq, userId);
......
package cn.quantgroup.xyqb.service.user.impl;
import cn.quantgroup.tech.db.DSType;
import cn.quantgroup.tech.db.TargetDataSource;
import cn.quantgroup.user.enums.BizType;
import cn.quantgroup.user.enums.IncomeRangeEnum;
import cn.quantgroup.xyqb.Constants;
......@@ -100,6 +102,14 @@ public class UserServiceImpl implements IUserService, IBaseController {
}
@Override
@TargetDataSource(type = DSType.SLAVE)//查询从库
// @Cacheable(value = "usercache", key = "'xyqbuser' + #phone", unless = "#result == null", cacheManager = "cacheManager")
public User findSlaveByPhoneInDb(String phone) {
return userRepository.findByPhoneNo(phone);
}
@Override
@TargetDataSource(type = DSType.SLAVE)//查询从库
public Map<Long, String> findPhoneByIdsInDb(List<Long> userIds) {
if (CollectionUtils.isEmpty(userIds)) {
return Maps.newHashMap();
......@@ -261,7 +271,7 @@ public class UserServiceImpl implements IUserService, IBaseController {
List<UserHashMapping> userHashMappings = userHashMappingRepository.findByIdNoMd5AndIdNoMd5Short(md5Value, value);
if (!CollectionUtils.isEmpty(userHashMappings)) {
//如果多个只返回最新的
userHashMapping = userHashMappings.stream().max(Comparator.comparing(UserHashMapping::getId)).get();
userHashMapping = userHashMappings.stream().max(Comparator.comparing(UserHashMapping::getId)).orElse(null);
}
} else {
userHashMapping = null;
......
......@@ -221,8 +221,11 @@ public class RedisLock {
retryCount++;
if (timeout > 100) {
timeout -= 100; }
else
timeout = 1; {
else {
timeout = 1;
}
// TODO sonar检查,else语句缺少大括号发现问题,下面这个大括号什么鬼?
{
Thread.sleep(100); }
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment