The first part of SpringCloudAlibaba (Nacos, Ribbon, Fegin, Nacos-config) (Super invincible, serious and easy to use, Wanzi collection!!!!)

Some of the previous architecture evolution knowledge is always a cliché, so I won’t go into details here. For details, please see my unfinished blog SpringCloud (unfortunately unfinished series...) and Dubbo (super invincible, serious and easy to use, 10,000-character collection articles!! !)This article


SpringCloudAlibaba上(Nacos,Ribbon,Fegin,Nacos-config)

foreword


spring-cloud-alibaba: currently the most active implementation in the Spring Cloud ecosystem with the best development experience .

springcloud ecological comparison

insert image description here

1 Springcloud environment construction (create parent project spring-cloud-alibaba)

For this demo

springboot版本:2.3.12.RELEASE,

springcloud版本:Hoxton.SR12

springcloud-alibaba版本:2.2.9.RELEASE

Introduce dependencies

<?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.jiazhong.springcloudalibaba</groupId>
    <artifactId>spring-cloud-alibabba</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>Order</module>
        <module>stock</module>
    </modules>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.boot.version>2.3.12.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR12</spring.cloud.version>
        <spring.cloud.alibaba.version>2.2.9.RELEASE</spring.cloud.alibaba.version>
    </properties>
    <packaging>pom</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <!-- spring-cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- spring-boot-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- spring-cloud-alibaba-->
            <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>
        </plugins>
    </build>
</project>

2 Nacos (marking registration center and configuration center)

internal death

  • Nacos /nɑ:kəʊs/ is the acronym for Dynamic Naming and Configuration Service, a dynamic service discovery , configuration management and service management platform that is easier to build cloud-native applications

    insert image description here

Key features of Nacos include :

① Service discovery and service health monitoring

② Dynamic configuration service

③ Dynamic DNS service

④ Service and metadata management

2.1 Nacos discovery (service registration discovery)

Nacos Discovery Starter can help you automatically register services to the Nacos server and dynamically sense and refresh the service list of a service instance. In addition, Nacos Discovery Starter also registers some metadata information of the service instance itself - such as host, port, health check URL, home page, etc. - with Nacos

Comparison of mainstream registries

insert image description here

2.1.1 Nacos Service Deployment (Windows)

  • Download the corresponding version installation package, here is the 2.1.0Windos version

https://github.com/alibaba/nacos/releases

insert image description here

  • decompress

insert image description here

  • Because the default is cluster, novice learning is changed to stand-alone

    insert image description here

	set MODE="standalone"
  • Modify the configuration file

conf/application.propertiesIt can be configured, context path, port number, data source storage

  • Stand-alone startup.cmd starts nacos

    Start successfully and enter the nacos page: http://169.254.182.169:8848/nacos/index.html

    The default account password is: nacos

    insert image description here

2.1.2 Nacos client construction

① Create three service producers - stock_8001 (stock_8003, stock_8002)

Here is only stock_8002, the other two are the same

  • Introduce dependencies

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--nacos 服务注册与发现-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
        </dependencies>
    
  • configuration

    server:
       port: 8002
    
    #应用名称,(服务名称)
    spring:
       application:
          name: stock-service
       cloud:
          #配置nacos
          nacos:
             server-addr: 169.254.182.169:8848
             discovery:
                #配置用户名和密码
                username: nacos
                password: nacos
                namespace: public
    
  • Controller

    @RestController
    @RequestMapping("/stock")
    public class StockController {
          
          
        @Value("${server.port}")
        private String port;
    
        @RequestMapping("/del")
        public String del() {
          
          
            System.out.println("库存减少!!!");
            return port+"库存减少!!!";
        }
    }
    
  • startup class

    @SpringBootApplication
    @EnableDiscoveryClient
    public class Stock_8001 {
          
          
        public static void main(String[] args) {
          
          
            SpringApplication.run(Stock_8001.class);
        }
    }
    

② Create service consumer-order_7001

  • Introduce dependencies

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--nacos 服务注册与发现-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
        </dependencies>
    
  • configuration

    server:
       port: 7001
    
    #应用名称,(服务名称)
    spring:
       application:
          name: order-service
       cloud:
          #配置nacos
          nacos:
             server-addr: 169.254.182.169:8848
             discovery:
                #配置用户名和密码
                username: nacos
                password: nacos
                namespace: public
    
  • Controller

    @RestController
    @RequestMapping("/order")
    public class OrderController {
          
          
        @Resource
        private RestTemplate restTemplate;
        private static final String STOCK_URL ="http://stock-service";
    
        @RequestMapping("/add")
        public String add(){
          
          
            String message = restTemplate.getForObject(STOCK_URL + "/stock/del", String.class);
            System.out.println("下单成功!!!");
            return "下单成功!!!"+message;
        }
    }
    
    
  • startup class

    @SpringBootApplication
    @EnableDiscoveryClient
    public class Order_7001 {
          
          
        public static void main(String[] args) {
          
          
            SpringApplication.run(Order_7001.class);
        }
        @Bean
        @LoadBalanced//必须配置负载均衡
        public RestTemplate restTemplate(){
          
          
            return new RestTemplate();
        }
    }
    
  • avalanche protection

    • Protection threshold: set a value between 0-1;
    • Temporary instance: spring.cloud.nacos.discovery.ephemeral=fasleWhen it is a permanent instance, the service will not be removed from the service list even if the service is down;
    • Healthy instances/total instances < protection threshold, unhealthy instances will still be used by service consumers

2.1.3 Detailed Explanation of Registration Center Configuration Items

configuration item Key Defaults illustrate
服务端地址 spring.cloud.nacos.discovery
.server-addr
Nacos Server 启动监听的ip地址和端口
服务名 spring.cloud.nacos.discovery
.service
spring.app
lication.name
给当前的服务命名
服务分组 spring.cloud.nacos.discovery
.group
DEFAULT_GROUP 设置服务所处的分组,做更细致的分割管理
权重 spring.cloud.nacos.discovery
.weight
1 取值范围 1 到 100,数值越大,权重越大
网卡名 spring.cloud.nacos.discovery
.network-interface
当IP未配置时,注册的IP为此网卡所对应的IP地址,如果此项也未配置,则默认取第一块网卡的地址
注册的IP地址 spring.cloud.nacos.discovery
.ip
优先级最高
注册的端口 spring.cloud.nacos.discovery
.port
-1 默认情况下不用配置,会自动探测
命名空间 spring.cloud.nacos.discovery
.namespace
常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
AccessKey spring.cloud.nacos.discovery
.access-key
当要上阿里云时,阿里云上面的一个云账号名
SecretKey spring.cloud.nacos.discovery
.secret-key
当要上阿里云时,阿里云上面的一个云账号密码
Metadata spring.cloud.nacos.discovery
.metadata
使用Map格式配置,用户可以根据自己的需要自定义一些和服务相关的元数据信息
日志文件名 spring.cloud.nacos.discovery
.log-name
集群 spring.cloud.nacos.discovery
.cluster-name
DEFAULT 配置成Nacos集群名称
接入点 spring.cloud.nacos.discovery
.enpoint
UTF-8 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
是否集成Ribbon ribbon.nacos.enabled true 一般都设置成true即可
是否开启Nacos Watch spring.cloud.nacos.discovery
.watch.enabled
true 可以设置成false来关闭 watch
注册的IP地址类型 spring.cloud.nacos.discovery
.ip-type
IPv4 可以配置IPv4和IPv6两种类型
设置永久实例 spring.cloud.nacos.discovery
.ephemeral
false 是否开启永久实例,宕机后,超过心跳,Nacos不会剔除

2.2 Nacos cluster (Linux)

2.2.1 Install nacos

  1. Download the corresponding version installation package, here is the 2.1.0Linux version

https://github.com/alibaba/nacos/releases

  1. Unzip three copies of Nocas

Respectively nocas8849, nocas8850, nocas8851

insert image description here

  1. Delete the compressed package

2.2.2 Configure nacos

Here is only 8849, the other two are the same

① Modify application.properties, nacos-mysql.sqlimport your own data source

Modify port number, data source

insert image description here

insert image description here

② will cluster.conf.examplebe changed cluster.confto add node configuration

copy cluster.conf.exampleit tocluster.conf

insert image description here

③ If there is insufficient memory, modifystartup.sh

insert image description here

2.2.3 Start Test

Execute in the bin directory./startup.sh

insert image description here

Browser input:http://192.168.198.129:8849/nacos/index.html

insert image description here

-------------success---------------------

Log in to other ports nacos


At this time, the reporting port is occupied because

Compared with Nacos 1.X, Nacos 2.0 has added the gRPC communication method, so 2 ports need to be added. The newly added port is automatically generated with a certain offset based on the configured main port (server.port).

The solution is to modify the port number, here we changed 8850 and 8851 to 8859 and 8869

Run other ports again, success...


2.2.4 Use nginxfor load balancing

① download nginx

#下载nginx安装包
wget -c http://nginx.org/download/nginx-1.24.0.tar.gz

② Decompression

③ Enter the directory

cd /usr/local/nginx

④ Modify the configuration file

  upstream nacoscluster {
        server 127.0.0.1:8849;
        server 127.0.0.1:8859;
        server 127.0.0.1:8869;
    }

    server {
        listen       8001;
        server_name  localhost;

        location /nacos {
        proxy_pass http://nacoscluster;
        }
    }

⑤ Other commands

./nginx -s reload: restart nginx

ps -ef | grep nginx: close nginx according to the process number

⑥ test

insert image description here

------------------------------------------success------- ------------------------------

  1. Modify the registration addresses of the three nacos clients respectively

    Here, the registration address starts to use the path of nginx to report an error, com.alibaba.nacos.api.exception.NacosException: Request nacos server failed, modify it to any address in nacos and find that the registration has come in (logging in to other ports is also registered, and the click service details are also in the cluster, so it can be judged to be registered in the cluster) . . .

  • I don't know the specific reason. It may be that when setting up the cluster, the three nacos are related to each other.

   spring:
     cloud:
       #配置nacos
       nacos:
         server-addr: 192.168.198.129:8849
          #集群名称
          clusterName : nginx01

insert image description here

2.2.5 Supplement

Under the parent folders of the three nacos, the logs and work directories are automatically generated

3 Ribbon (load balancing)

Mizumoto

At present, there are two main types of mainstream load balancing:

  • Centralized load balancing, using an independent proxy method for load between consumers and service providers, such as nginx
  • The client performs load balancing according to its own request, and Ribbon belongs to the client to perform load balancing by itself

3.1 Use of Ribbon

spring-cloud-starter-alibaba-nacos-discoveryThe dependencies include ribbon dependencies, so you don't need to import them repeatedly

IRule: parent interface of all load balancing policies

AbstractLoadBalancerRule: Abstract class, which mainly defines a LoadBlancer

load balancing strategy
Strategy explain
RoundRobinRule polling strategy
RandomRule random strategy
AvailabilityFilteringRule Filter out the problematic services first, and access the remaining polling
RetryRule If the service acquisition fails, it will retry within the specified time
BestAvailableRule After filtering out the faulty servers, choose a server with the least concurrency
ZoneAvoidanceRule By default, the monolithic architecture has no region and is polling, but when deployed in microservices, it is to select a service instance with the best performance from the best region instance set
WeightedResponseTimeRule 针对响应时间加权轮询

利用@LoadBalanced,实现负载均衡

3.1.1 通过配置类使用负载均衡策略

  • 坑:配置类不能放在@SpringBootApplication@ComponentScan能扫描到的地方

  • 创建配置类在@SpringBootApplication@ComponentScan不能扫描到的地方

    @Configuration
    public class LBConfig {
          
          
         @Bean
         //方法名必须为iRule
        public IRule iRule(){
          
          
            //可以换成其他负载均衡策略
             return new RandomRule();
         }
    }
    
  • 启动类

    @RibbonClients(
            value = {
           
           
                    /**
                     * 参数1:访问服务名
                     * 参数2:配置类
                     */
                    @RibbonClient(value = "stock-service",configuration = LBConfig.class )
            }
    )
    
    @SpringBootApplication
    //@EnableDiscoveryClient
    @RibbonClients(
            value = {
          
          
                    /**
                     * 参数1:访问服务名
                     * 参数2:配置类
                     */
                    @RibbonClient(value = "stock-service",configuration = LBConfig.class )
            }
    )
    public class Order_ribbon_7002 {
          
          
        public static void main(String[] args) {
          
          
            SpringApplication.run(Order_ribbon_7002.class);
        }
    
        @Bean
        @LoadBalanced//必须配置负载均衡
        public RestTemplate restTemplate(){
          
          
            return new RestTemplate();
        }
    }
    

3.1.2 通过配置文件使用负载均衡策略

  • 修改配置文件application.yml

    #被调用微服务名
    stock-service:
      ribbon:
        #使用指定负载均衡策略
        NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
    

3.1.3 自定义负载均衡策略

  • 实现IRule接口或者,继承AbstractLoadBalancerRule

    public class MyRule extends AbstractLoadBalancerRule {
          
          
    
    
        @Override
        public Server choose(Object o) {
          
          
            ILoadBalancer loadBalancer = this.getLoadBalancer();
            //获得当前请求服务的实例
            List<Server> reachableServers = loadBalancer.getReachableServers();
            //获得随机数
            int random = ThreadLocalRandom.current().nextInt(reachableServers.size());
            Server server = reachableServers.get(random);
    //        if (server.isAlive()){
          
          
    //            return null;
    //        }
            return server;
        }
        //初始化一些配置
        @Override
        public void initWithNiwsConfig(IClientConfig iClientConfig) {
          
          
    
        }
    }
    
    
  • ribbon负载均衡默认是懒加载模式

    开启饥饿加载

    ribbon:
    	eager-load:
    		#开启饥饿加载
    		enabled: true
    		#配置客户端使用饿加载
    		clients: stock-service
    

3.2 使用Spring Cloud LoadBalancer负载均衡替代ribbon

RestTemplate

RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Htp服务的方法,能够大大提高客户端的编写效率。默认情况下,RestTempate默认依赖jdk的HTTP连接工具。

WebClient

WebCient是从Sprng WebFlux5.0版本开始提供的一个非阻塞的基于响应式编程的进行Http请的客户端工具。它的响成式编程的基于Reactor的 ,WebCient中提供了标推Http请求方式对应的get ,post put delete方法,可以用来发起相应的请求。

①移除ribbon支持

  • 在pom.xml
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
  • 配置文件禁用springcloud中不使用ribbon
spring:
	cloud:
       #不使用ribbon	
       loadbalancer:
           ribbon:
               enabled: false

② 添加loadbalancer依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
  • 添加后自动使用负载均衡

    默认为:RoundRobinLoadBalancer:轮询使用负载均衡

4 Fegin(远程服务调用,对标RestTemplate)

与RestTemplate不同的是Fegin是面向对象式的,声明式的, 我们只需要创建一个接口并使用注解的方式来配置它(类似于以前Dao接口上标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可。)

  • 具体使用哪种看个人习惯和公司要求

Spring Cloud openfeign对Netflix Feign进行了增强,使其支持Spring MVC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便

4.1 OpenFegin的简单使用

①引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

② 添加调用对象对应的fegin接口

/**
 * 参数1:指定调用服务名
 * 参数2:指定调用路径,路径为@RequestMapping指定路径,若没有@RequestMapping则不需指定路径
 */
@FeignClient(name = "stock-service", path = "/stock ")
public interface StockFeginService {
    
    
    //声明需要调用的方法
    @RequestMapping("/del")
    String del();
}

③ 消费者Controller层调用

@RestController
@RequestMapping("/order")
public class OrderController {
    
    

   @Resource
   private StockFeginService stockFeginService;

    @RequestMapping("/add")
    public String add(){
    
    
        String message =stockFeginService.del();
        System.out.println("下单成功!!!");
        return "下单成功!!!"+message;
    }
}

④ 启动类

@SpringBootApplication
//@EnableDiscoveryClient
@EnableFeignClients//启动fegin
public class Order_openfegin_7004 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(Order_openfegin_7004.class);
    }
}

4.2 OpenFegin自定义配置

4.2.1 OpenFegin日志配置

  • 全局配置: 当使用@Configuration,会将配置作用于服务提供方

  • 局部配置:

    ①如果只想针对某一个(几个)服务进行配置就不要加@Configuration

    ②使用配置文件配置

日志等级有4中,分别是:

  • NONE[性能最佳,适用于生产]不记录任何日志(默认值)。
  • BASIC[适用于生产环境追踪问题]: 仅记录请求方法、URL、响应状态代码以及执行时间.
  • HEADERS:记录BASIC级别的基础上,记录请求和响应的header。
  • FULL[比较适用于开发及测试环境定位问题]: 记录请求和响应的header、 body和元数据 ​

① 自定义配置类,指定日志级别,使用@Configuration进行全局配置

/**
 * 全局配置: 当使用@Configuration,会将配置作用于服务提供方
 * 局部配置: 如果只想针对某一个(几个)服务进行配置就不要加@Configuration
 */
@Configuration
public class FeginConfig {
    
    

    @Bean
    /**
    * fegin下的Logger.Level
    **/
    Logger.Level feginLoggerLevel() {
    
    
            return Logger.Level.FULL;
    }
}

springboot默认的日志级别是info ,feign的dubug日志级别就不会输出,需要在application.yml中配置

# springboot默认的日志级别是info ,feign的dubug日志级别就不会输出
logging:
  level:
    com.jiazhong.order.fegin: debug

局部配置

  1. 通过配置类
  • 不使用注解@Configuration

  • 在Fegin接口中使用注解@FeginClient配置

    @FeignClient(name = "product-service",path = "/product",configuration = FeginConfig.class)
    
  1. 配置文件局部配置

    #fegin局部配置
    feign:
      client:
        config:
          #要进行局部配置的服务名
          product-service:
            loggerLevel: BASIC
    

4.2.2 OpenFegin契约配置

Spring Cloud 1 早期版本使用的原生Fegin,随着netflix的停更替换成了Open feign,

  • 两者注解例如@RequestLine@RequestMapper,@PathVariable@Param不相同,当使用早期SpringCloud的项目需要升级时,可使用契约配置,来避免修改原生注解的风险性

① 在配置类中配置

    /**
     * 修改契约配置,支持原生注解
     */
    @Bean
    Contract feginContract() {
    
    
        return new Contract.Default();
    }

配置文件中配置

#fegin局部配置
feign:
  client:
    config:
      #要进行局部配置的服务名
      product-service:
        loggerLevel: BASIC
        #还原成原生注解
        contract: fegin.Contract.Default 

4.2.3 超时时间配置

原生RestTemplateBuilder可以通过builder.setConnectTimeout();来设置超时时间,Fegin中没有RestTemplateBuilder,但是有相应配置

① 在配置类中配置

    /**
     * 配置超时时间
     */
    Request.Options options(){
    
    
        return new Request.Options(5000,10000);
    }

配置文件中配置

#fegin局部配置
feign:
  client:
    config:
      #要进行局部配置的服务名
      product-service:
        loggerLevel: BASIC
        #连接超时时间,默认2s
        connectTimeout: 5000
        #请求超时时间,默认为5s
        readTimeout: 3000

4.2.3 自定义拦截器

①自定义拦截器继承RequestInterceptor接口

public class MyFeginInterceptor implements RequestInterceptor {
    
    
    Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 可以做一些拦截
     * @param requestTemplate
     */
    @Override
    public void apply(RequestTemplate requestTemplate) {
    
    
        requestTemplate.header("xxx", "xxxx");
        requestTemplate.query("id", "111");
        requestTemplate.uri("/9");

        logger.info("一些日志信息");
    }
}

② 配置自定义拦截器

  1. 配置类实现

      /**
         * 自定义拦截器
         */
        @Bean
        public MyFeginInterceptor myFeginInterceptor(){
          
          
            return new MyFeginInterceptor();
        }
    
  2. 配置文件实现

    #fegin局部配置
    feign:
      client:
        config:
          #要进行局部配置的服务名
          product-service:
            #配置拦截器
            requestInterceptors[0]: com.jiazhong.order.interceptor.fegin.MyFeginInterceptor
            loggerLevel: BASIC
            #连接超时时间,默认2s
            connectTimeout: 5000
            #请求超时时间,默认为5s
            readTimeout: 3000
    

5 Nacos-config(配置中心)

Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。

5.1 什么是配置中心

随着服务的越来越多,每个服务都有自己的配置,但会有许多配置都冗余了,冗余配置一旦一个服务修改,其他服务都要修改,维护起来非常麻烦。。。

  • 原始配置缺点:

    ① 维护性

    ② 时效性:修改完配置文件,服务都需要进行重启

    ③ 安全性: ip,端口等都会暴露在配置文件中

  • 配置中心解决了上述问题

市面上三大配置中心对比

  • springcloud config大部分场景结合git 使用,动态变更还需要依赖Spring Cloud Bus 消息总线来通过所有的客户端变化
  • springcloud config不提供可视化界面
  • nacos config使用长轮询更新配置,一旦配置有变动后,通知Provider的过程非常的迅速,从速度上秒杀springcloud原来的config几条街,

主流配置中心对比

对比项目 Spring Cloud Config Apollo Nacos
配置实时推送 支持(Spring Cloud Bus) 支持(HTTP长轮询1s内) 支持(HTTP长轮询1s内)
版本管理 支持(Git) 支持 支持
配置回滚 支持(Git) 支持 支持
灰度发布 支持 支持 不支持
权限管理 支持(依赖Git) 支持 不支持
多集群 支持 支持 支持
多环境 支持 支持 支持
监听查询 支持 支持 支持
多语言 只支持Java 主流语言,提供了Open API 主流语言,提供了Open API
配置格式校验 不支持 支持 支持
单机读(QPS) 7(限流所致) 9000 15000
单机写(QPS) 5(限流所致) 1100 1800
3节点读(QPS) 21(限流所致) 27000 45000
3节点写(QPS) 5(限流所致) 3300 5600

5.2 配置管理界面

①配置列表:

维护配置中心所有配置文件

  • 可以快速克隆到其他命名空间里

② 新建配置

下图各项分别对应

  • Data ID:配置集ID,Data ID 通常采用类Java包(如com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。
  • Group:配置集所属组,对应一个项目
  • 配置格式:支持如下图几种

insert image description here

  • 点击发布,发布的数据文件在对应nacos数据库中的config的Info表里

③历史版本

历史版本里面有修改之前版本的配置内容

  • 修改后,如果出现某些错误可以回滚到之前版本

④ 监听查询

监听配置文件正确性

  • 例如:查询配置文件有没有正确推送到客户端。。。

⑤ 权限管理

  1. *前提:
  • 将nocas的conf文件夹下的application.properties开启权限管理nacos.core.auth.enabled=true

    注意 阿里 Nacos 惊爆,安全漏洞以绕过身份验证(附修复建议)通过查看该功能,需要在application.properties添加配置nacos.core.auth.enable.userAgentAuthWhite:false,才能避免User-Agent: Nacos-Server绕过鉴权的安全问题。

  1. 权限管理可以针对不同角色进行读写权限的管理

5.3 Nocas-config Client 读取配置文件

① 在Nacos添加如下的配置

Data ID:    com.jiazhong.order

Group  :    DEFAULT_GROUP

配置格式:    Properties

配置内容:   user.name=Huozhexiao
		    user.age=18

② 客户端使用方式

  • 如果要在您的项目中使用 Nacos 来实现应用的外部化配置,使用 group ID 为 com.alibaba.cloud 和 artifact ID 为 spring-cloud-starter-alibaba-nacos-config 的 starter。
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  • 现在就可以创建一个标准的 Spring Boot 应用。
@SpringBootApplication
public class ConfigApplication {
    
    
    public static void main(String[] args) {
    
    
        // 加载时自动调用所有配置文件
        ConfigurableApplicationContext applicationContext = SpringApplication.run(ConfigApplication.class, args);
        String userName = applicationContext.getEnvironment().getProperty("user.name");
        String userAge = applicationContext.getEnvironment().getProperty("user.age");
        System.err.println("user name :"+userName+"; age: "+userAge);
    }
}
  • 在运行此 Example 之前, 必须使用 bootstrap.properties/yml 配置文件来配置Nacos Server 地址,例如:

bootstrap.yml

spring:
  application:
    #会自动识别dataid与服务名一致的配置文件,若不一致需要手动指定dataid
    name: com.jiazhong.order
  cloud:
    nacos:
      server-addr: 192.168.198.129:8849
      username: nacos
      password: nacos
      namespace: public
  • 注意当你使用域名的方式来访问 Nacos 时,spring.cloud.nacos.config.server-addr 配置的方式为 域名:port。 例如 Nacos 的域名为abc.com.nacos,监听的端口为 80,则 spring.cloud.nacos.config.server-addr=abc.com.nacos:80。 注意 80 端口不能省略。

  • 启动,控制台输出

    user name :Huozhexiao; age: 18
    

5.4 其他扩展配置

① Nacos默认为properties文件扩展名,使用其他扩展名需要配置

spring:
  cloud:
    nacos:
      config:
        file-extension: yaml

②配置动态更新

@SpringBootApplication
public class ConfigApplication_7005 {
    
    
    public static void main(String[] args) {
    
    
        ConfigurableApplicationContext applicationContext = SpringApplication.run(ConfigApplication_7005.class, args);
        while (true) {
    
    
            String userName = applicationContext.getEnvironment().getProperty("user.name");
            String userAge = applicationContext.getEnvironment().getProperty("user.age");
            System.err.println("user name :" + userName + "; age: " + userAge);
            try {
    
    
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}
  • 你可以通过配置 spring.cloud.nacos.config.refresh.enabled=false 来关闭动态刷新

③ 可支持profile粒度的配置

在配置中心:可以通过profile进行设置粒度,根据不同开发环境指定配置文件

只有默认配置文件,才能结合profile使用(dataid跟服务名相同的配置文件为默认配置文件)

对应Dataid:${spring.application.name}-${profile}.${file-extension:properties}

除了默认配置文件,其他配置文件必须写上后缀,profile的配置文件必须根据默认配置文件格式来

  • profile优先级>默认配置文件

    Larger priorities override smaller ones

spring:
	profiles:
		active: dev

④ Support custom namespace configuration

Set namespace according to different development environments

spring:
  cloud:
    nacos:
      config:
        namespace: dev

⑤ Support custom Group configuration

Set Group according to different projects

spring:
  cloud:
    nacos:
      config:
		group: DEVELOP_GROUP

⑥ Support custom extended Data Id configuration

Configure shared DataId among multiple applications

The priority of shared-configs is lower than the default configuration, and the larger the subscript of shared-configs will overwrite the configuration with smaller subscripts

spring:
  cloud:
    nacos:
      config:
        shared-configs: 
          #- 表示集合多个
          - data-id: com.order.common.properties
            refresh: true #配置动态更新
            #group: 默认为DEFAULT_GROUP

extension-configs priority > shared-configs, the larger the subscript of shared-configs will overwrite the configuration with smaller subscript

spring:
  cloud:
    nacos:
      config:
        extension-configs[0]:
          data-id: com.order.common02.properties
          refresh: true
          #group: 默认为DEFAULT_GROUP

⑦ Configuration file priority

profile> default configuration file > extension-configs>shared-configs

5.6 @RefreshScope

@ValueAnnotations can get the value of the configuration center, but cannot dynamically perceive the modified value, you need to use @RefreshScopeannotations

@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
    
    
    @Value("${user.name}")
    private String username;

    @RequestMapping("/show")
    public String show(){
    
    
        return username;
    }
}

  • Learning comes from station b Turing

Guess you like

Origin blog.csdn.net/woschengxuyuan/article/details/130610642