Spring Cloud Alibaba 致力于提供微服务开发 的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里 微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
SpringCloud Alibaba官方文档
- 服务发现和服务健康监测
- 动态配置服务
- 动态DNS服务
- 服务及其元数据管理
Nacos 可以说就是 注册中心+配置中心 的组合,等价于:Nacos = Eureka+Config+Bus
1.下载:「nacos-server-1.1.4」https://www.aliyundrive.com/s/owtAZ27gNNd
点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。
我把安装包放在了阿里云盘大家可以自行下载,也可以去GitHub下载:https://github.com/alibaba/nacos/archive/1.1.4.tar.gz
2.解压
3.启动命令: cmd startup.cmd 或者双击 startup.cmd 运行文件。

1.拉取需要的nacos镜像
docker pull nacos/nacos-server:【指定版本号】
2.在宿主机创建个docker文件夹专门来放docker容器相关的挂载数据
3.vim custom.properties编辑custom.properties文件,加上以下内容
【management.endpoints.web.exposure.include=*】4.启动nacos容器:
docker run -d -p 8848:8848 -e MODE=standalone -v /docker/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties -v /docker/nacos/logs:/home/nacos/logs --restart always --name nacos nacos/nacos-server

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qbb</groupId> <artifactId>nacos-provider-movie6600</artifactId> <version>0.0.1-SNAPSHOT</version> <name>nacos-provider-movie6600</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version> </properties> <dependencies> <dependency> <groupId>com.qbb</groupId> <artifactId>cloud-common</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <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> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <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.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.7.RELEASE</version> <configuration> <mainClass>com.qbb.cloud2022.NacosProviderMovie6600Application</mainClass> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build></project>server: port: 6600spring: application: name: nacos-provider-movie cloud: nacos: discovery: server-addr: 192.168.137.72:8848 #nacos服务端地址 # 数据源 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/qbbit3?serverTimezone=UTC username: root password: rootpackage com.qbb.cloud2022;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@MapperScan("com.qbb.cloud2022.mapper")@EnableDiscoveryClient // 开启Nacos客户端服务@SpringBootApplicationpublic class NacosProviderMovie6600Application { public static void main(String[] args) { SpringApplication.run(NacosProviderMovie6600Application.class, args); }}controller
package com.qbb.cloud2022.controller;import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;import com.qbb.cloud2022.service.MovieService;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-04-02 22:42 * @Description: */@RestController@RequestMapping("/movie")@Slf4jpublic class MovieController { @Autowired private MovieService movieService; @Value("${server.port}") private String port; @GetMapping("/findById/{id}") public Movie findById(@PathVariable("id") Integer id) { log.info("port:{}", port); return movieService.findById(id); }}service
package com.qbb.cloud2022.service.impl;import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;import com.qbb.cloud2022.mapper.MovieMapper;import com.qbb.cloud2022.service.MovieService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;/** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-04-02 22:45 * @Description: */@Servicepublic class MovieServiceImpl implements MovieService { @Autowired private MovieMapper movieMapper; @Override public Movie findById(Integer id) { return movieMapper.findById(id); }}mapper
package com.qbb.cloud2022.mapper;import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;import org.apache.ibatis.annotations.Select;/** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-04-02 22:46 * @Description: */public interface MovieMapper { @Select("select * from movie where id=#{id}") Movie findById(Integer id);}测试一下:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qbb</groupId> <artifactId>nacos-consumer-user6700</artifactId> <version>0.0.1-SNAPSHOT</version> <name>nacos-consumer-user6700</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version> </properties> <dependencies> <dependency> <groupId>com.qbb</groupId> <artifactId>cloud-common</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <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> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <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.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.3.7.RELEASE</version> <configuration> <mainClass>com.qbb.cloud2022.NacosConsumerUser6700Application</mainClass> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build></project>server: port: 6700spring: application: name: nacos-consumer-user cloud: nacos: discovery: server-addr: 192.168.137.72:8848 # 数据源 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/qbbit3?serverTimezone=UTC username: root password: rootpackage com.qbb.cloud2022;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@MapperScan("com.qbb.cloud2022.mapper")@EnableDiscoveryClient // 开启nacos注册中心支持@SpringBootApplicationpublic class NacosConsumerUser6700Application { public static void main(String[] args) { SpringApplication.run(NacosConsumerUser6700Application.class, args); }}controller
package com.qbb.cloud2022.controller;import com.qbb.cloud2022.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.Map;/** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-04-03 13:31 * @Description: */@RestController@RequestMapping("/user")public class UserController { @Autowired private UserService userService; @GetMapping("/findUserAndMovie/{id}") public Map findUserAndMovie(@PathVariable("id") Integer id) { Map<String, Object> map = userService.findUserAndMovie(id); return map; }}service
package com.qbb.cloud2022.service.impl;import com.qbb.cloud2022.com.qbb.springcloud.entity.User;import com.qbb.cloud2022.mapper.UserMapper;import com.qbb.cloud2022.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.HashMap;import java.util.Map;/** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-04-03 13:32 * @Description: */@Servicepublic class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public Map<String, Object> findUserAndMovie(Integer id) { User user = userMapper.findById(id); Map<String, Object> map = new HashMap<>(); map.put("user", user); map.put("movie", null); return map; }}mapper
package com.qbb.cloud2022.mapper;import com.qbb.cloud2022.com.qbb.springcloud.entity.User;import org.apache.ibatis.annotations.Select;/** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-04-03 13:48 * @Description: */public interface UserMapper { @Select("select * from user where id=#{id}") User findById(Integer id);}测试一下:
Nacos注册中心的服务信息:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.2.RELEASE</version></dependency>@EnableFeignClients // 开启Feign远程调用支持package com.qbb.cloud2022.feign;import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;/** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-04-03 19:56 * @Description: */@FeignClient(value = "nacos-provider-movie") // value属性指定被调用服务的在注册中心的服务名public interface FeignMovieService { @GetMapping("/movie/findById/{id}") public Movie findById(@PathVariable("id") Integer id);}测试一下:

右键电影微服务,选择Copy Configuration

修改相关参数

运行相关的四个微服务
远程调用测试一下
Nacos为我们提供了两种凡是实现负载均衡策略
方式一:和原来一样,整一个配置类提供相应的IRule实现类对象
package com.qbb.cloud2022.config;import com.netflix.loadbalancer.IRule;import com.netflix.loadbalancer.RandomRule;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-04-03 20:22 * @Description: */@Configurationpublic class IRuleConfig { @Bean public IRule iRule(){ return new RandomRule(); // 使用随机的负载均衡策略 }}方式二:yml配置文件方式(当然也可以自定义的)
stock-service: ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重) eager-load: enabled: true #开启ribbon饥饿加载 clients: stock-service #配置stock-service使用ribbon饥饿加载,多个使用逗号分隔<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.2.2.RELEASE</version></dependency>@EnableCircuitBreaker // 开启Hystrixpackage com.qbb.cloud2022.handler;import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;import com.qbb.cloud2022.feign.FeignMovieService;import org.springframework.stereotype.Component;/** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-04-03 20:42 * @Description: */@Componentpublic class FeignMovieServiceExceptionHandler implements FeignMovieService { @Override public Movie findById(Integer id) { Movie movie = new Movie(); movie.setId(-1); movie.setName("网络故障,请稍后再试"); return movie; }}feign: hystrix: enabled: true # 开启feign对hystrix的支持修改服务端代码,关闭所有的服务端和重启消费端,测试一下



Namespace 命名空间、Group 分组、集群这些都是为了进?归类管理,把服务和配置?件进?归类,归类之后就可以实 现?定的效果, ?如,对于服务来说,不同命名空间中的服务不能够互相访问调?。

推荐用法:

每个服务也可以组成多个集群,多个集群又包含了多个实例.并且微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。
如何给服务分配集群呢?
重启微服务:
访问:http://localhost:6700/user/findUserAndMovie/1 发现,默认的ZoneAvoidanceRule并不能实现根据同集群优先来实现负载均衡, 因此 Nacos 中提供了一个 NacosRule的实现,可以优先从同集群中挑选实例。
nacos-provider-movie: #被调用方在nacos注册中心的服务名 ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule权重配置:
如果权重修改为 0,则该实例永远不会被访问,可以实现无缝上线应用
环境隔离
同一个命名空间下的服务是可以相互调用的,反之则不能
我现在修改nacos-provider-movie6600的namespace
namespace: 3ad61d82-3435-4729-86e2-57f828280e9f # 修改namespace环境重启测试:
注意在Nacos分为两种实例,临时实例和永久实例(eureka只有临时实例),临时实例采用心跳模式,非临时实例采用主动检测模式
修改yml配置文件可以将实例设置为永久实例.这样即使实例宕机了,Nacos服务端也不会将其剔除,等宕机的服务重新启动了,又会自动注册进注册中心
ephemeral: true # 将此服务设置为永久实例Nacos没有永久实例时,遵循AP(可用性,分区容错性!eureka也是如此),有永久实例时,遵循CP(强一致性,分区容错性)

当我把服务nacos-provider-movie6600关掉,会发现Nacos并不会将服务剔除掉
Nacos 除了可以做注册中心,同样可以做配置管理来使用。nacos 作为配置中心可以做到系统配置的集中管理(编辑、 存储、分发)、动态更新不重启、回滚配置(变更管理、历史版本管理、变更审计)等所有与配置相关的活动。有 Nacos 之后,分布式配置就简单很多 Github 不需要了(配置信息直接配置在 Nacos server 中),Bus 也不需要了(依然可 以完成配置文件的热更新, 及时通知微服务)。如果微服务架构中没有使用统一配置中心时,所存在的问题:
- 配置文件分散在各个项目?,微服务实例的数量达到上百个的时候,实在是不方便维护
- 配置内容安全与权限
- 更新配置后,项目需要重启,即使不需要重启也需要运维人员使用curl发送请求执行更新


注意dataId格式
1.prefix 默认为所属工程配置spring.application.name 的值(nacos-provider-movie*),也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
2.spring.profile.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profile.active 为 空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
3.file-exetension 为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency>spring: cloud: nacos: server-addr: 192.168.137.72:8848 config: file-extension: yml # 配置文件默认的后缀是properties文件,如果是yml,必须指定 profiles: active: devpackage com.qbb.cloud2022.controller;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;/** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-04-06 18:49 * @Description: */@RestControllerpublic class HelloController { @Value("${user.age}") private Integer age; @GetMapping("/hello") public Integer hello() { return age; }}
只需要在指定位置加上注解@RefreshScope 实现自动更新
@RefreshScope


namespace: c6ab48bd-2159-450e-aef8-65095e015036 # 指定环境变量的唯一标识



在dev命名空间下创建mysql.yml,redis.yml

修改bootstrap.yml
extension-configs: - dataId: mysql.yml refresh: true - dataId: redis.yml refresh: true修改controller层代码
package com.qbb.cloud2022.controller;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.RestController;/** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-04-06 18:49 * @Description: */@RestController@RefreshScopepublic class HelloController { @Value("${user.age}") private Integer age; @Value("${mysql.port}") private Integer mysqlPort; @Value("${redis.port}") private Integer redisPort; @GetMapping("/hello1") public String hello1() { return "age:" + age + "=mysql:" + mysqlPort + "=redis:" + redisPort; } @GetMapping("/hello") public Integer hello() { return age; }}测试一下:
我们还可以给配置文件添加group
group: order # 用于区分业务由于我们nacos配置中心并没有order这个组,所以启动报错了
我们添加一个order组试试
修改两个order组的配置文件内容,具体内容大家自行修改就好了,直接测试