沉默是金,总会发光
大家好,我是沉默
设想一个最常见的微服务架构场景:
你有服务 A 和服务 B,它们要相互调用。但不同于单体架构时的“同一个屋檐下,随便喊一嗓子就行”,现在它们部署在不同机器、不同容器里,通信得通过 HTTP。问题来了:
服务 A 怎么知道服务 B 的地址?
服务 B 扩容或迁移了怎么办?A 难道要跟着改代码?
最初,我们会“写死”IP 和端口,用 RestTemplate 点对点访问。这在服务少的时候凑合用,一旦服务多了,简直就是灾难:
-
服务一动,配置跟着改,代码频繁部署;
-
多个服务互相引用,像蜘蛛网一样缠绕;
-
环境一变,全靠运维拍脑袋补锅。
硬编码依赖就像写死朋友的住址,搬个家就联系不上,靠不住!
**-**01-
注册中心登场
为了让服务自动“报到”并互相“认人”,注册中心应运而生。
它负责两件事:
-
服务注册(Register):服务上线后,自动把自己的“地址名片”报给注册中心。
-
服务发现(Discovery):服务消费者从注册中心那里获取目标服务的地址,实现动态调用。
来看一张图就明白了:
整个流程相当于:
-
服务提供者:我是谁,我在哪,来注册中心登记一下;
-
服务消费者:我要找谁,去注册中心查一查;
-
注册中心:你们都别喊了,我来牵线搭桥。
**-**02-
Nacos 打造注册中心
1 启动注册中心(Nacos)
Nacos 是阿里出品的注册中心,功能强大,界面友好。我们直接本地启动单机版:
# 进入 bin 目录,执行启动命令.\startup.cmd -m standalone
浏览器访问:http://localhost:8848
看到控制台界面,Nacos 就成功上线啦!
2 构建服务提供者(cloud-provider)
我们用 Spring Boot 创建一个简单的用户服务 UserController,提供用户信息接口:
@RestController@RequestMapping("/user")public class UserController { @GetMapping("info/{id}") public String getUserInfo(@PathVariable String id) { return JSONUtil.toJsonStr(newUserInfo(id, "cloud-provider")); }}
spring: profiles: active: dev cloud: nacos: discovery: server-addr: localhost:8848 namespace: dev application: name: cloud-provider
3 构建服务消费者(cloud-consumer)
另一个服务通过 RestTemplate 调用上面的接口:
@RestController@RequestMapping("userConsumers")public class UserConsumer { @Autowired private RestTemplate restTemplate; @GetMapping("info/{id}") public ResponseEntity<String> getUserInfo(@PathVariable String id){ return restTemplate.getForEntity("http://cloud-provider/user/info/" + id, String.class); }}
spring:
profiles:
active: dev
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: dev
application:
name: cloud-consumer
注意:服务名 cloud-provider 是注册到 Nacos 的逻辑名称,调用时无需关心 IP。
4 项目结构与依赖配置
我们采用 Maven 父子工程结构,服务提供者和消费者分别作为子模块。核心依赖如下:
<dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> </dependency> <!-- 其他依赖省略 --></dependencies>
<project> <parent> <groupId>com.example</groupId> <artifactId>nacos-demo</artifactId> <version>1.0.0</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies></project>
**-**03-
服务注册到底怎么发生的?
做开发不能只会用,还得懂它“是怎么跑起来的”。让我们揭开注册流程的幕后机制!
当你引入了 spring-cloud-starter-alibaba-nacos-discovery 依赖,Spring Boot 会自动加载:
@Configurationpublic class NacosServiceRegistryAutoConfiguration { @Bean public NacosServiceRegistry nacosServiceRegistry(...) {...} @Bean public NacosRegistration nacosRegistration(...) {...} @Bean public NacosAutoServiceRegistration nacosAutoServiceRegistration(...) {...}}
三大关键角色出现了:
| 组件
|
职责
|
| --- | --- |
| NacosServiceRegistry |
和 Nacos 通信,发起注册请求
|
| NacosRegistration |
封装当前服务实例的元数据
|
| NacosAutoServiceRegistration |
应用启动时自动注册服务
|
从注册动作开始,链路大致是:
服务启动 →NacosAutoServiceRegistration →创建 NacosRegistration →交给 NacosServiceRegistry →注册到 Nacos Server
关键注册方法:
public void register(Registration registration) { Instanceinstance= getNacosInstanceFromRegistration(registration); namingService.registerInstance(serviceId, group, instance);}
核心动作是:
1. 构建当前服务实例对象;
2. 调用 `registerInstance` 注册进 Nacos。
**\-****04\-**
****总结****
**注册中心的意义**
它是微服务通信的“导航台”,让服务不再靠硬编码找朋友,而是动态发现、自动连接。
**Nacos 的优势**
使用简单、界面友好、支持注册+配置中心功能,还能热更新服务实例。
热门文章
[一套能保命的高并发实战指南](https://mp.weixin.qq.com/s?__biz=MzUzNTYzMjI1OQ==&mid=2247484731&idx=1&sn=c523b4d5dbd1bba759f60ff739935728&scene=21#wechat_redirect)
[架构师必备:用 AI 快速生成架构图](https://mp.weixin.qq.com/s?__biz=MzUzNTYzMjI1OQ==&mid=2247484676&idx=1&sn=b3c06294233d74905b15492108d9272f&scene=21#wechat_redirect)
**\-****05\-**
**粉丝福利**
我这里创建一个程序员成长&副业交流群,和一群志同道合的小伙伴,一起聚焦自身发展,可以聊:技术成长与职业规划,分享路线图、面试经验和效率工具,探讨多种副业变现路径,从写作课程到私活接单,主题活动、打卡挑战和项目组队,让志同道合的伙伴互帮互助、共同进步。如果你对这个特别的群,感兴趣的,可以加一下,微信通过后会拉你入群,但是任何人在群里打任何广告,都会被我T掉。