Merge branch 'dev'
This commit is contained in:
commit
d04251da8c
|
@ -0,0 +1,10 @@
|
||||||
|
DROP TABLE IF EXISTS `t_api_count_history`;
|
||||||
|
CREATE TABLE `t_api_count_history` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`version` bigint COMMENT '数据版本号,从0递增',
|
||||||
|
`current_count`bigint COMMENT '当前总数,只有最新一条有效',
|
||||||
|
`history_count`bigint COMMENT '保存历史重启的数量',
|
||||||
|
`create_time` datetime NULL DEFAULT NULL,
|
||||||
|
`update_time` datetime NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
) ENGINE = InnoDB COMMENT = '网关历史调用总数';
|
|
@ -5,6 +5,7 @@ import cn.hutool.core.net.URLEncoder;
|
||||||
import cn.hutool.core.util.URLUtil;
|
import cn.hutool.core.util.URLUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import io.renren.modules.gateway.service.MonitorServiceV2;
|
||||||
import io.renren.modules.monitor.entity.Result;
|
import io.renren.modules.monitor.entity.Result;
|
||||||
import io.renren.modules.resource.dao.AttrDao;
|
import io.renren.modules.resource.dao.AttrDao;
|
||||||
import io.renren.modules.resource.dao.ResourceDao;
|
import io.renren.modules.resource.dao.ResourceDao;
|
||||||
|
@ -62,6 +63,9 @@ public class MonitorController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private SysDeptDao sysDeptDao;
|
private SysDeptDao sysDeptDao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MonitorServiceV2 monitorServiceV2;
|
||||||
|
|
||||||
// @RequestMapping("/metrics/**")
|
// @RequestMapping("/metrics/**")
|
||||||
void forward(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
void forward(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
//类似nginx匹配前缀
|
//类似nginx匹配前缀
|
||||||
|
@ -326,4 +330,11 @@ public class MonitorController {
|
||||||
return Result.success(selectCount);
|
return Result.success(selectCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/gateway-monitor/getCallCount")
|
||||||
|
@ApiOperation("查询总api调用总量")
|
||||||
|
public Result getCallCount(){
|
||||||
|
Long callCount = monitorServiceV2.getCallCount();
|
||||||
|
return Result.success(callCount);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package io.renren.modules.gateway.dao;
|
||||||
|
|
||||||
|
import io.renren.common.dao.BaseDao;
|
||||||
|
import io.renren.modules.gateway.entity.ApiCountHistoryEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface ApiCountHistoryDao extends BaseDao<ApiCountHistoryEntity> {
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
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 io.renren.common.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据同步算法
|
||||||
|
* 数据库需要存两个值 1: 上一次来监控系统拉取的 "历史调用总数" A,每次拉取都覆盖
|
||||||
|
* 2. 第二个值:拉取"历史调用总数"A1后,跟存储的"上一次来监控系统拉取的 历史调用总数"A比较,
|
||||||
|
* 如果新拉取的(A1)较小(代表了网关重启了),先把"上一次拉取的 历史调用总数"A存储起来,
|
||||||
|
* 每次出现这种情况都存储一份,记做 B1,B2, ... Bn, 存储完之后使用A1的值覆盖A
|
||||||
|
* 最终界面展示"历史调用总数"时,值的算法:B1 + B2 +... + Bn + A
|
||||||
|
*
|
||||||
|
* 实体类A对应currentCount,B对应historyCount
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@TableName(value = "t_api_count_history", autoResultMap = true)
|
||||||
|
public class ApiCountHistoryEntity implements Serializable {
|
||||||
|
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据版本递增
|
||||||
|
*/
|
||||||
|
private Long version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前数据量
|
||||||
|
*/
|
||||||
|
private Long currentCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 历史数据量
|
||||||
|
*/
|
||||||
|
private Long historyCount;
|
||||||
|
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
private Date updateTime;
|
||||||
|
}
|
|
@ -1,13 +1,22 @@
|
||||||
package io.renren.modules.gateway.service;
|
package io.renren.modules.gateway.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
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.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import javax.annotation.PostConstruct;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class MonitorServiceV2 {
|
public class MonitorServiceV2 {
|
||||||
|
@ -15,10 +24,29 @@ public class MonitorServiceV2 {
|
||||||
@Value("${hisense.gateway.url}")
|
@Value("${hisense.gateway.url}")
|
||||||
private String gatewayDomain;
|
private String gatewayDomain;
|
||||||
|
|
||||||
|
@Value("${hisense.gateway.sync-enabled}")
|
||||||
|
private Boolean enableSync;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RestTemplate restTemplate;
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
void fetchCallCount(){
|
@Autowired
|
||||||
|
private ApiCountHistoryDao apiCountHistoryDao;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init(){
|
||||||
|
if (enableSync) {
|
||||||
|
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
|
||||||
|
service.scheduleAtFixedRate(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
fetchCallCount();
|
||||||
|
}
|
||||||
|
}, 0, 60, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fetchCallCount(){
|
||||||
Long currentTime = System.currentTimeMillis() / 1000;
|
Long currentTime = System.currentTimeMillis() / 1000;
|
||||||
String query = "sum(apigateway_http_status)";
|
String query = "sum(apigateway_http_status)";
|
||||||
String url = gatewayDomain + "/juapi/metrics/api/v1/query?query={query}" + "&time=" + currentTime.toString();
|
String url = gatewayDomain + "/juapi/metrics/api/v1/query?query={query}" + "&time=" + currentTime.toString();
|
||||||
|
@ -29,7 +57,76 @@ public class MonitorServiceV2 {
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
List<HashMap> result = (List) data.get("result");
|
List<HashMap> result = (List) data.get("result");
|
||||||
if (result.size() == 1) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** 数据同步算法
|
||||||
|
* * 数据库需要存两个值 1: 上一次来监控系统拉取的 "历史调用总数" A,每次拉取都覆盖
|
||||||
|
* * 2. 第二个值:拉取"历史调用总数"A1后,跟存储的"上一次来监控系统拉取的 历史调用总数"A比较,
|
||||||
|
* * 如果新拉取的(A1)较小(代表了网关重启了),先把"上一次拉取的 历史调用总数"A存储起来,
|
||||||
|
* * 每次出现这种情况都存储一份,记做 B1,B2, ... Bn, 存储完之后使用A1的值覆盖A
|
||||||
|
* * 最终界面展示"历史调用总数"时,值的算法:B1 + B2 +... + Bn + A
|
||||||
|
*
|
||||||
|
* @param currentCount 网关那边当前的总数
|
||||||
|
*/
|
||||||
|
public void handleDataCompare(Long currentCount) {
|
||||||
|
LambdaQueryWrapper<ApiCountHistoryEntity> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询历史总数
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Long getCallCount(){
|
||||||
|
LambdaQueryWrapper<ApiCountHistoryEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.orderByDesc(ApiCountHistoryEntity::getVersion)
|
||||||
|
.last("LIMIT 1");
|
||||||
|
ApiCountHistoryEntity apiCountHistoryEntity = apiCountHistoryDao.selectOne(queryWrapper);
|
||||||
|
if (apiCountHistoryEntity != null) {
|
||||||
|
Long currentCount = apiCountHistoryEntity.getCurrentCount();
|
||||||
|
QueryWrapper<ApiCountHistoryEntity> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ census:
|
||||||
# 海信网关
|
# 海信网关
|
||||||
hisense:
|
hisense:
|
||||||
gateway:
|
gateway:
|
||||||
|
sync-enabled: false
|
||||||
url: http://devtest-security-app.hismarttv.com:8080
|
url: http://devtest-security-app.hismarttv.com:8080
|
||||||
# Tomcat
|
# Tomcat
|
||||||
server:
|
server:
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package io.renren;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.UUID;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import io.renren.modules.gateway.service.MonitorServiceV2;
|
||||||
|
import io.renren.modules.processForm.service.ApiGatewayService;
|
||||||
|
import io.renren.modules.resource.dao.ResourceDao;
|
||||||
|
import io.renren.modules.resource.entity.ResourceEntity;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
public class GatewaySyncServiceTest {
|
||||||
|
@Autowired
|
||||||
|
private MonitorServiceV2 monitorServiceV2;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void syncCount() {
|
||||||
|
|
||||||
|
Integer[] dataSet = {10, 11, 50, 30, 44, 2,44,9};
|
||||||
|
for (Integer count : dataSet) {
|
||||||
|
monitorServiceV2.handleDataCompare(Long.valueOf(count));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue