这里写自定义目录标题
- 学习目标
- 1.背景
- 2.系统架构的演变
- 3.SpringCloud概述
- 4.Spring Cloud Alibaba概述
- 5.Nacos概述和安装
- 6.Nacos注册中心
- 7.Nacos配置中心
- 8.Nacos集群和持久化
- 9.Nacos开机自启
学习目标
- 背景
- 系统架构的演变
- Spring Cloud 概述
- Spring Cloud Alibaba 概述
- Nacos概述和安装
- Nacos注册中心
- Nacos配置中心
- Nacos集群和持久化
1.背景
2008年以后,国内互联网行业飞速发展,我们对软件系统的需求已经不再是过去”能用就行”这种很low的档次了,像**抢红包、双十一这样的活动**不断逼迫我们去突破软件系统的性能上限,传统的IT企业”能用就行”的开发思想已经不能满足互联网**高并发、大流量的性能要求**。系统架构**走向分布式**已经是服务器开发领域解决该问题唯一的出路,然而分布式系统由于天生的复杂度,并不像开发单体应用一样把框架一堆就能搞定,因此各大互联网公司都在投入技术力量研发自己的基础设施。这里面比较有名的如**阿里的开源项目dubbo, Netflix开发的一系列服务框架**。在这种“百花齐放”、重复造轮子的状况下,必然要出现一种统一的标准来简化分布式系统的开发,**Spring Cloud**应运而生。
随着互联网的发展,网站应用的规模不断扩大,常规的应用架构已无法应对,分布式服务架构以及微服务架构势在必行,亟需一个治理系统确保架构有条不紊的演进。
2.系统架构的演变
2.1. 单体架构
Web应用程序发展的早期,大部分web工程(包含前端页面,web层代码,service层代码,dao层代码)是将 所有的功能模块,打包到一起并放在一个web容器中运行。
比如搭建一个电商系统:客户下订单,商品展示,用户管理。这种将所有功能都部署在一个web容器中 运行的系统就叫做单体架构。
![image-20220929183947850](assets/image-20220929183947850.png)
存在的问题:
-
代码耦合:模块的边界模糊、依赖关系不清晰,整个项目非常复杂,每次修改代码都心惊胆战
-
迭代困难:每次功能的变更或bug的修复都会导致重新部署整个应用,随着代码的增多,构建、测试和部署的时间也会增加
-
扩展受限:单体应用只能作为一个整体进行扩展,无法根据业务模块的需要进行伸缩
-
技术债务:随着时间推移、需求变更和人员更迭,会逐渐形成应用程序的技术债务,并且“越积越多不坏不修”
2.2.分布式架构
随着企业业务的不断发展,发现单节点的单体应用不足以支撑业务的发展,于是企业会将单体应用部署多份,分别放在不同的服务器上。但是,此时会发现不是所有的模块都会有比较大的访问量。如果想针对项目中的某些模块进行优化和性能提升,此时对于单体应用来说,是做不到的。于是乎,分布式架构诞生了。
分布式架构,就是将原来一个项目应用进行拆分,将其拆分为互不想干的几个应用,以此来提升系统的整体性能。
![image-20220929184231475](assets/image-20220929184231475.png)
存在的问题:
- 各系统难免存在重叠的业务
2.2.SOA架构
我们将系统演变为分布式架构之后,当业务越来越多,重复编写的业务代码就会越来越多。此时,我们需要将重复的代码抽象出来,形成统一的服务供其他系统或者业务模块来进行调用。此时,系统就会演变为SOA架构。
在SOA架构中,我们会将系统整体拆分为服务层和表现层。服务层封装了具体的业务逻辑供表现层调用,表现层则负责处理与页面的交互操作。
当部署的服务越来越多,就会出现服务集群地址硬编码的问题,此时,我们就需要增加一个注册中心来解决各个服务之间的注册与发现。
![image-20220929184403808](assets/image-20220929184403808.png)
存在的问题:
- 抽取服务的粒度较大,服务提供方与调用方接口耦合度较高
2.3.微服务
随着业务的发展,我们在SOA架构的基础上进一步扩展,将其彻底拆分为一个个小的可以独立部署的微服务。
![image-20220713133837299](assets/image-20220713133837299.png)
微服务架构特征:
- 面向服务:微服务对外暴露Restful等轻量协议的接口
- 单一职责:微服务拆分粒度更小,做到单一职责
3.SpringCloud概述
3.1.SpringCloud是什么?
Spring Cloud是一系列框架的有序集合如服务发现注册、配置中心、消息总线、负载均衡、熔断器、数据监控等。
Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装,屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
SpringCloud是一个相对比较新的微服务框架,2016年才推出1.0的release版本,虽然Spring Cloud时间最短, 但是相比Dubbo等RPC框架, Spring Cloud提供了全套的分布式系统解决方案(微服务开发的”全家桶”)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zRMW8Cnr-1665325873600)(assets/v2-2d78afcc4e7019b9788478345059a9a3_r.jpg)]
3.2.Spring Cloud 和 Spring Boot的关系
Spring boot 是 Spring 的一套快速配置脚手架,可以基于spring boot 快速开发单个微服务;
Spring Cloud是一个基于SpringBoot实现的微服务开发方案;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z41l1jQi-1665325873601)(assets\1587639568314.png)]
Spring boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Springboot,属于依赖的关系。
4.Spring Cloud Alibaba概述
4.1.Netflix公司项目进入维护模式
有了spring cloud这个微服务的框架,为什么又要使用spring cloud alibaba这个框架了?最重要的原因在于spring cloud中的几乎所有的组件都使用Netflix公司的产品,然后在其基础上做了一层封装。然而Netflix的众多组件在2020年停止维护,所以急需其他的一些替代产品,也就是spring cloud alibaba,目前正处于蓬勃发展的态式,马老师左手双十一,右手阿里开源组件,不仅占据了程序员的购物车,还要攻占大家的开发工具。
4.2.Spring Cloud Alibaba是什么?
同 Spring Cloud 一样,Spring Cloud Alibaba 也是一套微服务解决方案,包含开发微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
作为 Spring Cloud 体系下的新实现,Spring Cloud Alibaba 跟Spring Cloud官方的组件或其它的第三方实现如 Netflix, Consul,Zookeeper 等对比,具备了更多的功能:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Ei8py2K-1665325873608)(assets/v2-3a132c503bb7cde19314acc8a4866c4b_r.jpg)]
4.3.Spring Boot和Spring Cloud的版本号说明
-
版本号说明
Spring Cloud是基于Springboot的对应版本号开发的,属于依赖的关系,所以不能都选用最新版本
-
Spring Boot和Spring Cloud的版本号如下:
Spring Boot版本号:https://spring.io/projects/spring-boot#learn
Spring Cloud版本号:https://spring.io/projects/spring-cloud#learn
Spring Cloud Alibaba版本号:https://spring.io/projects/spring-cloud-alibaba#learn
-
下表为按时间顺序发布的 Spring Cloud Alibaba 以及对应的适配 Spring Cloud 和 Spring Boot 版本关系:
Spring Cloud Alibaba Version Spring Cloud Version Spring Boot Version 2021.0.1.0 Spring Cloud 2021.0.1 2.6.3 2.2.7.RELEASE Spring Cloud Hoxton.SR12 2.3.12.RELEASE 2021.1 Spring Cloud 2020.0.1 2.4.2 2.2.6.RELEASE Spring Cloud Hoxton.SR9 2.3.2.RELEASE 2.1.4.RELEASE Spring Cloud Greenwich.SR6 2.1.13.RELEASE 2.2.1.RELEASE Spring Cloud Hoxton.SR3 2.2.5.RELEASE 2.2.0.RELEASE Spring Cloud Hoxton.RELEASE 2.2.X.RELEASE 2.1.2.RELEASE Spring Cloud Greenwich 2.1.X.RELEASE 2.0.4.RELEASE(停止维护,建议升级) Spring Cloud Finchley 2.0.X.RELEASE 1.5.1.RELEASE(停止维护,建议升级) Spring Cloud Edgware 1.5.X.RELEASE
5.Nacos概述和安装
5.1.案例准备
5.1.1.创建springcloud_parent
5.1.1.1.pom.xml
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjpowernode</groupId>
<artifactId>springcloud_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<!-- 项目源码及编译输出的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 项目编译JDK版本 -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<!--Spring Boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Netflix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud 阿里巴巴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
5.1.2.创建springcloud_common
5.1.2.1.pom.xml
<?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>springcloud_parent</artifactId>
<groupId>com.bjpowernode</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud_common</artifactId>
</project>
5.1.2.2.pojo
public class User {
private Integer id;
private String name;
private Integer age;
public User() {
}
public User(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
5.1.3.创建nacos_provider
5.1.3.1.pom.xml
<?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>springcloud_parent</artifactId>
<groupId>com.bjpowernode</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos_provider</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.bjpowernode</groupId>
<artifactId>springcloud_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
5.1.3.2.application.yml
server:
port: 9090
5.1.3.3.APP
package com.bjpowernode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class);
}
}
5.1.3.4.service
package com.bjpowernode.service;
import com.bjpowernode.pojo.User;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Override
public User getUserById(Integer id) {
return new User(id,"王粪堆",18);
}
}
5.1.3.5.controller
package com.bjpowernode.controller;
import com.bjpowernode.pojo.User;
import com.bjpowernode.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/provider")
public class ProviderController {
@Autowired
private UserService userService;
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
return userService.getUserById(id);
}
}
5.1.4.创建nacos_consumer
5.1.4.1.pom.xml
<?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>springcloud_parent</artifactId>
<groupId>com.bjpowernode</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos_consumer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.bjpowernode</groupId>
<artifactId>springcloud_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
5.1.4.2.application.yml
server:
port: 80
5.1.4.3.App
package com.bjpowernode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class);
}
}
5.1.4.4.config
package com.bjpowernode.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ConfigBean {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
5.1.4.5.controller
package com.bjpowernode.controller;
import com.bjpowernode.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping(value = "/consumer")
public class ConsumerController {
//访问Rest服务的客户端
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value="/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
//调用服务
String url = "http://127.0.0.1:9090/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
}
5.1.5.问题
通过上一章的操作,我们已经可以实现微服务之间的调用。但是我们把服务提供者的网络地址(ip,端口)等硬编码到了代码中,这种做法存在许多问题:
- 一旦服务提供者地址变化,就需要手工修改代码
- 一旦是多个服务提供者,无法实现负载均衡功能
- 一旦服务变得越来越多,人工维护调用关系困难
那么应该怎么解决呢,这时候就需要通过注册中心动态的实现服务治理。
5.1.Nacos简介
5.1.1.为什么叫Nacos
前面四个字母分别表示 Naming 和 Configuration 的前两个字母, 最后一个s 为 Service
5.1.2.Nacos是什么
Nacos 是阿里巴巴的新开源项目,其核心定位是 “一个更易于帮助构建云原生应用的集注册中心与配置中心于一体的管理平台”。
5.2.Nacos安装和启动
5.2.1.下载
下载地址:https://github.com/alibaba/nacos/tags
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M0JcjlLw-1665325873609)(assets/image-20220326125801475.png)]
5.2.2.安装
解压安装包:
[root@localhost ~]# cd /usr/upload
[root@localhost upload]# tar -zxvf nacos-server-1.4.1.tar.gz -C /usr/local
5.2.3.启动和关闭
启动:
[root@localhost local]# cd nacos/bin/
[root@localhost bin]# ./startup.sh -m standalone #非集群模式启动
... ...
nacos is starting with standalone
nacos is starting,you can check the /usr/java/nacos/logs/start.out
关闭:
[root@localhost bin]# ./shutdown.sh
The nacosServer(3543) is running...
Send shutdown request to nacosServer(3543) OK
[root@localhost bin]
5.2.4.测试
浏览器访问:http://192.168.209.129:8848/nacos,默认用户名/密码为: nacos/nacos
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cUBY178i-1665325873610)(assets/image-20201219104006064.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N6CWrXeR-1665325873610)(assets/image-20220326130252395.png)]
6.Nacos注册中心
6.1.什么是Nacos注册中心
![jy](assets/jy.png)
注册中心主要有三部分组成:
Ø Nacos-Server:注册中心
提供服务的注册和发现。
Ø Nacos-Provider:服务提供方
把自身的服务实例注册到 Nacos Server 中
Ø Nacos-Consumer:服务调用方
通过 Nacos Server 获取服务列表,消费服务。
6.2.Nacos注册中心入门
6.2.1.修改nacos_provider
6.2.1.1.pom.xml
<!--nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
6.2.1.2.application.yml
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.209.129:8848 #nacos服务的地址
application:
name: nacos-provider #向注册中心注册的名字
6.2.1.3.APP
@SpringBootApplication
@EnableDiscoveryClient//向注册中心注册该服务,并可以获取其他服务的调用地址
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class);
}
}
6.2.1.4.测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xVr3MSoI-1665325873611)(assets/image-20220326130403785.png)]
6.3.2.修改nacos_consumer
6.3.1.1.pom.xml
<!--nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
6.3.1.2.application.yml
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.209.129:8848 #nacos服务的地址
application:
name: nacos-consumer #向注册中心注册的名字
6.3.1.3.APP
@SpringBootApplication
@EnableDiscoveryClient//向注册中心注册该服务,并可以获取其他服务的调用地址
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class);
}
}
6.3.1.4.controller
@RestController
@RequestMapping(value = "/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping(value="/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
//获取nacos中注册的所有服务信息
List<String> serviceList = discoveryClient.getServices();
for (String service : serviceList) {
System.out.println(service);
}
//获取nacos中注册的指定服务信息
ServiceInstance instance = discoveryClient.getInstances("nacos-provider").get(0);
String serviceUrl = instance.getHost() + ":" + instance.getPort();
String url = "http://"+serviceUrl+"/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
}
6.3.1.5.测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4a8fEAqs-1665325873611)(assets/image-20220326130658238.png)]
7.Nacos配置中心
7.1.什么是Nacos配置中心
首先我们来看一下,微服务架构下关于配置文件的一些问题:
- 配置文件相对分散。在一个微服务架构下,配置文件会随着微服务的增多变的越来越多,而且分散在各个微服务中,不好统一配置和管理。
- 配置文件无法区分环境。微服务项目可能会有多个环境,例如:测试环境、预发布环境、生产环境。每一个环境所使用的配置理论上都是不同的,一旦需要修改,就需要我们去各个微服务下手动维护,这比较困难。
- 配置文件无法实时更新。我们修改了配置文件之后,必须重新启动微服务才能使配置生效,这对一个正在运行的项目来说是非常不友好的。
基于上面这些问题,我们就需要配置中心的加入来解决这些问题,配置中心的思路是:
-
首先把项目中各种配置全部都放到一个集中的地方进行统一管理。
-
当各个服务需要获取配置的时候,就来配置中心的接口拉取自己的配置。
-
当配置中心中的各种参数有更新的时候,也能通知到各个服务实时的过来同步最新的信息,使之动态更新。
7.2.Nacos配置中心入门
7.2.1.创建nacos_config
7.2.1.1.pom.xml
<?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>springcloud_parent</artifactId>
<groupId>com.bjpowernode</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos_config</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
</project>
7.2.1.2.bootstrap.yml
- 注意:
- 客户端配置文件的名称必须为
bootstrap.yml
- 客户端配置文件的名称必须为
- bootstrap/ application 的应用场景:
bootstrap.yml
比applicaton.yml
优先加载,应用于系统级别参数配置,一般不会变动;application.yml
应用于SpringBoot项目的自动化配置;
- 案例:
spring:
cloud:
nacos:
config:
server-addr: 192.168.204.129:8848
file-extension: yaml #后缀名,只支持 properties 和 yaml 类型
prefix: nacos-config #文件名,如果没有配置则默认为 ${spring.appliction.name}
7.2.1.3.App
package com.bjpowernode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConfigApp {
public static void main(String[] args) {
SpringApplication.run(NacosConfigApp.class);
}
}
7.2.1.4.controller
package com.bjpowernode.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope //重新从BeanFactory获取一个新的实例(该实例使用新的配置)
public class ConfigController {
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.type}")
private String type;
@GetMapping("/config/info")
public String getConfigInfo() {
System.out.println(this);
String configInfo = driverClassName+"<br>"+url+"<br>"+username+"<br>"
+password+"<br>"+type;
return configInfo;
}
}
7.2.2.往Nacos添加配置信息
7.2.2.1.Nacos的Data ID
-
在 Nacos 中,dataId(配置文件的命名的规则) 的完整格式如下:
${spring.cloud.nacos.config.prefix}.${spring.cloud.nacos.config.file-extension}
-
说明:
- spring.cloud.nacos.config.prefix:默认是当前服务的服务名称
- spring.cloud.nacos.config.file-extension:配置文件的格式(后缀),目前只支持yaml和properties
-
例如:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K8wqlcOR-1665325873612)(assets/image-20220803131809181.png)]
7.2.2.2.创建配置文件
-
新建配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Qfs5Eq3-1665325873613)(assets/image-20220326140155907.png)]
-
添加配置文件
- 填写配置文件名称、格式、内容
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nLzBVRMG-1665325873614)(assets/image-20220803132034703.png)]
- 内容如下:
server: port: 80 spring: cloud: nacos: discovery: server-addr: 192.168.204.129:8848 application: name: nacos-config datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/health?characterEncoding=UTF-8 username: root password: 1111 type: com.alibaba.druid.pool.DruidDataSource
7.2.3.测试
-
启动时加载配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GWNBjrPk-1665325873614)(assets/image-20220325163938915.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hr09vWoS-1665325873615)(assets/image-20220713172023193.png)]
-
修改配置文件后nacos监听到MD5有变化则推送消息给客户端,客户端收到消息后会拉取最新配置(参考
配置管理->监听查询
菜单)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xmmxxBhQ-1665325873615)(assets/image-20220325171015583.png)]
3.浏览器访问:http://127.0.0.1/config/info
7.3.配置隔离
7.3.1.Nacos配置管理模型
-
对于Nacos配置管理,通过Namespace、group、Data ID能够定位到一个配置集。
-
配置隔离
配置文件按照命名空间、组的不同进行隔离,互不干扰
相同命名空间、组不能有相同的配置文件
-
Namespace Group DataId介绍:
- Namespace: 代表不同的环境的配置隔离, 如: 开发、测试, 生产等
- Group: 可以代表某个项目, 如XX医疗项目, XX电商项目
- DataId: 每个项目下往往有若干个工程, 每个配置集(DataId)是一个工程的主配置文件
-
获取配置集需要指定:
- nacos服务地址,必须指定
- namespace,如不指定默认public
- group,如不指定默认 DEFAULT_GROUP
- dataId,必须指定
7.3.2.namespace隔离
前面已经介绍过,命名空间(Namespace)是用于隔离多个环境的(如开发、测试、生产),而每个应用在不同环境的同一个配置(如数据库数据源)的值是不一样的。因此,我们应针对企业项目实际研发流程、环境进行规划。如某软件公司拥有开发、测试、生产三套环境,那么我们应该针对这三个环境分别建立三个namespace。
7.3.2.1.新建namespace
1.新建namespace
2.建立好所有namespace后,在配置管理与服务管理模块下所有页面,都会包含用于切换namespace的选项卡,如下图:
7.3.2.2.克隆配置文件
点击左下角克隆
按钮,将会弹出克隆对话框,此功能可用于将配置迁移到其他Namespace。
7.3.2.3.读取配置文件
spring:
cloud:
nacos:
config:
server-addr: 192.168.182.132:8848 #注册中心的地址#配置文件的前缀
prefix: nacos-config #配置文件的前缀,默认是spring.application.name
file-extension: yaml #配置文件的后缀,默认是properties
namespace: dev
#Data ID的语法:${spring.cloud.nacos.config.prefix}.${spring.cloud.nacos.config.file-extension}
7.3.2.4.测试
修改dev中配置文件的password为123123,之后在测试类中进行读取测试
7.3.3.group隔离
7.3.3.1.新建配置文件
1.新建配置文件并修改Group名
2.不同的配置分组下可以有相同的配置
此时两个配置文件在同一个namespace下,但是由于分组不同,所以两个文件是相互隔离的,因此名字可以相同
7.3.2.3.读取配置文件
spring:
cloud:
nacos:
config:
server-addr: 192.168.182.132:8848 #注册中心的地址#配置文件的前缀
prefix: nacos-config #配置文件的前缀,默认是spring.application.name
file-extension: yaml #配置文件的后缀,默认是properties
namespace: text
group: NACOS_GROUP
#Data ID的语法:${spring.cloud.nacos.config.prefix}.${spring.cloud.nacos.config.file-extension}
7.3.2.4.测试
修改命名空间为test,组为NACOS_GROUP的配置文件 password为test888
7.4.服务隔离
服务隔离
注册的服务按照命名空间、组的不同进行隔离,互不干扰
我找不到你,你找不到我
如果两个服务的命名空间不同,同时所在的组也不同,那么两个服务是没有办法互相调用的,如果一个服务去调用另一个服务,调用者会去自己的命名空间以及组下去找被调用的服务
7.4.1.修改配置文件
修改provider的配置文件,将其注册到命名空间为namespace的空间下
server:
port: 8090
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.182.132:8848 #注册中心的地址
namespace: test
group: DEFAULT_GROUP
application:
name: nacos-provider #注册到nacos的服务名
7.4.2.测试
此时看consumer是否能调通provider
此时当consumer调用provider的时候出现错误,原因是在同一个consumer的命名空间以及组下找不到provider的服务
8.Nacos集群和持久化
Nacos默认有自带嵌入式数据库derby,但是如果做集群模式的话,就不能使用自己的数据库不然每个节点一个数据库,那么数据就不统一了,需要使用外部的mysql
8.1.持久化
为什么要持久化?
nacos默认使用自带的嵌入式数据库derby,集群模式下会导致每台nacos的配置文件不一样
8.1.1.持久化步骤
持久化步骤
1)修改conf/application.properties:
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://192.168.182.130:3306/nacos?characterEncoding=utf8&connectTimeout=10000&socketTimeout=30000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=1111
2)建库建表
1.新建nacos库
2.建表:
找到conf/nacos-mysql.sql并执行
3)测试
1.启动mysql
2.启动nacos
3.新建配置文件,观察nacos是否把配置信息存储到mysql中
8.2.集群
8.2.1.部署架构图:
集群nacos,集群的数目最少为三个,并且还有一个主要的nacos,假设集群3个nacos分别为1、2、3,其中1为老大,当注册到2的时候,2会通知老大1,有服务注册到我这了,同时老大1会同步该服务,并且同通知3也要进行同步
8.2.2.节点规划
节点 | 端口 |
---|---|
192.168.204.156 | 8848 |
192.168.204.156 | 8849 |
192.168.204.156 | 8850 |
8.3.3.集群搭建
1、nacos集群搭建
1)将 cluster.conf.example复制一份(重要)复制为cluster.conf
修改cluster.conf:
cd /usr/local/nacos/conf
cp cluster.conf.example cluster.conf
vim cluster.conf:
# ip:port
192.168.182.132:8848
192.168.182.132:8849
192.168.182.132:8850
2)赋值3份nacos
cd /usr/local
mkdir nacos_cluster
cp -r nacos nacos_cluster/nacos_8848
cp -r nacos nacos_cluster/nacos_8849
cp -r nacos nacos_cluster/nacos_8850
3)修改conf/application.properties:
server.port=8849
server.port=8850
4)启动nacos集群(把虚拟机内存调至>=2g)
cd /usr/local/nacos_cluster/nacos_8848/bin
./startup.sh
cd /usr/local/nacos_cluster/nacos_8849/bin
./startup.sh
cd /usr/local/nacos_cluster/nacos_8850/bin
./startup.sh
8.3.4.测试
在nacos集群管理中查看,启动的节点
8.3.配置代理服务
8.3.1.安装nginx
1) 安装c语言环境
yum -y install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
2)下载nginx
cd /usr/upload
wget -c https://nginx.org/download/nginx-1.12.0.tar.gz
3)解压
cd /usr/upload
tar -zxvf nginx-1.12.0.tar.gz
4)配置安装路径
cd /usr/upload
cd nginx-1.12.0
./configure --prefix=/usr/local/nginx
5)编译并安装
make && make install
6)启动和关闭
cd /usr/local/nginx/sbin
启动:./nginx
关闭:./nginx -s stop
3、配置nginx代理nacos集群
vim /usr/local/nginx/conf/nginx.conf:
upstream nacosList {
server 192.168.182.132:8848;
server 192.168.182.132:8849;
server 192.168.182.132:8850;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://nacosList;
}
}
8.5.测试
1.启动nacos集群
[root@localhost upload]# cd /usr/local/nacos_cluster/nacos_8848/bin
[root@localhost bin]# ./startup.sh
[root@localhost bin]# cd /usr/local/nacos_cluster/nacos_8849/bin
[root@localhost bin]# ./startup.sh
[root@localhost bin]# cd /usr/local/nacos_cluster/nacos_8850/bin
[root@localhost bin]# ./startup.sh
2.启动nginx
[root@localhost nginx]# cd /usr/local/nginx/sbin/
[root@localhost sbin]# ./nginx
3.将微服务注册到Nacos集群
4.访问nacos集群
启动nacos-config服务,并通过nginx访问nacos集群:http://192.168.209.129/nacos
9.Nacos开机自启
9.1.编写开机启动文件
- 添加nacos.service文件
vim /lib/systemd/system/nacos.service
- 文件内容如下:
[Unit]
Description=nacos
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nacos/bin/startup.sh -m standalone
ExecReload=/usr/local/nacos/bin/shutdown.sh
ExecStop=/usr/local/nacos/bin/shutdown.sh
PrivateTmp=true
[Install]
WantedBy=multi-user.target
9.2.修改nacos的startup.sh
- 修改JAVA_HOME路径并注销之后的3行配置,如下:
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/local/jdk1.8.0_191
#[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
#[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/opt/taobao/java
#[ ! -e "$JAVA_HOME/bin/java" ] && unset JAVA_HOME
9.3.设置开机启动
systemctl daemon-reload #重新加载服务配置
systemctl enable nacos.service #设置为开机启动
systemctl start nacos.service #启动nacos服务
systemctl stop nacos.service #停止nacos服务