本文参考转载自:Nacos注册中心的部署与用法详细介绍
相关内容:Nacos统一配置中心使用详解
我们知道微服务彼此间独立部署、具有清晰的边界,服务间通过远程调用来构建复杂的业务功能。而服务册中心在微服务项目中扮演着非常重要的角色,那么注册中心又是什么,使用服务注册中心可以解决微服务中的哪些问题呢?
注册中心是微服务架构中的纽带,类似于“通讯录”,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就到这里找到服务的地址并进行调用。注册中心本质上是为了解耦服务提供者和服务消费者。对于任何一个微服务,原则上都应存在或者支持多个提供者,这是由微服务的分布式属性决定的,更进一步,为了支持弹性扩缩容特性,一个微服务的提供者的数量和分布往往是动态变化的,也是无法预先确定的。因此,原本在单体应用阶段常用的静态LB机制就不再适用了,需要引入额外的组件来管理微服务提供者的注册与发现,而这个组件就是服务注册中心。
(1)屏蔽、解耦服务之间相互依赖的细节:
服务之间的远程调用必须要知道对方IP、端口。但是该调用方式存在明显的问题,如被调用的IP、端口变化后,调用方也要同步修改。通过服务发现,将服务之间IP与端口的依赖转化为服务名的依赖,服务名可以根据具体微服务业务来做标识。
(2)对服务进行动态管理:
在微服务架构中,服务数量多且依赖错综复杂,无论是服务主动停止、意外挂掉,还是因为流量增加对服务扩容,这些服务状态上的动态变化,都需要尽快的通知到被调用方,被调用方才采取相应的措施。所以,对于服务注册中心要实时管理服务的数据与状态,包括服务的注册上线、服务主动下线,异常服务的剔除。
(3)降低服务端负载均衡中间件的压力:
当服务越来越多时,服务 URL 配置管理变得非常困难,服务端的负载均衡中间件,比如 F5、Nginx 压力也越来越大。通过服务注册中心,就可以实现动态地注册和发现服务,使服务的位置透明,并通过在消费方获取服务提供方地址列表,实现软负载均衡和 Failover,降低对服务端的负载均衡中间件,也能减少部分成本。
上面提到,硬件的 F5、软件的 Nginx 也可以实现服务的发现,那么这与注册中心的服务发现有什么区别呢?这其实是服务发现与注册的两种实现模式:服务端的发现模式 和 客户端的发现模式。F5、Nginx 属于服务端的发现模式,服务注册中心属于客户端的发现模式,两种模式各有优缺点,也适用于不同的场景,对于大型应用一般会有多层负载,外层用服务器端负载均衡,内部用客户端负载均衡。接下来我们就具体看看两种服务发现模式是怎么样的:
(1)服务端的发现模式:
服务端的发现模式是通过使用一个中间的服务器,来屏蔽被调用服务的复杂性与变动性,当有新的服务加入或老服务剔除时,只需要修改中间服务器上的配置即可,此模式的显著特点是:引入独立的中间代理服务器来屏蔽真实服务的具体细节。
如下图所示:当服务A要调用服务B时,先通过 DNS 域名解析找到 Nginx 服务器,然后将请求发送给Nginx,因为在 Nginx 上配置了服务B的真实访问地址,Nginx 收到请求后根据负载均衡算法,将请求转发到某个真实的服务B,服务B将请求结果返回给 Nginx,Nginx 再将返回结果给服务A,整个请求流程结束。当然中间服务器不一定非得是 Nginx,还可以是基于硬件的 F5,也可以是工作在传输层的 IP 负载均衡等。
该模式的优点是:配置集中在独立的中间服务器端完成,对代码没有任何入侵,也不存在跨平台跨语言的问题。但缺点也很明显,因为所有请求都需要穿透中间服务器,所以中间服务器会成为一个单点,对性能也会有所影响。
(2)客户端的发现模式:
我们再看看客户端的发现模式,服务A调用服务B时,不需要通过中间服务器,而是在自己进程内维护了服务B的信息,再通过负载算法选择一个服务B直接调用。那服务A具体是怎么维护服务B的信息呢?为此引入了服务注册中心的概念,当服务B启动时向注册中心注册自己(将自己的信息发送到注册中心的注册表里),服务A再从注册中心获取所有注册的服务,这就是客户端模式的基本原理。
客户端模式因为在进程内直接调用服务,也叫做进程内负载,由于不需要穿透中间服务器,所以客户端模式的性能损耗比较小。但是,需要在服务内部维护服务注册信息,负载算法等,有一定的代码入侵性,对于跨平台,跨语言的支持不太友好。
微服务架构中,所有的服务启动后都通过注册中心来注册自己,同时把注册中心里面的服务信息拉回本地,后续调用时就直接检查本地的服务和节点信息来进行服务节点的调用。每个服务节点都会来注册中心进行服务注册,那注册信息是如何在服务端保存的呢,其实就是注册表,服务注册的时候把自己的信息上报上来,然后注册中心把注册表,返回给客户端,那服务之间就知道要调用服务的节点了。
服务注册表需要高可用而且随时更新。客户端能够缓存从服务注册表中获取的服务地址,然而,这些信息最终会过时,客户端也就无法发现服务实例。因此,服务注册表会包含若干服务端,并使用复制协议保持一致性。服务注册表不能是单点,否则存在单点故障,当服务注册表有多台服务器的时需要考虑服务注册表的信息在多台机器上的实时同步和一致。
(1)Zookeeper
和 Consul 遵循 CP 原则,保证了强一致性和分区容错性,放弃可用性,在分布式环境中,如果涉及数据存储的场景,数据一致性应该是首先被保证的,但对于服务发现来说,可用性才是最核心的,针对同一个服务,即使注册中心的不同节点保存的服务提供者信息不相同,也并不会造成灾难性的后果。因为对于服务消费者来说,能消费才是最重要的,消费者拿到不正确的服务实例信息后尝试消费一下,也胜过因为无法获取实例信息而不去消费而导致系统异常
(2)Eureka
遵循 AP 原则,保证可用性,放弃数据一致性,基本能满足注册中心所需的核心功能,但 Eureka 2.x 版本已停止开发,并且宣布如果继续使用的话,风险自负。
(3)Nacos
同时支持 AP 与 CP,默认是 AP,同时功能更丰富,与 SpringCloud Alibaba 的兼容性更好,使用更简单灵活,可以满足更多的业务场景,且支持 K8S 的集成。
此模式一般用于 demo 和测试,不用改任何配置,直接bin目录下敲以下命令执行
sh startup.sh -m standalone
如果报错not found、java.net.UnknownHostException: jmenv.tbsite.net
则使用:
./startup.sh -m standalone
windows系统打开命令行进入bin目录:
startup.cmd -m standalone
然后从 http://cdh1:8848/nacos/index.html
进入控制台就能看到如下界面了,默认账号和密码为:nacos nacos
进入config目录下,打开application.properties配置文件
修改以下mysql配置:
#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/network_nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=name
db.password.0=password
使用以下代码对要使用的密码进行加密,
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("password"));
}
启动nacos后进入数据库,修改user表里面的password字段即可
需使用mysql,修改如下
#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/network_nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=name
db.password.0=password
只需要将 cluster.conf.example 这个文件复制一份为 cluster.conf 放在 conf 目录下,其中配置的内容如下:
#example
192.168.16.101:8847
192.168.16.102
192.168.16.103
./startup.sh
启动即可
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
在配置文件中配置连接信息:
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.cloud.nacos.discovery.namespace=d9045f9f-8a80-4698-80d2-22f1d6386122
spring.cloud.nacos.discovery.enabled=true
spring.cloud.nacos.discovery.username=name
spring.cloud.nacos.discovery.password=password
/**
* SpringBoot启动类
* @EnableDiscoveryClient 开启服务注册发现的功能
*/
@EnableDiscoveryClient
@SpringBootApplication
public class DemoApplication
{
public static void main(String[] args)
{
SpringApplication.run(ProducerApplication.class, args);
}
}
然后就可以在nacos服务列表中看到注册的服务。