目录儿

  • 二、SpringCloud技术栈
  • 三、环境搭建
    • 3.1 开发环境搭建
    • 3.2 安装部署mysql
    • 3.3 创建 SpringBoot 项目
      • 3.3.1 简介
      • 3.3.2 构建项目
      • 3.3.3 热部署
    • 3.4 建立 Spring Cloud Alibaba 模板项目
      • 3.4.1创建父项目
  • 四、服务中心、配置中心-Nacos
    • 4.1 Nacos 简介
    • 4.2 Nacos下载安装
    • 4.3 使用Nacos的服务注册中心功能
      • 4.3.1 创建第一个服务provider
      • 4.3.2 创建服务消费者
    • 4.4 使用Nacos 配置中心功能
      • 4.4.1 集成 Nacos 配置中心
      • 4.4.2 Nacos DataId 配置
      • 4.4.3 Nacos Group 配置
      • 4.4.4 Nacos Namespace 配置
      • 4.4.5 Namespace、Group、DataId 之间的关系
    • 4.5 Nacos 持久化配置
      • 4.5.1 为 Nacos 配置数据库
      • 4.5.2 重新创建配置
    • 4.6 Nacos 集群部署
      • 4.6.1 Nacos + OpenResty 搭建简单集群
        • 搭建 Nacos 集群节点
        • 安装 OpenResty
    • 4.7 Nacos+OpenResty+Keepalived高可用集群
      • 4.7.1部署 OpenResty 集群
      • 部署 Keepalived 服务
    • 注册中心产品对比

二、SpringCloud技术栈

Spring Cloud 本身并不是一个拿来即用的框架,而是一套规范。主流的 Spring Cloud NetfixSpring Cloud Alibaba 实现了这一套规范

微服务常用技术栈:

技术栈 落地实现
服务注册与返现 Eureka、Zookeeper、Consul、Nacos
服务熔断、限流、降级 Hystrix、Reslience4j、Sentinel
服务调用 Ribbin、Loadbalancer、Feign、OpenFeign、Dubbo
配置中心 Config、Zookeeper、Consul、Nacos
服务网关 Zuul、Gateway
消息总线 Bus、Nacos

Spring Cloud Alibaba 微服务解决方案提供的组件:

组件名 详情
Nacos 服务注册与发现、服务管理、配置中心
RocketMQ 分布式消息中间件,主要提供可靠的消息发布与订阅消费服务
Dubbo Spring Cloud 远程调用框架
Sentinel 流程控制框架,提供服务限流、降级、熔断等功能,保证服务的稳定性
Seata 分布式事务解决方案,保证数据一致性
OSS (收费)高可用的文件存储服务
SchedulerX (收费)分布式任务调度
SMS (收费)短信服务

三、环境搭建

3.1 开发环境搭建

  • JDK1.8(最低)
  • Maven 3.6.3
  • IDEA 2019.3.4

3.2 安装部署mysql

版本5.7.24

3.3 创建 SpringBoot 项目

3.3.1 简介

Spring Boot简化了Spring MVC:

  • 集成了很多第三方技术框架如数据库MQ等
  • 简化了配置文件,不需要 XML 文件配置
  • 内嵌Tomcat、Jetty、Undertow Servlet容器,默认用Tomcat

3.3.2 构建项目

创建 SpringBoot项目有很多种方式

  • 到 SpringBoot 官网用网页创建,地址:https://start.spring.io
  • 使用IDEA创建,主界面点击Create New Project,选择 Spring Initializr
  • 使用阿里云的网页创建,地址:https://start.aliyun.com

这里选择到官网用网页创建
创建之前先查询版本依赖关系,选择一个
https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
![在这里插入图片描述](https://img-blog.csdnimg.cn/2734fe806aa0425d86dc0980b28747a6.png

这里选了springboot 2.6.11,(随便选)后面再改 ,依赖只加了个 Spring Web

3.3.3 热部署

添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional>
</dependency>

配置

配置注册表

3.4 建立 Spring Cloud Alibaba 模板项目

搭建 Spring Cloud Alibaba 需要基于 Spring Boot 项目

3.4.1创建父项目

以父子项目的形式管理整个 Spring Cloud Alibaba 项目
先创建一个 Maven 项目作为父项目,再把之前生成的 smaple 项目加进去即可

再修改 pom 文件,做好基础依赖
父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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><!-- 在依赖管理中声明了spring boot 依赖,就可以不用继承这种方式 --><!-- <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.11</version><relativePath/> &lt;!&ndash; lookup parent from repository &ndash;&gt;</parent>--><!-- 项目信息 --><groupId>com.echoo</groupId><artifactId>parent</artifactId><version>1.0.0</version><name>echoo-cloud</name><description>Parent For Spring Cloud Alibaba</description><modules><module>sample</module></modules><!-- 版本管理 --><properties><java.version>1.8</java.version><spring.boot.version>2.3.2.RELEASE</spring.boot.version><spring.cloud.version>Spring Cloud Hoxton.SR9</spring.cloud.version><spring.cloud.alibaba.version>2.2.6.RELEASE</spring.cloud.alibaba.version></properties><!-- 依赖管理 --><dependencyManagement><dependencies><!-- spring-boot 依赖,代替继承的方式 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring.boot.version}</version><type>pom</type><scope>import</scope></dependency><!-- spring-boot-starter-web 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>${spring.boot.version}</version></dependency><!-- spring-boot测试 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>${spring.boot.version}</version><scope>test</scope></dependency><!-- spring-cloud-dependencies --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud.version}</version><type>pom</type><scope>import</scope></dependency><!-- spring-cloud-alibaba-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><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><!-- maven 编译插件,用于编译java代码 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.7.0</version><configuration><!-- 指定源代码和目标代码的JDK版本否则会使用与当前maven版本对应的默认JDK版本去识别、编译代码很有可能会识别、编译失败 --><source>${java.version}</source> <!-- 指定源代码使用的 JDK 版本,用于事变 --><target>${java.version}</target> <!-- 生成目标(.class)文件的JDK版本,用于编译--><encoding>UTF-8</encoding> <!-- 字符集编码 --></configuration></plugin></plugins></build><!-- 使用远程仓库 --><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><snapshots><enabled>true</enabled></snapshots></repository></repositories><!-- 使用远程插件仓库 --><pluginRepositories><pluginRepository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url></pluginRepository><pluginRepository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><snapshots><enabled>true</enabled></snapshots></pluginRepository></pluginRepositories></project>

sample.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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.echoo</groupId><artifactId>parent</artifactId><version>1.0.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.echoo.base</groupId><artifactId>sample</artifactId><version>0.0.1-SNAPSHOT</version><name>sample</name><description>base project for Spring Cloud Alibaba</description><properties><java.version>1.8</java.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-test</artifactId><scope>test</scope></dependency><!-- 热部署,单独作用于模块,所以不用声明在父pom --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency></dependencies></project>

四、服务中心、配置中心-Nacos

4.1 Nacos 简介

Nacos = Naming + Configuration +Service
           = 服务命名管理 + 配置管理 + 服务注册中心

4.2 Nacos下载安装

地址:https://github.com/alibaba/nacos/releases
根据推荐版本,这里选择下载 v1.4.2

我选择了用 docker 镜像装在自己的云服务器上,参考:https://blog.csdn.net/qq_31856061/article/details/123621927
安装后直接访问,修改密码即可。

4.3 使用Nacos的服务注册中心功能

下面正式开始编写代码,将会编写一个消费服务,两个服务供应,服务之间的调用暂时用 RestTemplate + Ribbon 实现,顺带测试一下负载均衡的效果。

4.3.1 创建第一个服务provider

在之前创建了一个父子项目 echoo-cloud
复制一份修改一下项目名称路径pom.xml文件即可
父 pom.xml

    <!-- 项目信息 --><groupId>com.echoo.cloud.nacos</groupId><artifactId>spring-cloud-alibaba-nacos-sample</artifactId><version>1.0.0</version><name>spring-cloud-alibaba-nacos-sample</name><description>nacos-sample</description>

子 pom.xml

    <parent><groupId>com.echoo.cloud.nacos</groupId><artifactId>spring-cloud-alibaba-nacos-sample</artifactId><version>1.0.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.echoo.cloud.nacos.provicer</groupId><artifactId>provider8031</artifactId><version>1.0.0</version><name>provider8031</name><description>nacos-provider8031</description>

修改项目的项目名和目录名

因为子项目的目录修改了,所以父项目的 pom.xml 对子项目的引用也要改

    <!-- 引入子模块(子模块的相对目录) --><modules><module>provider8031</module></modules>

在 Provider8031 的 pom.xml 中添加 Nacos 注册中心/服务发现和健康监控依赖

<!-- 服务健康监控 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Nacos 服务注册/服务发现 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

配置文件:

server:port: 8031 # 服务端口spring:application:name: nacos-provider-one # 应用名cloud:nacos:discovery:server-addr: 124.221.89.209:8849 # Nacos 服务地址management:endpoints:web:exposure:include: '*' # 公开所有端点

编写测试接口

@RestController
public class TestController {@Value("${server.port}")private String port;@RequestMapping("/test")public String test() {return "信息返回自①号服务,服务端口:" + port;}
}

复制一份 provider8031 项目,修改成 provider8032 ,添加到父项目中
此时就有两个服务供应了

启动后可以看到 Nacos 上注册了两个服务供应

服务接口通过 postman 或 curl 测试也是完全没问题

4.3.2 创建服务消费者

复制一份 provider 项目,修改成 consumer8041
至此有了三个子项目, 两个供应者一个消费者

注意,两个服务供应者的名字是一样的,端口不同(后续通过这个名字调取服务)

使用 Java Config 的方式配置一个负载均衡的 RestTemplate

@Configuration
public class GenericConfig {@Bean@LoadBalanced // 必须添加负载均衡注解public RestTemplate restTemplate() {return new RestTemplate();}
}

在测试接口处通过 RestTemplate 来远程调用

@RestController
public class TestController {@Value("${server.port}")private String port;private final String SERVER_URL = "http://nacos-provider"; // 这里不写具体的某个服务的ip和端口,而是通过注册到 Nacos 的服务名代替@Resourceprivate RestTemplate restTemplate;@RequestMapping("/test")public String test() {String result = restTemplate.getForObject(SERVER_URL + "/test", String.class);return "①号消费者(" + port + "):" + result;}
}

调用消费者测试接口

可以看到消费者测试接口轮流调用两个供应服务的接口,实现了负载均衡
这个负载均衡是由 Ribbon 框架实现的,而 Nacos 整合了 Ribbon

RestTemplate 在Config类中已经被 Ribbon 代理, 当调 用 restTemplate的 postForObject()、getForObject() 时根据微服务名称,到注册中心查找对应的具体的服务地址。

4.4 使用Nacos 配置中心功能

通常我们在项目的 application.propertiesd 或 application.yml 文件里写配置,有个非常明显的缺点,就是每次修改配置后需要重启项目才能生效。如果对多个相同的服务做了集群,那么就有了很多个重复的配置文件,修改起来非常麻烦。为此,Nacos 提供了配置中心解决方案。

4.4.1 集成 Nacos 配置中心

我们直接用消费者项目修改,引入 Nacos 配置中心。

修改 pom.xml : 引入 nacos 配置中心的依赖

<!-- Nacos 配置中心 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

创建基础配置文件 bootstrap.yml 或 bootstrap.properties

在 SpringBoot 框架中,配置文件不止一种,名为 bootstrap 的配置文件 优先级 比名为 application 的配置文件高,启动时会先加载 bootstrap 配置文件。因此我们把启动项目的基本配置写在 bootstrap 中,待项目启动后再从 Nacos 配置中心拉取哪些次要配置。是这样一个逻辑

server:port: 8041 # 服务端口spring:application:name: nacos-consumer-one # 应用名cloud:nacos:discovery:server-addr: 124.221.89.209:8849 # Nacos 注册中心地址config:server-addr: 124.221.89.209:8849 # Nacos 配置中心地址(因为是同一个所以和注册中心地址一样)file-extension: yml              # 指定配置文件的数据格式management:endpoints:web:exposure:include: '*' # 公开所有端点

4.4.2 Nacos DataId 配置

DataId 目的是使项目快速切换多套配置内容。
DataId 格式:

${prefix}-${spring.profiles.active}.${file-extention}
  • prefix 默认值是 spring.application.name 的值

注意:
可以通过 spring.cloud.nacos.config.prefix 配置项覆盖

  • spring.profiles.active 是当前选择的环境

注意:
当 spring.profiles.active 为空时,对应的连接符 “-” 也将不存在,dataId 的格式变成 prefix.{prefix}.prefix.{file-extention}

  • file-extention 是配置内容的数据格式

注意:
通过 spring.cloud.nacos.config.file-extention 配置项来配置

有了基础认识后,我们开始用 DataId 创建配置
先在消费者的 application.yml 配置中:

spring:profiles:active: dev

在 Nacos 平台上添加配置
开发配置 DataId:

nacos-consumer-dev.yml

配置项:

custom:info: nacos config dev

生产配置 DataId:

nacos-consumer-prod.yml

配置项:

custom:info: nacos config prod


然后在消费者项目中添加一个测试接口

@RefreshScope // 配置自动更新
@RestController
public class TestController {@Value("${custom.info}") // 从配置文件读取配置private String config;@RequestMapping("/getConfig")public String getConfig() {return config;}
}

@RefreshScope 是 SpringCloud 的原生注解
测试:

成功拿到 开发配置 的配置项的值
修改开发配置

custom:info: nacos config dev update

再测试看看有没有自动更新


更新成功,完美

4.4.3 Nacos Group 配置

group 是分组,表示配置归属于哪个组,默认是 DEFAULT_GROUP 组。

我们可以通过 spring.cloud.nacos.config.group 配置项 指定获取哪个组的配置

在 Nacos 配置中心新建一个配置

修改 bootstrap.yml 文件,增加 spring.cloud.nacos.config.group 配置项,指定 CUSTOM_GROUP 组

spring:application:name: nacos-consumer # 应用名cloud:nacos:discovery:server-addr: 124.221.89.209:8849 # Nacos 注册中心地址config:server-addr: 124.221.89.209:8849 # Nacos 配置中心地址(因为是同一个所以和注册中心地址一样)file-extension: yml              # 指定配置文件的数据格式group: CUSTOM_GROUP              # 指定组

完了拿到的就是 CUSTOM_GROUP 的配置了

4.4.4 Nacos Namespace 配置

namespace 命名空间,是一种粗粒度的控制。默认的命名空间是 public。
命名空间囊括了 Group、DataId。
创建自定义命名空间

回到配置列表,public 旁多出了个 fatst_team 命名空间

选择 fast_team 命名空间,添加一条配置

在消费者 bootstrap.yml 增加一项配置项,指定命名空间(必须是命名空间的 id)

spring:application:name: nacos-consumer # 应用名cloud:nacos:discovery:server-addr: 124.221.89.209:8849 # Nacos 注册中心地址config:server-addr: 124.221.89.209:8849 # Nacos 配置中心地址(因为是同一个所以和注册中心地址一样)file-extension: yml              # 指定配置文件的数据格式group: CUSTOM_GROUP              # 指定组namespace: 19b1fec0-b937-457b-b322-171086446ba2 # 命名空间 id

测试取到的值就是 fast_team 命名空间下 dev 配置文件的值

4.4.5 Namespace、Group、DataId 之间的关系

三者都是用于将区分配置,其中 Namespace 为第一级,Group 为第二级,DataId 为第三级,粒度由粗到细。
比如用 Namespace 区分团队,以 Group 区分功能模块,以 DataId 做最后的环境区分。

4.5 Nacos 持久化配置

Nacos 默认使用嵌入式数据库 - Derby 数据库,因为 存储容量限制,不方便查询、优化,做集群时不能将应用和数据分开 等原因,往往需要一个外部的数据库做为数据的持久化仓库。目前仅支持 MySql ,版本要求为 5.6.5+ 。

4.5.1 为 Nacos 配置数据库

先创建一个数据库 nacos_config (任意名),并通过脚本文件 nacos-mysql.sql 导入对应的表

nacos-mysql.sql 脚本文件可以在源码找到(nacos-1.4.2.zip\nacos-1.4.2\distribution\conf\nacos-mysql.sql
也可以在安装目录找到 (安装目录\conf\nacos-mysql.sql )

然后修改 Nacos 的配置文件
我用的是 docker 部署 Nacos,所以先进入容器

docker exec -it 594c187f55f9 /bin/bash

编辑 /conf/application.properties 配置文件

spring.datasource.platform=mysql
db.url.0=jdbc:mysql://124.221.89.200:3305/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=xxxxx

重启容器

docker stop 594c187f55f9
docker start 594c187f55f9

重新访问 Nacos ,此时的 Nacos 是初始状态
刷新看看服务注册是否正常,至此完成对单机版 Nacos 的持久化。

4.5.2 重新创建配置

重新创建命名空间和配置

custom:info: nacos config namespace fast_team group CUSTOM_GROUP active dev repository with mysql

修改消费者项目 bootstrap.yml 中的 namespace 项并重启项目

测试没问题,完美。

4.6 Nacos 集群部署

上面实现的 Nacos 数据持久化,就是在为集群部署奠定基础。在实际生产中,如果以单机模式运行 Nacos 服务,一旦宕机,就会引发单点故障,而 Nacos 作为一个基础服务,影响非常大。
首先看看 Nacos 的集群架构

客户端指代所有连接到 Nacos 的服务,如浏览器
负载均衡常用 Nginx 、Keepalived、OpenResty 等
所有 Nacos 节点都用的同一数据库(集群),保证数据统一。

4.6.1 Nacos + OpenResty 搭建简单集群

业界常用的负载均衡中间件是 Keepalived,它能解决使用静态路由地址单点故障的问题,保证99.99%高可用 。
但是 Keepalived 使用起来比较麻烦,这里先选择 OpenResty 实现,后面再引申到 Keepalived

OpenResty:
有一个大名鼎鼎的中间件 Nginx,它有两个重要的功能:反向代理和负载均衡。OpenResty 就是基于 Nginx 开发的,集成了很多优秀的 Nginx模块,其中最出名的就是 Lua 了,OpenResty 相当于是 Nginx 的增强。

搭建 Nacos 集群节点

① 下载安装 nacos-server

Nacos 集群至少 3 个节点,我这里用自己的云服务器搭。
下载 nacos-server-1.4.2.tar.gz 压缩包 (地址:https://github.com/alibaba/nacos/releases)
上传服务器、解压即可

② 配置文件配置 mysql数据库

修改 conf/application.properties 配置文件

#*************** 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://124.221.89.200:3305/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=true&serverTimezone=UTC
db.user.0=root
db.password.0=xxxxx

注意:

  1. url 中的默认 useSSL=false,在启动过程中报错 Public Key Retrieval is not allowed,改成 useSSL=true 后正常启动。
  2. 集群节点共用一个 数据库(集群)。

③ 添加集群配置

conf/ 下添加一个集群配置文件 cluster.conf
内容如下:

124.221.89.200:8848
124.221.89.200:8847
124.221.89.200:8846

注意:分别是3个 Nacos (包括自己)的地址和端口

④ 复制 nacos 文件夹

因为我们需要3个 Nacos 服务,因此直接将 nacos 改名,再复制2份即可,分别命名 nacos1、nacos2,nacos3

mv nacos/ nacos1
cp -R nacos1/ nacos2
cp -R nacos1/ nacos3

⑤ 修改启动脚本

vi nacos1/bin/startup.sh

定位到启动命令行

nohup $JAVA ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &

插入指定启动端口配置项: -Dserver.port=8848

nohup $JAVA -Dserver.port=8848 ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &

其他两个 nacos 同理指定 8847,8846 端口即可

⑥ 启动三个服务

./nacos1/bin/startup.sh
./nacos2/bin/startup.sh
./nacos3/bin/startup.sh

分别查看启动日志观察是否有如下启动成功日志

2022-08-25 09:11:16,636 INFO Nacos started successfully in cluster mode. use external storage

至此 nacos 集群节点搭建好了,访问任意 nacos 服务平台可看到节点信息

安装 OpenResty

下载 OpenResty 及其依赖的安装包

wget -O openresty-1.15.8.2.tar.gz -c https://sourceforge.net/projects/generic-software/files/php/openresty-1.15.8.2.tar.gz/download
wget -O openssl-1.0.2q.tar.gz -c https://sourceforge.net/projects/generic-software/files/php/openssl-1.0.2q.tar.gz/download
wget -O pcre-8.41.tar.gz -c https://sourceforge.net/projects/generic-software/files/php/pcre-8.41.tar.gz/download
wget -O zlib-1.2.11.tar.gz -c https://sourceforge.net/projects/generic-software/files/php/zlib-1.2.11.tar.gz/download
wget -O perl-5.30.1.tar.gz -c https://sourceforge.net/projects/generic-software/files/php/perl-5.30.1.tar.gz/download

安装 perl (安装路径随意)

tar -zxvf perl-5.30.1.tar.gz
cd perl-5.30.1
./Configure -des -Dprefix=$HOME/localperl
make
make test
make install

分别解压 openssl pcre zlib

tar -zxvf openresty-1.15.8.2.tar.gz
tar -zxvf openssl-1.0.2q.tar.gz
tar -zxvf pcre-8.41.tar.gz
tar -zxvf zlib-1.2.11.tar.gz

安装 OpenResty

cd openresty-1.15.8.2
./configure --prefix=/usr/openresty --with-pcre=/usr/pcre/pcre-8.41 --with-zlib=/usr/zlib/zlib-1.2.11 --with-http_ssl_module   --with-openssl=/usr/ssl/openssl-1.0.2q
make & make install

–prefix : 指定 OpenResty 安装路径
–with-pcre : 指定 pcre 所在路径
–with-zlib : 指定 zlib 所在路径
–with-openssl : 指定 openssl 所在路径
–with-http_ssl_module : 是个 ssl 模块,支持配置 https

如果执行make & make install的时候出现编译器错误:

checking for gcc... cc
sed: can't read conftest.err: No such file or directory

安装 gcc gcc-c++ 编译器即可

yum install -y gcc gcc-c++

启动 OpenResty 服务

/usr/openresty/bin/openresty

OpenResty 服务的默认端口是 80 端口
启动成功后直接访问,页面出现 Welcome to OpenResty! 即成功

接下来是把 nacos 集群挂载到 OpenResty 上
编辑 /usr/openresty/nginx/conf 配置文件
http{}代码块中添加一个upstream (溯源流) 对象,给此对象起名为 nacosCluster (起名随意), 对象内容是指定 nacos 集群的服务节点地址,

http {upstream nacosCluster{server 127.0.0.1:8848;server 127.0.0.1:8847;server 127.0.0.1:8846;}
}

server{} 代码块的 location / {} 对象中添加代理

server {location / {proxy_pass http://nacosCluster;index  index.html index.htm;}
}

重载配置文件

/usr/openresty/bin/openresty -s reload

proxy_pass http://nacosCluster
nacosCluster 为溯源流对象名,意思是通过 nginx 代理 nacosCluster 中的 nacos 服务地址
例如:
     当访问 http://124.221.89.200:80/nacos 时,自动把 124.221.89.200:80 替换成 127.0.0.1:8847,再拼接上资源路径 /nacos,即 http://127.0.0.1:8847/nacos, 至于负载均衡策略先忽略.

测试
修改消费之模块的 nacos 服务地址端口为 OpenResty 的服务地址

spring:application:name: nacos-consumer # 应用名cloud:nacos:discovery:server-addr: 124.221.89.200:80 # Nacos 注册中心地址config:server-addr: 124.221.89.200:80 # Nacos 配置中心地址(因为是同一个所以和注册中心地址一样)file-extension: yml              # 指定配置文件的数据格式group: CUSTOM_GROUP              # 指定组namespace: 8f60737f-6b74-47f7-8f29-2c908d133fca # 命名空间 id

启动访问是否能获取配置数据
如果能,说明 OpenResty 算部署好了
接下来关掉一个 nacos 节点

此时只有两个可用节点.再测试是否能正常获取配置数据
如果能,则我们想要的 nacos 集群高可用就算实现了.

4.7 Nacos+OpenResty+Keepalived高可用集群

在4.6中实现了 Nacos 集群服务的基本高可用,短板此时来到了 OpenResty 身上,因为只有一个 OpenResty 服务,如果它挂了,下面的 Nacos 服务都废了,这就引发了单点故障。解决方案就是 OpenResty 也做一个集群,联合 Keepalived。
架构如下:

VIP 就是 Visual IP ,虚拟IP,也就是等下要用的 Keepalived 服务。我们主要用到 Keepalived 服务的 VRRP 功能。

VRRP:
  虚拟路由器冗余协议功能,用来解决静态路由单点故障问题,保证服务高可用。
  VRRP 协议为两台或以上设备提供一个或多个虚拟IP,内部节点分为 MASTER 主节点和 BACKUP 备用节点两种。假如有两台服务,一个 MASTER 一个 BACKUP 。首先会选举 MASTER 作为服务节点提供服务,当 MASTER 挂了,BACKUP 节点没有接受到 MASTER 节点的反馈时会重新选举(根据优先级)BACKUP 节点作提供服务。

4.7.1部署 OpenResty 集群

因为上面已经部署了一台 OpenResty 服务器,已经有一个节点了。接下载再部署另外一台 OpenResty 服务器形成双节点集群即可。部署方式直接参考 安装 OpenResty

注意:
新部署的这台 OpenResty 服务器不需要部署 Nacos 服务了,直接配置现有的那 3 个 Nacos 服务即可,这次的 ip 就不是 127.0.0.1 了。
upstream nacosCluster{
  server 124.221.89.200:8848;
  server 124.221.89.200:8847;
  server 124.221.89.200:8846;
}

部署 Keepalived 服务

两台服务器都需要部署 Keepalived 服务。

1.下载 Keepalived 安装包

下载地址:https://www.keepalived.org/download.html
上传、解压

2.配置安装路径

进入解压目录
直接配置,后面编译和安装就按默认的安装路径去装,比较不好找

 ./configure

指定目录,后面编译和安装就安装在自己指定的目录,更加清晰

./configure -- prefix=/usr/local/keepalived

如果配置或者后面编译的时候出现

这是因为缺少了一些头文件(库),装上即可:

yum install -y openssl-devel

3.编译安装

make && make install

4.把 Keepalived 设置为系统服务
如果是没有配置指定目录安装的,需要先查看安装位置

whereis keepalived
/etc/keepalived /usr/local/sbin/keepalived /usr/local/etc/keepalived

三个路径分别是 启动目录 执行文件 配置文件目录

如果是自己指定安装目录的,创建一个系统配置文件目录/etc/keepalived的配置文件存放目录

mkdir /etc/keepalived

把安装路径(注意自己的安装路径)下的配置文件复制一份到启动目录

# 没有指定目录
cp /usr/local/etc/keepalived/keepalived.conf  /etc/keepalived/
# 指定安装目录
cp /usr/local/keepalived/etc/keepalived/keepalived.conf  /etc/keepalived/

把执行文件拷贝一份到 /usr/sbin/ 目录下

# 没有指定目录
cp /usr/local/sbin/keepalived /usr/sbin/
# 指定安装目录
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/

将源码包中的初始化脚本拷贝一份到系统初始化目录下,系统初始化的时候会初始化keepalived

cp /usr/keepalived-2.1.5/keepalived/etc/init.d/keepalived /etc/init.d/

给执行文件添加可执行权限

chmod +x /etc/init.d/keepalived

将源码包中的配置文件拷贝一份到系统配置目录中,系统初始化keepalived的时候用

cp /usr/keepalived-2.1.5/keepalived/etc/sysconfig/keepalived /etc/sysconfig/

加入开机自启动

chkconfig --add keepalived
chkconfig keepalived  on


允许 vrrp 包发送(两台主机都要这样设置)

firewall-cmd --direct --permanent --add-rule  ipv4 filter  INPUT 0 --protocol vrrp  -j ACCEPT
firewall-cmd --reload

编辑 MASTER /etc/keepalived/keepalived.conf 文件

vrrp_script chk_openresty {script "/etc/keepalived/openresty_check.sh"interval 2weight -20
}vrrp_instance VI_1 {state MASTERinterface ens33virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}track_script {chk_openresty}virtual_ipaddress {192.168.1.115/24}
}

编辑 BACKUP /etc/keepalived/keepalived.conf 文件

vrrp_script chk_openresty {script "/etc/keepalived/openresty_check.sh"interval 2weight -20
}vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 51priority 50advert_int 1authentication {auth_type PASSauth_pass 1111}track_script {chk_openresty}virtual_ipaddress {192.168.1.115/24}
}

编写检测 OpenResty 服务的脚本

touch /etc/keepalived/openresty_check.sh
#!/bin/bash
echo "开始执行 openresty 进程检查脚本"echo "当前 openresty 进程数:$n"
if [ $n -eq 0 ];thenecho "开始启动 openresty"/usr/openresty/bin/openrestysleep 2if [ `/usr/openresty/bin/openresty` -eq 0 ];thenecho "openresty 启动失败,关闭 keepalived"killall keepalived fi
fi

注意 shell 脚本中命令行用的不是单引号 '',而是反引号 ``

启动keepalived

service keepalived start

如下启动成功

[root@VM-16-13-centos bin]# service keepalived start
Starting keepalived (via systemctl):  [  OK  ]

看看虚拟地址有没有起来

ip addr


5.测试访问
用虚拟地址访问 nacos 服务

关掉一台服务模拟宕机再访问
如果也没问题就是成功啦
到这里 Nacos + OpenResty + Keepalived 的集群高可用就部署完成噜

注册中心产品对比

CAP:

  • 一致性(Consistency):集群所有节点同一时间的数据是一致的,每次读取要么是最新的数据,要么是一个错误。
  • 可用性(Availability):client 在任何时刻的读写操作都能在限定的延迟内完成的,即每次请求都能获得一个响应(非错误),但不保证是最新的数据。
  • 分区容错性(Partition tolerance):在分布式系统中,服务之间通过网络相互通信,但网络不一定实时可靠,出现网络故障时,就有可能造成数据不一致,也就是发生了网络分区,分区容错性就是系统应该能保证在这种情况下可以正常工作。

CAP理论:
  对于C A P这三个特性,我们只能三选二,无法同时满足这三个特性,而现大多数是分布式系统,P一般是必须存在的,所以一般是在CA之间做取舍。具体详情参考某大鸟博客https://blog.csdn.net/paolei/article/details/119912023

承上:无
启下:SpringCloudAlibaba系列微服务搭建笔记二_RestTemplate+Ribbon

SpringCloudAlibaba系列微服务搭建笔记一_Nacos相关推荐

  1. 牌类游戏使用微服务重构笔记(四): micro框架使用经验

    项目依赖 推荐使用go module, 我选择go module的最主要原因是足够简单,可以脱离gopath,就跟写nodejs一样,随便在一个地方新建一个文件夹就可以撸代码了,clone下来的源码也 ...

  2. 牌类游戏使用微服务重构笔记(八): 游戏网关服务器

    网关服务器 所谓网关,其实就是维持玩家客户端的连接,将玩家发的游戏请求转发到具体后端服务的服务器,具有以下几个功能点: 长期运行,必须具有较高的稳定性和性能 对外开放,即客户端需要知道网关的IP和端口 ...

  3. Linux 常用服务搭建笔记(精简笔记)

    Linux 常用服务搭建笔记(精简笔记) 阅读目录 部署DNS实现解析 部署DNS主从同步 部署DNS缓存服务 部署DNS加密同步 部署DNS分离解析 部署DNS负载均衡 配置DHCP自动分配IP 配 ...

  4. SpringCloud微服务搭建(四 搭建EurekaServer集群)

    在上一章的基础上 在EurekasServer里面添加三个yml: bootstrap-server1.yml: server:port: 8794eureka:instance:hostname: ...

  5. 8 位阿里大佬合著“Dubbo 微服务进阶笔记”

    前言 微服务是近几年流行起来的软件架构风格.回顾历史,从传统的单体应用架构,到面向服务架构 SOA,再到今天逐渐被大众接受的微服务架构 MSA,本质上来说,都是为了解决随着软件复杂度的上升,如何有效提 ...

  6. 8位阿里P8合著“Dubbo微服务进阶笔记”一经面世,Github上标星93K+

    前言 微服务是近几年流行起来的软件架构风格.回顾历史,从传统的单体应用架构,到面向服务架构SOA,再到今天逐渐被大众接受的微服务架构MSA,本质上来说,都是为了解决随着软件复杂度的上升,如何有效提升开 ...

  7. Java微服务学习笔记(一):微服务架构的概念理解

    Java微服务学习笔记 Tips:入门学习时粗略整理,仅供参考 (一):架构的基础理解 文章目录 Java微服务学习笔记 前言 一.微服务是什么? 二.常用开源微服务框架演化 1. Dubbo 2. ...

  8. 巧用springboot微服务搭建一个网站

    想到微服务搭建博客其实挺多的,那就用微服务简单做个记账的网站,并部署在站点 1. 首先除了要了解什么是微服务之外,因为是用Springboot框架,还要了解一下父子项目,thymeleaf,sprin ...

  9. SpringCloud工程搭建之网关微服务搭建(可选)

    五.网关微服务搭建(可选) 完整工程源码:https://gitee.com/forwardxiang/spring-cloud-demo.git 5.1 创建网关服务子工程 5.1.1 引入依赖 创 ...

最新文章

  1. ICCV 2021 | 英伟达新研究:直接通过视频就能捕获3D人体动作!
  2. 【c语言】测量字符串长度
  3. Spring Boot 入门之基础篇(一)
  4. rxandroid 源码分析
  5. html中css路径和xpath路径,6.1 HTML的简单介绍和快速获取XPath和CSS路径
  6. ASP.NET中网站访问量统计方法
  7. 初一模拟赛总结(3.30)
  8. Asp.Net水晶报表边框不显示之解决方法
  9. python炫酷烟花表白源代码-python烟花效果的代码实例
  10. 微型计算机的一般结构,微型计算机的基本结构
  11. linux开机启动项怎么设置bios,bios怎么设置开机启动项
  12. java学习o_基础学习之---Java I/O学习(一)
  13. hive向mysql导数据_Mysql Hive 导入导出数据
  14. long类型强转成int类型解析
  15. c语言内部收益率,内部收益率 (C++代码)
  16. 无人驾驶数据库汇总(不断更新)
  17. CloudCompare源码分析:读取ply文件
  18. nginx-http-flv-module使用鉴权完整版
  19. 心理学在生活中的表现和应用_心理学在我们日常生活中的应用
  20. 足球运动员身价估计(随机森林)

热门文章

  1. 中国配电盘行业市场供需与战略研究报告
  2. 微信小程序报错 errcode: 40029, errmsg: “invalid code 针对狮子鱼
  3. RAISERROR语句
  4. 如何测试一个网页登录界面
  5. 淘宝618每日一猜答案(6月8日)明星孙怡最喜欢的显瘦单品?
  6. css中white-space:nowrap,css强制不换行white-space:nowrap
  7. Excel破解工作表编辑保护密码
  8. Wireshark入门与进阶系列十二之IP冲突
  9. 主板、二板、三板、中小板、国际板、新三板、A,B股
  10. Java里面reverse_Java Java lang.Long.reverse()用法及代码示例