1.服务注册与发现
1.1 注册中心原理
在微服务远程调用的过程中,包括俩个角色:
- 服务提供者:提供接口供其他微服务访问
- 服务消费者:调用其他微服务接口
在大型微服务项目中,服务提供者的数量会非常多,为了管理这些服务就引入注册中心的概念。
1.2 数据库准备 用作持久化
我们基于Docker来部署Nacos的注册中心,首先我们要准备MySQL数据库表,用来存储Nacos的数据。由于是Docker部署,所以大家需要将资料中的SQL文件(github上可以找到这个sql文件)导入到你Docker中的MySQL容器中:
然后修改nacos文件中的custom.env文件
1 2 3 4 5 6 7 8 9
| PREFER_HOST_MODE=hostname MODE=standalone SPRING_DATASOURCE_PLATFORM=mysql MYSQL_SERVICE_HOST=192.168.163.128//宿主机ip地址修改为自己的 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
|
最后将nacos目录上传至虚拟机/root目录。进入root目录执行:
1 2 3 4 5 6 7 8
| docker run -d \ --name nacos \ --env-file ./nacos/custom.env \ -p 8848:8848 \ -p 9848:9848 \ -p 9849:9849 \ --restart=always \ nacos/nacos-server:v2.1.0-slim
|
启动完成后,访问下面地址:http://192.168.163.128:8848/nacos/,注意将`192.168.163.128`替换为你自己的虚拟机IP地址。
首次访问会跳转到登录页,账号密码都是nacos
1.3 服务注册
1.3.1 添加依赖
1 2 3 4 5
| <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>${latest.version}</version> </dependency>
|
1.3.2 配置nacos
application.yml
中添加nacos地址配置:
1 2 3 4 5 6
| spring: application: name: item-service # 服务名称 cloud: nacos: server-addr: 192.168.163.128:8848 # nacos地址
|
1.4 服务发现
服务的消费者要去nacos订阅服务,这个过程就是服务发现,步骤如下:
1.4.1 引入依赖
1 2 3 4 5
| <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>${latest.version}</version> </dependency>
|
可以发现,这里Nacos的依赖于服务注册时一致,这个依赖中同时包含了服务注册和发现的功能。因为任何一个微服务都可以调用别人,也可以被别人调用,即可以是调用者,也可以是提供者。
1.4.2 配置Nacos地址
1 2 3 4
| spring: cloud: nacos: server-addr: 192.168.163.128:8848
|
1.4.3 发现并调用服务
服务发现需要用到一个工具,DiscoveryClient,SpringCloud已经帮我们自动装配,我们可以直接注入使用:
1 2 3 4 5 6 7 8
| @Service @RequiredArgsConstructor public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {
private final RestTemplate restTemplate;
private final DiscoveryClient discoveryClient;
|
其中 DiscoveryClient用于服务发现:RestTemplate用于服务调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet()); List<ServiceInstance> instances = discoveryClient.getInstances("item-service"); if(CollUtils.isEmpty(instances)){ return; } ServiceInstance instance = instances.get(RandomUtil.randomInt(instances.size())); ResponseEntity<List<ItemDTO>> response = restTemplate.exchange( instance.getUri()+"/items?ids={ids}", HttpMethod.GET, null, new ParameterizedTypeReference<List<ItemDTO>>() { }, Map.of("ids", CollUtil.join(itemIds, ",")) ); if(!response.getStatusCode().is2xxSuccessful()){ return; }
|
利用RestTemplate调用了解即可,因为更合适的还是利用Openfeign组件来进行服务调用。