1. Nacos注册中心
1.1. Nacos Server服务安装
自行百度安装教程:
- windows安装nacos
- windows安装nacos实现高可用
- Linux安装nacos
- Linux安装nacos实现高可用
安装完成以后启动nacos-server;在nacos.bin目录下面CMD输入启动命令如下:
startup.cmd -m standalone # 单例模式运行nacos,非集群(高可用)模式
1.2. Nacos客户端
前提:父工程cloud-demo引入Spring Cloud Alibaba的依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
步骤一:引入nacos依赖;这里以Order服务为例,其余的服务按照这个步骤集成即可
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
步骤二:编写nacos-client客户端的配置
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
测试:打开游览器访问nacos控制台http://localhost:8848/nacos/
1.3. Nacos分级存储模型
定义:同一个服务会存在多个节点;一部分节点的服务器存于上海,一部分节点的数据存于广州等,每个节点都属于特定的区域或者机房内(也可简称本地集群服务器)。
解决的问题:服务调用尽可能有限选择本地集群服务,跨集群服务调用延迟高,只有本地集群不可用时,才会尝试去请求别的区域的其他服务集群。
在配置文件中配置当前服务节点属于的集群名称(cluster-name):比如Order服务我设置的集群名为HZ,Product和User设置的是SH。
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
cluster-name: HZ # 指明其属于哪一个集群
控制台查看集群服务器:
1.4. Nacos负载均衡
负载均衡:Spring Cloud Alibaba默认还是使用ribbon的轮询规则(微服务调用章节有提到过);如下如果是有三台User服务节点,则order发起服务远程调用时,就会进行轮询调用,但是user1是和order一个地区的,user2和user3是SH地区的服务器,order如果轮询调用到他们了就是跨集群调用了,这是非常影响服务性能的。所以我们需要更改负载策略,使得order服务节点发起的请求优先路由到跟它同一个集群中的user节点(即下图中的user1)。
修改Ribbon负载均衡策略:即将默认轮询的规则换成NacosRule,这样会优先调用本地集群中的生产者服务节点,只有本地服务节点全部挂掉了才会去跨集群调用别的集群节点。
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
权重负载:nacos提供了权重配置来控制访问频次;权重越大的节点被访问的频次越高;一般生产环境中性能配置更好的服务器分配到的负载权重会大一些。具体配置步骤就是:nacos控制台 -> 编辑 -> 更改权重;如果权重设置为0,则不会有请求路由过来此节点,一般这种情况可以用作线上服务器平滑更新云端系统。
1.5. 环境隔离之命名空间(namespace)
- 默认的命名空间名是public;nacos提供的命名空间的目的就是做环境隔离,比如开发服、测试服、正式服等。命名空间可以去nacos控制台创建即可,创建成功以后会生成一个命名空间id。
- nacos-client客户端配置命名空间:
spring:
cloud:
nacos:
discovery:
namespace: 命名空、间id
2. Nacos配置中心
2.1. 统一配置管理
定义:实现配置更改热更新,远程读取云端配置并重启服务
控制台创建远程配置文件:控制台 -> 配置管理 -> 新加配置(名字,内容,分组,描述)
微服务读取配置文件流程:
bootstrap.yml文件 :读取优先级最高,一般存放服务名称、开发环境、nacos配置地址、远程配置文件等应用级别信息。
2.2. 客户端进行远程配置更新
- 以Order服务为例,其它服务一次按照下面的步骤更改即可
nacos控制台创建order-service-local.yaml文件:
student:
name: zahngsan
age: 23
sex: man
引入nacos-config依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
配置bootstrap.yml:会通过spring.application.name + profiles.active + nacos.config.file-extension = order-service-local.yaml文件名来拉取云端的远程配置文件。
server:
port: 8081
spring:
application:
name: order-service
profiles:
active: local
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://localhost:3306/mc_mall?useSSL=false&useUnicode=true&characterEncoding=utf-8
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 50 #初始化时建立物理连接的个数
minIdle: 30 #最小连接池数量
maxActive: 200 #最大连接池数量
maxWait: 60000 #获取连接时最大等待时间
timeBetweenEvictionRunsMillis: 60000 #Destory线程检测连接的间隔时间
minEvictableIdleTimeMillis: 300000 #连接保持空闲而不被驱逐的最长时间
redis:
host: localhost
port: 6379
password: 123456
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
cluster-name: HZ # 指明其属于哪一个集群
config:
file-extension: yaml #配置文件后缀
#eureka:
# client:
# fetch-registry: true
# register-with-eureka: true
# service-url:
# defaultZone: http://127.0.0.1:10081/eureka/
feign:
client:
config:
default:
loggerLevel: FULL # 日志等级
httpclient:
enabled: true # 开启feign对Apache HttpClient的支持
max-connections: 200 # 最大的连接数
max-connections-per-route: 50 # 每个路径的最大连接数
验证远程配置是否生效: 新增getStudent接口
@RestController
@RequestMapping("order")
public class OrderController {
private static final Logger logger = LoggerFactory.getLogger(OrderController.class);
@Autowired
private RestTemplate restTemplate;
@Autowired
private UserClient userClient;
@Value("${student.name}")
private String studentName;
@Value("${student.age}")
private int studentAge;
@Value("${student.sex}")
private String studentSex;
@GetMapping("getStudent")
public StudentVO getStudent(){
StudentVO studentVO = new StudentVO();
studentVO.setName(studentName);
studentVO.setAge(studentAge);
studentVO.setSex(studentSex);
return studentVO;
}
}
测试结果:成功拿到远程配置
2.2. 实现配置热更新
- 虽然现在能够拿到远程配置了,但是现在还有一个问题,就是如果我更改了远程配置的内容,应用并没有即实的读取,必须要手动重启服务器才能读到新的配置,所以这里就存在一个配置热更新的问题。
如果配置属性是@Value标签进行注入:在属性注入类上面加上@RefreshScope标签
package com.acx.controller;
import com.acx.client.UserClient;
import com.acx.pojo.vo.ActorInfoVO;
import com.acx.pojo.vo.OrderInfoVO;
import com.acx.pojo.vo.StudentVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("order")
@RefreshScope //远程配置热更新注解
public class OrderController {
private static final Logger logger = LoggerFactory.getLogger(OrderController.class);
@Autowired
private RestTemplate restTemplate;
@Autowired
private UserClient userClient;
@Value("${student.name}")
private String studentName;
@Value("${student.age}")
private int studentAge;
@Value("${student.sex}")
private String studentSex;
@GetMapping("getStudent")
public StudentVO getStudent(){
StudentVO studentVO = new StudentVO();
studentVO.setName(studentName);
studentVO.setAge(studentAge);
studentVO.setSex(studentSex);
return studentVO;
}
}
如果配置是使用@ConfigurationProperties标签进行注入:不需要加上@RefreshScope标签即可实现热更新
package com.acx.pojo.vo;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "student")
public class StudentVO {
private String name;
private int age;
private String sex;
}
package com.acx.controller;
import com.acx.client.UserClient;
import com.acx.pojo.vo.ActorInfoVO;
import com.acx.pojo.vo.OrderInfoVO;
import com.acx.pojo.vo.StudentVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("order")
public class OrderController {
private static final Logger logger = LoggerFactory.getLogger(OrderController.class);
@Autowired
private RestTemplate restTemplate;
@Autowired
private UserClient userClient;
@Autowired
private StudentVO studentVO;
@GetMapping("getStudent")
public StudentVO getStudent(){
return studentVO;
}
}
2.3. 多环境配置共享
- 前面我们创建的远程配置文件都是 服务名 + profile + .yaml的文件,profile就是代表的开发环境:如local、dev、test、prod等,不同的profile代表不同的环境配置文件。
- nacos还支持创建 服务名 + .yaml的配置文件,这个文件里面主要存贮一些公共的、默认的配置属性,这个文件可以理解为此服务的默认配置文件。
- springboot应用读取远程配置文件的优先级是:环境配置文件 > 默认配置文件 > 本地配置文件
2.4. Nacos集群配置(高可用)
集群架构:这里配置的操作系统是windows环境
搭建步骤:
- 下载nacos
- 搭建nacos数据库,初始化nacos表结构
- 将下载下来的nacos复制几份,然后进行nacos配置
- 启动nacos集群
- ngnix反向代理
下载nacos:https://github.com/alibaba/nacos/tags
初始化数据库:创建一个名为nacos的数据库,然后初始化表sql;初始化表sql在/nacos/conf/文件下面的nacos-mysql.sql文件里面。拿到sql语句以后再mysql里面执行初始化sql命令。
nacos配置:
- 配置数据源:进入nacos的conf目录,打开application.properties文件
### Default web server port: nacos端口
server.port=8845
### If user MySQL as datasource: 使用的持久层数据库类型
spring.datasource.platform=mysql
### Count of DB: 数据库数量,mysql单机这个值就=1
db.num=1
### Connect URL of DB: 数据库连接配置
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456
- 集群配置:进入nacos的conf目录,修改配置文件cluster.conf.example,重命名为cluster.conf 并添加如下配置
127.0.0.1:8845
127.0.0.1:8846
127.0.0.1:8847
- 将nacos文件复制两份并把端口号分别改为8846和8847
启动三台nacos:
- 直接在响应的/nacos/bin目录下执行startup.cmd命令,直接就是集群启动了
Nginx反向代理:
upstream nacos-cluster {
server 127.0.0.1:8845;
server 127.0.0.1:8846;
server 127.0.0.1:8847;
}
server {
listen 8848;
server_name localhost;
location /nacos {
proxy_pass http://nacos-cluster;
}
}
测试结果:访问http://localhost:8848/nacos/ 能够访问nacos控制台