当前位置:网站首页>自定义RPC项目——常见问题及详解(注册中心)
自定义RPC项目——常见问题及详解(注册中心)
2022-07-06 09:21:00 【李孛欢】
书接上回,自定义RPC项目——常见问题及详解(Netty篇)_李孛欢的博客-CSDN博客,我们接着来谈,这个RPC项目的常见问题:
项目地址:https://blog.csdn.net/qq_40856284/category_10138756.html
四、注册中心
1.为什么要用注册中心?
在进行注册中心使用和学习之前,我们首先就要明确一点,为什么要用注册中心呢?随着互联网架构发展(单一应用架构==>垂直应用架构==>分布式架构==>SOA架构==>微服务架构),服务越来越多,服务间的依赖关系也更加复杂,采用直接调用服务方式难度大,实现过程也更复杂,以及为了提高服务的可靠性,注册中心应运而生。
注册中心这一概念在面向服务设计的架构中起着举足轻重的作用,不论是在SOA架构还是微服务架构之中,注册中心的作用一句话概括就是存放和调度服务,实现服务和注册中心,服务和服务之间的相互通信。注册中心可以说是微服务架构中的”通讯录“,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就到这里找到服务的地址,进行调用。以下是常用的一些注册中心特点:
2.为什么要用Nacos作为项目的注册中心?
Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。(配置中心、注册中心)
看上面的表,nacos支持的特性最多最全面。开箱即用,上手简洁,暂时也没发现有太大的坑,nacos功能更加丰富,社区更加活跃。 如果你面试的是阿里,直接说因为是阿里开发的,经受大厂各种应用考验,肯定没问题。
3.常用注册中心差异?
见这篇文章。微服务:注册中心ZooKeeper、Eureka、Consul 、Nacos对比_琦彦的博客-CSDN博客_consul nacos
4.注册中心至少要具备哪些条件?
服务注册接口:服务提供者通过调用服务注册接口来完成服务注册。
服务反注册接口:服务提供者通过调用服务反注册接口来完成服务注销。
心跳汇报接口:服务提供者通过调用心跳汇报接口完成节点存活状态上报。
服务订阅接口:服务消费者通过调用服务订阅接口完成服务订阅,获取可用的服务提供者节点列表。
服务变更查询接口:服务消费者通过调用服务变更查询接口,获取最新的可用服务节点列表。
服务查询接口:查询注册中心当前注册了哪些服务信息。
服务修改接口:修改注册中心中某一服务的信息。
5. 注册中心单机还是集群的,其中一个挂了怎么办?一致性,可靠性怎么保证的?
在我的项目中,实现的是单机版nacos。nacos的集群部署方案可以看下面这个博客
Nacos服务注册与发现、集群部署方案_祁_z的博客-CSDN博客_nacos 服务集群配置
那么要实现注册中心从单机版到分布式集群,有几个关键问题要解决:
集群成员间的关系与成员发现问题
集群成员间数据复制与一致性问题
数据副本机制和数据分区策略
具体的解决方案可见:微服务注册中心分布式集群设计原理与 Golang 实现 (136.la)
6.分布式数据一致性协议都知道哪些?
(1条消息) 常用的分布式一致性协议_TJtulong的博客-CSDN博客_分布式一致性协议
7.CAP理论了解嘛?
CAP理论是分布式架构中最重要的理论
- C 一致性 :对于客户端的每次读操作,要么读到的是最新的数据,要么读取失败。换句话说,一致性是站在分布式系统的角度,对访问本系统的客户端的一种承诺:要么我给您返回一个错误,要么我给你返回绝对一致的最新数据,不难看出,其强调的是数据正确。
- A 可用性 :任何客户端的请求都能得到响应数据,不会出现响应错误。换句话说,可用性是站在分布式系统的角度,对访问本系统的客户的另一种承诺:我一定会给您返回数据,不会给你返回错误,但不保证数据最新,强调的是不出错。
- P 分区容忍性 :由于分布式系统通过网络进行通信,网络是不可靠的。当任意数量的消息丢失或延迟到达时,系统仍会继续提供服务,不会挂掉。换句话说,分区容忍性是站在分布式系统的角度,对访问本系统的客户端的再一种承诺:我会一直运行,不管我的内部出现何种数据同步问题,强调的是不挂掉。
所有的分布式系统都必须有分区容忍性,因为分区容忍性是分布式系统的基本条件,但一致性和可用性只能有一种,也就是只有CP或者AP的系统,目前不存在CAP都成立的系统。因为当系统为了满足一致性就必须对数据进行复制到每个微服务中,这就导致了很大的性能消耗,就会出现可用性的问题,所以二者不可兼得。
8.任何一个请求(流量)过来都会打到注册中心么?
第一次会,当请求注册中心之后,则将服务列表保存到本地(消费者内存中),方便以后使用。
9.如果是你如何设计一个nacos ,rpc如何调用。
【Nacos】Nacos原理解析_Coinker的博客-CSDN博客_nacos的原理
10.raft了解嘛?
Nacos的Raft 算法_加班狂魔的博客-CSDN博客_nacos raft
11.项目中nacos注册中心的具体使用
引入依赖
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.3.0</version>
</dependency>
首先定义一个接口,ServiceRegistry作为远程注册表(Nacos)的使用
public interface ServiceRegistry {
/**
* 将一个服务注册进注册表
*
* @param serviceName 服务名称
* @param inetSocketAddress 提供服务的地址
*/
void register(String serviceName, InetSocketAddress inetSocketAddress);
}
register 方法就是将服务的名称(接口名)和地址注册进服务注册中心,接口有了,我们就可以写实现类了,我们实现一个 Nacos 作为注册中心的实现类:NacosServiceRegistry,我们也可以使用 ZooKeeper 作为注册中心,实现接口就可以。
public class NacosServiceRegistry implements ServiceRegistry {
private static final Logger logger = LoggerFactory.getLogger(NacosServiceRegistry.class);
@Override
public void register(String serviceName, InetSocketAddress inetSocketAddress) {
try {
NacosUtil.registerService(serviceName, inetSocketAddress);
} catch (NacosException e) {
logger.error("注册服务时有错误发生:", e);
throw new RpcException(RpcError.REGISTER_SERVICE_FAILED);
}
}
}
这里是用到了一个Nacos工具类的registerService方法来注册服务的,NacosUtil类定义如下,主要实现了三个方法,注册服务,获取服务所有实例以及注销服务。
public class NacosUtil {
private static final Logger logger = LoggerFactory.getLogger(NacosUtil.class);
private static final NamingService namingService;
private static final Set<String> serviceNames = new HashSet<>();
private static InetSocketAddress address;
private static final String SERVER_ADDR = "127.0.0.1:8848";
static {
namingService = getNacosNamingService();
}
public static NamingService getNacosNamingService() {
try {
return NamingFactory.createNamingService(SERVER_ADDR);
} catch (NacosException e) {
logger.error("连接到Nacos时有错误发生: ", e);
throw new RpcException(RpcError.FAILED_TO_CONNECT_TO_SERVICE_REGISTRY);
}
}
public static void registerService(String serviceName, InetSocketAddress address) throws NacosException {
namingService.registerInstance(serviceName, address.getHostName(), address.getPort());
NacosUtil.address = address;
serviceNames.add(serviceName);
}
public static List<Instance> getAllInstance(String serviceName) throws NacosException {
return namingService.getAllInstances(serviceName);
}
public static void clearRegistry() {
if(!serviceNames.isEmpty() && address != null) {
String host = address.getHostName();
int port = address.getPort();
Iterator<String> iterator = serviceNames.iterator();
while(iterator.hasNext()) {
String serviceName = iterator.next();
try {
namingService.deregisterInstance(serviceName, host, port);
} catch (NacosException e) {
logger.error("注销服务 {} 失败", serviceName, e);
}
}
}
}
}
Nacos 的使用很简单,通过 NamingFactory 创建 NamingService 连接 Nacos,连接的过程写在了静态代码块中,在类加载时自动连接。namingService 提供了两个很方便的接口,registerInstance 和 getAllInstances 方法,前者可以直接向 Nacos 注册服务,后者可以获得提供某个服务的所有提供者的列表。所以接口的这两个方法只需要包装一下就好了。
在 NacosUtil中我们通过 getAllInstance 获取到某个服务的所有提供者列表后,需要选择一个,这里就涉及了负载均衡策略,这里我们先选择第 0 个,后面我们详细讲解负载均衡。
接下来,我们修改 RpcServer 接口,新增一个方法 publishService,用于向 Nacos 注册服务:
<T> void publishService(Object service, Class<T> serviceClass);
然后只需要实现这个方法即可,以 NettyServer 的实现为例,NettyServer 在创建时需要创建一个 ServiceRegistry 了:
public NettyServer(String host, int port) {
this.host = host;
this.port = port;
serviceRegistry = new NacosServiceRegistry();
serviceProvider = new ServiceProviderImpl();
}
public <T> void publishService(Object service, Class<T> serviceClass) {
if(serializer == null) {
logger.error("未设置序列化器");
throw new RpcException(RpcError.SERIALIZER_NOT_FOUND);
}
serviceProvider.addServiceProvider(service);
serviceRegistry.register(serviceClass.getCanonicalName(), new InetSocketAddress(host, port));
}
这里的serviceProvider是本地保存服务类的实例对象,publishService 需要将服务保存在本地的注册表,同时注册到 Nacos 上。
最后还有服务发现部分,就放到后面和负载均衡一起总结吧!觉得对大家有用的,可以给博主点个赞哦~
边栏推荐
- 最新坦克大战2022-全程开发笔记-2
- Wei Pai: the product is applauded, but why is the sales volume still frustrated
- (ultra detailed onenet TCP protocol access) arduino+esp8266-01s access to the Internet of things platform, upload real-time data collection /tcp transparent transmission (and how to obtain and write L
- A brief introduction to the database of tyut Taiyuan University of technology in previous years
- E-R graph to relational model of the 2022 database of tyut Taiyuan University of Technology
- 9. Pointer (upper)
- Alibaba cloud microservices (III) sentinel open source flow control fuse degradation component
- Redis cache obsolescence strategy
- 12 excel charts and arrays
- 2.C语言矩阵乘法
猜你喜欢
Quickly generate illustrations
一段用蜂鸣器编的音乐(成都)
Questions and answers of "signal and system" in the first semester of the 22nd academic year of Xi'an University of Electronic Science and technology
甲、乙机之间采用方式 1 双向串行通信,具体要求如下: (1)甲机的 k1 按键可通过串行口控制乙机的 LEDI 点亮、LED2 灭,甲机的 k2 按键控制 乙机的 LED1
Tyut Taiyuan University of technology 2022 "Mao Gai" must be recited
(原创)制作一个采用 LCD1602 显示的电子钟,在 LCD 上显示当前的时间。显示格式为“时时:分分:秒秒”。设有 4 个功能键k1~k4,功能如下:(1)k1——进入时间修改。
西安电子科技大学22学年上学期《基础实验》试题及答案
Abstract classes and interfaces
(super detailed II) detailed visualization of onenet data, how to plot with intercepted data flow
System design learning (I) design pastebin com (or Bit.ly)
随机推荐
Questions and answers of "basic experiment" in the first semester of the 22nd academic year of Xi'an University of Electronic Science and technology
Mortal immortal cultivation pointer-2
【快趁你舍友打游戏,来看道题吧】
8. C language - bit operator and displacement operator
西安电子科技大学22学年上学期《射频电路基础》试题及答案
【九阳神功】2021复旦大学应用统计真题+解析
Small exercise of library management system
2.初识C语言(2)
TYUT太原理工大学2022数据库之关系代数小题
Tyut outline of 2022 database examination of Taiyuan University of Technology
TYUT太原理工大学2022数据库大题之E-R图转关系模式
Relational algebra of tyut Taiyuan University of technology 2022 database
C language Getting Started Guide
The latest tank battle 2022 - full development notes-3
4.分支语句和循环语句
甲、乙机之间采用方式 1 双向串行通信,具体要求如下: (1)甲机的 k1 按键可通过串行口控制乙机的 LEDI 点亮、LED2 灭,甲机的 k2 按键控制 乙机的 LED1
TYUT太原理工大学往年数据库简述题
TYUT太原理工大学2022数据库大题之数据库操作
(原创)制作一个采用 LCD1602 显示的电子钟,在 LCD 上显示当前的时间。显示格式为“时时:分分:秒秒”。设有 4 个功能键k1~k4,功能如下:(1)k1——进入时间修改。
Comparison between FileInputStream and bufferedinputstream