diff --git a/VehicleSimulation/pom.xml b/VehicleSimulation/pom.xml index 18d9811..34b0f5b 100644 --- a/VehicleSimulation/pom.xml +++ b/VehicleSimulation/pom.xml @@ -131,7 +131,7 @@ com.alibaba fastjson - 1.2.73 + 1.2.75 diff --git a/ZhiLian-LoadBalancing/pom.xml b/ZhiLian-LoadBalancing/pom.xml index 14798f7..331910b 100644 --- a/ZhiLian-LoadBalancing/pom.xml +++ b/ZhiLian-LoadBalancing/pom.xml @@ -18,6 +18,11 @@ + + + org.springframework.boot + spring-boot-starter-amqp + com.aliyun ecs20140526 diff --git a/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/common/req/ConnectWeight.java b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/common/req/ConnectWeight.java new file mode 100644 index 0000000..ad293d5 --- /dev/null +++ b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/common/req/ConnectWeight.java @@ -0,0 +1,26 @@ +package com.zhiLian.common.req; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * 连接权重 车子服务器 + * @author YunFei.Du + * @date 22:31 2024/5/28 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ConnectWeight { + + /** + * 服务器ip + */ + private String carServerIp; + /** + * 权重值 + */ + private Integer weightValue; +} diff --git a/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/common/req/UsersReq.java b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/common/req/UsersReq.java new file mode 100644 index 0000000..95825e2 --- /dev/null +++ b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/common/req/UsersReq.java @@ -0,0 +1,15 @@ +package com.zhiLian.common.req; + +import lombok.Data; + +/** + * @ClassName UsersReq + * @Description 描述 + * @Author YunFei.Du + * @Date 2024/5/28 22:10 + */ +@Data +public class UsersReq { + private String username; + private String password; +} diff --git a/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/config/RabbitmqConfig.java b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/config/RabbitmqConfig.java new file mode 100644 index 0000000..88e1538 --- /dev/null +++ b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/config/RabbitmqConfig.java @@ -0,0 +1,54 @@ +package com.zhiLian.config; + +import org.springframework.amqp.core.*; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * rabbitMq配置类 + * + * @author YunFei Du + * @ClassName: RabbitmqConfig + * @Description: rabbitMq配置类 + * @CreateTime: 2024/5/27 16:56 + */ +@Configuration +public class RabbitmqConfig { + public static final String QUEUE_INFORM_EMAIL = "queue_inform_email"; + public static final String QUEUE_INFORM_SMS = "disconnect_connect"; + public static final String EXCHANGE_TOPICS_INFORM="exchange_topics_inform"; + public static final String ROUTINGKEY_EMAIL="inform.#.email.#"; + public static final String ROUTINGKEY_SMS="inform.#.sms.#"; + + + @Bean(EXCHANGE_TOPICS_INFORM) + public Exchange EXCHANGE_TOPICS_INFORM(){ + //durable(true) 持久化,mq重启之后交换机还在 + return ExchangeBuilder.topicExchange(EXCHANGE_TOPICS_INFORM).durable(true).build(); + } + + //声明QUEUE_INFORM_EMAIL队列 + @Bean(QUEUE_INFORM_EMAIL) + public Queue QUEUE_INFORM_EMAIL(){ + return new Queue(QUEUE_INFORM_EMAIL); + } + //声明QUEUE_INFORM_SMS队列 + @Bean(QUEUE_INFORM_SMS) + public Queue QUEUE_INFORM_SMS(){ + return new Queue(QUEUE_INFORM_SMS); + } + + //ROUTINGKEY_EMAIL队列绑定交换机,指定routingKey + @Bean + public Binding BINDING_QUEUE_INFORM_EMAIL(@Qualifier(QUEUE_INFORM_EMAIL) Queue queue, + @Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange){ + return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY_EMAIL).noargs(); + } + //ROUTINGKEY_SMS队列绑定交换机,指定routingKey + @Bean + public Binding BINDING_ROUTINGKEY_SMS(@Qualifier(QUEUE_INFORM_SMS) Queue queue, + @Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange){ + return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY_SMS).noargs(); + } +} diff --git a/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/config/RedisConfig.java b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/config/RedisConfig.java new file mode 100644 index 0000000..e5309d7 --- /dev/null +++ b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/config/RedisConfig.java @@ -0,0 +1,33 @@ +package com.zhiLian.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * redsi配置类 + * + * @author YunFei Du + * @ClassName: RedisConfoig + * @Description: redsi配置类 + * @CreateTime: 2024/5/27 14:16 + */ +@Configuration +public class RedisConfig { + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){ + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class)); + + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashValueSerializer(new StringRedisSerializer()); + return redisTemplate; + + } +} diff --git a/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/config/RestTemplateConfig.java b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/config/RestTemplateConfig.java new file mode 100644 index 0000000..05fd9ef --- /dev/null +++ b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/config/RestTemplateConfig.java @@ -0,0 +1,33 @@ +package com.zhiLian.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +/** + * rest配置类 + * + * @author YunFei Du + * @ClassName: RestTemplateConfig + * @Description: rest配置类 + * @CreateTime: 2024/5/27 10:01 + */ +@Configuration +public class RestTemplateConfig { + @Bean + public RestTemplate restTemplate(ClientHttpRequestFactory factory) { + return new RestTemplate(factory); + } + + @Bean + public ClientHttpRequestFactory simpleClientHttpRequestFactory() { + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + //超时设置 + factory.setReadTimeout(5000);//ms + factory.setConnectTimeout(15000);//ms + return factory; + } +} + diff --git a/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/controller/LoadBalanceController.java b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/controller/LoadBalanceController.java index 69d9ba0..f197778 100644 --- a/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/controller/LoadBalanceController.java +++ b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/controller/LoadBalanceController.java @@ -1,16 +1,22 @@ package com.zhiLian.controller; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; import com.zhiLian.common.Result; +import com.zhiLian.common.req.ConnectWeight; 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 org.springframework.data.redis.core.RedisTemplate; +import org.springframework.http.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.RestTemplate; -import java.util.List; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; /** * @ClassName LoadBalanceController @@ -24,6 +30,14 @@ import java.util.List; public class LoadBalanceController { + private static List< String > ipListThread = new ArrayList<> ( ); + + @Autowired + private RestTemplate restTemplate; + + @Autowired + private RedisTemplate redisTemplate; + @Autowired private LoadBalanceService loadBalanceService; @@ -32,8 +46,8 @@ public class LoadBalanceController { */ @GetMapping("/createConnect") public void createConnect() { - loadBalanceService.createConnect(); - log.info("创建实例成功"); + loadBalanceService.createConnect ( ); + log.info ( "创建实例成功" ); } // /** @@ -51,17 +65,97 @@ public class LoadBalanceController { */ @GetMapping("/removeConnect") public void removeConnect(@RequestParam String instanceId) { - loadBalanceService.removeConnect(instanceId); - log.info("销毁实例成功"); + loadBalanceService.removeConnect ( instanceId ); + log.info ( "销毁实例成功" ); } /** * 获取实例连接 */ @GetMapping("/getIpList") - public Result< List > getIpList() { - List ipList = loadBalanceService.getIpList(); -// ipListThread = ipList; - return Result.success(ipList); + public Result< List< String > > getIpList() { + List< String > ipList = loadBalanceService.getIpList ( ); + ipListThread=ipList; + return Result.success ( ipList ); } + + /** + * 获取token + */ + @PostMapping("/getToken") + public void getToken() { + + List< ConnectWeight > connectWeightList = new ArrayList<> ( ); + + for (String ip : ipListThread) { + // 向服务器发送登录请求 + String url = "http://" + ip + ":8080/public/login"; + Map< String, Object > request = new HashMap<> ( ); + request.put ( "username", "fluxmq" ); + request.put ( "password", "fluxmq" ); + HttpHeaders httpHeaders = new HttpHeaders ( ); + httpHeaders.setContentType ( MediaType.APPLICATION_JSON ); + HttpEntity< Map< String, Object > > r = new HttpEntity< Map< String, Object > > ( request, httpHeaders ); + String result = restTemplate.postForObject ( url, r, String.class ); + // 添加随机参数以避免缓存 + int nextInt = new Random ( ).nextInt ( 1000 ); + String getInfoUrl = "http://" + ip + ":8080/public/cluster?random=" + nextInt; + // 使用获取到的token向服务器查询当前连接数 + HttpHeaders httpHeadersGetInfo = new HttpHeaders ( ); + httpHeadersGetInfo.setContentType ( MediaType.APPLICATION_JSON ); + httpHeadersGetInfo.setAccept ( Collections.singletonList ( MediaType.APPLICATION_JSON ) ); + httpHeadersGetInfo.set ( "Cookie", result ); + HttpEntity getInfoRequest = new HttpEntity ( httpHeadersGetInfo ); + ResponseEntity< String > responseInfo = restTemplate.exchange ( getInfoUrl, HttpMethod.GET, getInfoRequest, String.class, 1 ); + + // 将字符串转换为有效的JSON格式 + + JSONArray jsonArray = JSON.parseArray ( responseInfo.getBody ( ) ); + log.info ( "响应是" + jsonArray ); + + if (jsonArray.size ( ) > 0) { + + JSONObject jsonObject = jsonArray.getJSONObject ( 0 ); + Integer connectSize = Integer.valueOf ( jsonObject.getJSONObject ( "mqttInfo" ).getString ( "connectSize" ) ); + connectWeightList.add ( new ConnectWeight ( ip, 100 - connectSize ) ); + log.error ( "链接数量:{}", connectSize ); + } else { + log.error ( "得到的相应数据为null" ); + } + } + Integer sum = 0; + for (ConnectWeight connectWeight : connectWeightList) { + sum = sum + connectWeight.getWeightValue ( ); + } + + int max = 0; + for (ConnectWeight connectWeight : connectWeightList) { + log.error ( "权重值:{}", connectWeight.getWeightValue ( ) ); + Integer result = BigDecimal.valueOf ( connectWeight.getWeightValue ( ) * 100 ).divide ( BigDecimal.valueOf ( sum ), 0, RoundingMode.DOWN ).intValue ( ); + if (result > max) { + max = result; + } + connectWeight.setWeightValue ( result ); + log.error ( "100次轮询次数:{}", result ); + } + + ArrayList< String > weightIpList = new ArrayList<> ( ); + + //轮询出现次数 + for (int i = 0; i <= max; i++) { + for (ConnectWeight connectWeight : connectWeightList) { + if (connectWeight.getWeightValue ( ) > i) { + weightIpList.add ( connectWeight.getCarServerIp ( ) ); + } else if (connectWeight.getWeightValue ( ) == max) { + weightIpList.add ( connectWeight.getCarServerIp ( ) ); + } + } + } + //存入redis + redisTemplate.delete ( "ipList" ); + for (String ip : weightIpList) { + redisTemplate.opsForList ( ).rightPush ( "ipList", ip ); + } + } + } diff --git a/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/service/impl/LoadBalanceServiceImpl.java b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/service/impl/LoadBalanceServiceImpl.java index ba4eca0..ed19939 100644 --- a/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/service/impl/LoadBalanceServiceImpl.java +++ b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/service/impl/LoadBalanceServiceImpl.java @@ -49,7 +49,7 @@ public class LoadBalanceServiceImpl implements LoadBalanceService { @SneakyThrows @Override public List< String > getIpList() { - FindInstance ( "cn-zhangjiakou" ); - return null; + List< String > ipList = FindInstance ( "cn-zhangjiakou" ); + return ipList; } } diff --git a/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/utils/ECSTool.java b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/utils/ECSTool.java index b1e93b2..e1cb4c1 100644 --- a/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/utils/ECSTool.java +++ b/ZhiLian-LoadBalancing/src/main/java/com/zhiLian/utils/ECSTool.java @@ -1,5 +1,6 @@ package com.zhiLian.utils; +import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.aliyun.ecs20140526.Client; @@ -9,10 +10,13 @@ import com.aliyun.tea.TeaModel; import com.aliyun.teaopenapi.models.Config; import com.aliyun.teautil.Common; import com.aliyun.teautil.models.RuntimeOptions; +import com.zhiLian.common.req.ConnectWeight; import lombok.extern.log4j.Log4j2; +import org.springframework.http.*; -import java.util.ArrayList; -import java.util.List; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -24,6 +28,8 @@ import java.util.stream.IntStream; */ @Log4j2 public class ECSTool { + + /** * 创建ECS客户端 * @return ECS客户端实例 @@ -135,41 +141,43 @@ public class ECSTool { - public static void FindInstance( String regionId) throws Exception { + public static List FindInstance( String regionId) throws Exception { // 创建ECS客户端 - Client client = ECSTool.createClient(); - DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest () - .setRegionId(regionId); - RuntimeOptions runtime = new RuntimeOptions(); - List ipList = new ArrayList<> (); + 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> ipListList = response.getBody().instances.getInstance().stream().map(instance -> instance.publicIpAddress.ipAddress).collect( Collectors.toList()); - for (List strings : ipListList) { + 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); + ipList.add ( ip ); } - System.out.println("------------------------"); + System.out.println ( "------------------------" ); } - log.info ( "ipList: " + ipList ); + log.info ( "ipList: " + ipList ); // [39.100.89.218, 39.100.87.192] + return ipList; } catch (TeaException error) { // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。 // 错误 message - System.out.println(error.getMessage()); + System.out.println ( error.getMessage ( ) ); // 诊断地址 - System.out.println(error.getData().get("Recommend")); - com.aliyun.teautil.Common.assertAsString(error.message); + System.out.println ( error.getData ( ).get ( "Recommend" ) ); + com.aliyun.teautil.Common.assertAsString ( error.message ); } catch (Exception _error) { - TeaException error = new TeaException(_error.getMessage(), _error); + TeaException error = new TeaException ( _error.getMessage ( ), _error ); // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。 // 错误 message - System.out.println(error.getMessage()); + System.out.println ( error.getMessage ( ) ); // 诊断地址 - System.out.println(error.getData().get("Recommend")); - com.aliyun.teautil.Common.assertAsString(error.message); + System.out.println ( error.getData ( ).get ( "Recommend" ) ); + com.aliyun.teautil.Common.assertAsString ( error.message ); } + return null; } } diff --git a/ZhiLian-LoadBalancing/src/main/resources/application.yml b/ZhiLian-LoadBalancing/src/main/resources/application.yml index 52ca826..deda590 100644 --- a/ZhiLian-LoadBalancing/src/main/resources/application.yml +++ b/ZhiLian-LoadBalancing/src/main/resources/application.yml @@ -1,2 +1,13 @@ server: port: 84 +spring: + rabbitmq: + host: 111.229.102.61 + port: 5672 + username: guest + password: guest + virtualHost: / + redis: + host: 127.0.0.1 + port: 6379 + password: dyf@123