diff --git a/renren-admin/src/main/java/io/renren/modules/gateway/controller/HibrianGatewayController.java b/renren-admin/src/main/java/io/renren/modules/gateway/controller/HibrianGatewayController.java new file mode 100644 index 00000000..b0be8c04 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/gateway/controller/HibrianGatewayController.java @@ -0,0 +1,110 @@ +package io.renren.modules.gateway.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.modules.gateway.service.HibrianGatewayService; +import io.renren.modules.monitor.entity.Result; +import io.renren.modules.resource.dao.ResourceDao; +import io.renren.modules.resource.entity.ResourceEntity; +import io.renren.modules.sys.dao.SysDeptDao; +import io.renren.modules.sys.entity.SysDeptEntity; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.log4j.Log4j2; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.*; + +/** + * @Auther:lizhicheng2@hisense.com + * @date:2022/9/8 + * @des + */ +@RestController +@Api(tags = "云脑群网关统计") +@Log4j2 +@RequestMapping("hibrian-gateway") +public class HibrianGatewayController { + + @Autowired + private ResourceDao resourceDao; + + @Autowired + private HibrianGatewayService hibrianGatewayService; + + @Autowired + private SysDeptDao sysDeptDao; + + @GetMapping("/queryGroupCount") + @ApiOperation("查询总api数量") + public Result queryGroupCount() { + LambdaQueryWrapper queryWrapper = new QueryWrapper().lambda(); + queryWrapper.isNotNull(ResourceEntity::getGroupId).eq(ResourceEntity::getDelFlag, 0); + Integer selectCount = resourceDao.selectCount(queryWrapper); + return Result.success(selectCount); + } + + @GetMapping("/getCallCount") + @ApiOperation("查询api调用总量") + public Result getCallCount() { + Long callCount = hibrianGatewayService.getCallCount(); + return Result.success(callCount); + } + + @GetMapping("/getSuccessCallCount") + @ApiOperation("查询api调用成功总量") + public Result getSuccessCallCount() { + Long currentTime = System.currentTimeMillis() / 1000; + ResponseEntity entity = hibrianGatewayService.postQuery("sum(apigateway_http_status{code=~\"^2..\"})", currentTime.toString()); + HashMap body = entity.getBody(); + HashMap data = (HashMap) body.get("data"); + if (data != null) { + List result = (List) data.get("result"); + if (result.size() == 1) { + HashMap map = result.get(0); + List value = (List) map.get("value"); + if (value.size() == 2) { + String count = (String) value.get(1); + long currentCount = Long.parseLong(count); + return Result.success(currentCount); + } + } + } + return Result.error("数据异常"); + } + + @GetMapping("/queryGroupByDeptInRange") + @ApiOperation("统计数据按部门显示趋势") + public Result queryGroupByDeptInRange(String query, String start, String end, String step){ + ResponseEntity entity = hibrianGatewayService.getQueryRange(query, start, end, step); + HashMap body = entity.getBody(); + HashMap data = (HashMap) body.get("data"); + if (data != null){ + List result = (List) data.get("result"); + ArrayList results = new ArrayList<>(result.size()); + for (HashMap hashMap : result) { + Map metric = (Map) hashMap.get("metric"); + if (metric != null && metric.get("deptInfo") != null){ + try{ + Long filterId = Long.valueOf((String) metric.get("deptInfo")); + SysDeptEntity sysDeptEntity = sysDeptDao.selectById(filterId); + if (sysDeptEntity != null && StringUtils.isNotBlank(sysDeptEntity.getName())){ + metric.put("name", sysDeptEntity.getName()); + results.add(hashMap); + } + }catch (Exception e){ + log.warn("数据异常忽略", e); + } + } + } + return Result.success(results); + } + + return Result.success(Collections.emptyList()); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/gateway/entity/ApiCountHistoryEntity.java b/renren-admin/src/main/java/io/renren/modules/gateway/entity/ApiCountHistoryEntity.java index 8a1a8fe9..82e71e48 100644 --- a/renren-admin/src/main/java/io/renren/modules/gateway/entity/ApiCountHistoryEntity.java +++ b/renren-admin/src/main/java/io/renren/modules/gateway/entity/ApiCountHistoryEntity.java @@ -1,9 +1,6 @@ package io.renren.modules.gateway.entity; -import com.baomidou.mybatisplus.annotation.FieldFill; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.*; import io.renren.common.entity.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -27,7 +24,7 @@ import java.util.Date; @TableName(value = "t_api_count_history", autoResultMap = true) public class ApiCountHistoryEntity implements Serializable { - @TableId + @TableId(type = IdType.AUTO) private Long id; diff --git a/renren-admin/src/main/java/io/renren/modules/gateway/service/HibrianGatewayService.java b/renren-admin/src/main/java/io/renren/modules/gateway/service/HibrianGatewayService.java new file mode 100644 index 00000000..be9e54b8 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/gateway/service/HibrianGatewayService.java @@ -0,0 +1,144 @@ +package io.renren.modules.gateway.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.modules.gateway.dao.ApiCountHistoryDao; +import io.renren.modules.gateway.entity.ApiCountHistoryEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.PostConstruct; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * @Auther:lizhicheng2@hisense.com + * @date:2022/9/8 + * @des + */ +@Service +public class HibrianGatewayService { + + @Value("${hisense.gateway.sync-enabled}") + private Boolean enableSync; + + @Value("${hisense.gateway.name}") + private String gatewayName; + + @Value("${hisense.gateway.dp-url}") + private String gatewayDomain; + + @Autowired + private ApiCountHistoryDao apiCountHistoryDao; + + @Autowired + private RestTemplate restTemplate; + + @PostConstruct + public void init() { + if (enableSync && "云脑群网关".equals(gatewayName)) { + ScheduledExecutorService service = Executors.newScheduledThreadPool(1); + service.scheduleAtFixedRate(() -> fetchCallCount(), 0, 60, TimeUnit.SECONDS); + } + } + + private void fetchCallCount() { + Long currentTime = System.currentTimeMillis() / 1000; + ResponseEntity entity = postQuery("sum(apigateway_http_status)", currentTime.toString()); + HashMap body = entity.getBody(); + HashMap data = (HashMap) body.get("data"); + if (data != null) { + List result = (List) data.get("result"); + if (result.size() == 1) { + HashMap map = result.get(0); + List value = (List) map.get("value"); + if (value.size() == 2) { + String count = (String) value.get(1); + long currentCount = Long.parseLong(count); + handleDataCompare(currentCount); + } + } + } + } + + /** + * 查询历史总数 + * @return + */ + public Long getCallCount(){ + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.orderByDesc(ApiCountHistoryEntity::getVersion) + .last("LIMIT 1"); + ApiCountHistoryEntity apiCountHistoryEntity = apiCountHistoryDao.selectOne(queryWrapper); + if (apiCountHistoryEntity != null) { + Long currentCount = apiCountHistoryEntity.getCurrentCount(); + QueryWrapper hisQueryWrapper = new QueryWrapper<>(); + hisQueryWrapper.select("sum(history_count) as history_count"); + ApiCountHistoryEntity historyEntity = apiCountHistoryDao.selectOne(hisQueryWrapper); + if (historyEntity != null) { + return historyEntity.getHistoryCount() + currentCount; + } + } + + return 0L; + } + + /** + ** 数据同步算法 + * * 数据库需要存两个值 1: 上一次来监控系统拉取的 "历史调用总数" A,每次拉取都覆盖 + * * 2. 第二个值:拉取"历史调用总数"A1后,跟存储的"上一次来监控系统拉取的 历史调用总数"A比较, + * * 如果新拉取的(A1)较小(代表了网关重启了),先把"上一次拉取的 历史调用总数"A存储起来, + * * 每次出现这种情况都存储一份,记做 B1,B2, ... Bn, 存储完之后使用A1的值覆盖A + * * 最终界面展示"历史调用总数"时,值的算法:B1 + B2 +... + Bn + A + * + * @param currentCount 网关那边当前的总数 + */ + public void handleDataCompare(Long currentCount) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.orderByDesc(ApiCountHistoryEntity::getVersion) + .last("LIMIT 1"); + ApiCountHistoryEntity apiCountHistoryEntity = apiCountHistoryDao.selectOne(queryWrapper); + if (apiCountHistoryEntity == null){ + apiCountHistoryEntity = new ApiCountHistoryEntity(); + apiCountHistoryEntity.setCurrentCount(currentCount); + apiCountHistoryEntity.setHistoryCount(0L); + apiCountHistoryEntity.setVersion(0L); + apiCountHistoryDao.insert(apiCountHistoryEntity); + }else if (currentCount < apiCountHistoryEntity.getCurrentCount()){ + //保存旧值 + apiCountHistoryEntity.setHistoryCount(apiCountHistoryEntity.getCurrentCount()); + apiCountHistoryEntity.setUpdateTime(new Date()); + apiCountHistoryDao.updateById(apiCountHistoryEntity); + //新增记录 + ApiCountHistoryEntity newHistoryEntity = new ApiCountHistoryEntity(); + newHistoryEntity.setCurrentCount(currentCount); + newHistoryEntity.setHistoryCount(0L); + newHistoryEntity.setVersion(apiCountHistoryEntity.getVersion() + 1); + apiCountHistoryDao.insert(newHistoryEntity); + }else if (currentCount > apiCountHistoryEntity.getCurrentCount()){//相等时没有必要更新 + apiCountHistoryEntity.setCurrentCount(currentCount); + apiCountHistoryDao.updateById(apiCountHistoryEntity); + } + } + + public ResponseEntity postQuery(String query, String time) { + String url = gatewayDomain + "/metrics/api/v1/query?query={query}" + "&time=" + time; + return restTemplate.getForEntity(url, HashMap.class, query); + } + + public ResponseEntity getQueryRange(String query, String start, String end, String step) { + String url = gatewayDomain + "/metrics/api/v1/query_range?query={query}" + + "&start=" + start + + "&end=" + end + + "&step=" + step; + return restTemplate.getForEntity(url, HashMap.class, query); + } + +} diff --git a/renren-admin/src/main/java/io/renren/modules/gateway/service/MonitorServiceV2.java b/renren-admin/src/main/java/io/renren/modules/gateway/service/MonitorServiceV2.java index 94adf0dc..a32c6241 100644 --- a/renren-admin/src/main/java/io/renren/modules/gateway/service/MonitorServiceV2.java +++ b/renren-admin/src/main/java/io/renren/modules/gateway/service/MonitorServiceV2.java @@ -24,6 +24,9 @@ public class MonitorServiceV2 { @Value("${hisense.gateway.dp-url}") private String gatewayDomain; + @Value("${hisense.gateway.name}") + private String gatewayName; + @Value("${hisense.gateway.sync-enabled}") private Boolean enableSync; @@ -35,7 +38,7 @@ public class MonitorServiceV2 { @PostConstruct public void init(){ - if (enableSync) { + if (enableSync && "聚好看网关".equals(gatewayName)) { ScheduledExecutorService service = Executors.newScheduledThreadPool(1); service.scheduleAtFixedRate(new Runnable() { @Override diff --git a/renren-admin/src/main/java/io/renren/modules/resource/service/impl/ResourceServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/resource/service/impl/ResourceServiceImpl.java index ddb86ebc..d5c7edf0 100644 --- a/renren-admin/src/main/java/io/renren/modules/resource/service/impl/ResourceServiceImpl.java +++ b/renren-admin/src/main/java/io/renren/modules/resource/service/impl/ResourceServiceImpl.java @@ -939,10 +939,15 @@ public class ResourceServiceImpl extends CrudServiceImpl resourceList = resourceDao.selectByDeptId(deptIds.get(0)); HashMap maxdeptMap = new HashMap<>(); maxdeptMap.put("resourceList", resourceList); - maxdeptMap.put("deptName", sysDeptDao.selectById(deptIds.get(0)).getName()); + maxdeptMap.put("deptName", deptName); maxdeptMap.put("deptId", deptIds.get(0)); resultMap.put("maxDept", maxdeptMap); List deptList = resourceDao.selectDeptCountList();