SpringCloudAlibaba之nacos

1. Nacos注册中心

1.1. Nacos Server服务安装

自行百度安装教程:

  1. windows安装nacos
  2. windows安装nacos实现高可用
  3. Linux安装nacos
  4. 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.cloudgroupId>
            <artifactId>spring-cloud-dependenciesartifactId>
            <version>Greenwich.SR1version>
            <type>pomtype>
            <scope>importscope>
        dependency>
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-alibaba-dependenciesartifactId>
            <version>2.1.4.RELEASEversion>
            <type>pomtype>
            <scope>importscope>
        dependency>
    dependencies>
dependencyManagement>

步骤一:引入nacos依赖;这里以Order服务为例,其余的服务按照这个步骤集成即可

<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>

步骤二:编写nacos-client客户端的配置

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

测试:打开游览器访问nacos控制台http://localhost:8848/nacos/

SpringCloudAlibaba之nacos_第1张图片

1.3. Nacos分级存储模型

定义:同一个服务会存在多个节点;一部分节点的服务器存于上海,一部分节点的数据存于广州等,每个节点都属于特定的区域或者机房内(也可简称本地集群服务器)。

解决的问题:服务调用尽可能有限选择本地集群服务,跨集群服务调用延迟高,只有本地集群不可用时,才会尝试去请求别的区域的其他服务集群。

SpringCloudAlibaba之nacos_第2张图片

在配置文件中配置当前服务节点属于的集群名称(cluster-name):比如Order服务我设置的集群名为HZ,Product和User设置的是SH。

 cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        cluster-name: HZ # 指明其属于哪一个集群

控制台查看集群服务器

SpringCloudAlibaba之nacos_第3张图片

1.4. Nacos负载均衡

负载均衡:Spring Cloud Alibaba默认还是使用ribbon的轮询规则(微服务调用章节有提到过);如下如果是有三台User服务节点,则order发起服务远程调用时,就会进行轮询调用,但是user1是和order一个地区的,user2和user3是SH地区的服务器,order如果轮询调用到他们了就是跨集群调用了,这是非常影响服务性能的。所以我们需要更改负载策略,使得order服务节点发起的请求优先路由到跟它同一个集群中的user节点(即下图中的user1)。

SpringCloudAlibaba之nacos_第4张图片

修改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. 统一配置管理

定义:实现配置更改热更新,远程读取云端配置并重启服务

控制台创建远程配置文件:控制台 -> 配置管理 -> 新加配置(名字,内容,分组,描述)

微服务读取配置文件流程

SpringCloudAlibaba之nacos_第5张图片

bootstrap.yml文件 :读取优先级最高,一般存放服务名称、开发环境、nacos配置地址、远程配置文件等应用级别信息。

2.2. 客户端进行远程配置更新

  • 以Order服务为例,其它服务一次按照下面的步骤更改即可

nacos控制台创建order-service-local.yaml文件

student:
  name: zahngsan
  age: 23
  sex: man

引入nacos-config依赖

<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
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;
    }
}

测试结果:成功拿到远程配置

SpringCloudAlibaba之nacos_第6张图片

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环境

SpringCloudAlibaba之nacos_第7张图片

搭建步骤:

  1. 下载nacos
  2. 搭建nacos数据库,初始化nacos表结构
  3. 将下载下来的nacos复制几份,然后进行nacos配置
  4. 启动nacos集群
  5. ngnix反向代理

下载nacos:https://github.com/alibaba/nacos/tags

初始化数据库:创建一个名为nacos的数据库,然后初始化表sql;初始化表sql在/nacos/conf/文件下面的nacos-mysql.sql文件里面。拿到sql语句以后再mysql里面执行初始化sql命令。

SpringCloudAlibaba之nacos_第8张图片


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控制台

SpringCloudAlibaba之nacos_第9张图片

你可能感兴趣的:(微服务,linux,java,运维)