SpringCloud Alibaba系列 Nacos(一)
SpringCloudAlibaba官网:Spring Cloud Alibaba
SpringCloudAlibaba全家桶
服务注册发现:Nacos
服务限流降级:Sentinel
分布配置中心:Nacos
服务网关:SpringCloud Gateway
服务之间调用:Feign、Ribbon
链路追踪:Sleuth+Zipkin
注册中心(服务治理)
-
什么是注册中心(服务治理)?
- 服务注册:服务提供者provider,启动的时候向注册中心上报自己的网络信息
- 服务发现:服务消费者consumer,启动的时候向注册中心上报自己的网络信息,拉取provider的相关网络信息
- 核心:服务管理,有个服务注册表,心跳机制动态维护,服务实例在启动时注册到服务注册表,并在关闭时注销
- 注册中心的作用?
微服务应用和机器越来越多,调用方需要知道接口的网络地址,如果靠配置文件的方式去控制网络地址,对于动态新增机器,维护带来很大问题
-
主流的注册中心有哪些?
zookeeper、Eureka、consul、etcd、Nacos
什么是Nacos?
Nacos官网:https://nacos.io/zh-cn/
- Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
- Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
- Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
上手Nacos
-
环境准备
- 64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。
- 64 bit JDK 1.8+
- Maven 3.2.x+
- Nacos需要至少2核CPU 4G内存 60g*3的机器配置下运行。
-
从 Github 上下载 Nacos
https://github.com/alibaba/nacos
-
启动 Nacos 服务
Windows
cd nacos/bin
startup.cmd -m standalone // 单机启动
Linux
cd nacos/bin
sh startup.sh -m standalone // 单机启动
-
关闭 Nacos 服务
Windows
双击 shutdown.cmd
Linux
sh shutdown.sh
默认端口 8848
访问地址:http://ip:8848/nacos
默认账号密码:nacos/nacos
SpringCloud Alibaba 整合 Nacos 实现服务的注册与发现
maven版本管理如下
<properties>
<!-- jdk版本 -->
<java.version>17</java.version>
<!-- maven 打包版本 -->
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
<!-- 编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring.boot.version>2.7.4</spring.boot.version>
<spring.cloud.version>2021.0.4</spring.cloud.version>
<spring.cloud.alibaba.version>2021.0.4.0</spring.cloud.alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- spring boot 版本 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud 版本 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud alibaba 版本 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
子服务 pom 中添加注册发现依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
application.yml 文件配置 nacos
spring:
application:
# 配置子服务名称
name: user-service
cloud:
nacos:
# 配置 nacos 服务地址
discovery:
server-addr: 127.0.0.1:8848
通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能
启动子服务,可以看到服务已经在 nacos 注册成功
Nacos注册中心的作用?
当没有注册中心的时候,A服务调用B服务如下
http://B的ip:端口/api?xxx=xxx
使用Nacos
http://serviceInstance.getHost()+serviceInstance.getPort()/api?xxx=xxx
示例 (没有负载均衡)
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
/**
* 用户服务调用订单服务
* @param orderId 订单id
*/
@Override
public OrderDO getOrderDetail(Long orderId) {
List<ServiceInstance> list = discoveryClient.getInstances("order-service");
ServiceInstance serviceInstance = list.get(0);
OrderDO orderDO = restTemplate.getForObject("http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/order/one?orderId="+orderId, OrderDO.class);
return orderDO;
}
}
示例(带客户端负载均衡)
<!-- 调用方添加此依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private RestTemplate restTemplate;
/**
* 用户服务调用订单服务
*
* @param orderId 订单id
*/
@Override
public OrderDO getOrderDetail(Long orderId) {
OrderDO orderDO = restTemplate.getForObject("http://order-service/order/one?orderId=" + orderId, OrderDO.class);
return orderDO;
}
}