1.SpringCloud Alibaba
1.1.SpringCloud Alibaba功能
- 服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
- 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
- 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
- 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
- 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。。
- 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
- 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
- 阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
1.2组件
- Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
- Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
- RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
- Dubbo:Apache Dubbo? 是一款高性能 Java RPC 框架。
- Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
- Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
- Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。
- Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
2.Nacos
2.1Nacos简介
nacos(NAming COnfiguration Service):服务注册和配置中心 Nacos = Eureka + Config + Bus 替代Eureka做服务注册中心 替代Config做服务配置中心 github地址: https://github.com/alibaba/Nacos Nacos 地址: https://nacos.io/zh-cn/
服务注册与服务框架 | CAP模型 | 控制台管理 | 社区活跃度 |
---|
Eureka | AP高可用 | 支持 | 低(2.x版本闭源) | Zookeeper | CP一致 | 支持 | 中 | Consul | CP | 支持 | 高 | Nacos | AP(可以切换) | 支持 高 | |
2.2安装并运行Nacos
- 条件:本地java8和maven环境ok
- 从官网下载Nacos
- 解压安装包,直接运用bin目录下的startup.cmd
- 命令 运行成功后直接访问:http://localhost:8848/nacos
- 结果页面
2.3基于nacos的服务提供者
2.3.1 建父工程
- 建一个名为spring-cloud-alibaba的父工程
- 改pom,进行相应的版本控制
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
<mysql.version>5.1.47</mysql.version>
<druid.version>1.1.16</druid.version>
<mybatis.spring.boot.version>1.3.2</mybatis.spring.boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>
<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>
2.3.2建立服务的提供者alibaba-provider-payment9001
- 改pom
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- 建yml(application.yml)
server:
port: 9001
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848
management:
endpoints:
web:
exposure:
include: "*"
- 主启动
@SpringBootApplication
@EnableDiscoveryClient
public class AlibabaProviderPayment9001Application {
public static void main(String[] args) {
SpringApplication.run(AlibabaProviderPayment9001Application.class, args);
}
}
- 业务类(PaymentController )
@RestController
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id) {
return "nacos registry, serverPort: " + serverPort + "\t id" + id;
}
}
2.3.4建立服务的提供者alibaba-provider-payment9002
- 改pom
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- 建yml(application.yml)
server:
port: 9002
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848
management:
endpoints:
web:
exposure:
include: "*"
- 主启动
@SpringBootApplication
@EnableDiscoveryClient
public class AlibabaProviderPayment9002Application {
public static void main(String[] args) {
SpringApplication.run(AlibabaProviderPayment9001Application.class, args);
}
}
- 业务类(PaymentController )
@RestController
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id) {
return "nacos registry, serverPort: " + serverPort + "\t id" + id;
}
}
结果查看 分别启动nacos、alibaba-provider-payment9001和alibaba-provider-payment9002 在浏览器上输入网址:http://localhost:8848/nacos/ 可以看出两个服务的提供者都注册进来了
2.4基于nacos的服务消费者
nacos自带负载均衡机制
- 建立一个名为consumer-nacos-order80的module
- 导入相关的依赖
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- 写yaml
server:
port: 80
undertow:
decode-url:
spring:
application:
name: consumer-nacos-order
cloud:
nacos:
discovery:
server-addr: localhost:8848
server-url:
nacos-user-service: http://nacos-payment-provider
- 主启动
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerNacosOrder80 {
public static void main(String[] args) {
SpringApplication.run(ConsumerNacosOrder80.class,args);
}
}
- 配置类
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
- controller
@RestController
@Slf4j
public class NacosOrderController {
@Resource
private RestTemplate restTemplate;
@Value("${server-url.nacos-user-service}")
private String serverUrl;
@GetMapping(value="consumer/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") int id)
{
return restTemplate.getForObject(serverUrl+"/payment/nacos/"+id,String.class);
}
}
测试 启动nacos,启动9001,9002和80端口,访问http://localhost/consumer/payment/nacos/111会发现轮询端口9001和端口9002
2.5各种服务中心对比
服务注册与服务框架 | CAP模型 | 控制台管理 | 社区活跃度 |
---|
Eureka | AP高可用 | 支持 | 低(2.x版本闭源) | Zookeeper | CP一致 | 支持 | 中 | Consul | CP | 支持 | 高 | Nacos | AP(可以切换) | 支持 高 | |
组件名 | 语言 | CAP | 服务健康检查 | 对外暴露接口 | SpringCloud集合 |
---|
Eureka | java | AP | 可配支持 | HTTP | 已集成 | Consul | Go | CP | 支持 | HTTP/DNS | 已集成 | Zookeeper | java | CP | 支持 | 客户端 | 已集成 |
Nacos的AP和CP C是所有节点在同一时间看到的数据是一致的,而A的定义是所有的请求都会收到响应
何时选择使用何种模式? 一般来说,如果不需要存储服级的信息且服务实例是通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。当前主流的服务如Spring cloud和Dubbo服务,都适用于AP模式,AP模式为了服务的可用性而减弱了一致性,因此AP模式下只支持注册临时实例。 如果需要在服务级别编辑或者存储配置信息,那么CP是必须,K8S服务和DNS服务则适用于CP模式CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下汪册实例之前须先注册服务,如果服务不存在,则会返回错误
切换命令:curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
2.6nacos作为配置中心
2.6.1 基础配置
- 创建config-nacos-client-3377module
- 改pom
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- 写yml
Nacos同SpringCloud-config一样,在项目初始化时,要保证从配置中心拉取配置拉取配置后才能保证项目的正常启动 springboot中配置文件的加载时存在优先级顺序的,bootstrap优先级高于application 在boostrap.yml中
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848
config:
server-addr: localhost:8848
file-extension: yaml
在application.yml中
spring:
profiles:
active: dev
- 主启动
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConfig3377 {
public static void main(String[] args) {
SpringApplication.run(NacosConfig3377.class,args);
}
}
- 业务类
@RestController
@RefreshScope
public class ConfigCenterController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo()
{
return configInfo;
}
}
nacos同springcloud-config一样,在项目初始化时,要先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动。springboot的配置文件的加载是存在优先级的,bootstrap优先级高于application。(bootstrap中放共性,application中放个性) nacos中的dataid的组成格式及与springboot配置文件中的匹配规则: 在 Nacos Spring Cloud 中,dataId 的完整格式如下:(就是说在nacos端我们怎么命名文件的)
${prefix}-${spring.profiles.active}.${file-extension}
prefix 默认为spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix 来配置。spring.profiles.active 即为当前环境对应的 profile ,详情可以参考 Spring Boot文档。 注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension} file-exetension 为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。(注意nacos里必须使用yaml) 综合以上说明,和下面的截图,Nacos 的dataid(类似文件名)应为: nacos-config-client-dev.yaml (必须是yaml) 访问http://localhost:3377/config/info会得到里面的配置信息并且自带刷新功能
2.6.2作为分类配置
2.6.2.1开发中遇到的问题
- 问题一:在实际开发中,通常一个系统会准备dev开发环境、test测试环境,prod生产环境,如何保证指定环境启动服务时能正确的读取到Nacos上响应的环境配置文件呢?
- 问题二:一个大型微服务系统会有很多微服务子项目,每个为项目由会有相应的开发环境,测试环境,预发环境,正式环境,有该如何对微服务的配置进行管理
2.6.2.2namespace命名空间
namespace类似于就java里面的package名和类名 最外面的namespace是用于分区部署环境,Group和DataID逻辑上区分为两个目标对象 Nacos的默认命名空间是public,Namespace主要用来实现隔离,比如现在我们有三个环境:开发、生产、测试环境,我们可以创建三个namespace,不同的namespace之间的隔离的 Group默认是DEAFULT_GROUP,Group可以把不同的微服务划分到同一分组里面 Service就是微服务,一个service可以包含多个cluster集群,nacos默认cluster是DEFAULT,Cluster是对指定微服务的一个虚拟划分。比方说为了容灾,将service微服务分别部署在了杭州机房和广州机房,这是就可以给杭州机房的service微服务起一个集群名称HZ给广州的service微服务起一个集群名称GZ,还可以尽量让同一个机房的微服务互相调用,以提升虚拟。最后instance就是微服务的实例
2.6.3常见的分组
3.6.3.1DataID分组方案
- 指定spring.profile.active和配置文件的dataID来,使不同环境下读取不同的配置
- 配置空间+配置分组+新建dev和test两个dataid:就是创建-后不同的两个文件名nacos-config-client-dev.yaml、nacos-config-client-test.yaml
- 通过IDEA里的spring.profile.active属性就能进行多环境下配置文件的读取
- 测试:http://localhost:3377/config/info 配置什么就加载什么
3.6.3.2Group分组方案
- 在nacos创建配置文件时,给文件指定分组。
- 在IDEA中该group内容
- 实现的功能:当修改开发环境时,只会从同一group中进行切换。
3.6.3.3namesapce分组
- 默认是default这个是不允许删除的,可以创建一个新的命名空间,会自动给创建的命名空间一个流水号。
- 在nacos新建命名空间,自动出现流水号
- 在IDEA的yml中指定命名空间namespace: 流水号
步骤:
- 选择名空间下面的新建命名空间
- 输入命名空间名和描述
- 在服务列表中会显示新建的命名空间
- 同上面一样建立服务
- bootstrap.yml配置
访问结果
|