186 lines
7.5 KiB
Java
186 lines
7.5 KiB
Java
// This file is auto-generated, don't edit it. Thanks.
|
||
package com.mobai.openApi;
|
||
|
||
|
||
import com.aliyun.ecs20140526.models.DescribeInstancesResponse;
|
||
import com.aliyun.ecs20140526.models.DescribeInstancesResponseBody;
|
||
import com.aliyun.tea.TeaException;
|
||
import com.mobai.domain.ApifoxModel;
|
||
import com.mobai.domain.Result;
|
||
import com.mobai.service.FluxGetInfoService;
|
||
import lombok.AllArgsConstructor;
|
||
import lombok.Builder;
|
||
import lombok.Data;
|
||
import lombok.NoArgsConstructor;
|
||
import lombok.extern.log4j.Log4j2;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.data.redis.core.RedisTemplate;
|
||
import org.springframework.scheduling.annotation.Scheduled;
|
||
import org.springframework.stereotype.Component;
|
||
import org.springframework.stereotype.Indexed;
|
||
import reactor.core.publisher.Flux;
|
||
|
||
import java.math.BigDecimal;
|
||
import java.math.RoundingMode;
|
||
import java.util.*;
|
||
import java.util.stream.Collector;
|
||
import java.util.stream.Collectors;
|
||
|
||
@Log4j2
|
||
@Component
|
||
public class SelectInstences {
|
||
|
||
@Autowired
|
||
private FluxGetInfoService fluxGetInfoService;
|
||
|
||
@Autowired
|
||
private RedisTemplate<String,String> redisTemplate;
|
||
/**
|
||
* 使用AK&SK初始化账号Client
|
||
*
|
||
* @return Client
|
||
* @throws Exception
|
||
*/
|
||
public static com.aliyun.ecs20140526.Client createClient() throws Exception {
|
||
// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
|
||
// 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
|
||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
|
||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
|
||
.setAccessKeyId("LTAI5t7vsLXtqTJKve7JipnX")
|
||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
|
||
.setAccessKeySecret("AIyMaSTKQtsB1V5sVqlNAGbQzxgXnS");
|
||
// Endpoint 请参考 https://api.aliyun.com/product/Ecs
|
||
config.endpoint = "ecs.cn-zhangjiakou.aliyuncs.com";
|
||
return new com.aliyun.ecs20140526.Client(config);
|
||
}
|
||
|
||
@Scheduled(cron = "0/10 * * * * ? ")
|
||
public void saveIps() throws Exception {
|
||
List<String> ips = new ArrayList<>();
|
||
com.aliyun.ecs20140526.Client client = SelectInstences.createClient();
|
||
com.aliyun.ecs20140526.models.DescribeInstancesRequest describeInstancesRequest = new com.aliyun.ecs20140526.models.DescribeInstancesRequest()
|
||
// .setImageId("m-8vb8qnidv34yj3nbirhc")
|
||
.setRegionId("cn-zhangjiakou");
|
||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||
try {
|
||
// 复制代码运行请自行打印 API 的返回值
|
||
DescribeInstancesResponse describeInstancesResponse = client.describeInstancesWithOptions(describeInstancesRequest, runtime);
|
||
DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstances instances = describeInstancesResponse.getBody().getInstances();
|
||
List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> instance =
|
||
instances.getInstance();
|
||
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance inst : instance) {
|
||
List<String> ipAddress = inst
|
||
.getPublicIpAddress()
|
||
.getIpAddress();
|
||
if (ipAddress.isEmpty()){
|
||
continue;
|
||
}else {
|
||
ipAddress.forEach(ip -> ips.add(ip));
|
||
}
|
||
}
|
||
log.info("当前实例ip为{}", ips);
|
||
} catch (TeaException error) {
|
||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||
// 错误 message
|
||
log.error("错误信息::{}",error.getMessage());
|
||
// 诊断地址
|
||
log.warn("诊断地址::{}",error.getData().get("Recommend"));
|
||
com.aliyun.teautil.Common.assertAsString(error.message);
|
||
} catch (Exception _error) {
|
||
TeaException error = new TeaException(_error.getMessage(), _error);
|
||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||
// 错误 message
|
||
log.error("错误信息::{}",error.getMessage());
|
||
// 诊断地址
|
||
if (error.getData() == null) {
|
||
log.error("错误信息::{}","error.getData()为空");
|
||
} else {
|
||
log.error("诊断地址::{}",error.getData().get("Recommend"));
|
||
}
|
||
|
||
com.aliyun.teautil.Common.assertAsString(error.message);
|
||
}
|
||
List<SmallNode> nodes = new ArrayList<>();
|
||
for (String ip : ips) {
|
||
Result<ApifoxModel> info = fluxGetInfoService.getInfo(ip);
|
||
//连接总数
|
||
long connectSize = info.getData().getMqttInfo().getConnectSize();
|
||
log.info("{}::{}",ip,connectSize);
|
||
//添加到一个容器
|
||
nodes.add(new SmallNode(ip,connectSize));
|
||
}
|
||
//负载均横方法
|
||
this.getArithmetic(nodes);
|
||
}
|
||
|
||
/**
|
||
* 负载均衡算法
|
||
*
|
||
* @param nodes
|
||
*/
|
||
private void getArithmetic(List<SmallNode> nodes) {
|
||
// ip num 数量的容器
|
||
Map<String, BigDecimal> arithmet = new HashMap<>();
|
||
BigDecimal sum = new BigDecimal(0);
|
||
//获取所有的 键
|
||
for (SmallNode node : nodes) {
|
||
BigDecimal value = BigDecimal.valueOf(80 - node.getNum());
|
||
//获取总量
|
||
sum = sum.add(value);
|
||
arithmet.put(node.getIp(),value);
|
||
}// 根据权重总和计算每个节点的特定比例
|
||
System.out.println (arithmet );
|
||
log.info("总可负载量:{}",arithmet);
|
||
List<String> ips = new ArrayList<>();
|
||
//获取每个ip的分配率
|
||
for (String ip : arithmet.keySet()) {
|
||
//概率
|
||
BigDecimal probability = arithmet.get(ip).divide(sum,4,BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
|
||
arithmet.put(ip,probability);
|
||
log.info(ip+"可负载率(权重值):{}",probability);
|
||
}
|
||
Set<String> ipSet = arithmet.keySet();
|
||
|
||
BigDecimal finalSum = sum;
|
||
Map<String, Integer> map = new HashMap<>();
|
||
// 转换成数量
|
||
ipSet.forEach(ip ->
|
||
map.put(ip,arithmet.get(ip).multiply(finalSum).intValue()/100)
|
||
);
|
||
Long i = 0L;
|
||
System.out.println(map);
|
||
while (true){
|
||
ipSet = map.keySet();
|
||
Iterator<String> iterator = ipSet.iterator();
|
||
i++;
|
||
while (iterator.hasNext()){
|
||
i++;
|
||
String ip = iterator.next();
|
||
ips.add(ip);
|
||
int i1 = map.get(ip) - 1;
|
||
map.put(ip,i1);
|
||
if (map.get(ip).equals(0)){
|
||
map.remove(ip);
|
||
}
|
||
}
|
||
if (i.equals(finalSum)){
|
||
break;
|
||
}
|
||
System.out.println(i);
|
||
}
|
||
|
||
// 可负载IP轮询排列
|
||
System.out.println(arithmet);
|
||
System.out.println(ips);
|
||
}
|
||
|
||
|
||
@Data
|
||
@AllArgsConstructor
|
||
@NoArgsConstructor
|
||
class SmallNode{
|
||
private String ip;
|
||
private long num;
|
||
}
|
||
}
|