一、Nacos 服务注册中心
1. Nacos 简介
- Nacos 的组成:命名配置服务
- Naming(命名):前两个字母
- Configuration(配置):前两个字母
- Service(服务):第一个字母
- 一个更易于构建 云原生应用 的动态 服务发现、配置管理 和 服务管理 平台。
- Nacos = Eureka(注册中心) + Config(配置中心) + Bus
- 据说 Nacos 在 阿里巴巴内部 有超过 10 万的实例运行。
- 已经过了 类似双十一 等各种大型流量的考验。
2. Nacos 安装
- 下载 nacos-server-1.1.4.zip
- 测试地址:http://localhost:8848/nacos
默认账号密码都是:nacosstartup.cmd -m standa|one
3. 服务提供者
1. 新建 Module cloudalibaba-provider-payment-nacos9001
2. POM
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud-2020</artifactId>
<groupId>com.qs.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-provider-payment-nacos9001</artifactId>
<dependencies>
<!--nacos-discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--web + actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3. YML
server:
port: 9001
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
# 配置`Nacos`地址
server-addr: localhost:8848
management:
endpoints:
web:
exposure:
include: '*'
4. 主启动
@EnableDiscoveryClient
@SpringBootApplication
public class PaymentMain9001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9001.class, args);
}
}
5. PaymentController
@RestController
@RequestMapping("payment")
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "getPayment/{id}")
public String getPayment(@PathVariable("id") Integer id) {
return serverPort + " id: " + id;
}
}
6. 测试
4. 服务消费者
1. 新建 Module cloudalibaba-consumer-order-nacos90
2. POM
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud-2020</artifactId>
<groupId>com.qs.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-consumer-order-nacos90</artifactId>
<dependencies>
<!--spring-cloud-ailibaba-nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--自定义API通用包-->
<dependency>
<groupId>com.qs.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3. YML
server:
port: 90
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
# 消费者 将要去访问的 微服务名称(注册成功进`Nacos`的微服务提供者)
service-url:
nacos-user-service: http://nacos-payment-provider
4. 主启动
@EnableDiscoveryClient
@SpringBootApplication
public class OrderNacosMain90 {
public static void main(String[] args) {
SpringApplication.run(OrderNacosMain90.class, args);
}
}
5. ApplicationContextBean
@Configuration
public class ApplicationContextBean {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
6. OrderNacosController
@RestController
@RequestMapping("order")
public class OrderNacosController {
@Value("${service-url.nacos-user-service}")
private String serverURL;
@Resource
private RestTemplate restTemplate;
@GetMapping("getPayment/{id}")
public String getPayment(@PathVariable("id") Long id) {
return restTemplate.getForObject(serverURL + "/payment/getPayment/" + id, String.class);
}
}
7. 测试
5. 服务注册中心 对比
1. Nacos 支持 AP 和 CP 模式切换
- C 的定义:所有节点 在 同一时间 看到的数据是 一致的。
- A 的定义:所有的请求都会收到响应。
2. 何时选择使用何种模式?
# `Nacos`修改为`CP`原则
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
1. AP 模式
- 如果不需要 存储服务级别 的信息。
- 且 服务实例 是通过 nacos-client 注册。
- 并能够 保持心跳上报,那么就可以选择 AP 模式。
- 当前主流的服务,如 Spring Cloud 和 Dubbo 服务,都适用于 AP 模式。
- AP 模式为了服务的可能性,而减弱了一致性。
- 因此 AP 模式下只支持 注册临时实例。
2. CP 模式
- 如果需要在 服务级别编辑 或者 存储配置信息。
- 那么 CP 是必须,K8S 服务和 DNS 服务则适用于 CP 模式。
- CP 模式下则 支持注册持久化实例,此时,则是以 Raft 协议为集群运行模式。
- 该模式下 注册实例 之前 必须先注册服务,如果 服务不存在,则会返回错误。
二、Nacos 服务配置中心
1. Config Client
1. 新建 Module cloudalibaba-nacos-config-client3377
2. POM
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud-2020</artifactId>
<groupId>com.qs.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-nacos-config-client3377</artifactId>
<dependencies>
<!--nacos-config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--nacos-discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--web + actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3. YML
- Nacos 同 Spring Cloud Config 一样:
- 在项目初始化时,要保证 先从配置中心 进行配置拉取。
- 拉取配置之后,才能保证项目的正常启动。
bootstrap.yml
# `Nacos`配置
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
# `Nacos`服务注册中心地址。
server-addr: localhost:8848
config:
# `Nacos`作为配置中心地址。
server-addr: localhost:8848
# 指定`yaml`格式的配置。
file-extension: yaml
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
application.yml
spring:
profiles:
# 表示开发环境。
active: dev
4. 主启动
@EnableDiscoveryClient
@SpringBootApplication
public class NacosConfigClientMain3377 {
public static void main(String[] args) {
SpringApplication.run(NacosConfigClientMain3377.class, args);
}
}
5. ConfigClientController
- 注解
@RefreshScope
支持 Nacos 的动态刷新功能
@RestController
// 在控制器类加入`@RefreshScope`注解。
// 使当前类下的配置支持`Nacos`的动态刷新功能。
@RefreshScope
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo() {
return configInfo;
}
}
6. Nacos 配置
- Nacos 中的匹配规则
- Nacos 会保留 配置文件 的 历史版本(默认保留 30 天)。
- 此外还有 一键回滚 功能,回滚操作 将会 触发配置更新。
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
# prefix: 默认为spring.application.name的值
# spring.profile.active: 即为当前环境对应的profile,可以通过配置项spring.profile.active来配置
# file-exetension: 为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension来配置
nacos-config-client-dev.yaml
7. 测试
2. 分类配置
- Namespace + Group + Data Id
默认:public + DEFAULT_GROUP + 自定义
- Namespace:比如 开发、测试、生产 环境。
- Group:不同的微服务。
- Data Id:不同的开发环境。
1. Data Id
application.yml
spring:
profiles:
# 开发环境
# active: dev
# 测试环境
# active: test
# 生产环境
active: prod
2. Group
bootstrap.yml
# `Nacos`配置
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
# `Nacos`服务注册中心地址。
server-addr: localhost:8848
config:
# `Nacos`作为配置中心地址。
server-addr: localhost:8848
# 指定`yaml`格式的配置。
file-extension: yaml
group: DEV_GROUP
application.yml
spring:
profiles:
# 开发环境
# active: dev
# 测试环境
# active: test
active: info
3. Namespace
bootstrap.yml
。
# `Nacos`配置
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
# `Nacos`服务注册中心地址。
server-addr: localhost:8848
config:
# `Nacos`作为配置中心地址。
server-addr: localhost:8848
# 指定`yaml`格式的配置。
file-extension: yaml
# group: DEV_GROUP
namespace: 8acc3381-7392-42bf-8b5c-02c17711b3db
三、Nacos 集群 和 持久化
- Nacos 集群部署说明
- Nacos 默认 使用嵌入式数据库 derby 实现数据的存储。
- 所以,如果启动多个。默认配置下的 Nacos 节点,数据存储 是存在 一致性问题的。
- 为了解决这个问题。Nacos 采用了集中式存储的方式来支持集群化部署,目前只支持 MySQL 的存储。
1. 切换 MySQL 数据源
nacos\conf\nacos-mysql.sql
2. Linux 集群配置
- 1个Nginx + 3个Nacos注册中心 + 1个MySQL
1. 配置 Nacos
# 1. 解压
tar -zxvf nacos-server-1.1.4.tar.gz
# 2. 切换`MySQL`数据源
# 获取`IP`
hostname -i
# 3. vim nacos/conf/cluster.conf
192.168.137.155:3333
192.168.137.155:4444
192.168.137.155:5555
# 4. vim nacos/bin/startup.sh
while getopts ":m:f:s:p:" opt
do
case $opt in
m)
MODE=$OPTARG;;
f)
FUNCTION_MODE=$OPTARG;;
s)
SERVER=$OPTARG;;
p)
PORT=$OPTARG;;
?)
echo "Unknown parameter"
exit 1;;
esac
done
nohup $JAVA -Dserver.port=${PORT} ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
2. 启动 Nacos
./startup.sh -p 3333
./startup.sh -p 4444
./startup.sh -p 5555
ps -ef | grep nacos
# 查看`Nacos`数量。
ps -ef | grep nacos | grep -v grep | wc -l
3. 配置 Nginx 作为 负载均衡器
upstream cluster {
server 127.0.0.1:3333;
server 127.0.0.1:4444;
server 127.0.0.1:5555;
}
server {
listen 1111;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#root html;
#index index.html index.htm;
proxy_pass http://cluster;
}
}
./nginx -C /usr/local/nginx/config/nginx.conf