feat():创建实例+获取实例ip
parent
b27d094f93
commit
a3968b7b3f
|
@ -3,6 +3,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/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/resources" charset="UTF-8" />
|
||||
<file url="PROJECT" charset="UTF-8" />
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
|
|
|
@ -5,15 +5,12 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<relativePath>org.springframework.boot</relativePath>
|
||||
<version>2.7.15</version>
|
||||
<groupId>com.fei</groupId>
|
||||
<artifactId>open-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.muyu</groupId>
|
||||
<artifactId>VehicleSimulation</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<artifactId>CarNet-VehicleSimulation</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
|
@ -23,8 +20,55 @@
|
|||
</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>
|
||||
|
||||
<!-- 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>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
|
@ -95,5 +139,37 @@
|
|||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</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>
|
||||
</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
|
||||
@AllArgsConstructor
|
||||
public class ServerNode {
|
||||
/**
|
||||
* ip地址
|
||||
*/
|
||||
private String ip;
|
||||
/**
|
||||
* 端口号
|
||||
*/
|
||||
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) {
|
||||
// 这里为了简化,我们随机选择一个节点
|
||||
List< ServerNode > serverNodes = Arrays.asList (
|
||||
new ServerNode ( "192.168.1.1", 8080 ),
|
||||
new ServerNode ( "192.168.1.2", 8081 )
|
||||
new ServerNode ( "192.168.1.1", 8080,0.23 ),
|
||||
new ServerNode ( "192.168.1.2", 8081 ,0.50)
|
||||
);
|
||||
|
||||
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:
|
||||
port: 82
|
||||
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:
|
||||
static-path-pattern: /static/**
|
||||
|
||||
|
@ -86,7 +98,7 @@ forest:
|
|||
# 服务器配置
|
||||
mqtt:
|
||||
server:
|
||||
host: tcp://47.92.65.101:1883
|
||||
host: tcp://39.100.87.192:1883
|
||||
topic: test1
|
||||
admin:
|
||||
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>
|
||||
<modules>
|
||||
<module>VehicleSimulation</module>
|
||||
<module>ZhiLian-LoadBalancing</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<parent>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<version>2.6.2</version>
|
||||
<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>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.fei;
|
||||
package com.zhiLian;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
|
|
Loading…
Reference in New Issue