随着互联网发展,网站应用的规模也不断扩大,进而导致系统架构也在不断地进行变化,从互联网早期到现在,系统架构大体经历几个过程:
单体应用架构
把所有应用都集中在一个项目中,统一部署,开发成本低、部署成本和运维成本低
垂直应用架构
所谓垂直应用架构,其实就是把之前的单体应用拆分成多个应用,以提升效率
分布式架构
随着业务增加,在垂直应用系统架构中冗余的业务代码越来越多,就需要讲冗余的部分抽取出来,统一做成业务层单独处理,变成一个单独的服务,控制层调用不同的业务层,就能完成不同的业务,具体表现就是一个项目拆分成表现层和服务层两个部分,服务层中包含业务逻辑,表现层只需要处理页面交互,业务逻辑都是调用服务层的服务来实现,就是分布式架构
SOA架构
分布式架构中缺点就是调用复杂,而且当服务越来越多或者当某一个服务压力过大需要水平扩展和负债均衡,对于资源调度和治理就需要用到治理中心SOA(Service Oriented Architecture)为核心来解决,同时治理中心还可以帮助我们解决服务之间协议不通的问题
微服务架构
微服务架构在某种程度上面是SOA架构继续发展的下一个架构,它更加强调服务的拆分,目的就是提高效率,微服务架构中,每个服务必须独立部署同时互不影响,微服务架构更加轻巧,轻量级
Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
Nacos(Naming Configuration Service) 是一个易于使用的动态服务发现、配置和服务管理平台,用于构建云原生应用程序
服务发现是微服务架构中的关键组件之一。Nacos 致力于帮助你发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助你快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
Nacos = 注册中心+配置中心组合
微服务架构内部发起通讯调用方法的一方成为“服务消费者”,提供远程方法调用的服务器称为“服务提供者”,往往为了提高系统性能,会提供多个服务器作为服务提供者,此时服务消费者找到服务提供者的过程,就类似于用户在找房间的过程。为了帮助服务消费者快速的发现服务提供者,在微服务框架中都会引入注册中心。注册中心类似于酒店的前台,提供在软件服务的注册和发现功能,服务提供者会先在注册中心进行注册,声明可以对外提供服务,而服务消费者只需要在注册中心就可以快速发现找到可以使用的服务,快速使用服务。注册中心实现了服务提供和服务消费的快速撮合功能。
官网网址:https://nacos.io/zh-cn/index.html
官方文档网址:
nacos 1.x 官方文档
nacos 2.x 官方文档
官方下载地址:https://github.com/alibaba/nacos/releases
Linux/Unix/Mac
启动命令(standalone代表着单机模式运行,非集群模式):
sh startup.sh -m standalone
Windows
启动命令(standalone代表着单机模式运行,非集群模式):
startup.cmd -m standalone
验证是否成功开启Nacos,我们需要访问:http://localhost:8848/nacos ,默认的账号、密码是:nacos/nacos
服务发现是微服务架构中的关键组件之一。Nacos Discovery 帮助你自动将你的服务注册到 Nacos 服务器,Nacos 服务器会跟踪服务并动态刷新服务列表。此外,Nacos Discovery 将服务实例的一些元数据,如主机、端口、健康检查 URL、主页等注册到 Nacos。
学习任何知识我们都需要从它的官方文档入手,所以我们直接来看官网给我们提供的文档:https://spring.io/projects/spring-cloud-alibaba#learn
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
# 应用名称
spring.application.name=nacos-provder
#端口
server.port=9001
#用户名
spring.cloud.nacos.discovery.username=nacos
#密码
spring.cloud.nacos.discovery.password=nacos
# Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#暴露所有端点
management.endpoints.web.exposure.include=*
@SpringBootApplication
@EnableDiscoveryClient
public class Nacos9001Application {
public static void main(String[] args) {
SpringApplication.run(Nacos9001Application.class, args);
}
}
@RestController
public class TestController {
@Value("${server.port}")
private String port;
@GetMapping("hello")
public String getTest(){
return "hello "+port;
}
}
# 应用名称
spring.application.name=nacos-concumer
# 应用服务 WEB 访问端口
server.port=8083
#用户名
spring.cloud.nacos.discovery.username=nacos
#密码
spring.cloud.nacos.discovery.password=nacos
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
server.url.name=http://nacos-provder
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConcumerApplication {
public static void main(String[] args) {
SpringApplication.run(NacosConcumerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
什么是Ribbon
它是一个基于HTTP和TCP客户端负载均衡器。它虽然只是一个工具类库,它却是每一个微服务的基础设施。因为实际上,对于服务间调用、API网关请求转发都需要经过Ribbon负载均衡来实现。总体来说,Ribbon的主要作用是:从注册服务器端拿到对应服务列表后以负载均衡的方式访问对应服务。要注意的是Nacos已经整合了Ribbon,所以我们想要使用只需要导入Spring Cloud Alibaba Nacos的依赖就可以直接使用了。
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConcumerApplication {
public static void main(String[] args) {
SpringApplication.run(NacosConcumerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
public class NacosConcumerTestController {
@Autowired
private RestTemplate restTemplate;
@Value("${server.url.name}")
private String serverName;
@GetMapping("concumer")
public String handerConcumer(){
return restTemplate.getForObject(serverName+"/hello",String.class);
}
}
服务注册与发现框架 | CAP模型 | 控制台管理 | 社区活跃度 |
---|---|---|---|
Eureka | AP | 支持 | 低(2.x版本闭源) |
Zookeeper | CP | 不支持 | 中 |
Consul | CP | 支持 | 高 |
Nacos | AP/CP | 支持 | 高 |
计算机专家 埃里克·布鲁尔(Eric Brewer)于 2000 年在 ACM 分布式计算机原理专题讨论会(简称:PODC)中提出的分布式系统设计要考虑的三个核心要素:
一致性(Consistency):同一时刻的同一请求的实例返回的结果相同,所有的数据要求具有强一致性(Strong Consistency)
可用性(Availability):所有实例的读写请求在一定时间内可以得到正确的响应
分区容错性(Partition tolerance):在网络异常(光缆断裂、设备故障、宕机)的情况下,系统仍能提供正常的服务
以上三个特点就是CAP原则(又称CAP定理),但是三个特性不可能同时满足,所以分布式系统设计要考虑的是在满足P(分区容错性)的前提下选择C(一致性)还是A(可用性),即:CP或AP
CP 原则属于强一致性原则,要求所有节点可以查询的数据随时都要保持一直(同步中的数据不可查询),即:若干个节点形成一个逻辑的共享区域,某一个节点更新的数据都会立即同步到其他数据节点之中,当数据同步完成后才能返回成功的结果,但是在实际的运行过程中网络故障在所难免,如果此时若干个服务节点之间无法通讯时就会出现错误,从而牺牲了以可用性原则(A),例如关系型数据库中的事务。
AP原则属于弱一致性原则,在集群中只要有存活的节点那么所发送来的所有请求都可以得到正确的响应,在进行数据同步处理操作中即便某些节点没有成功的实现数据同步也返回成功,这样就牺牲一致性原则(C 原则)。
使用场景:对于数据的同步一定会发出指令,但是最终的节点是否真的实现了同步,并不保证,可是却可以及时的得到数据更新成功的响应,可以应用在网络环境不是很好的场景中。
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
注意:临时和持久化的区别主要在健康检查失败后的表现,持久化实例健康检查失败后会被标记成不健康,而临时实例会直接从列表中被删除。
<dependency>
<groupId> com.alibaba.cloud </groupId>
<artifactId> spring-cloud-starter-alibaba-nacos-config </artifactId>
</dependency>
要注意的是这里我们要配置两个,因为Nacos同SpringCloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动。
springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application
分别要配置的是,这里bootstrap.properties配置好了以后,作用是两个,第一个让3377这个服务注册到Nacos中,第二个作用就是去Nacos中去读取指定后缀为yaml的配置文件:
bootstrap.properties
server.port=3377
spring.profiles.active=dev
spring.application.name=nacos-config-client
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.file-extension=yaml
spring.cloud.nacos.config.group=TEST_GROUP
spring.cloud.nacos.config.namespace=0daba406-601b-42ea-810b-ff5908061800
@RestController
@RefreshScope
public class ConfigTestController {
@Value("${config.info}")
private String configInfo;
@Value("${server.port}")
private String port;
@GetMapping("config")
public String getConfig() {
return "config " + configInfo;
}
}
在 Nacos Spring Cloud 中,dataId
的完整格式如下(官网 https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html):
${prefix}-${spring.profiles.active}.${file-extension}
prefix
默认为 spring.application.name
的值,也可以通过配置项 spring.cloud.nacos.config.prefix
来配置。spring.profiles.active
即为当前环境对应的 profile,注意:当 spring.profiles.active
为空时,对应的连接符 -
也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
(不能删除)file-exetension
为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension
来配置。目前只支持 properties
和 yaml
类型。@RefreshScope
实现配置自动更新:# ${spring.application.name}-${spring.profiles.active}.${file-extension}
# nacos-config-client-dev.yaml
命名空间(Namespace)
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
配置分组(Group)
Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。
配置集 ID(Data ID)
Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。
配置集:一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配置集,包含了系统各个方面的配置。例如,一个配置集可能包含了数据源、线程池、日志级别等配置项。
默认情况
Namespace=public,Group=DEFAULT_GROUP,默认Cluster是DEFAULT
默认Nacos使用嵌入式数据库实现数据的存储,所以,如果启动多个默认配置下的Nacos节点,数据储存存在一致性问题,为了解决这个问题,Nacos采用了集中存储方式来支持集群化部署,目前仅支持MySql的存储。
CREATE DATABASE nacos_config;
USE nacos_config;
修改conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&serverTimezone=UTC
db.user=root
db.password=root
首先我们要更改cluter.conf这个配置文件,当然我们也需要备份,但是这里它的原始名称为:cluster.conf.example,我们需要把它保留同时复制出一个cluster.conf来进行更改
# ip:port
127.0.0.1:8848
127.0.0.1:8848
127.0.0.1:8848
启动三个nacos节点,分别进入到三个Nacos节点的bin目录中进行启动:
sh startup.sh //启动命令
验证集群配置
我们需要找到Nginx的配置文件,然后做备份
cd /usr/local/nginx
cp nginx.conf nginx.conf.bk
修改nginx.conf,并且启动
worker_processes 1;
events {
worker_connections 1024;
}
stream {
upstream nacos {
server 192.168.189.129:8848;
server 192.168.189.129:8868;
server 192.168.189.129:8888;
}
server {
listen 81;
proxy_pass nacos;
}
}
访问nginx端口