feat():创建实例+获取实例ip
parent
b27d094f93
commit
a3968b7b3f
|
@ -3,6 +3,8 @@
|
||||||
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
||||||
<file url="file://$PROJECT_DIR$/VehicleSimulation/src/main/java" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/VehicleSimulation/src/main/java" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/VehicleSimulation/src/main/resources" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/VehicleSimulation/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/ZhiLian-LoadBalancing/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/ZhiLian-LoadBalancing/src/main/resources" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||||
<file url="PROJECT" charset="UTF-8" />
|
<file url="PROJECT" charset="UTF-8" />
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="EntryPointsManager">
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="org.springframework.beans.factory.annotation.Autowired" />
|
||||||
|
</list>
|
||||||
|
</component>
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="MavenProjectsManager">
|
<component name="MavenProjectsManager">
|
||||||
<option name="originalFiles">
|
<option name="originalFiles">
|
||||||
|
|
|
@ -5,15 +5,12 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>com.fei</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>open-api</artifactId>
|
||||||
<relativePath>org.springframework.boot</relativePath>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<version>2.7.15</version>
|
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.muyu</groupId>
|
<artifactId>CarNet-VehicleSimulation</artifactId>
|
||||||
<artifactId>VehicleSimulation</artifactId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
@ -23,8 +20,55 @@
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
||||||
|
<description>
|
||||||
|
CarNet-VehicleSimulation车联网平台
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<url>https://github.com/aliyun/alibabacloud-code-sample</url>
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>The Apache License, Version 2.0</name>
|
||||||
|
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<id>aliyundeveloper</id>
|
||||||
|
<name>Aliyun SDK</name>
|
||||||
|
<email>aliyunsdk@aliyun.com</email>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
<distributionManagement>
|
||||||
|
<snapshotRepository>
|
||||||
|
<id>sonatype-nexus-snapshots</id>
|
||||||
|
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
<repository>
|
||||||
|
<id>sonatype-nexus-staging</id>
|
||||||
|
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||||
|
</repository>
|
||||||
|
</distributionManagement>
|
||||||
|
<scm>
|
||||||
|
<connection></connection>
|
||||||
|
<developerConnection></developerConnection>
|
||||||
|
<url></url>
|
||||||
|
</scm>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- rabbitMQ -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>ecs20140526</artifactId>
|
||||||
|
<version>5.1.8</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
@ -95,5 +139,37 @@
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>aliyun-java-auth</artifactId>
|
||||||
|
<version>0.2.8-beta</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>ecs20140526</artifactId>
|
||||||
|
<version>5.1.8</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>tea-openapi</artifactId>
|
||||||
|
<version>0.3.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>tea-rpc</artifactId>
|
||||||
|
<version>0.1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.kafka</groupId>
|
||||||
|
<artifactId>kafka-clients</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>darabonba-java-core</artifactId>
|
||||||
|
<version>0.2.8-beta</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
package com;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.DoubleStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName demo_01
|
||||||
|
* @Description 描述
|
||||||
|
* @Author YunFei.Du
|
||||||
|
* @Date 2024/5/27 14:44
|
||||||
|
*/
|
||||||
|
public class Demo1 {
|
||||||
|
/**
|
||||||
|
* 主函数示例,展示了如何从一个HashMap中提取信息,
|
||||||
|
* 计算权重总和,按权重分配特定数量的节点,并进行相应的排序和归约。
|
||||||
|
*
|
||||||
|
* @param args 命令行参数(未使用)
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 初始化一个HashMap,存储节点ID及其对应的权重
|
||||||
|
HashMap< String, Double > nodeMap = new HashMap<> ( ){{
|
||||||
|
put ( "node_1",0.35 );
|
||||||
|
put ( "node_2",0.53 );
|
||||||
|
put ( "node_3",0.17 );
|
||||||
|
put ( "node_4",0.46 );
|
||||||
|
}};
|
||||||
|
|
||||||
|
// 将节点Map转换为NodeInfo对象的List
|
||||||
|
List< NodeInfo > nodeInfoList = nodeMap.entrySet ( )
|
||||||
|
.stream ( ).map ( NodeInfo::new )
|
||||||
|
.toList ( );
|
||||||
|
System.out.println (nodeInfoList );
|
||||||
|
|
||||||
|
// 计算所有节点权重的总和
|
||||||
|
double sum = nodeInfoList.stream ( )
|
||||||
|
.flatMapToDouble ( nodeInfo -> DoubleStream.of ( nodeInfo.getWeight ( ) ) )
|
||||||
|
.sum ( );
|
||||||
|
System.out.println (sum );
|
||||||
|
|
||||||
|
// 根据权重总和计算每个节点的特定比例
|
||||||
|
BigDecimal spec = new BigDecimal ( 100 ).divide ( new BigDecimal ( sum ), 2, BigDecimal.ROUND_HALF_UP );
|
||||||
|
|
||||||
|
|
||||||
|
// 使用计算出的比例,为每个节点分配整数数量
|
||||||
|
Map< String, Integer > collect = nodeInfoList.stream ( ).collect ( Collectors.toMap ( NodeInfo::getId,
|
||||||
|
nodeInfo -> spec.multiply ( BigDecimal.valueOf ( nodeInfo.getWeight ( ) ) ).setScale ( 0, RoundingMode.DOWN ).intValue (),
|
||||||
|
(o1, o2) -> o1 ) );
|
||||||
|
System.out.println (collect );
|
||||||
|
|
||||||
|
// 计算已分配节点数量的总和
|
||||||
|
int reduce = collect.values ( ).stream ( ).reduce ( 0, Integer::sum );
|
||||||
|
System.out.println (reduce );
|
||||||
|
|
||||||
|
// 计算剩余的未分配节点数量
|
||||||
|
int free=100-reduce;
|
||||||
|
|
||||||
|
// 为剩余的未分配节点分配数量
|
||||||
|
nodeInfoList.stream ()
|
||||||
|
.sorted ( Comparator.comparingInt ( o->o.getWeight ().intValue () ) )
|
||||||
|
.limit ( free )
|
||||||
|
.forEach ( nodeInfo -> {
|
||||||
|
collect.put ( nodeInfo.getId (),collect.get ( nodeInfo.getId ())+1 );
|
||||||
|
} );
|
||||||
|
System.out.println (collect );
|
||||||
|
|
||||||
|
// 准备一个字符串数组,以存储最终的节点分配结果
|
||||||
|
String[] nodeArray = new String[100];
|
||||||
|
int intArrCursor= -1;
|
||||||
|
|
||||||
|
// 将分配了数量的节点填充到字符串数组中,直到数组满或所有节点都已处理完毕
|
||||||
|
while (collect.size ()>1){
|
||||||
|
Iterator< Map.Entry< String, Integer > > specMapIterator = collect.entrySet ( ).iterator ( );
|
||||||
|
while (specMapIterator.hasNext ()){
|
||||||
|
Map.Entry< String, Integer > entry = specMapIterator.next ( );
|
||||||
|
Integer value = entry.getValue ( );
|
||||||
|
if (value>0){
|
||||||
|
nodeArray[++intArrCursor] = entry.getKey ( );
|
||||||
|
entry.setValue ( value-1 );
|
||||||
|
}
|
||||||
|
if (value==0){
|
||||||
|
specMapIterator.remove ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println (collect );
|
||||||
|
System.out.println (Arrays.toString ( nodeArray ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class NodeInfo{
|
||||||
|
private String id;
|
||||||
|
private Double weight;
|
||||||
|
|
||||||
|
public NodeInfo (String id, Double weight){
|
||||||
|
this.id=id;
|
||||||
|
this.weight=weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NodeInfo (Map.Entry<String,Double> entry){
|
||||||
|
this.id=entry.getKey ();
|
||||||
|
this.weight=entry.getValue ()*100;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public Double getWeight(){
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
//package com.muyu.config;
|
||||||
|
//
|
||||||
|
//import org.springframework.amqp.rabbit.connection.CorrelationData;
|
||||||
|
//import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
//import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
//import org.springframework.stereotype.Component;
|
||||||
|
//
|
||||||
|
//import javax.annotation.PostConstruct;
|
||||||
|
//
|
||||||
|
///**
|
||||||
|
// * 消息发送确认配置 消息发送到交换机的确认
|
||||||
|
// */
|
||||||
|
//@Component
|
||||||
|
//public class ConfirmCallbackConfig implements RabbitTemplate.ConfirmCallback {
|
||||||
|
//
|
||||||
|
// @Autowired
|
||||||
|
// private RabbitTemplate rabbitTemplate;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @PostContruct是spring框架的注解,在⽅法上加该注解会在项⽬启动的时候执⾏该⽅法,也可以理解为在spring容器初始化的时候执
|
||||||
|
// * @PostConstruct bean 被初始化的时候执行的方法的注解
|
||||||
|
// * @PreDestory bean 被销毁的时候执行的方法的注解
|
||||||
|
// */
|
||||||
|
// @PostConstruct
|
||||||
|
// public void init() {
|
||||||
|
// rabbitTemplate.setConfirmCallback(this);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 交换机不管是否收到消息的一个回调方法
|
||||||
|
// *
|
||||||
|
// * @param correlationData 消息相关数据
|
||||||
|
// * @param ack 交换机是否收到消息
|
||||||
|
// * @param cause 失败原因
|
||||||
|
// */
|
||||||
|
// @Override
|
||||||
|
// public void confirm(CorrelationData correlationData, boolean ack, String cause) {
|
||||||
|
// if (ack) {
|
||||||
|
// // 消息投递到 broker 的状态,true表示成功
|
||||||
|
// System.out.println("消息发送成功!");
|
||||||
|
// } else {
|
||||||
|
// // 发送异常
|
||||||
|
// System.out.println("发送异常原因 = " + cause);
|
||||||
|
// // TODO 可以将消息 内容 以及 失败的原因 记录到 日志表中
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
|
@ -0,0 +1,53 @@
|
||||||
|
//package com.muyu.config;
|
||||||
|
//
|
||||||
|
//import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
|
||||||
|
//import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||||
|
//import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||||
|
//import org.springframework.beans.factory.annotation.Value;
|
||||||
|
//import org.springframework.context.annotation.Bean;
|
||||||
|
//import org.springframework.context.annotation.Configuration;
|
||||||
|
//
|
||||||
|
///**
|
||||||
|
// * RabbitAdmin是RabbitMQ的一个Java客户端库,它提供了管理RabbitMQ资源的功能。它是通过与RabbitMQ服务器进行交互来执行管理操作的。
|
||||||
|
// */
|
||||||
|
//@Configuration
|
||||||
|
//public class RabbitAdminConfig {
|
||||||
|
//
|
||||||
|
// @Value("${spring.rabbitmq.host}")
|
||||||
|
// private String host;
|
||||||
|
// @Value("${spring.rabbitmq.username}")
|
||||||
|
// private String username;
|
||||||
|
// @Value("${spring.rabbitmq.password}")
|
||||||
|
// private String password;
|
||||||
|
// @Value("${spring.rabbitmq.virtualhost}")
|
||||||
|
// private String virtualhost;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 构建 RabbitMQ的连接工厂
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// @Bean
|
||||||
|
// public ConnectionFactory connectionFactory() {
|
||||||
|
// CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
|
||||||
|
// connectionFactory.setAddresses(host);
|
||||||
|
// connectionFactory.setUsername(username);
|
||||||
|
// connectionFactory.setPassword(password);
|
||||||
|
// connectionFactory.setVirtualHost(virtualhost);
|
||||||
|
// // 配置发送确认回调时,次配置必须配置,否则即使在RabbitTemplate配置了ConfirmCallback也不会生效
|
||||||
|
// connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
|
||||||
|
// connectionFactory.setPublisherReturns(true);
|
||||||
|
// return connectionFactory;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 自己初始化 RabbitAdmin
|
||||||
|
// * @param connectionFactory
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// @Bean
|
||||||
|
// public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
|
||||||
|
// RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
|
||||||
|
// rabbitAdmin.setAutoStartup(true);
|
||||||
|
// return rabbitAdmin;
|
||||||
|
// }
|
||||||
|
//}
|
|
@ -0,0 +1,15 @@
|
||||||
|
//package com.muyu.config;
|
||||||
|
//
|
||||||
|
//import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
|
//import org.springframework.amqp.support.converter.MessageConverter;
|
||||||
|
//import org.springframework.context.annotation.Bean;
|
||||||
|
//import org.springframework.context.annotation.Configuration;
|
||||||
|
//
|
||||||
|
//@Configuration
|
||||||
|
//public class RabbitmqConfig {
|
||||||
|
// // 消息转换配置
|
||||||
|
// @Bean
|
||||||
|
// public MessageConverter jsonMessageConverter() {
|
||||||
|
// return new Jackson2JsonMessageConverter();
|
||||||
|
// }
|
||||||
|
//}
|
|
@ -0,0 +1,34 @@
|
||||||
|
//package com.muyu.config;
|
||||||
|
//
|
||||||
|
//import org.springframework.amqp.core.ReturnedMessage;
|
||||||
|
//import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
//import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
//import org.springframework.stereotype.Component;
|
||||||
|
//
|
||||||
|
//import javax.annotation.PostConstruct;
|
||||||
|
//
|
||||||
|
///**
|
||||||
|
// * 消息发送到队列的确认 一旦消息发送到队列失败 则会执行 returnedMessage 方法
|
||||||
|
// */
|
||||||
|
//@Component
|
||||||
|
//public class ReturnCallbackConfig implements RabbitTemplate.ReturnsCallback {
|
||||||
|
//
|
||||||
|
// @Autowired
|
||||||
|
// private RabbitTemplate rabbitTemplate;
|
||||||
|
//
|
||||||
|
// @PostConstruct // @PostContruct是spring框架的注解,在⽅法上加该注解会在项⽬启动的时候执⾏该⽅法,也可以理解为在spring容器初始化的时候执
|
||||||
|
// public void init() {
|
||||||
|
// rabbitTemplate.setReturnsCallback(this);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 消息发送到 队列失败 执行的 方法
|
||||||
|
// * @param returnedMessage the returned message and metadata.
|
||||||
|
// */
|
||||||
|
// @Override
|
||||||
|
// public void returnedMessage(ReturnedMessage returnedMessage) {
|
||||||
|
// System.out.println("消息" + returnedMessage.getMessage().toString() + "被交换机" + returnedMessage.getExchange() + "回退!"
|
||||||
|
// + "退回原因为:" + returnedMessage.getReplyText());
|
||||||
|
// // 回退了所有的信息,可做补偿机制 记录到 数据库
|
||||||
|
// }
|
||||||
|
//}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.muyu.constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName RabbitMQOneConstants
|
||||||
|
* @Description 描述
|
||||||
|
* @Author YunFei.Du
|
||||||
|
* @Date 2024/5/27 22:04
|
||||||
|
*/
|
||||||
|
public class RabbitMQOneConstants {
|
||||||
|
/**
|
||||||
|
* 验证码
|
||||||
|
*/
|
||||||
|
public static final String SEND_CODE="send_code_queue";
|
||||||
|
|
||||||
|
|
||||||
|
//发送短消息队列名称
|
||||||
|
public static final String SEND_SHORT_MESSAGE_QUEUE_NAME = "send_short_message";
|
||||||
|
|
||||||
|
|
||||||
|
//查看的日志队列名称
|
||||||
|
public static final String QUERY_LOG_QUEUE_NAME = "query_log_message";
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.muyu.consumer;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.rabbitmq.client.Channel;
|
||||||
|
import org.springframework.amqp.core.Message;
|
||||||
|
import org.springframework.amqp.rabbit.annotation.Queue;
|
||||||
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName ConnectionConsumer
|
||||||
|
* @Description 描述
|
||||||
|
* @Author YunFei.Du
|
||||||
|
* @Date 2024/5/27 21:57
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ConnectionConsumer {
|
||||||
|
|
||||||
|
@RabbitListener(queuesToDeclare = @Queue(name = "ADD_LOG_AAA"))
|
||||||
|
public void receive(Message message, Channel channel) {
|
||||||
|
ObjectMapper mapper = new ObjectMapper ( );
|
||||||
|
// mapper.convertValue ( messageConverter. )
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,16 @@ import lombok.Data;
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class ServerNode {
|
public class ServerNode {
|
||||||
|
/**
|
||||||
|
* ip地址
|
||||||
|
*/
|
||||||
private String ip;
|
private String ip;
|
||||||
|
/**
|
||||||
|
* 端口号
|
||||||
|
*/
|
||||||
private Integer port;
|
private Integer port;
|
||||||
|
/**
|
||||||
|
* 服务器的负载百分比
|
||||||
|
*/
|
||||||
|
private Double loadPercentage;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.muyu.loadcenter.common;
|
||||||
|
|
||||||
|
import com.muyu.domain.model.MqttServerModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName AccessPool
|
||||||
|
* @Description 描述
|
||||||
|
* @Author YunFei.Du
|
||||||
|
* @Date 2024/5/27 22:39
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Log4j2
|
||||||
|
public class AccessPool {
|
||||||
|
private static Integer sequence = 0;
|
||||||
|
|
||||||
|
private static Map<String, MqttServerModel > accessPools = new HashMap<> ();
|
||||||
|
|
||||||
|
public static void initAccessPools(List<MqttServerModel> mqttServerModels){
|
||||||
|
accessPools = mqttServerModels.stream().collect( Collectors.toMap(MqttServerModel::getBroker, Function.identity()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addAccessPool(MqttServerModel mqttServerModel){
|
||||||
|
accessPools.put(mqttServerModel.getBroker(),mqttServerModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void lookAccessPools(){
|
||||||
|
accessPools.forEach((k,v)->{
|
||||||
|
log.info("key:"+k+" value:"+v.toString());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MqttServerModel getMqttServerModel(){
|
||||||
|
if (sequence == accessPools.size()){
|
||||||
|
sequence = 0;
|
||||||
|
}
|
||||||
|
Set<String> strings = accessPools.keySet();
|
||||||
|
return accessPools.get(strings.toArray()[sequence++]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.muyu.service;
|
||||||
|
|
||||||
|
import com.muyu.common.Result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName LoadCenterService
|
||||||
|
* @Description 描述
|
||||||
|
* @Author YunFei.Du
|
||||||
|
* @Date 2024/5/27 22:35
|
||||||
|
*/
|
||||||
|
public interface LoadCenterService {
|
||||||
|
Result getDescribeInstances();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.muyu.service.impl;
|
||||||
|
|
||||||
|
import com.muyu.common.Result;
|
||||||
|
import com.muyu.service.LoadCenterService;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import static com.muyu.utils.ECSTool.runEcsInstance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName LoadCenterServiceImpl
|
||||||
|
* @Description 描述
|
||||||
|
* @Author YunFei.Du
|
||||||
|
* @Date 2024/5/27 22:36
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Log4j2
|
||||||
|
public class LoadCenterServiceImpl implements LoadCenterService {
|
||||||
|
@Override
|
||||||
|
public Result getDescribeInstances() {
|
||||||
|
try {
|
||||||
|
runEcsInstance("cn-zhangjiakou", "lt-8vbepqjihmawbkqcwkcm");
|
||||||
|
return Result.success ();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error ( "getDescribeInstances error:{}", e );
|
||||||
|
throw new RuntimeException ( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -142,8 +142,8 @@ public class VechileServiceImpl extends ServiceImpl<VehicleMapper, Vehicle> impl
|
||||||
public ServerNode assignServerNode(String vehicleId) {
|
public ServerNode assignServerNode(String vehicleId) {
|
||||||
// 这里为了简化,我们随机选择一个节点
|
// 这里为了简化,我们随机选择一个节点
|
||||||
List< ServerNode > serverNodes = Arrays.asList (
|
List< ServerNode > serverNodes = Arrays.asList (
|
||||||
new ServerNode ( "192.168.1.1", 8080 ),
|
new ServerNode ( "192.168.1.1", 8080,0.23 ),
|
||||||
new ServerNode ( "192.168.1.2", 8081 )
|
new ServerNode ( "192.168.1.2", 8081 ,0.50)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (serverNodes.isEmpty()) {
|
if (serverNodes.isEmpty()) {
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
package com.muyu.utils;
|
||||||
|
import com.aliyun.ecs20140526.Client;
|
||||||
|
import com.aliyun.ecs20140526.models.RunInstancesRequest;
|
||||||
|
import com.aliyun.tea.TeaException;
|
||||||
|
import com.aliyun.teaopenapi.models.Config;
|
||||||
|
import com.aliyun.teautil.models.RuntimeOptions;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import okhttp3.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ECS工具类,提供创建ECS实例的功能
|
||||||
|
*/
|
||||||
|
public class ECSTool {
|
||||||
|
/**
|
||||||
|
* 创建ECS客户端
|
||||||
|
* @return ECS客户端实例
|
||||||
|
* @throws Exception 如果配置信息不正确或网络问题,将抛出异常
|
||||||
|
* 注意:此方法用于演示,实际使用时请替换为安全的鉴权方式,如STS
|
||||||
|
* 更多鉴权访问方式参考:https://help.aliyun.com/document_detail/378657.html
|
||||||
|
*/
|
||||||
|
public static Client createClient() throws Exception {
|
||||||
|
// 配置ECS客户端的基本信息,包括访问密钥和endpoint
|
||||||
|
Config config = new Config()
|
||||||
|
.setAccessKeyId("LTAI5tPTk3MFkmCGBbnQgmrM") // 示例Access Key ID,实际使用时应从环境变量获取
|
||||||
|
.setAccessKeySecret("q7rLjxrI0SLBXlvNT4VmYcHCNCY2p6"); // 示例Access Key Secret,实际使用时应从环境变量获取
|
||||||
|
config.endpoint = "ecs.cn-zhangjiakou.aliyuncs.com"; // 设置ECS服务的访问地址
|
||||||
|
// 创建并返回ECS客户端实例
|
||||||
|
return new Client(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并运行ECS实例
|
||||||
|
* @param regionId 地域ID
|
||||||
|
* @param launchTemplateId 启动模板ID
|
||||||
|
* @throws Exception 如果调用API时发生错误,将抛出异常
|
||||||
|
*/
|
||||||
|
public static void runEcsInstance(String regionId, String launchTemplateId) throws Exception {
|
||||||
|
// 创建ECS客户端
|
||||||
|
Client client = ECSTool.createClient();
|
||||||
|
// 设置运行实例的请求参数
|
||||||
|
RunInstancesRequest runInstancesRequest = new RunInstancesRequest()
|
||||||
|
.setRegionId(regionId)
|
||||||
|
.setLaunchTemplateId(launchTemplateId);
|
||||||
|
// 创建运行选项
|
||||||
|
RuntimeOptions runtime = new RuntimeOptions();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 调用API运行实例
|
||||||
|
client.runInstancesWithOptions(runInstancesRequest, runtime);
|
||||||
|
} catch (Exception error) {
|
||||||
|
// 处理API调用过程中出现的异常
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
if (error instanceof TeaException) {
|
||||||
|
// 处理特定类型的异常,如TeaException
|
||||||
|
TeaException teaError = (TeaException) error;
|
||||||
|
System.out.println(teaError.getData().get("Recommend")); // 打印诊断推荐链接
|
||||||
|
com.aliyun.teautil.Common.assertAsString(teaError.getMessage()); // 断言错误信息
|
||||||
|
} else {
|
||||||
|
// 处理其他类型的异常
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
List<String> argsList = Arrays.asList(args);
|
||||||
|
// 示例调用,实际使用时需要传入 区域 ID 和 启动模板 ID
|
||||||
|
runEcsInstance("cn-zhangjiakou", "lt-8vbepqjihmawbkqcwkcm");
|
||||||
|
}
|
||||||
|
|
||||||
|
// @SneakyThrows
|
||||||
|
// public static void main(String[] args) {
|
||||||
|
// OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
// .build();
|
||||||
|
//
|
||||||
|
// // 注意:GET请求通常不需要MediaType和RequestBody
|
||||||
|
// Request request = new Request.Builder()
|
||||||
|
// .url("http://fluxmq.muyu.icu/public/cluster")
|
||||||
|
// .method("GET", null) // 对于GET请求,通常不需要设置RequestBody,所以传入null
|
||||||
|
// .addHeader("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
|
||||||
|
// .addHeader("Access-Token", "2f68dbbf-519d-4f01-9636-e2421b68f379") // 确保使用正确的头部名称和令牌值
|
||||||
|
// .build();
|
||||||
|
//
|
||||||
|
// try (Response response = client.newCall(request).execute()) {
|
||||||
|
// if (!response.isSuccessful()) {
|
||||||
|
// throw new IOException("Unexpected code " + response);
|
||||||
|
// } else {
|
||||||
|
// // 打印响应体
|
||||||
|
// System.out.println(response );
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
|
@ -1,6 +1,18 @@
|
||||||
server:
|
server:
|
||||||
port: 82
|
port: 82
|
||||||
spring:
|
spring:
|
||||||
|
rabbitmq:
|
||||||
|
host: 111.229.102.61
|
||||||
|
port: 5672
|
||||||
|
username: guest
|
||||||
|
password: guest
|
||||||
|
virtual-host: /
|
||||||
|
listener:
|
||||||
|
simple:
|
||||||
|
prefetch: 1
|
||||||
|
acknowledge-mode: manual # 接收 消费 消息手动确认
|
||||||
|
direct:
|
||||||
|
acknowledge-mode: manual # 接收 消费 消息手动确认
|
||||||
mvc:
|
mvc:
|
||||||
static-path-pattern: /static/**
|
static-path-pattern: /static/**
|
||||||
|
|
||||||
|
@ -86,7 +98,7 @@ forest:
|
||||||
# 服务器配置
|
# 服务器配置
|
||||||
mqtt:
|
mqtt:
|
||||||
server:
|
server:
|
||||||
host: tcp://47.92.65.101:1883
|
host: tcp://39.100.87.192:1883
|
||||||
topic: test1
|
topic: test1
|
||||||
admin:
|
admin:
|
||||||
host: http://127.0.0.1:${server.port}
|
host: http://127.0.0.1:${server.port}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.fei</groupId>
|
||||||
|
<artifactId>open-api</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>ZhiLian-LoadBalancing</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>ecs20140526</artifactId>
|
||||||
|
<version>5.1.8</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!--lombok-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
<version>2.0.47</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
|
<artifactId>okhttp</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mybatis</groupId>
|
||||||
|
<artifactId>mybatis-spring</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.zhiLian;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class LoadBalancingApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run ( LoadBalancingApplication.class );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
package com.zhiLian.common;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Result<T> implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成功
|
||||||
|
* =================================================================================================================
|
||||||
|
*/
|
||||||
|
public static final int SUCCESS = ResultConstants.SUCCESS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 失败
|
||||||
|
* =================================================================================================================
|
||||||
|
*/
|
||||||
|
public static final int FAIL = ResultConstants.ERROR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回状态码
|
||||||
|
* =================================================================================================================
|
||||||
|
*/
|
||||||
|
private int code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应信息
|
||||||
|
* =================================================================================================================
|
||||||
|
*/
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应数据
|
||||||
|
* =================================================================================================================
|
||||||
|
*/
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
public static <T> Result<T> success() {
|
||||||
|
return restResult(null, SUCCESS, ResultConstants.SUCCESS_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> success(T data) {
|
||||||
|
return restResult(data, SUCCESS, ResultConstants.SUCCESS_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> success(T data, String msg) {
|
||||||
|
return restResult(data, SUCCESS, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> error() {
|
||||||
|
return restResult(null, FAIL, ResultConstants.ERROR_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> error(String msg) {
|
||||||
|
return restResult(null, FAIL, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> error(T data) {
|
||||||
|
return restResult(data, FAIL, ResultConstants.ERROR_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> error(T data, String msg) {
|
||||||
|
return restResult(data, FAIL, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> error(int code, String msg) {
|
||||||
|
return restResult(null, code, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> Result<T> restResult(T data, int code, String msg) {
|
||||||
|
Result<T> apiResult = new Result<>();
|
||||||
|
apiResult.setCode(code);
|
||||||
|
apiResult.setData(data);
|
||||||
|
apiResult.setMsg(msg);
|
||||||
|
return apiResult;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.zhiLian.common;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class ResultConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成功标记
|
||||||
|
* =================================================================================================================
|
||||||
|
*/
|
||||||
|
public static final Integer SUCCESS = 200;
|
||||||
|
public static final String SUCCESS_MSG = "操作成功";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 失败标记
|
||||||
|
* =================================================================================================================
|
||||||
|
*/
|
||||||
|
public static final Integer ERROR = 500;
|
||||||
|
public static final String ERROR_MSG = "操作异常";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.zhiLian.controller;
|
||||||
|
|
||||||
|
import com.zhiLian.common.Result;
|
||||||
|
import com.zhiLian.service.LoadBalanceService;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName LoadBalanceController
|
||||||
|
* @Description 描述
|
||||||
|
* @Author YunFei.Du
|
||||||
|
* @Date 2024/5/28 9:12
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("loadBalance")
|
||||||
|
@Log4j2
|
||||||
|
public class LoadBalanceController {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LoadBalanceService loadBalanceService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建实例
|
||||||
|
*/
|
||||||
|
@GetMapping("/createConnect")
|
||||||
|
public void createConnect() {
|
||||||
|
loadBalanceService.createConnect();
|
||||||
|
log.info("创建实例成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 停止实例
|
||||||
|
// */
|
||||||
|
// @GetMapping("/stopConnect")
|
||||||
|
// public void stopConnect(@RequestParam String instanceId) {
|
||||||
|
// loadBalanceService.stopConnect(instanceId);
|
||||||
|
// log.info("停止实例成功");
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销毁实例
|
||||||
|
* instanceId 实例id
|
||||||
|
*/
|
||||||
|
@GetMapping("/removeConnect")
|
||||||
|
public void removeConnect(@RequestParam String instanceId) {
|
||||||
|
loadBalanceService.removeConnect(instanceId);
|
||||||
|
log.info("销毁实例成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取实例连接
|
||||||
|
*/
|
||||||
|
@GetMapping("/getIpList")
|
||||||
|
public Result< List<String> > getIpList() {
|
||||||
|
List<String> ipList = loadBalanceService.getIpList();
|
||||||
|
// ipListThread = ipList;
|
||||||
|
return Result.success(ipList);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,236 @@
|
||||||
|
package com.zhiLian.resp;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接响应
|
||||||
|
* @author YunFei.Du
|
||||||
|
* @date 9:10 2024/5/27
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class ConnectResp {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点名称
|
||||||
|
*/
|
||||||
|
private String nodeName;
|
||||||
|
/**
|
||||||
|
* 节点版本
|
||||||
|
*/
|
||||||
|
private String version;
|
||||||
|
/**
|
||||||
|
* 启动时间
|
||||||
|
*/
|
||||||
|
private String startJvmTime;
|
||||||
|
/**
|
||||||
|
* 节点ID
|
||||||
|
*/
|
||||||
|
private String clusterId;
|
||||||
|
/**
|
||||||
|
* HTTP请求地址
|
||||||
|
*/
|
||||||
|
private String httpUrl;
|
||||||
|
/**
|
||||||
|
* MQTTS请求地址
|
||||||
|
*/
|
||||||
|
private String mqttUrl;
|
||||||
|
/**
|
||||||
|
* websocket请求地址
|
||||||
|
*/
|
||||||
|
private String websocketUrl;
|
||||||
|
|
||||||
|
|
||||||
|
private FlowInfo flowInfo;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点状态
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
private static class FlowInfo {
|
||||||
|
/**
|
||||||
|
* 写入总吞吐量
|
||||||
|
*/
|
||||||
|
private String writeBytesHistory;
|
||||||
|
/**
|
||||||
|
* 读取总吞吐量
|
||||||
|
*/
|
||||||
|
private String readBytesHistory;
|
||||||
|
/**
|
||||||
|
* 上次读取吞吐量
|
||||||
|
*/
|
||||||
|
private String lastReadThroughput;
|
||||||
|
/**
|
||||||
|
* 上次写入吞吐量
|
||||||
|
*/
|
||||||
|
private String lastWriteThroughput;
|
||||||
|
/**
|
||||||
|
* 实写字节
|
||||||
|
*/
|
||||||
|
private String realWriteBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CpuInfo cpuInfo;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cpu使用信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public static class CpuInfo {
|
||||||
|
/**
|
||||||
|
* CPU使用信息
|
||||||
|
*/
|
||||||
|
private String cSys;
|
||||||
|
/**
|
||||||
|
* 空闲率
|
||||||
|
*/
|
||||||
|
private String idle;
|
||||||
|
/**
|
||||||
|
* I/O等待
|
||||||
|
*/
|
||||||
|
private String iowait;
|
||||||
|
/**
|
||||||
|
* 用户态使用率
|
||||||
|
*/
|
||||||
|
private String user;
|
||||||
|
/**
|
||||||
|
* CPU核数
|
||||||
|
*/
|
||||||
|
private Integer cpuNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public JvmInfo jvmInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jvm使用信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public static class JvmInfo {
|
||||||
|
/**
|
||||||
|
* JAVA目录
|
||||||
|
*/
|
||||||
|
private String jdkHome;
|
||||||
|
/**
|
||||||
|
* 堆内存
|
||||||
|
*/
|
||||||
|
private String heapCommit;
|
||||||
|
/**
|
||||||
|
* 堆最大内存
|
||||||
|
*/
|
||||||
|
private String heapMax;
|
||||||
|
/**
|
||||||
|
* 线程数量
|
||||||
|
*/
|
||||||
|
private Integer threadCount;
|
||||||
|
/**
|
||||||
|
* 文件描述(句柄
|
||||||
|
*/
|
||||||
|
private String fileDescriptors;
|
||||||
|
/**
|
||||||
|
* 非堆最大空间
|
||||||
|
*/
|
||||||
|
private String noHeapMax;
|
||||||
|
/**
|
||||||
|
* 非堆初始化空间
|
||||||
|
*/
|
||||||
|
private String noHeapInit;
|
||||||
|
/**
|
||||||
|
* JDK版本
|
||||||
|
*/
|
||||||
|
private String jdkVersion;
|
||||||
|
/**
|
||||||
|
* 堆初始化空间
|
||||||
|
*/
|
||||||
|
private String heapInit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 堆使用空间
|
||||||
|
*/
|
||||||
|
private String heapUsed;
|
||||||
|
/**
|
||||||
|
* 非堆空间
|
||||||
|
*/
|
||||||
|
private String noHeapCommit;
|
||||||
|
/**
|
||||||
|
* 非堆使用空间
|
||||||
|
*/
|
||||||
|
private String noHeapUsed;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public MqttInfo mqttInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MQTT事件信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public static class MqttInfo {
|
||||||
|
/**
|
||||||
|
* 连接事件数量
|
||||||
|
*/
|
||||||
|
private Integer connectEventSize;
|
||||||
|
/**
|
||||||
|
* 订阅事件数量
|
||||||
|
*/
|
||||||
|
private Integer subscribeEventSize;
|
||||||
|
/**
|
||||||
|
* 发布重试事件数量
|
||||||
|
*/
|
||||||
|
private Integer publishRetryEventSize;
|
||||||
|
/**
|
||||||
|
* 主题数量
|
||||||
|
*/
|
||||||
|
private Integer topicSize;
|
||||||
|
/**
|
||||||
|
* 断开链接数量
|
||||||
|
*/
|
||||||
|
private Integer disconnectEventSize;
|
||||||
|
/**
|
||||||
|
* 订阅数量
|
||||||
|
*/
|
||||||
|
private Integer subscribeSize;
|
||||||
|
/**
|
||||||
|
* 推送数量
|
||||||
|
*/
|
||||||
|
private Integer publishEventSize;
|
||||||
|
/**
|
||||||
|
* 关闭事件数量
|
||||||
|
*/
|
||||||
|
private Integer closeEventSize;
|
||||||
|
/**
|
||||||
|
* 链接总数
|
||||||
|
*/
|
||||||
|
private Integer connectSize;
|
||||||
|
/**
|
||||||
|
* 保留消息数量
|
||||||
|
*/
|
||||||
|
private Integer retainSize;
|
||||||
|
/**
|
||||||
|
* 取消订阅数量
|
||||||
|
*/
|
||||||
|
private Integer unSubscribeEventSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.zhiLian.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName LoadBalanceService
|
||||||
|
* @Description 描述
|
||||||
|
* @Author YunFei.Du
|
||||||
|
* @Date 2024/5/28 9:25
|
||||||
|
*/
|
||||||
|
public interface LoadBalanceService {
|
||||||
|
void createConnect();
|
||||||
|
|
||||||
|
void removeConnect(String instanceId);
|
||||||
|
|
||||||
|
void stopConnect(String instanceId);
|
||||||
|
|
||||||
|
List< String> getIpList();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.zhiLian.service.impl;
|
||||||
|
|
||||||
|
import com.aliyun.ecs20140526.models.DescribeInstancesResponse;
|
||||||
|
import com.aliyun.ecs20140526.models.ModifySecurityGroupRuleResponse;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.zhiLian.service.LoadBalanceService;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.zhiLian.utils.ECSTool.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName LoadBalanceService
|
||||||
|
* @Description 描述
|
||||||
|
* @Author YunFei.Du
|
||||||
|
* @Date 2024/5/28 9:25
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Log4j2
|
||||||
|
public class LoadBalanceServiceImpl implements LoadBalanceService {
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public void createConnect() {
|
||||||
|
runEcsInstance("cn-zhangjiakou", "lt-8vbepqjihmawbkqcwkcm");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeConnect(String instanceId) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
runEcsStop (instanceId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error ( "getDescribeInstances error:{}", e );
|
||||||
|
throw new RuntimeException ( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public void stopConnect(String instanceId) {
|
||||||
|
runEcsRemove ( instanceId );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public List< String > getIpList() {
|
||||||
|
FindInstance ( "cn-zhangjiakou" );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,175 @@
|
||||||
|
package com.zhiLian.utils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.aliyun.ecs20140526.Client;
|
||||||
|
import com.aliyun.ecs20140526.models.*;
|
||||||
|
import com.aliyun.tea.TeaException;
|
||||||
|
import com.aliyun.tea.TeaModel;
|
||||||
|
import com.aliyun.teaopenapi.models.Config;
|
||||||
|
import com.aliyun.teautil.Common;
|
||||||
|
import com.aliyun.teautil.models.RuntimeOptions;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* ECS实例工具类
|
||||||
|
* @author YunFei.Du
|
||||||
|
* @date 9:30 2024/5/28
|
||||||
|
*/
|
||||||
|
@Log4j2
|
||||||
|
public class ECSTool {
|
||||||
|
/**
|
||||||
|
* 创建ECS客户端
|
||||||
|
* @return ECS客户端实例
|
||||||
|
* @throws Exception 如果配置信息不正确或网络问题,将抛出异常
|
||||||
|
* 注意:此方法用于演示,实际使用时请替换为安全的鉴权方式,如STS
|
||||||
|
* 更多鉴权访问方式参考:https://help.aliyun.com/document_detail/378657.html
|
||||||
|
*/
|
||||||
|
public static Client createClient() throws Exception {
|
||||||
|
// 配置ECS客户端的基本信息,包括访问密钥和endpoint
|
||||||
|
Config config = new Config()
|
||||||
|
.setAccessKeyId("LTAI5tPTk3MFkmCGBbnQgmrM") // 示例Access Key ID,实际使用时应从环境变量获取
|
||||||
|
.setAccessKeySecret("q7rLjxrI0SLBXlvNT4VmYcHCNCY2p6"); // 示例Access Key Secret,实际使用时应从环境变量获取
|
||||||
|
config.endpoint = "ecs.cn-zhangjiakou.aliyuncs.com"; // 设置ECS服务的访问地址
|
||||||
|
// 创建并返回ECS客户端实例
|
||||||
|
return new Client(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并运行ECS实例
|
||||||
|
* @param regionId 地域ID
|
||||||
|
* @param launchTemplateId 启动模板ID
|
||||||
|
* @throws Exception 如果调用API时发生错误,将抛出异常
|
||||||
|
*/
|
||||||
|
public static void runEcsInstance(String regionId, String launchTemplateId) throws Exception {
|
||||||
|
// 创建ECS客户端
|
||||||
|
Client client = ECSTool.createClient();
|
||||||
|
// 设置运行实例的请求参数
|
||||||
|
RunInstancesRequest runInstancesRequest = new RunInstancesRequest()
|
||||||
|
.setRegionId(regionId)
|
||||||
|
.setLaunchTemplateId(launchTemplateId);
|
||||||
|
// 创建运行选项
|
||||||
|
RuntimeOptions runtime = new RuntimeOptions();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 调用API运行实例
|
||||||
|
client.runInstancesWithOptions(runInstancesRequest, runtime);
|
||||||
|
} catch (Exception error) {
|
||||||
|
// 处理API调用过程中出现的异常
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
if (error instanceof TeaException) {
|
||||||
|
// 处理特定类型的异常,如TeaException
|
||||||
|
TeaException teaError = (TeaException) error;
|
||||||
|
System.out.println(teaError.getData().get("Recommend")); // 打印诊断推荐链接
|
||||||
|
com.aliyun.teautil.Common.assertAsString(teaError.getMessage()); // 断言错误信息
|
||||||
|
} else {
|
||||||
|
// 处理其他类型的异常
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止实例
|
||||||
|
*/
|
||||||
|
public static void runEcsStop(String instanceId) throws Exception {
|
||||||
|
// 创建ECS客户端
|
||||||
|
Client client = ECSTool.createClient();
|
||||||
|
StopInstanceRequest stopInstanceRequest = new StopInstanceRequest ()
|
||||||
|
.setInstanceId(instanceId);
|
||||||
|
RuntimeOptions runtime = new RuntimeOptions();
|
||||||
|
try {
|
||||||
|
// 复制代码运行请自行打印 API 的返回值
|
||||||
|
client.stopInstanceWithOptions(stopInstanceRequest, runtime);
|
||||||
|
} catch (TeaException error) {
|
||||||
|
// 处理API调用过程中出现的异常
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
if (error instanceof TeaException) {
|
||||||
|
// 处理特定类型的异常,如TeaException
|
||||||
|
TeaException teaError = (TeaException) error;
|
||||||
|
System.out.println(teaError.getData().get("Recommend")); // 打印诊断推荐链接
|
||||||
|
com.aliyun.teautil.Common.assertAsString(teaError.getMessage()); // 断言错误信息
|
||||||
|
} else {
|
||||||
|
// 处理其他类型的异常
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 销毁实例
|
||||||
|
*/
|
||||||
|
public static void runEcsRemove(String instanceId) throws Exception {
|
||||||
|
// 创建ECS客户端
|
||||||
|
Client client = ECSTool.createClient();
|
||||||
|
DeleteInstanceRequest deleteInstanceRequest = new DeleteInstanceRequest ()
|
||||||
|
.setInstanceId(instanceId);
|
||||||
|
RuntimeOptions runtime = new RuntimeOptions();
|
||||||
|
try {
|
||||||
|
// 复制代码运行请自行打印 API 的返回值
|
||||||
|
client.deleteInstanceWithOptions(deleteInstanceRequest, runtime);
|
||||||
|
} catch (TeaException error) {
|
||||||
|
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||||
|
// 错误 message
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
// 诊断地址
|
||||||
|
System.out.println(error.getData().get("Recommend"));
|
||||||
|
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||||
|
} catch (Exception _error) {
|
||||||
|
TeaException error = new TeaException(_error.getMessage(), _error);
|
||||||
|
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||||
|
// 错误 message
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
// 诊断地址
|
||||||
|
System.out.println(error.getData().get("Recommend"));
|
||||||
|
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void FindInstance( String regionId) throws Exception {
|
||||||
|
// 创建ECS客户端
|
||||||
|
Client client = ECSTool.createClient();
|
||||||
|
DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest ()
|
||||||
|
.setRegionId(regionId);
|
||||||
|
RuntimeOptions runtime = new RuntimeOptions();
|
||||||
|
List<String> ipList = new ArrayList<> ();
|
||||||
|
try {
|
||||||
|
// 复制代码运行请自行打印 API 的返回值
|
||||||
|
DescribeInstancesResponse response = client.describeInstancesWithOptions ( describeInstancesRequest, runtime );
|
||||||
|
|
||||||
|
List<List<String>> ipListList = response.getBody().instances.getInstance().stream().map(instance -> instance.publicIpAddress.ipAddress).collect( Collectors.toList());
|
||||||
|
for (List<String> strings : ipListList) {
|
||||||
|
for (String ip : strings) {
|
||||||
|
ipList.add(ip);
|
||||||
|
}
|
||||||
|
System.out.println("------------------------");
|
||||||
|
}
|
||||||
|
log.info ( "ipList: " + ipList );
|
||||||
|
} catch (TeaException error) {
|
||||||
|
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||||
|
// 错误 message
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
// 诊断地址
|
||||||
|
System.out.println(error.getData().get("Recommend"));
|
||||||
|
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||||
|
} catch (Exception _error) {
|
||||||
|
TeaException error = new TeaException(_error.getMessage(), _error);
|
||||||
|
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||||
|
// 错误 message
|
||||||
|
System.out.println(error.getMessage());
|
||||||
|
// 诊断地址
|
||||||
|
System.out.println(error.getData().get("Recommend"));
|
||||||
|
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
server:
|
||||||
|
port: 84
|
40
pom.xml
40
pom.xml
|
@ -10,11 +10,41 @@
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<modules>
|
<modules>
|
||||||
<module>VehicleSimulation</module>
|
<module>VehicleSimulation</module>
|
||||||
|
<module>ZhiLian-LoadBalancing</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<parent>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<version>2.6.2</version>
|
||||||
</properties>
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
<!-- 依赖声明 -->
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<!-- SpringCloud 微服务 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
|
<version>2021.0.0</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- SpringCloud Alibaba 微服务 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||||
|
<version>2021.1</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- Alibaba Nacos 配置 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.nacos</groupId>
|
||||||
|
<artifactId>nacos-client</artifactId>
|
||||||
|
<version>2.0.4</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.fei;
|
package com.zhiLian;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
Loading…
Reference in New Issue