提交后端服务器信息查看

This commit is contained in:
nm_duanzhixin 2025-02-20 17:46:16 +08:00
parent 553638a078
commit 477c05ae31
15 changed files with 411 additions and 2 deletions

View File

@ -24,4 +24,6 @@ public interface StatisticsService {
Map<String, Object> getRunningCount();
Map<String, Object> getLogMonitoringOptions();
Map<String,Object> getInvokeNumToday(String id);
}

View File

@ -24,6 +24,9 @@ import javax.persistence.criteria.Root;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@ -143,6 +146,36 @@ public class StatisticsServiceImpl implements StatisticsService {
return res;
}
@Override
public Map<String, Object> getInvokeNumToday(String id) {
Map<String,Object> map = new HashMap<>();
List<Long> interfaceIds = interfaceManageRepository.getAllByExecuteInstanceId(id);
if(interfaceIds!=null && interfaceIds.size()!=0){
// 获取当天的开始时间和结束时间
LocalDateTime startTime = LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MIDNIGHT);
LocalDateTime endTime = LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MAX);
// 指定时区将LocalDateTime转换为ZonedDateTime
ZonedDateTime startZonedDateTime = startTime.atZone(ZoneId.systemDefault());
ZonedDateTime endZonedDateTime = endTime.atZone(ZoneId.systemDefault());
// 将ZonedDateTime转换为Date
Date startDate = Date.from(startZonedDateTime.toInstant());
Date endDate = Date.from(endZonedDateTime.toInstant());
List<String> interfaceIdsStr = new ArrayList<>();
for(Long interfaceId : interfaceIds){
interfaceIdsStr.add(interfaceId.toString());
}
Long count = callApiLogRepository.countByRequestStartTimeBetweenAndInterfaceIdIn(startDate,endDate,interfaceIdsStr);
map.put("data",count);
return map;
}else {
return null;
}
}
@Override
public Map<String, Object> getLogMonitoringInfo(Map<String, Object> conditionMap) {
Map<String, Object> res = new HashMap<>();

View File

@ -105,6 +105,10 @@ public class InterfaceManageDTO extends BaseEntity implements Serializable{
private Boolean isResponseFile;
private String executeInstanceId;
private String executeInstanceIdBack;
public InterfaceManageDTO(InterfaceManage dto) {
this.id = dto.getId();
this.interfaceName = dto.getInterfaceName();
@ -138,6 +142,8 @@ public class InterfaceManageDTO extends BaseEntity implements Serializable{
this.systemId = dto.getSystemId();
this.systemName = dto.getSystemName();
this.isResponseFile = dto.getIsResponseFile();
this.executeInstanceId = dto.getExecuteInstanceId();
this.executeInstanceIdBack = dto.getExecuteInstanceIdBack();
}
}

View File

@ -0,0 +1,30 @@
package net.risesoft.y9public.entity;
public class InstanceNum {
private Integer num;
private String instanceId;
public InstanceNum() {
}
public InstanceNum(Long num, String instanceId) {
this.num = num.intValue();
this.instanceId = instanceId;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getInstanceId() {
return instanceId;
}
public void setInstanceId(String instanceId) {
this.instanceId = instanceId;
}
}

View File

@ -156,6 +156,13 @@ public class InterfaceManage extends BaseEntity implements Serializable{
@Comment(value = "是否返回文件")
private Boolean isResponseFile;
@Column(name = "EXECUTE_INSTANCE_ID", columnDefinition = "varchar(500) default '' comment '执行端实例ID'")
@Comment(value = "执行实例ID")
private String executeInstanceId;
@Column(name = "EXECUTE_INSTANCE_ID_BACK", columnDefinition = "varchar(500) default '' comment '备选执行端实例ID'")
@Comment(value = "备用实例ID")
private String executeInstanceIdBack;
public InterfaceManage(InterfaceManageDTO dto) {
this.id = dto.getId();
@ -190,6 +197,8 @@ public class InterfaceManage extends BaseEntity implements Serializable{
this.systemId = dto.getSystemId();
this.systemName = dto.getSystemName();
this.isResponseFile = dto.getIsResponseFile();
this.executeInstanceId = dto.getExecuteInstanceId();
this.executeInstanceIdBack = dto.getExecuteInstanceIdBack();
}
}

View File

@ -6,6 +6,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import java.util.Date;
import java.util.List;
import java.util.Map;
@ -20,4 +21,6 @@ public interface CallApiLogRepository extends JpaRepository<CallApiRequestLogInf
@Query(value = "SELECT GROUP_CONCAT(DISTINCT APPLYSYSTEMNAME) as applySystemName,DEPTNAME as deptName" +
" from y9_call_api_request_log_info group by DEPTNAME" ,nativeQuery = true)
List<Map<String,Object>> getDataGroupByDeptName();
Long countByRequestStartTimeBetweenAndInterfaceIdIn(Date start, Date end, List<String> interfaceIds);
}

View File

@ -34,4 +34,7 @@ public interface InterfaceManageRepository extends JpaRepository<InterfaceManage
@Query(value="select count(*) from Y9_INTERFACE_MANAGE_INFO",nativeQuery = true)
long getAllCount();
@Query(value="select id from InterfaceManage where interfaceStatus='发布' and isDelete='N' and executeInstanceId =?1")
List<Long> getAllByExecuteInstanceId(String id);
}

View File

@ -161,6 +161,10 @@
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 通用产品版本只使用一个mysql数据库-->
<dependency>
<groupId>net.risesoft</groupId>

View File

@ -1,6 +1,8 @@
package net.risesoft.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import net.risesoft.model.user.UserInfo;
import net.risesoft.service.UseInterfaceService;
import net.risesoft.util.*;
@ -15,6 +17,8 @@ import net.risesoft.y9public.repository.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
@ -58,6 +62,11 @@ public class UseInterfaceServiceImpl implements UseInterfaceService {
private CallLogUtil calllogUtil;
@Autowired
private BlacklistingRepository blacklistingRepository;
@Qualifier("eurekaClient")
@Autowired
private EurekaClient eurekaClient;
@Value("${eureka.server-application}")
private String serviceName;
public static final String regx = "@-@";
@ -75,7 +84,34 @@ public class UseInterfaceServiceImpl implements UseInterfaceService {
Map<String, Object> body = new HashMap<>();
try {
InstanceInfo instanceInfo = null;
try {
instanceInfo = eurekaClient.getNextServerFromEureka(serviceName, false);
}catch (Exception e){
map.put("msg", "请求失败!未查询到实例");
logMap.put("status", "未查询到实例");
logMap.put("errMsg", "请求失败!未查询到实例");
logMap.put("code", "401");
return ResponseEntity.ok().body(map);
}
try {
if (instanceInfo == null || StringUtils.isBlank(instanceInfo.getInstanceId())) {
map.put("msg", "请求失败!未注册的实例");
logMap.put("status", "未注册的实例");
logMap.put("errMsg", "请求失败!未注册的实例");
logMap.put("code", "401");
return ResponseEntity.ok().body(map);
}
if(!InstanceInfo.InstanceStatus.UP.equals(instanceInfo.getStatus())){
map.put("msg", "请求失败!当前实例未在线");
logMap.put("status", "实例未在线");
logMap.put("errMsg", "请求失败!"+instanceInfo.getInstanceId()+"实例未在线");
logMap.put("code", "401");
return ResponseEntity.ok().body(map);
}
interfaceApply = interfaceApplyRepository.findDataByUserKey(id);
if (StringUtils.isBlank(interfaceApply.getIsEffective()) || "N".equals(interfaceApply.getIsEffective())) {
map.put("msg", "请求失败!申请信息已经过期请重新申请");
@ -124,6 +160,13 @@ public class UseInterfaceServiceImpl implements UseInterfaceService {
logMap.put("code", "501");
return ResponseEntity.ok().body(map);
}
if(!(instanceInfo.getInstanceId().equals(interfaceManage.getExecuteInstanceId()) || instanceInfo.getInstanceId().equals(interfaceManage.getExecuteInstanceIdBack()))){
map.put("msg", "请求失败!该接口未注册到当前实例");
logMap.put("status", "请求失败");
logMap.put("errMsg", "请求失败!该接口未注册到当前实例");
logMap.put("code", "401");
return ResponseEntity.ok().body(map);
}
InterfaceManageDTO interfaceManageDTO = new InterfaceManageDTO(interfaceManage);
//判断开启限流
if ("".equals(interfaceManageDTO.getIsLimit())) {

View File

@ -16,12 +16,21 @@ server:
tomcat:
uri-encoding: UTF-8
eureka:
server-application: "interfaceplatform" #eureka服务端服务名
client:
enabled: true # 启用Eureka客户端
service-url:
defaultZone: http://admin:123@localhost:7055/interfaceManager/eureka/ # Eureka服务器地址
fetch-registry: true # 是否从Eureka服务器获取注册信息
register-with-eureka: true # 是否注册自身到Eureka服务
management:
endpoints:
web:
exposure:
include: "*" # 暴露所有端点,或者你可以指定具体要暴露的端点名称,用逗号分隔
endpoint:
health:
show-details: always
spring:
application:
name: interfaceExecute
@ -183,7 +192,7 @@ y9:
allowBasicAuthentication: true
allowFormEncodedBodyParameter: true
allowUriQueryParameter: true
protectedUrlPatterns: /api/*
protectedUrlPatterns: /api/*,/actuator/*
opaque:
client-id: clientid
client-secret: secret

View File

@ -269,6 +269,39 @@ public class RestInterfaceManageController {
}
//获取注册接口数
@RequestMapping("/getRegisterNum")
@ResponseBody
@RiseLog(operationType = OperationTypeEnum.BROWSE, operationName = "获取执行端注册接口数量")
public Map<String, Object> getRegisterNum(String id) {
Map<String, Object> map = new HashMap<>();
List<InstanceNum> list = interfaceManageService.getRegisterNum(id);
if (list != null) {
map.put("status", "success");
} else {
map.put("status", "error");
}
map.put("code", "0");
map.put("data", list);
return map;
}
//根据接口id获取实例ip端口
@RequestMapping("/getIpPortByInterfaceId")
@ResponseBody
@RiseLog(operationType = OperationTypeEnum.BROWSE, operationName = "根据接口id获取实例ip端口")
public Map<String, Object> getIpPortByInterfaceId(String id) {
Map<String, Object> map = new HashMap<>();
Map<String,Object> data = interfaceManageService.getIpPortByInterfaceId(id);
if (data != null) {
map.put("status", "success");
} else {
map.put("status", "error");
}
map.put("code", "0");
map.put("data", data);
return map;
}
}

View File

@ -109,4 +109,21 @@ public class RestStatisticsController {
public Map<String, Object> getRealTimeLog(int page, int limit){
return statisticsService.getRealTimeLog(page, limit);
}
//获取今日调用次数
@RequestMapping("/getInvokeNumToday")
@ResponseBody
@RiseLog(operationType = OperationTypeEnum.BROWSE, operationName = "获取执行端今日调用接口数量")
public Map<String, Object> getInvokeNumToday(String id) {
Map<String, Object> map = new HashMap<>();
Map<String,Object> data = statisticsService.getInvokeNumToday(id);
if (data != null) {
map.put("status", "success");
} else {
map.put("status", "error");
}
map.put("code", "0");
map.put("data", data!=null?data.get("data"):0);
return map;
}
}

View File

@ -64,4 +64,8 @@ public interface InterfaceManageService {
//下载接口文档
void downLoadInterfaceFile(String sameId,String version,String fileName, HttpServletResponse response);
List<InstanceNum> getRegisterNum(String instanceId);
Map<String,Object> getIpPortByInterfaceId(String instanceId);
}

View File

@ -1,6 +1,7 @@
package net.risesoft.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import net.risesoft.enums.platform.ManagerLevelEnum;
@ -24,10 +25,16 @@ import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import javax.persistence.criteria.CriteriaBuilder;
@ -41,6 +48,7 @@ import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@ -65,6 +73,13 @@ public class InterfaceManageServiceImpl implements InterfaceManageService {
@Autowired
private AuthDictRepository authDictRepository;
@Value("${eureka.client.service-url.defaultZone}")
private String eurekaUrl;
@Value("${spring.eureka.token}")
private String token;
private final RestTemplate restTemplate = new RestTemplate();
@Override
public Page<InterfaceManageDTO> getInterfaceList(InterfaceManageDTO interfaceManageDTO) {
Specification<InterfaceManage> spec = new Specification<InterfaceManage>() {
@ -186,9 +201,60 @@ public class InterfaceManageServiceImpl implements InterfaceManageService {
interfaceManage.setPersonName(person.getName());
}
String base64Token = Base64.getEncoder().encodeToString(token.getBytes(StandardCharsets.UTF_8));
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic "+base64Token);
HttpEntity<String> entity = new HttpEntity<>(null, headers);
ResponseEntity<String> response = restTemplate.exchange(eurekaUrl+"apps", HttpMethod.GET, entity, String.class);
String jsonData = response.getBody();
HashMap apps = JSONArray.parseObject(jsonData,HashMap.class);
List<String> instanceIds = getInstanceIds(apps);
if(instanceIds.size()==0){
map.put("status", false);
map.put("errMsg","保存失败,实例已经下线");
return map;
}else {
Boolean isUp = false;
for(String instanceId : instanceIds){
if(instanceId.equals(interfaceManage.getExecuteInstanceId())){
isUp = true;
break;
}
}
if(!isUp){
map.put("status", false);
map.put("errMsg","实例已经下线");
return map;
}
List<InstanceNum> instances = interfaceManageRepository.getAllCountGroupByInstanceID();
int min = 100000;
String instanceId = "";
HashMap<String,Integer> instanceMap = new HashMap<>();
for(InstanceNum instance : instances){
instanceMap.put(instance.getInstanceId(),instance.getNum());
}
for(String id : instanceIds){
if(instanceMap.get(id)!=null){
try {
if(instanceMap.get(id)<min){
min = instanceMap.get(id);
instanceId = id;
}
}catch (Exception e){
}
}else {
instanceId = id;
break;
}
}
interfaceManage.setExecuteInstanceIdBack(instanceId);
}
InterfaceManage interfaceManage1 = interfaceManageRepository.save(interfaceManage);
if (interfaceManage1 == null) {
map.put("status", false);
map.put("errMsg","保存接口信息时失败");
} else {
map.put("id", interfaceManage1.getId());
map.put("status", true);
@ -370,7 +436,7 @@ public class InterfaceManageServiceImpl implements InterfaceManageService {
}
} else {
dataMap.put("status", false);
dataMap.put("msg", "新增失败");
dataMap.put("msg", "新增失败"+map.get("errMsg"));
}
} catch (Exception e) {
e.printStackTrace();
@ -914,6 +980,94 @@ public class InterfaceManageServiceImpl implements InterfaceManageService {
}
}
@Override
public List<InstanceNum> getRegisterNum(String instanceId) {
List<InstanceNum> list = new ArrayList<>();
if(StringUtils.isNotBlank(instanceId)){
List<InstanceNum> instances = interfaceManageRepository.getAllCountGroupByInstanceID();
InstanceNum instanceNum = null;
for(InstanceNum instance : instances){
if(instanceId.equals(instance.getInstanceId())){
instanceNum = instance;
}
}
if(instanceNum == null){
instanceNum = new InstanceNum();
instanceNum.setNum(0);
instanceNum.setInstanceId(instanceId);
}
list.add(instanceNum);
}else {
String base64Token = Base64.getEncoder().encodeToString(token.getBytes(StandardCharsets.UTF_8));
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic "+base64Token);
HttpEntity<String> entity = new HttpEntity<>(null, headers);
ResponseEntity<String> response = restTemplate.exchange(eurekaUrl+"apps", HttpMethod.GET, entity, String.class);
String jsonData = response.getBody();
HashMap apps = JSONArray.parseObject(jsonData,HashMap.class);
List<String> instanceIds = getInstanceIds(apps);
HashMap<String,Integer> map = new HashMap<>();
List<InstanceNum> instances = interfaceManageRepository.getAllCountGroupByInstanceID();
for(InstanceNum instance : instances){
map.put(instance.getInstanceId(),instance.getNum());
}
for(String instance : instanceIds){
InstanceNum instanceNum = new InstanceNum();
if(map.get(instance)!=null){
instanceNum.setNum(map.get(instance));
instanceNum.setInstanceId(instance);
}else {
instanceNum.setInstanceId(instance);
instanceNum.setNum(0);
}
list.add(instanceNum);
}
}
return list;
}
@Override
public Map<String, Object> getIpPortByInterfaceId(String instanceId) {
Map<String,Object> ipPortMap = null;
InterfaceManage interfaceManage = interfaceManageRepository.findById(instanceId).orElse(null);
if(interfaceManage!=null){
String base64Token = Base64.getEncoder().encodeToString(token.getBytes(StandardCharsets.UTF_8));
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic "+base64Token);
HttpEntity<String> entity = new HttpEntity<>(null, headers);
ResponseEntity<String> response = restTemplate.exchange(eurekaUrl+"apps", HttpMethod.GET, entity, String.class);
String jsonData = response.getBody();
HashMap apps = JSONArray.parseObject(jsonData,HashMap.class);
List<Map<String,String>> list = getInstances(apps);
for(Map<String,String> map : list){
if(StringUtils.isNotBlank(interfaceManage.getExecuteInstanceId())){
if(interfaceManage.getExecuteInstanceId().equals(map.get("instanceId"))){
ipPortMap = new HashMap<>();
ipPortMap.put("ip",map.get("ip"));
ipPortMap.put("port",map.get("port"));
ipPortMap.put("hostName",map.get("hostName"));
return ipPortMap;
}
}
}
if(ipPortMap==null){
for(Map<String,String> map : list){
if(StringUtils.isNotBlank(interfaceManage.getExecuteInstanceIdBack())){
if(interfaceManage.getExecuteInstanceIdBack().equals(map.get("instanceId"))){
ipPortMap = new HashMap<>();
ipPortMap.put("ip",map.get("ip"));
ipPortMap.put("port",map.get("port"));
ipPortMap.put("hostName",map.get("hostName"));
return ipPortMap;
}
}
}
}
}
return null;
}
private InterfaceManageDTO readJson(InputStream inputStream) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
InterfaceManageDTO jsonStr = objectMapper.readValue(inputStream, InterfaceManageDTO.class);
@ -1089,4 +1243,61 @@ public class InterfaceManageServiceImpl implements InterfaceManageService {
}
return true;
}
//解析实例信息,获取全部实例ID
private List<String> getInstanceIds(Map data){
List<String> instanceIds = new ArrayList<>();
if(data.get("applications") instanceof Map){
HashMap applications = ((JSONObject)data.get("applications")).toJavaObject(HashMap.class);
if(applications.get("application") instanceof List){
for(Object obj : (JSONArray)applications.get("application")){
if(obj instanceof Map){
HashMap appMap = ((JSONObject) obj).toJavaObject(HashMap.class);
if(appMap.get("instance") instanceof List){
for(Object o : (JSONArray)appMap.get("instance")){
if(o instanceof Map){
HashMap map = ((JSONObject) o).toJavaObject(HashMap.class);
if(map.get("status").toString().toUpperCase().equals("UP")){
instanceIds.add(String.valueOf(map.get("instanceId")));
}
}
}
}
}
}
}
}
return instanceIds;
}
//解析实例信息,获取全部实例ID
private List<Map<String,String>> getInstances(Map data){
List<Map<String,String>> instances = new ArrayList<>();
if(data.get("applications") instanceof Map){
HashMap applications = ((JSONObject)data.get("applications")).toJavaObject(HashMap.class);
if(applications.get("application") instanceof List){
for(Object obj : (JSONArray)applications.get("application")){
if(obj instanceof Map){
HashMap appMap = ((JSONObject) obj).toJavaObject(HashMap.class);
if(appMap.get("instance") instanceof List){
for(Object o : (JSONArray)appMap.get("instance")){
if(o instanceof Map){
HashMap map = ((JSONObject) o).toJavaObject(HashMap.class);
if(map.get("status").toString().toUpperCase().equals("UP")){
HashMap<String,String> app = new HashMap<>();
app.put("instanceId",String.valueOf(map.get("instanceId")));
app.put("ip",String.valueOf(map.get("ipAddr")));
app.put("hostName",String.valueOf(map.get("hostName")));
HashMap portMap = ((JSONObject) map.get("port")).toJavaObject(HashMap.class);
app.put("port",String.valueOf(portMap.get("$")));
instances.add(app);
}
}
}
}
}
}
}
}
return instances;
}
}

View File

@ -24,6 +24,8 @@ eureka:
enabled: false # 启用服务面板
path: / # 服务面板路径
client:
service-url:
defaultZone: http://localhost:8080/interfaceManager/eureka/ # Eureka服务器地址本机地址
fetch-registry: false # 是否从Eureka服务器获取注册信息
register-with-eureka: false # 是否注册自身到Eureka服务器
spring: