服务治理
服务治理
在微服务项目中,由于每个服务都是一个独立的服务,那么如何实现服务之间的调用呢?
远程调用
就是服务A发起请求服务B的数据
如何发起请求
spring给我们提供了RestTemplate工具,可以方便的实现http请求
使用步骤
- 注入
RestTemplate到spring的IOC容器中
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
- 使用
RestTemplate发起请求
public <T> ResponseEntity<T> exchange(
String url, //请求路径
HttpMethod method,//请求方式
@Nullable HttpEntity<?> requestEntity,//请求实体
Class<T> responseType,//返回值类型
Map<String, ?> uriVariables//请求参数
) {
}
- 使用
public void getText() {
//发起请求
ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
"http://localhost:8082/items?ids={ids}",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<ItemDTO>>() {
},
Map.of("ids", CollUtil.join(itemIds, ","))
);
//查询是否请求成功
if (!response.getStatusCode().is2xxSuccessful()) return;
//请求成功 获取数据
List<ItemDTO> items = response.getBody();
}
服务远程调用存在的问题
- 在服务A中发起请求服务B的数据,需要写出服务B的接口地址,ip地址,端口号,请求参数,请求方式等等
- 服务A和B之间存在依赖关系,如果服务B的接口地址或者ip地址发生改变,那么服务A也需要跟着改变
- 在实际部署中,一个服务可能会部署多个实例,那么服务A如何知道请求的是哪一个实例呢?(负载均衡)
注册中心原理
服务治理中的三个角色
- 服务提供者:提供服务,将服务注册到注册中心中,
- 服务调用者:从注册中心中获取服务提供者,调用服务
- 注册中心:保存服务提供者的信息,提供服务调用者获取服务提供者的信息
调用者如何知道提供者的地址
- 所有的服务提供者在服务启动时都需要在注册中心中注册信息
- 当服务调用者向注册中心请求服务提供者信息时,注册中心会返回服务提供者的信息
调用者如何得知服务状态变更
心跳续约
- 如果某一个服务提供者挂了,那么注册中心会删除服务提供者的信息
- 服务提供者定期向注册中心发送请求,报告自己的存活状态
- 如果服务提供者没有向注册中心发送心跳,那么注册中心会认为服务提供者已经挂了,删除服务提供者的信息
推动变更
- 如果某一个服务提供者挂了,那么注册中心会删除服务提供者的信息,并推送一个事件给服务调用者,服务调用者会根据事件进行服务调用
当提供者有多个实例时,调用者该选择哪一个
负载均衡算法
- 随机: 随机选择一个实例
- 轮询: 按照顺序选择实例
- 权重: 按照权重选择实例
- 源地址Hash: 按照源地址Hash选择实例
- 最小连接数: 按照最小连接数选择实例
- 最小响应时间: 按照最小响应时间选择实例
- 源地址一致: 按照源地址一致选择实例
- 随机加权: 按照随机加权选择实例
- 源地址一致加权: 按照源地址一致加权选择实例
Nacos注册中心
-Nacos是目前国内企业中占比最多的注册中心组件,它是阿里巴巴的产品,目前已经加入SpringCloudAlibaba中。
配置
我们基于Docker来部署注册中心,首先要准备mySql数据库表,用来存储Nacos数据。
-- --------------------------------------------------------
-- 主机: 192.168.150.101
-- 服务器版本: 8.0.27 - MySQL Community Server - GPL
-- 服务器操作系统: Linux
-- HeidiSQL 版本: 12.2.0.6576
-- --------------------------------------------------------
/*!40101 SET @OLD_CHARACTER_SET_CLIENT = @@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE = @@TIME_ZONE */;
/*!40103 SET TIME_ZONE = '+00:00' */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS = @@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS = 0 */;
/*!40101 SET @OLD_SQL_MODE = @@SQL_MODE, SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES = @@SQL_NOTES, SQL_NOTES = 0 */;
-- 导出 nacos 的数据库结构
DROP DATABASE IF EXISTS `nacos`;
CREATE DATABASE IF NOT EXISTS `nacos` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION = 'N' */;
USE `nacos`;
-- 导出 表 nacos.config_info 结构
DROP TABLE IF EXISTS `config_info`;
CREATE TABLE IF NOT EXISTS `config_info`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
`group_id` varchar(128) COLLATE utf8_bin DEFAULT NULL,
`content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
`md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COLLATE utf8_bin COMMENT 'source user',
`src_ip` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
`app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL,
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
`c_desc` varchar(256) COLLATE utf8_bin DEFAULT NULL,
`c_use` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`effect` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`type` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`c_schema` text COLLATE utf8_bin,
`encrypted_data_key` text COLLATE utf8_bin NOT NULL COMMENT '秘钥',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`, `group_id`, `tenant_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb3
COLLATE = utf8_bin COMMENT ='config_info';
-- 正在导出表 nacos.config_info 的数据:~0 rows (大约)
DELETE
FROM `config_info`;
-- 导出 表 nacos.config_info_aggr 结构
DROP TABLE IF EXISTS `config_info_aggr`;
CREATE TABLE IF NOT EXISTS `config_info_aggr`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
`group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
`datum_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'datum_id',
`content` longtext COLLATE utf8_bin NOT NULL COMMENT '内容',
`gmt_modified` datetime NOT NULL COMMENT '修改时间',
`app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL,
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`, `group_id`, `tenant_id`, `datum_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb3
COLLATE = utf8_bin COMMENT ='增加租户字段';
-- 正在导出表 nacos.config_info_aggr 的数据:~0 rows (大约)
DELETE
FROM `config_info_aggr`;
-- 导出 表 nacos.config_info_beta 结构
DROP TABLE IF EXISTS `config_info_beta`;
CREATE TABLE IF NOT EXISTS `config_info_beta`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
`group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
`app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
`content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
`beta_ips` varchar(1024) COLLATE utf8_bin DEFAULT NULL COMMENT 'betaIps',
`md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COLLATE utf8_bin COMMENT 'source user',
`src_ip` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
`encrypted_data_key` text COLLATE utf8_bin NOT NULL COMMENT '秘钥',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`, `group_id`, `tenant_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb3
COLLATE = utf8_bin COMMENT ='config_info_beta';
-- 正在导出表 nacos.config_info_beta 的数据:~0 rows (大约)
DELETE
FROM `config_info_beta`;
-- 导出 表 nacos.config_info_tag 结构
DROP TABLE IF EXISTS `config_info_tag`;
CREATE TABLE IF NOT EXISTS `config_info_tag`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
`group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
`tag_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'tag_id',
`app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
`content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
`md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`src_user` text COLLATE utf8_bin COMMENT 'source user',
`src_ip` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`, `group_id`, `tenant_id`, `tag_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb3
COLLATE = utf8_bin COMMENT ='config_info_tag';
-- 正在导出表 nacos.config_info_tag 的数据:~0 rows (大约)
DELETE
FROM `config_info_tag`;
-- 导出 表 nacos.config_tags_relation 结构
DROP TABLE IF EXISTS `config_tags_relation`;
CREATE TABLE IF NOT EXISTS `config_tags_relation`
(
`id` bigint NOT NULL COMMENT 'id',
`tag_name` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'tag_name',
`tag_type` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'tag_type',
`data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
`group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
`nid` bigint NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`nid`),
UNIQUE KEY `uk_configtagrelation_configidtag` (`id`, `tag_name`, `tag_type`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb3
COLLATE = utf8_bin COMMENT ='config_tag_relation';
-- 正在导出表 nacos.config_tags_relation 的数据:~0 rows (大约)
DELETE
FROM `config_tags_relation`;
-- 导出 表 nacos.group_capacity 结构
DROP TABLE IF EXISTS `group_capacity`;
CREATE TABLE IF NOT EXISTS `group_capacity`
(
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`group_id` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
`quota` int unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
`max_aggr_size` int unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb3
COLLATE = utf8_bin COMMENT ='集群、各Group容量信息表';
-- 正在导出表 nacos.group_capacity 的数据:~0 rows (大约)
DELETE
FROM `group_capacity`;
-- 导出 表 nacos.his_config_info 结构
DROP TABLE IF EXISTS `his_config_info`;
CREATE TABLE IF NOT EXISTS `his_config_info`
(
`id` bigint unsigned NOT NULL,
`nid` bigint unsigned NOT NULL AUTO_INCREMENT,
`data_id` varchar(255) COLLATE utf8_bin NOT NULL,
`group_id` varchar(128) COLLATE utf8_bin NOT NULL,
`app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
`content` longtext COLLATE utf8_bin NOT NULL,
`md5` varchar(32) COLLATE utf8_bin DEFAULT NULL,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`src_user` text COLLATE utf8_bin,
`src_ip` varchar(50) COLLATE utf8_bin DEFAULT NULL,
`op_type` char(10) COLLATE utf8_bin DEFAULT NULL,
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
`encrypted_data_key` text COLLATE utf8_bin NOT NULL COMMENT '秘钥',
PRIMARY KEY (`nid`),
KEY `idx_gmt_create` (`gmt_create`),
KEY `idx_gmt_modified` (`gmt_modified`),
KEY `idx_did` (`data_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb3
COLLATE = utf8_bin COMMENT ='多租户改造';
-- 正在导出表 nacos.his_config_info 的数据:~0 rows (大约)
DELETE
FROM `his_config_info`;
-- 导出 表 nacos.permissions 结构
DROP TABLE IF EXISTS `permissions`;
CREATE TABLE IF NOT EXISTS `permissions`
(
`role` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
`resource` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
`action` varchar(8) COLLATE utf8mb4_general_ci NOT NULL,
UNIQUE KEY `uk_role_permission` (`role`, `resource`, `action`) USING BTREE
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
-- 正在导出表 nacos.permissions 的数据:~0 rows (大约)
DELETE
FROM `permissions`;
-- 导出 表 nacos.roles 结构
DROP TABLE IF EXISTS `roles`;
CREATE TABLE IF NOT EXISTS `roles`
(
`username` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
`role` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
UNIQUE KEY `idx_user_role` (`username`, `role`) USING BTREE
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
-- 正在导出表 nacos.roles 的数据:~1 rows (大约)
DELETE
FROM `roles`;
INSERT INTO `roles` (`username`, `role`)
VALUES ('nacos', 'ROLE_ADMIN');
-- 导出 表 nacos.tenant_capacity 结构
DROP TABLE IF EXISTS `tenant_capacity`;
CREATE TABLE IF NOT EXISTS `tenant_capacity`
(
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`tenant_id` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Tenant ID',
`quota` int unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
`max_aggr_size` int unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb3
COLLATE = utf8_bin COMMENT ='租户容量信息表';
-- 正在导出表 nacos.tenant_capacity 的数据:~0 rows (大约)
DELETE
FROM `tenant_capacity`;
-- 导出 表 nacos.tenant_info 结构
DROP TABLE IF EXISTS `tenant_info`;
CREATE TABLE IF NOT EXISTS `tenant_info`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
`kp` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'kp',
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
`tenant_name` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_name',
`tenant_desc` varchar(256) COLLATE utf8_bin DEFAULT NULL COMMENT 'tenant_desc',
`create_source` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'create_source',
`gmt_create` bigint NOT NULL COMMENT '创建时间',
`gmt_modified` bigint NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`, `tenant_id`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb3
COLLATE = utf8_bin COMMENT ='tenant_info';
-- 正在导出表 nacos.tenant_info 的数据:~0 rows (大约)
DELETE
FROM `tenant_info`;
-- 导出 表 nacos.users 结构
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users`
(
`username` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
`password` varchar(500) COLLATE utf8mb4_general_ci NOT NULL,
`enabled` tinyint(1) NOT NULL,
PRIMARY KEY (`username`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
-- 正在导出表 nacos.users 的数据:~1 rows (大约)
DELETE
FROM `users`;
INSERT INTO `users` (`username`, `password`, `enabled`)
VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', 1);
/*!40103 SET TIME_ZONE = IFNULL(@OLD_TIME_ZONE, 'system') */;
/*!40101 SET SQL_MODE = IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS = IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */;
/*!40101 SET CHARACTER_SET_CLIENT = @OLD_CHARACTER_SET_CLIENT */;
/*!40111 SET SQL_NOTES = IFNULL(@OLD_SQL_NOTES, 1) */;
新建nacos/custom.env配置文件
用于存储nacos配置信息
# nacos 配置
PREFER_HOST_MODE=hostname # 数据库模式
MODE=standalone # 运行模式
SPRING_DATASOURCE_PLATFORM=mysql # 使用的数据库
MYSQL_SERVICE_HOST=192.168.150.101 # 数据库地址
MYSQL_SERVICE_DB_NAME=nacos # 数据库名称
MYSQL_SERVICE_PORT=3306 # 数据库端口
MYSQL_SERVICE_USER=root # 数据库用户名
MYSQL_SERVICE_PASSWORD=123 # 数据库密码
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
上传nvcos镜像
-i:--input的缩写 用于指定输入的镜像文件
docker load -i .\nacos.tar
部署nacos
docker run -d --name nacos --env-file ./custom.env -p 8848:8848 -p 9848:9848 -p 9849:9849 --restart=always nacos/nacos-server:v2.1.0-slim
服务注册
引入nacos依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置nacos地址
spring:
application: name:item-service
cloud:
nacos:
server-addr: 192.168.150.101:8848 # nacos地址
启动nacos
启动nacos服务,并访问http://[nacos地址]:8848/nacos/ 出现nacos登录页面,登录成功后,在服务管理中即可查看服务注册情况
服务发现
订阅者需要链接nacos以拉取和订阅服务,因此服务发现的前两步与服务注册一样,后面再加上服务调用即可:
引入nacos discovery依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置nacos地址
spring:
cloud:
nacos:
server-addr: 192.168.150.101:8848
服务发现
private final DiscoveryClient discoveryClient;
private void handleCartItems(list<CartVo> cartItems) {
//通过nacos获取服务提供者列表
List<ServiceInstance> itemServiceInstanceList = discoveryClient.getInstances("item-service");
//通过负载均衡随机挑选一个调用者
ServiceInstance itemServiceInstance = itemServiceInstanceList.get(RandomUtil.randomInt(itemServiceInstanceList.size()));
//获取服务提供者的地址
URI itemServiceInstanceUri = itemServiceInstance.getUri();
//发起请求
ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
itemServiceInstanceUri + "/items?ids={ids}",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<ItemDTO>>() {
},
Map.of("ids", CollUtil.join(itemIds, ","))
);
}