为了避免单点故障,微服务架构下会采取集群方式的高可用部署
- 注册中心解决的问题
1.维护集群的每个节点的请求地址
2.防止请求发送到已宕机的节点上造成请求失败 - 注册中心功能
1.服务地址管理
2.服务注册
3.服务动态感知
ZooKeeper、Eureka、Consul、Etcd、Nacos等组件都可以实现以上功能
- 什么是Alibaba Nacos
- Nacos的基本使用
- Nacos的高可用部署(集群)
- Dubbo使用Nacos实现注册中心
- Spring Cloud Alibaba Nacos Discovery整合
- Nacos实现原理分析
- 解读Nacos源码
什么是Alibaba Nacos
官网地址: https://nacos.io/zh-cn/docs/what-is-nacos.html
Nacos致力于解决为服务中的统一配置、服务注册与发现,帮助开发者快速实现动态服务发现、服务配置、服务元数据及流量管理
看到nacos修复一个安全漏洞,🤣!!!
Nacos地图
!!!踩坑:Nacos编译后的版本不支持Mysql8
如果需要支持使用Mysql8,需要自己下载源码修改支持Mysql8的依赖后再编译
Nacos的关键特性
- 服务发现和服务健康检测
1.消费者可适用DNS、HTTP、API查找和发现服务
2.提供对服务的实时的健康检查,阻止向不健康主机或服务实例发送请求
3.提供统一的健康检查仪表盘,帮助根据健康状态管理服务的可用性及流量 - 动态配置服务
1.动态配置服务可去中心化,配置变更时不用重新打包部署,配置管理变得更加高效和敏捷
2.简洁易用的UI帮助用户管理所有服务和应用 - 动态DNS服务
更容易实现中间层负载均衡、更灵活的路由策略、流量控制 - 服务及其元数据管理
管理数据中心所有的服务及元数据
Nacos的基本使用
基于Java编写,需要JRE环境
Nacos的安装
https://nacos.io/zh-cn/docs/quick-start.html
官网说的很详细,不再赘述,贴个图,我选择编译好的1.4.1版本
Nacos服务注册与发现相关API说明
官网提供了Java SDK和Open API,其他语言的SDK非官方发布,官网也说的很详细,简单罗列服务注册相关核心接口
注册实例
将服务地址信息注册到Nacos Server
- OPAPI
- Java SDK
获取全部实例列表
- OPAPI
- Java SDK
监听服务
监听指定服务下的实例变化,让客户端及时感知服务提供者实例变化
- OPAPI
和获取全部实例列表的API是一样的 - Java SDK
Nacos集成Spring Boot实现服务注册与发现
实现一个简单的服务注册与发现
- 1.添加nacos注册中心依赖
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>0.2.4</version>
</dependency>
- 2.使用Nacos的@NacosInjected注解注入Nacos的NamingService,通过getAllInstances方法可得到所有实例
@RestController
public class DiscoveryController {
@NacosInjected
private NamingService namingService;
@GetMapping("/discovery")
public List<Instance> get(@RequestParam String serviceName) throws NacosException {
return namingService.getAllInstances(serviceName);
}
}
- 添加配置文件
nacos.discovery.server-addr=127.0.0.1:8848
- 单机启动Nacos(sh startup.sh -m standalone)及该项目
根据Open API调用查询名为example的提供者,返回空对象
- 利用Open API向Nacos注册提供者
注册成功后Nacos控制台可以查看到刚刚注册的提供者信息
- 由于Nacos的心跳机制健康检查,几秒后该服务提供者会从Nacos删去信息
Nacos的高可用部署(集群)
分布式架构中,任何中间件及应用都不应该单点存在,开源组件一般都支持高可用集群解决方案。
类似于ZooKeeper和Redis,Nacos集群也采用主从节点,其数据一致性算法采用Raft和Redis Sentinel选举一样
安装配置环境要求
- JDK1.8及以上
- Maven3.2及以上
- MySQL
- ...
官网有详细步骤不细说
Dubbo使用Nacos实现注册中心
Dubbo支持多种注册中心
接口暴露模块
public interface IHelloService {
String sayHello(String name);
}
接口实现模块
- 依赖
dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.gupaoedu.book.nacos</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>nacos-sample-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>0.2.4</version>
<exclusions>
<exclusion>
<groupId>com.alibaba.spring</groupId>
<artifactId>spring-context-support</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.5</version>
</dependency>
- 接口实现类及启动类
@Service
public class HelloServiceImpl implements IHelloService {
@Override
public String sayHello(String name) {
return "Hello World:"+name;
}
}
@DubboComponentScan
@SpringBootApplication
public class NacosSampleProviderApplication {
public static void main(String[] args) {
SpringApplication.run(NacosSampleProviderApplication.class, args);
}
}
- Nacos控制台数据
Spring Cloud Alibaba Nacos Discovery整合
Spring Cloud Alibaba Nacos Discovery可以基于Spring Cloud规范快速接入Nacos,实现服务注册与发现
服务端
接口暴露模块
public interface IHelloService {
String sayHello(String name);
}
接口实现模块
- 项目依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.gupaoedu.book.nacos</groupId>
<artifactId>spring-cloud-nacos-sample-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
- 实现类
@Service
public class HelloServiceImpl implements IHelloService {
@Override
public String sayHello(String s) {
return "Hello World:"+s;
}
}
- 启动类
@SpringBootApplication
public class SpringCloudNacosSampleProviderApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudNacosSampleProviderApplication.class, args);
}
}
- 配置文件
spring.application.name=spring-cloud-nacos-sample
dubbo.scan.base-packages=com.gupaoedu.book.nacos.bootstrap
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#Dubbo注册中心挂载到Spring Cloud注册中心,不配置会报没有注册中心的错误错
dubbo.registry.address=spring-cloud://localhost
#Nacos注册中心地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
- 启动提供者
消费端
- 项目依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.gupaoedu.book.nacos</groupId>
<artifactId>spring-cloud-nacos-sample-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
<version>2.1.1.RELEASE</version>
- 配置文件
dubbo.cloud.subscribed-services=spring-cloud-nacos-sample
dubbo.scan.base-packages=com.gupaoedu.book.nacos.bootstrap
spring.application.name=spring-cloud-nacos-consumer
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
- 远程引用类
@RestController
public class HelloController {
@Reference
private IHelloService helloService;
@GetMapping("/say")
public String sayHello(){
return helloService.sayHello("Mic");
}
}
- 启动类
@SpringBootApplication
public class SpringCloudNacosConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudNacosConsumerApplication.class, args);
}
}
- 启动项目,调取接口
总结
Zookeeper和Nacos基于Spring Cloud标准实现,所以集成方式差不大多
Nacos实现原理分析
Nacos架构图
https://nacos.io/zh-cn/docs/architecture.html
官网N多架构图,贴一张
- Provider APP:服务提供者
- Consumer APP:服务消费者
- Name Server:通过VIP(Vritual IP)或者DNS实现Nacos高可用集群路由
- Nacos Server:Nacos服务提供者,包含:
1.Open API:功能访问入口
2.Config Service:配置服务
3.Name Service:名字服务
4.Consistency Protocol:一致性协议,实现集群节点数据同步使用Raft算法 - Nacos Console:Nacos控制台
注册中心的原理
注册中心的功能体现
- 服务实例在启动时注册到服务注册表,关闭时注销
- 消费者轮询查询注册表,获得可用实例
- 注册中心可以调用服务实例的健康检查API验证其能否处理请求
解读Nacos源码
分析:
- 服务注册
- 服务地址的获取
- 服务地址变化感知
Spring Cloud注册服务
Spring Cloud规范提供服务注册标准的接口为ServiceRegistry,集成到Spring Cloud中实现注册服务的组件都需要实现该接口
package org.springframework.cloud.client.serviceregistry;
public interface ServiceRegistry<R extends Registration> {
void register(R registration);
void deregister(R registration);
void close();
void setStatus(R registration, String status);
<T> T getStatus(R registration);
}
Spring Cloud集成Nacos的实现过程
spring.factories文件类里面包含自动装配的信息,这也是SpringBoot自动装配的原理,
AutoServiceRegistrationAutoConfiguration是实现自动装配服务注册相关的配置类
@Configuration
@Import({AutoServiceRegistrationConfiguration.class})
@ConditionalOnProperty(
value = {"spring.cloud.service-registry.auto-registration.enabled"},
matchIfMissing = true
)
public class AutoServiceRegistrationAutoConfiguration {
@Autowired(
required = false
)
private AutoServiceRegistration autoServiceRegistration;
@Autowired
private AutoServiceRegistrationProperties properties;
public AutoServiceRegistrationAutoConfiguration() {
}
@PostConstruct
protected void init() {
if (this.autoServiceRegistration == null && this.properties.isFailFast()) {
throw new IllegalStateException("Auto Service Registration has been requested, but there is no AutoServiceRegistration bean");
}
}
}
//其他源代码略
//TODO
Comments | 0 条评论