架构发展历程:单体架构 - 垂直架构 - 分布式架构 - SOA架构(小微,Dubbo调控) - 微服务

服务发现:客人去酒店前台询问有哪些服务可以使用
服务注册:酒店前台统计哪些房间可以使用
注册中心(类似于Eureka)

首先在Nacos官网下载Naocs并解压
官网地址:https://nacos.io/zh-cn/index.html
解压缩之后进入到bin目录下,在cmd窗口执行startup.cmd -m standalone 表明单机启动
启动之后,访问http://localhost:8848/nacos我们就可以进入到nacos的访问地址了【账号密码默认:nacos/nacos】
注册服务之前需要保证本地或远端Nacos是运行着的
①创建父项目配置依赖(普通的SpringBoot项目,添加web模块即可)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.13.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.zi</groupId>
<artifactId>SpringCloudAlibabaAll</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringCloudAlibabaAll</name>
<packaging>pom</packaging>
<description>SpringCloudAlibabaAll</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud-alibaba-version>2.2.5.RELEASE</spring-cloud-alibaba-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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>
<modules>
<!-配置其他子模块->
<module>cloudAlibaba-Nacos-9001</module>
</modules>
</project>
②创建子模块,并继承父模块【同时添加nacos依赖】
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--继承父模块-->
<parent>
<groupId>com.zi</groupId>
<artifactId>SpringCloudAlibabaAll</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.zi</groupId>
<artifactId>cloudalibaba-nacos-9001</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cloudalibaba-nacos-9001</name>
<description>cloudalibaba-nacos-9001</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--添加nacos discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
③在启动类上添加对应注解@EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient//要注册服务到nacos必须加该注解
public class CloudalibabaNacos9001Application {
public static void main(String[] args) {
SpringApplication.run(CloudalibabaNacos9001Application.class, args);
}
}
④配置nacos注册中心的地址及项目相关参数
server:
port: 9001
spring:
application:
name: nacos-provider
cloud:
discovery:
#nacos地址
server-addr: 127.0.0.1:8848
management:
endpoint:
web:
exposure:
include: '*'
最后结果:

注意:maven项目中,父子模块,除了子要parent父,父也要module子
服务创建出来了,并且注册到nacos上了,那么我们应该如何调用服务呢?
通过Ribbon
它是一个基于HTTP和TCP客户端负载均衡器。它虽然只是一个工具类库,它却是每一个微服务的基础设施。因为实际上,对于服务间调用、API网关请求转发都需要经过Ribbon负载均衡来实现。总体来说,Ribbon的主要作用是:从注册服务器端拿到对应服务列表后以负载均衡的方式访问对应服务。【注意nacos内部已经整合了Ribbon,因此我们只需导入nacos依赖即可】
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
//restTemplate.getForObject(arg1,arg2,arg3...);
restTemplate.getForObject(arg1,arg2,arg3…);
http://nacos-provider/zi
第二个参数:返回值类型【如果返回的是List集合,要使用数组类型接收】
第三个参数:可变参数【其他参数】
①在之前两个服务(SpringBoot项目)中添加controller
DemoController.java:
@RestController
public class DemoController {
@Value("${server.port}")
private String serverPort;
@GetMapping("/zi")
public String getServerPort(){
return "hello nacos" + serverPort;
}
}
②创建消费者模块
首先导入nacos依赖,并且继承之前的父工程
然后编写启动类,注入RestTemplate
@SpringBootApplication
public class CloudalibabaConsumer8083Application {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(CloudalibabaConsumer8083Application.class, args);
}
}
server:
port: 8083
spring:
application:
name: nacos-consumer
cloud:
discovery:
server-addr: localhost:8848
# 消费者将要去访问的服务名称
service-url:
nacos-user-service: http://nacos-provider
@RestController
public class DemoController {
@Autowired
private RestTemplate restTemplate;
/**
* 消费者去访问具体的服务,实现配置文件和代码的分离
*/
@Value("${service-url.nacos-user-service}")
private String serverURL;
@GetMapping("/testDiscovery")
public String getDiscovery(){
//URL + 访问路径 + (动态参数)
return restTemplate.getForObject(serverURL+"/zi", String.class);
}
}
计算机专家 埃里克·布鲁尔提出分布式系统设计要考虑的三个核心要素:
以上就是CAP原则(定理),但是三者只能满足其二,即CP或AP
| 服务注册与发现框架 | CAP模型 | 控制台管理 | 社区活跃度 |
|---|---|---|---|
| Eureka (奈飞) | AP | 支持 | 低(2.x版本闭源) |
| Zookeeper (Apache) | CP | 不支持 | 中 |
| Consul | CP | 支持 | 高 |
| Nacos | AP/CP | 支持 | 高 |
Nacos无缝支持一些主流的开源生态,同时再阿里进行Nacos设计的时候重复的考虑到了市场化的运作(市面上大多都是以单一的实现形式为主,例如:Zookeeper使用的是 CP、而 Eureka采用的是AP),在Nacos中提供了两种模式的动态切换。
Nacos的AP与CP模式之间的切换:
切换命令(默认是AP):
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
注意:临时和持久化的区别主要在健康检查失败后的表现,持久化实例健康检查失败后会被标记成不健康,而临时实例会直接从列表中被删除。
Nacos不仅可以作为注册中心,还可以作为配置中心来使用
继承父项目:
父项目中引入了web依赖
<parent>
<groupId>com.zi</groupId>
<artifactId>SpringCloudAlibabaAll</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
引入config依赖:
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
application.yml:
spring:
profiles:
active: test# 表示测试环境
bootstrap.yml:
# nacos 配置
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 # nacos服务注册中心地址
config:
server-addr: localhost:8848 # nacos配置中心地址
file-extension: yaml # 指定文件扩展名为yaml
启动类上加上注解@EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
public class CloudalibabaConfig3377Application {
public static void main(String[] args) {
SpringApplication.run(CloudalibabaConfig3377Application.class, args);
}
}
创建controller:
【添加@RefreshScope支持动态刷新】
@RestController
@RefreshScope //支持Nacos动态刷新功能
public class ConfigClientControlelr {
//从远程nacos读取配置
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo(){
return configInfo;
}
}
Data ID:nacos-config-client-test.yaml
【DataID需要加上文件名后缀】
config:
info: nacos-config-client-test.yaml, DEFAULT_GROUP, version = 1
界面:

Data ID规则:

类比于IDEA中的项目名、包名、类名

一个Service可以包含多个Cluster,Nacos默认Cluster是DEFAULT,Cluster是对指定微服务的一个虚拟划分。比如说,将一个Service部署在北京和和杭州的机房中,北京机房的Service就可以起名为(BJ),杭州机房中的Service就可以起名为(HZ),这样就可以尽量让同一个机房的微服务互相调用,提升性能。
application.yml:
spring:
profiles:
active: test # 测试环境
# active: dev # 表示开发环境
# nacos 配置
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 # nacos服务注册中心地址
config:
server-addr: localhost:8848 # nacos配置中心地址
file-extension: yaml # 指定文件扩展名为yaml
group: DEV_GROUP # 配置组

注意分组与命名空间;
# nacos 配置
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 # nacos服务注册中心地址
config:
server-addr: localhost:8848 # nacos配置中心地址
file-extension: yaml # 指定文件扩展名为yaml
group: DEV_GROUP # 配置组
namespace: 75bbf7ab-7499-40b0-838d-0784c89322ca # 指定命名空间
官网地址:https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html
Nacos支持三种部署模式:
1.单机模式 - 用于测试和单机使用
2.集群模式 - 用于生产环境,确保高可用
3.多集群模式 - 用于多数据中心场景
架构图:部署生产使用的集群模式

具体拆分:

默认Nacos使用嵌入数据库derby实现数据(配置信息、注册信息)的存储,因此如果启动多个默认配置下的Nacos节点,存在数据存储一致性问题,为了解决该问题,Nacos采用了集中存储方式来支持集中化部署,目前仅支持MySQL的存储。
如果要想将nacos上对应的注册信息和配置信息持久化存储到MySQL中,只需要执行nacos目录下conf下的nacos-mysql.sql

同时修改该目录下的application.properties:

修改为对应mysql数据源的配置
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
①环境准备:需要先准备好jdk,nginx,mysql,nacos环境(3台为例);然后在nacos的配置文件中配置好mysql环境,在mysql中执行对应sql脚本文件
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=123456
②修改nacos的cluster.conf(复制另外两台nacos)
# 格式: ip地址:端口号
192.168.189.129:8848
192.168.189.129:8868
192.168.189.129:8888
③修改另外两台nacos的端口
#*************** Spring Boot Related Configurations ***************#
### Default web context path:
server.servlet.contextPath=/nacos
### Default web server port:
server.port=8888/8868
我们在修改端口号时,须要有一定的偏移量,因为在Nacos2.0的时候,本身就新增了占用端口,因此需要我们避开
④配置nginx【修改nginx.conf】
worker_processes 1;
events {
worker_connections 1024;
}
stream {
upstream nacos {
server 192.168.145.13:8848;
server 192.168.145.13:8868;
server 192.168.145.13:8888;
}
server {
listen 81;
proxy_pass nacos;
}
}
⑤关闭防火墙
// 关闭防火墙服务-但是开启还会自动启动
systemctl stop firewalld
// 彻底关闭-开机不会启动防火墙
systemctl disable firewalld
⑥启动nginx
cd /usr/local/nginx/sbin
./nginx
⑦访问nacos
http://192.168.145.13:81/nacos/
在UI界面下,点击集群管理即可查看
⑧添加对应配置,查看linux中的表是否有数据

⑨在SpringBoot项目中修改配置文件,将服务注册到nacos集群上
application.yml
server:
port: 9002
spring:
application:
name: nacos-provider
cloud:
nacos:
discovery:
# 换成nginx的81端口,做集群
server-addr: http://192.168.145.13:81
# server-addr: 127.0.0.1:8848
management:
endpoint:
web:
exposure:
include: '*'
Nacos集群:
