当前位置: 首页 > article >正文

Nacos学习(一)——基本介绍、安装与负载均衡策略

目录

一、Nacos基本介绍

二、安装与使用

(一)Nacos安装

1.上传到linux上解压

2.按需修改配置文件

3.单机启动

4.查看Nacos启动日志

5.浏览器访问Nacos服务

6.关闭Nacos服务

(二)Nacos使用

1.新建一个项目

2.最外部依赖如下

3.provider-service包的依赖

4.配置文件:application.properties

5.创建启动类

6.服务被成功注册

7.修改注册ip

三、使用Nacos实现服务间的简单通讯

1.新建Controller

2.新建Model——consumer-service

3.pom添加依赖

4.修改application.properties文件 

5.新建Controller 

6.启动两个Model

7.浏览器访问Consumer-Service中的接口

四、Nacos中负载均衡

(一)轮询策略(默认)

(二)随机策略

(三)权重策略

(四)调用不同的服务,使用不同的负载均衡策略

1.新建user-service模块

2.修改consumer-service模块

3.修改调用方ConsumerController

4.创建ProviderConfig

5.创建UserConfig

6.重新启动Consumer-service服务


一、Nacos基本介绍

        Nacos 是阿里巴巴开源的一个动态服务发现、配置管理和服务管理平台,旨在帮助开发者更轻松地构建云原生应用。它是 Naming and Configuration Service 的缩写,支持多种应用场景,包括微服务架构中的服务注册与发现、动态配置管理以及分布式系统的服务管理。

        官网:https://nacos.io/

主要功能和使用场景:

1. 服务发现

  • 提供服务的动态注册与发现能力。

2. 动态配置管理

  • 提供集中化的配置管理功能,允许开发者在运行时动态更新配置而无需重启应用。
  • 提供配置的历史版本管理和回滚功能。

3. 服务管理

  • 提供服务的元数据管理能力,支持自定义标签和属性。
  • 支持流量管理,例如负载均衡、灰度发布等。
  • 提供服务治理能力,如限流、熔断、降级等。

4. 多语言支持

  • Nacos 提供了多种语言的 SDK,包括 Java、Python、Go、Node.js 等。
  • 开发者可以方便地将 Nacos 集成到不同技术栈的应用中。

5. 高可用性和扩展性

  • Nacos 支持集群部署,提供高可用性。
  • 支持水平扩展,满足大规模微服务架构的需求。

6. 生态集成

  • Nacos 是 Spring Cloud Alibaba 的重要组件之一,能够无缝集成到 Spring Cloud 和 Dubbo 等微服务框架中。
  • 与 Kubernetes 等容器编排工具兼容,适合云原生环境。

使用场景

  • 微服务架构:作为服务注册中心和配置中心,支持服务间的通信和动态配置管理。
  • 分布式系统:用于管理分布式系统的配置和服务依赖关系。
  • 云原生应用:结合 Kubernetes 和其他云原生工具,提供统一的服务治理能力。 

二、安装与使用

(一)Nacos安装

安装前提:虚拟机已安装jdk,我这里使用jdk11

1.上传到linux上解压

 tar -zxvf nacos-server-2.0.4.tar.gz

2.按需修改配置文件

根据个人虚拟机情况修改

/home/soft/nacos/bin/startup.sh文件:

# 87行   JAVA_OPT="${JAVA_OPT} -Xms128m -Xmx128m -Xmn64m"

-Xms512m:堆内存初始大小为 512 MB。
-Xmx512m:堆内存最大大小为 512 MB。
-Xmn256m:年轻代大小为 256 MB,老年代大小为 256 MB。

3.单机启动

[root@lxm102 bin]# ./startup.sh -m standalone
/home/soft/jdk-11.0.17/bin/java   -Xms128m -Xmx128m -Xmn64m -Dnacos.standalone=true -Dnacos.member.list= -Xlog:gc*:file=/home/soft/nacos/logs/nacos_gc.log:time,tags:filecount=10,filesize=102400 -Dloader.path=/home/soft/nacos/plugins/health,/home/soft/nacos/plugins/cmdb,/home/soft/nacos/plugins/selector -Dnacos.home=/home/soft/nacos -jar /home/soft/nacos/target/nacos-server.jar  --spring.config.additional-location=file:/home/soft/nacos/conf/ --logging.config=/home/soft/nacos/conf/nacos-logback.xml --server.max-http-header-size=524288
nacos is starting with standalone
nacos is starting,you can check the /home/soft/nacos/logs/start.out

4.查看Nacos启动日志

[root@lxm102 bin]# tail -f ../logs/start.out 
2025-02-18 16:50:44,566 INFO Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@5d3f99d7, org.springframework.security.web.context.SecurityContextPersistenceFilter@782ac148, org.springframework.security.web.header.HeaderWriterFilter@7cc1f72c, org.springframework.security.web.csrf.CsrfFilter@79d63a4f, org.springframework.security.web.authentication.logout.LogoutFilter@23afc725, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@61d2f267, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@12365bd8, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@561d88ee, org.springframework.security.web.session.SessionManagementFilter@54463380, org.springframework.security.web.access.ExceptionTranslationFilter@1b8fa2fa]

2025-02-18 16:50:44,764 INFO Initializing ExecutorService 'taskScheduler'

2025-02-18 16:50:44,985 INFO Exposing 16 endpoint(s) beneath base path '/actuator'

2025-02-18 16:50:45,539 INFO Tomcat started on port(s): 8848 (http) with context path '/nacos'

2025-02-18 16:50:45,558 INFO Nacos started successfully in stand alone mode. use embedded storage

5.浏览器访问Nacos服务

http://虚拟机ip:8848/nacos

用户名和密码都是nacos,登录后页面如下:

6.关闭Nacos服务

[root@lxm102 bin]# sh shutdown.sh 
The nacosServer(26890) is running...
Send shutdown request to nacosServer(26890) OK

(二)Nacos使用

1.新建一个项目

2.最外部依赖如下

<modules>
    <module>provider-service</module>
</modules>
<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.6.11</version>
</parent>
<dependencyManagement>
    <dependencies>
        <!--spring cloud 依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--spring loud alibaba 依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2021.0.4.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

3.provider-service包的依赖

<parent>
    <artifactId>spring-cloud-alibaba-demo</artifactId>
    <groupId>org.javatest</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>provider-service</artifactId>
<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--nacos依赖,跟nacos通信使用-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

4.配置文件:application.properties

server.port=8000
spring.application.name=provider-service

#nacos的地址
spring.cloud.nacos.discovery.server-addr=192.168.157.102:8848

5.创建启动类

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

6.服务被成功注册

点击详情:

7.修改注册ip

application.properties文件新增一行

spring.cloud.nacos.discovery.ip=192.168.0.16

重新启动后,ip注册成功 

三、使用Nacos实现服务间的简单通讯

1.新建Controller

给provider-service包新建Controller

@RestController
public class ProviderController {
    @Value("${server.port}")
    private String port;

    @GetMapping("/provider")
    public String provider() {
        return "provider-service:" + port;
    }
}

2.新建Model——consumer-service

3.pom添加依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--nacos依赖,跟nacos通信使用-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

4.修改application.properties文件 

server.port=8888
spring.application.name=consumer-service

#nacos的地址
spring.cloud.nacos.discovery.server-addr=192.168.157.102:8848
spring.cloud.nacos.discovery.ip=192.168.0.16

5.新建Controller 

@RestController
public class ConsumerController {
    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/getport")
    public String hello() {
        List<ServiceInstance> instances = discoveryClient.getInstances("provider-service");
        ServiceInstance serviceInstance = instances.get(0);
        String ip = serviceInstance.getHost();
        int port = serviceInstance.getPort();
        String url = "http://" + ip + ":" + port + "/provider";
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject(url, String.class);
    }
}

6.启动两个Model

现在是Consumer-Service访问Provider-Service,启动后成功注册在Nacos中:

7.浏览器访问Consumer-Service中的接口

http://localhost:8888/getport

四、Nacos中负载均衡

(一)轮询策略(默认)

搭建provider伪集群

启动两个配置,有下面两个实例,就说明伪集群搭建成功

在consumer-service模块中添加下面的依赖:

注意:spring-cloud-starter-loadbalancer这个依赖,哪一方调用,哪一方才添加,被调用方不添加这个依赖。

<!--负载均衡组件-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

在consumer-service模块中新增Config类: 

@Configuration
public class Config {
    // 负载均衡的本质是AOP
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

ConsumerController中添加下面的接口: 

@Autowired
private RestTemplate restTemplate;

@GetMapping("/balancer")
public String balancer() {
    String url = "http://provider-service/provider";
    return restTemplate.getForObject(url, String.class);
}

在使用RestTemplate的时候,会自动将服务名替换为ip和端口号,进行负载均衡。

浏览器每刷新一次,都会访问不同的端口: 

                

负载均衡默认使用轮询策略的原因:

        在LoadBalancerClientConfiguration类中声明了new RoundRobinLoadBalancer()这一bean对象,说明默认使用的是轮询策略。

(二)随机策略

修改配置类,创建的是RandomLoadBalancer

@Configuration
// 告诉LoadBalance框架,使用的是当前的配置类获取负载均衡策略
@LoadBalancerClients(defaultConfiguration = Config.class)
public class Config {
    // 负载均衡的本质是AOP
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    // 使用随机策略
    @Bean
    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty("loadbalancer.client.name");
        return new RandomLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}

重启项目:

 

刷新浏览器后,8000和8001出现是随机的。 

(三)权重策略

将原来的RandomLoadBalancer改为NacosLoadBalancer,会报错,原因是缺少参数: 

缺少的就是这个参数:

点进这个参数 :

@ConfigurationProperties("spring.cloud.nacos.discovery") 是一个注解,用于将配置文件中以 spring.cloud.nacos.discovery 为前缀的属性绑定到 Java 对象的字段中。

因此,最终的Config: 

@Configuration
// 告诉LoadBalance框架,使用的是当前的配置类获取负载均衡策略
@LoadBalancerClients(defaultConfiguration = Config.class)
public class Config {
    // 负载均衡的本质是AOP
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    // 使用随机策略
    /*@Bean
    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty("loadbalancer.client.name");
        return new RandomLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }*/

    /**
     * 使用Nacos权重随机策略
     *
     * @param environment
     * @param loadBalancerClientFactory
     * @return
     */
    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Bean
    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty("loadbalancer.client.name");
        return new NacosLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name, nacosDiscoveryProperties);
    }
}

重启consumer服务,访问浏览器,8001的权重高,被访问到的概率更大,而不是访问次数。 

开发中,偏向于哪台机器承接更多的访问量,就把哪台机器的权重调的更大一些即可。

(四)调用不同的服务,使用不同的负载均衡策略

@LoadBalancerClients(defaultConfiguration = {Config.class})

这表示只有一个负责均衡策略 NacosLoadBalancer(权重随机策略),当我们想对不同的服务,采用不同的策略怎么办呢?

现在要求:调用provider-service集群使用权重随机,调用user-service服务使用轮询。

1.新建user-service模块

application.properties文件:

#server.port=7000
spring.application.name=user-service

#nacos的地址
spring.cloud.nacos.discovery.server-addr=192.168.157.102:8848
spring.cloud.nacos.discovery.ip=192.168.0.16

pom.xml文件: 

<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-discovery</artifactId>
    </dependency>
</dependencies>

UserController: 

@RestController
public class UserController {
    @Value("${server.port}")
    private String port;

    @GetMapping("/userport")
    public String userport() {
        return "user-service:" + port;
    }
}

user-service同样创建伪集群 

 

启动user-service集群

2.修改consumer-service模块

3.修改调用方ConsumerController

@RestController
public class ConsumerController {
    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/getport")
    public String hello() {
        List<ServiceInstance> instances = discoveryClient.getInstances("provider-service");
        ServiceInstance serviceInstance = instances.get(0);
        String ip = serviceInstance.getHost();
        int port = serviceInstance.getPort();
        String url = "http://" + ip + ":" + port + "/provider";
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject(url, String.class);
    }

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/balancer")
    public String balancer() {
        String url = "http://provider-service/provider";
        return restTemplate.getForObject(url, String.class);
    }

    /**
     * 调用user-service
     */
    @GetMapping("/user")
    public String user() {
        String url = "http://user-service/userport";
        return restTemplate.getForObject(url, String.class);
    }
}

4.创建ProviderConfig

/**
 * 配置访问provider-service时,使用的负载均衡策略
 */
public class ProviderConfig {
    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    /**
     * 使用权重随机策略
     * @param environment
     * @param loadBalancerClientFactory
     * @return
     */
    @Bean
    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty("loadbalancer.client.name");
        return new NacosLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name, nacosDiscoveryProperties);
    }
}

5.创建UserConfig

/**
 * 配置访问provider-service时,使用的负载均衡策略
 */
public class UserConfig {
    /**
     * 使用轮询策略
     * @param environment
     * @param loadBalancerClientFactory
     * @return
     */
    @Bean
    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty("loadbalancer.client.name");
        return new RoundRobinLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}

6.重新启动Consumer-service服务

访问provider-service时使用随机权重

访问user-service时使用轮询


http://www.kler.cn/a/553846.html

相关文章:

  • Ubuntu:20.04更新cmake到更高版本
  • Linux 文件与目录命令学习记录
  • 基于Flask的去哪儿网海南旅游攻略数据分析系统的设计与实现
  • vue-awesome-swiper 露出下一张图片部分+自定义按钮滑动到上一个/下一个slide
  • DeepSeek + Mermaid编辑器——常规绘图
  • Flutter开发如何高效布局
  • SpringBoot中自动装配机制的原理
  • ubuntu 多版本python冲突时设置临时环境
  • 重新出发的LLM本地部署——DeepSeek加持下的Ollama+OpenWebUI快速部署
  • 三、数据治理应用开发整体架构
  • 蓝桥杯 Day6 贪心
  • (前端基础)CSS(一)
  • 【练习】【滑动窗口】力扣热题100 3. 无重复字符的最长子串
  • docker修改镜像默认存储路径(基于页面迁移)
  • 马斯克放出AI核弹:Grok 3干碎OpenAI
  • Mybatis MyBatis延迟加载策略 二、多对一的延迟加载查询演示
  • 【后端】k8s
  • 中级软考笔记-基础知识-3-数据结构
  • 【核心算法篇十三】《DeepSeek自监督学习:图像补全预训练方案》
  • 1.16学习