服务的注册与发现(nacos)服务注册与发现 服务注册与发现是微服务架构中的核心概念之一。当我们在进行微服务的开发时,会
服务注册与发现
服务注册与发现是微服务架构中的核心概念之一。但我们在进行微服务的开发时,会产生多个不同的服务,然后每一个服务都在于不同的服务器当中,并且每一个服务都可能会进行部署多个实例。此时,如果另外一个服务需要调用当前服务时,我们当然可以在代码中写一个固定的url来进行调用,但是如果这个服务宕机了呢?
业务场景
现在有一个业务场景,你有一个商城的项目,它有支付模块,订单模块,购物车模块,商品模块,现在你需要将这些模块单独的查分出来每一个模块都需要部署在单独的服务器上,如图:
现在存在的一个业务场景就是,你需要将商品添加到购物车当中去,因此你需要调用商品的服务(item-service),你当然可以使用Spring提供的RestTemplate来调用远程服务,或者其他的方法,如下:
ResponseEntity<List<ItemDTO>> exchange = restTemplate.exchange(
"http://localhost:8080/items?ids={ids}",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<ItemDTO>>() {
},
Map.of("ids", CollUtil.join(itemIds, ","))
);
但是这样的话,商品服务的url就成为了硬编码了,不利于后续的修改。比如当你在一个服务器上部署了多个实例时,你当前使用的服务器宕机了,那么你就需要重新修改url,重启服务器,这时候就需要第三方来帮我们管理“存活”的服务器,然后我们在代码中只需要向第三方获取url就可以了。这时候就需要引入服务注册中心的概念了。
服务注册中心
在微服务远程调用的过程中,包括两个角色:
- 服务提供者:提供接口供其它微服务访问,比如
item-service
- 服务消费者:调用其它微服务提供的接口,比如
cart-service
整体流程:
- 服务启动时就会注册自己的服务信息(服务名、IP、端口)到注册中心
- 调用者可以从注册中心订阅想要的服务,获取服务对应的实例列表(1个服务可能多实例部署)
- 当服务有新实例启动时,会发送注册服务请求,其信息会被记录在注册中心的服务实例列表
- 当注册中心服务列表变更时,会主动通知微服务,更新本地服务列表(本地缓存)
nacos注册中心
常见的注册中心框架有:
- Eureka:Netflix 开源的服务发现框架,常用于 Spring Cloud 生态系统中。
- Consul:HashiCorp 提供的服务网格解决方案,支持服务发现、健康检查等功能。
- Zookeeper:Apache 的一款开源分布式协调服务,可以用来实现服务注册与发现。
- Nacos:阿里巴巴开源的服务发现与配置管理平台,集成了服务发现和动态配置管理功能。 nacos相较于其他的框架功能稍微强大一点,而且nacos是Alibaba开源,中文文档比较丰富,相对来说更友好。 新版的nacos需要导入一个数据库nacos.sql并且nacos需要依赖于Java环境,所以你需要确保有jdk,nacos官方文档(Nacos 快速开始)
服务注册
接下来试着将服务(item-service)这个到nacos上去,
- 引入依赖
- 配置Nacos地址
- 重启你的服务
添加依赖
在你的服务中添加nacos依赖
<!--nacos 服务注册发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置nacos
在项目的yaml文件中配置nacos的地址。
spring:
application:
name: item-service # 服务名称
cloud:
nacos:
discovery:
server-addr: localhost:8848 # nacos地址
启动nacos
启动你的nacos,进入你的nacos的bin目录,输入cmd进入命令行窗口输入
startup.cmd -m standalone
后然启动你的服务,在浏览器输入你配置的nacos地址,就可以看见的注册的服务了,别忘了后面加上nacos
http://localhost:8848/nacos
登录帐号,密码都是nacos 注册成功后就是如下页面了
服务发现
现在服务已经注册到了nacos中,就下来就是如何去发现并订阅这个服务了
服务发现除了要引入nacos依赖以外,由于还需要负载均衡,因此要引入SpringCloud提供的LoadBalancer依赖。我们在服务(cart-service
)中的pom.xml
中添加下面的依赖:
<!--nacos 服务注册发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
并且任何一个服务都可能是别的服务提供者,所以cart-service也需要注册到nacos中,
配置yaml
server:
port: 8082
spring:
application:
name: cart-service # 这一条一定不能为空,因为她是注册到naocs的服务名
cloud:
nacos:
discovery:
server-addr: localhost:8848
接下来,服务调用者cart-service
就可以去订阅item-service
服务了。不过item-service有多个实例,而真正发起调用时只需要知道一个实例的地址。
因此,服务调用者必须利用负载均衡的算法,从多个实例中挑选一个去访问。常见的负载均衡算法有:
- 随机
- 轮询
- IP的哈希
- 最近最少访问
- ....
这里使用随机负载均衡,服务发现需要用到一个工具,DiscoveryClient,SpringCloud已经帮我们自动装配,我们可以直接注入使用:
由于SpringCloud已经自带了DiscoveryClient我们只需要将他注入进来就行了
private final DiscoveryClient discoveryClient;
List<ServiceInstance> instances = discoveryClient.getInstances("item-service");
int index = RandomUtil.randomInt(instances.size());
// 2.远程调用
ResponseEntity<List<ItemDTO>> exchange = restTemplate.exchange(
instances.get(index).getUri() + "/items?ids={ids}",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<ItemDTO>>() {
},
Map.of("ids", CollUtil.join(itemIds, ","))
);
改造就到此结束辣,感谢您的观看,记得点赞哦,我只是一个菜鸡,欢迎点评。
转载自:https://juejin.cn/post/7424414729858433062