目录
一、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 {@Autowiredprivate 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@LoadBalancedpublic 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@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}// 使用随机策略@Beanpublic 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@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}// 使用随机策略/*@Beanpublic 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*/@Autowiredprivate NacosDiscoveryProperties nacosDiscoveryProperties;@Beanpublic 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 {@Autowiredprivate 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);}@Autowiredprivate 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 {@Autowiredprivate NacosDiscoveryProperties nacosDiscoveryProperties;/*** 使用权重随机策略* @param environment* @param loadBalancerClientFactory* @return*/@Beanpublic 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*/@Beanpublic 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时使用轮询: