搭建 Spring Cloud Alibaba 微服务框架
了解微服务搭建
版本说明
版本兼容参考: alibaba/spring-cloud-alibaba
Spring Cloud: https://spring.io/projects/spring-cloud#overview
组件版本关系
Spring Cloud Alibaba Version | Sentinel Version | Nacos Version | RocketMQ Version | Dubbo Version | Seata Version |
---|---|---|---|---|---|
2.2.5.RELEASE | 1.8.0 | 1.4.1 | 4.4.0 | 2.7.8 | 1.3.0 |
2.2.3.RELEASE or 2.1.3.RELEASE or 2.0.3.RELEASE | 1.8.0 | 1.3.3 | 4.4.0 | 2.7.8 | 1.3.0 |
2.2.1.RELEASE or 2.1.2.RELEASE or 2.0.2.RELEASE | 1.7.1 | 1.2.1 | 4.4.0 | 2.7.6 | 1.2.0 |
2.2.0.RELEASE | 1.7.1 | 1.1.4 | 4.4.0 | 2.7.4.1 | 1.0.0 |
2.1.1.RELEASE or 2.0.1.RELEASE or 1.5.1.RELEASE | 1.7.0 | 1.1.4 | 4.4.0 | 2.7.3 | 0.9.0 |
2.1.0.RELEASE or 2.0.0.RELEASE or 1.5.0.RELEASE | 1.6.3 | 1.1.1 | 4.4.0 | 2.7.3 | 0.7.1 |
毕业版本依赖关系(推荐使用)
Spring Cloud Version | Spring Cloud Alibaba Version | Spring Boot Version |
---|---|---|
Spring Cloud Hoxton.SR8 | 2.2.5.RELEASE | 2.3.2.RELEASE |
Spring Cloud Greenwich.SR6 | 2.1.3.RELEASE | 2.1.13.RELEASE |
Spring Cloud Hoxton.SR3 | 2.2.1.RELEASE | 2.2.5.RELEASE |
Spring Cloud Hoxton.RELEASE | 2.2.0.RELEASE | 2.2.X.RELEASE |
Spring Cloud Greenwich | 2.1.2.RELEASE | 2.1.X.RELEASE |
Spring Cloud Finchley | 2.0.3.RELEASE | 2.0.X.RELEASE |
Spring Cloud Edgware | 1.5.1.RELEASE(停止维护,建议升级) | 1.5.X.RELEASE |
服务注册与发现-Nacos
服务治理概念
在RPC远程调用过程中,服务与服务之间依赖关系非常大,服务Url地址管理非常复杂,所以这时候需要对我们服务的url实现治理,通过服务治理可以实现服务注册与发现、负载均衡、容错等。
服务注册中心的概念
- 每次调用该服务如果地址直接写死的话,一旦接口发生变化的情况下,这时候需要重新发布版本才可以该接口调用地址,所以需要一个注册中心统一管理我们的服务注册与发现。
- 注册中心:我们的服务注册到我们注册中心,key为服务名称、value为该服务调用地址,该类型为集合类型。Eureka、consul、zookeeper、nacos等。
- 服务注册:我们生产者项目启动的时候,会将当前服务自己的信息地址注册到注册中心。
- 服务发现: 消费者从我们的注册中心上获取生产者调用的地址(集合),在使用负载均衡的策略获取集群中某个地址实现本地rpc远程调用。
微服务调用接口常用名词
- 生产者:提供接口被其他服务调用
- 消费者:调用生产者接口实现消费
- 服务注册:将当前服务地址注册到
服务发现
Nacos的基本的介绍
Nacos可以实现分布式服务注册与发现/分布式配置中心框架。
官网的介绍: https://nacos.io/zh-cn/docs/what-is-nacos.html
windows安装nacos
首先去NACOS官网 下载相关jar,这里使用的是最新版本1.4.1
- 下载最新版本后进行解压,目前最新版本1.4.1
- 进入解压后的目录:E:\SpringCloudAlibaba\nacos\bin
- cmd 打开命令窗口
- 运行: startup.cmd -m standalone
Nacos端口为8848
http://127.0.0.1:8848/nacos/#/login 账号密码nacos naocs
nacos可以支持分布式配置中心和服务注册与发现
搭建Spring Cloud Alibaba项目
首先要有一个SpringBoot项目,微服务项目是基于SpringBoot项目的,主要是由于SpringBoot项目可以不用写太多繁琐的配置文件,写过SSM的都体验过,那滋味。。。。
注意事项:必须先启动nacos,才能启动cloud的项目
搭建父工程
修改 pom 文件
<?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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version> <!-- Spring Boot 版本 --><relativePath/> <!-- lookup parent from repository --></parent><!-- 子模块 --><modules><module></module></modules><groupId>com.cp</groupId><artifactId>springcloud-father</artifactId><version>0.0.1-SNAPSHOT</version><name>springcloud-father</name><description>Demo project for Spring Boot</description><!-- 统一版本号 --><properties><java.version>1.8</java.version><spring.cloud-version>Hoxton.SR8</spring.cloud-version><spring.cloud.alibaba-version>2.2.5.RELEASE</spring.cloud.alibaba-version></properties><!--统一依赖--><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 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>
创建生产者项目
这里我们现在Maven创建子模块,也可以使用SpringBoot创建子模块
使用SpringBoot 可以不用手动创建主启动类等一些文件
使用Maven 创建的子项目pom文件内容简短,方便建立父子模块关系
添加Nacos依赖
<!-- Nacos -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
修改主启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication
@EnableDiscoveryClient //添加注解,实现服务注册
public class SpringCloudProviderApplication {public static void main(String [] args){SpringApplication.run(SpringCloudProviderApplication.class,args);}
}
修改 application.yml 配置
server:port: 9000
spring:application:name: springcloud-provider #服务名称,微服务项目中必须设计服务名称cloud:nacos:discovery:server-addr: 127.0.0.1:8848 #Nacos的服务注册中心地址
创建一个controller进行测试
package com.cp.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author : CP* @version: 1.0* @program : springcloud-father* @description :* @date : 2021-03-06 10:08**/
@RestController
public class ProviderController {@GetMapping("/index")public String index(){return "Hello word";}
}
添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
注意事项:必须先启动nacos,才能启动cloud的项目
访问地址:http://localhost:8848/nacos
启动完成后去nacos服务注册中心看看,发现provider生产者已经注册到了nacos,说明生产者已经搭建完成。
访问地址:http://localhost:9000/index ,如图所示,生产者已经搭建完成
创建消费者项目
创建消费者,步骤和创建生产者一样,修改一下端口号和服务名称
server:port: 9001
spring:application:name: springcloud-consumer #服务名称,微服务项目中必须设计服务名称cloud:nacos:discovery:server-addr: 127.0.0.1:8848 #Nacos的服务注册中心地址
注意事项:必须先启动nacos,才能启动cloud的项目
访问地址:http://localhost:8848/nacos
启动完成后nacos注册服务中心可以看到消费者服务已经注册
服务发现
/*** 服务发现*/
@Autowired
private DiscoveryClient discoveryClient;@GetMapping("/instances")
public List<ServiceInstance> instances(){List<ServiceInstance> instances = discoveryClient.getInstances("springcloud-consumer");return instances;
}
注意事项:必须先启动nacos,才能启动cloud的项目
访问地址:http://localhost:9001/instances,如图所示:
消费者已经搭建完成并得到了注册信息
负载均衡-Ribbon
概述
LB(Load Balance,负载均衡)是一种集群技术,它将特定的业务(网络服务、网络流量等)分担给多台网络设备(包括服务器、防火墙等)或多条链路,从而提高了业务处理能力,保证了业务的高可靠性。
负载均衡简介
负载均衡是一种基础的网络服务,核心原理是按照指定的负载均衡算法,将请求分配到后端服务集群上,从而为系统提供并行处理和高可用的能力。
负载均衡一般分为以下两种:
- 集中式负载均衡,在消费者和服务提供方中间使用独立的代理方式进行负载,有硬件的负载均衡器,比如 F5,也有软件,比如 Nginx。
- F5,四层负载均衡通过虚拟 IP + 端口接收请求,然后再分配到真实的服务器
- Nginx,七层负载均衡通过虚拟的 URL 或主机名接收请求,然后再分配到真实的服务器。
- 客户端负载均衡,客户端根据自己的请求情况做负载,Ribbon 就属于客户端自己做负载均衡的框架。
集中式负载均衡
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F8AoPG0X-1616120955070)(https://images1.freesion.com/158/2a/2a380343a1444f63155c1499761c494e.png)]
客户端发送请求到负债均衡器,负载均衡器根据相关的负载均衡算法(随机、轮询、加权)选择其中一台服务器,将请求转发到服务器上。
客户端负载均衡
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b8Z9QJXe-1616120955070)(https://images2.freesion.com/499/b0/b06eaa2e8cf41870af8b798bcf6f48f3.png)]
如上图所示,和集中式负载均衡的不同是,客户端负载均衡器需要自己维护服务实例的信息,然后通过相关的负载均衡算法(随机、轮询、加权)从实例中选取一个实例,直接进行访问。
负载均衡策略
轮询策略
Ribbon 默认采用轮询策略
这里我们实现消费者(consumer)调用提供者(provider)
在提供者(provider)定义方法
import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;/*** @author : CP* @version: 1.0* @program : springcloud-father* @description :* @date : 2021-03-06 10:08**/ @RestController public class ProviderController {//获取端口号@Value("${server.port}")private String port;@GetMapping("/echo")public String echo(){//打印当前端口号return "Hello word ------->"+port;} }
修改消费者(consumer)主启动类
添加@LoadBalanced注解
/*** @LoadBalanced * 实现赋值均衡* 使用的是轮询策略*/ @Bean @LoadBalanced public RestTemplate restTemplate(){return new RestTemplate(); }
在消费者(consumer)定义service层
/*** 调用provider模块中的方法* @return String*/ String echo();
@Autowired private RestTemplate restTemplate;@Override public String echo() {/*** 第一个参数获取路径* 第二个参数是那边接口返回的类型* springcloud-provider 是提供者模块yml配置的名称* index 是提供者里有的提供方法*/String s = restTemplate.getForObject("http://springcloud-provider/index", String.class);return s; }
在消费者(consumer)定义Controller层
@Autowired private CousmerService cousmerService;/*** 调用生产者提供的方法* @return*/ @GetMapping("/echo") public String echo(){return cousmerService.echo(); }
注意事项:必须先启动nacos,才能启动cloud的项目
访问地址:http://localhost:9001/echo,如图所示
随机
修改消费者(consumer)模块中的配置
#springcloud-provider 是你提供者(provider)模块名称
springcloud-provider:ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
权重
在消费者(consumer)添加NacosWeightLoadBalancerRule类
package com.cp.config;import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;/*** 基于Nacos权重的负载均衡** @Author Administrator*/
@Slf4j
public class NacosWeightLoadBalancerRule extends AbstractLoadBalancerRule {@Autowiredprivate NacosDiscoveryProperties nacosDiscoveryProperties;@Overridepublic void initWithNiwsConfig(IClientConfig iClientConfig) {// 读取配置文件,并初始化NacosWeightLoadBalancerRule}@Overridepublic Server choose(Object o) {DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();// 请求的微服务名称String applicationName = loadBalancer.getName();try {// nacos 通过基于权重的负载均衡算法,算出一个健康的服务实例以供调用Instance instance = nacosDiscoveryProperties.namingServiceInstance().selectOneHealthyInstance(applicationName);return new NacosServer(instance);} catch (NacosException e) {log.error("获取服务实例异常:{}", e.getMessage());}return null;}
}
添加依赖
<!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
配置文件
#springcloud-provider 是你提供者(provider)模块名称
springcloud-provider:ribbon:NFLoadBalancerRuleClassName: com.cp.config.NacosWeightLoadBalancerRule #刚刚创建类的路径
服务调用-OpenFeign
OpenFeign简介
OpenFeign是一个声明式的Web服务客户端、让编写Web服务客户端变得更加容易只需要创建一个接口然后添加上注解即可,同时,它集成了Ribbon,可以轻松实现负载均衡的效果。
Feign和OpenFeign的区别:
快速开始
这里我们对消费者(consumer)调用提供者(provider)进行优化
在消费者(consumer)模块中添加依赖
<!-- OpenFeign -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在消费者(consumer)的主启动类添加注解
//支持 OpenFeign 组件的使用
@EnableFeignClients
修改消费者(consumer) service层
package com.cp.service;import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;/*** @FeignClient(value = "springcloud-provider") 声明要访问的服务* value = 需要访问的服务名称* @GetMapping("/echo") 声明要调用的方法* /echo 必须是访问服务里拥有的方法接口**/
@FeignClient(value = "springcloud-provider")
public interface ConsumerService {@GetMapping("/echo")String echo();
}
定义后可以不用编写实现类可直接通过Controller层(不需要改动)进行调用
注意事项:必须先启动nacos,才能启动cloud的项目
访问地址:http://localhost:9001/echo,如图所示
服务容错-Sentinel
服务雪崩效应
在分布式系统中,由于网络原因或者自身的原因,服务一般无法保证100%可用。如果一个服务出现了问题,调用这个服务就会出现线程阻塞的情况。此时若有大量的请求涌入,就会出现多条线程阻塞等待,进而导致服务瘫痪。
由于服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩效应”。
服务雪崩效应的定义
服务雪崩效应是一种因 服务提供者 的不可用导致 服务调用者 的不可用,并将不可用 逐渐放大 的过程.如果所示:
上图中, A为服务提供者, B为A的服务调用者, C和D是B的服务调用者. 当A的不可用,引起B的不可用,并将不可用逐渐放大C和D时, 服务雪崩就形成了
服务雪崩效应形成的原因
我把服务雪崩的参与者简化为 服务提供者 和 服务调用者, 并将服务雪崩产生的过程分为以下三个阶段来分析形成的原因:
- 服务提供者不可用
- 重试加大流量
- 服务调用者不可用
服务雪崩的每个阶段都可能由不同的原因造成, 比如造成 服务不可用 的原因有:
- 硬件故障
- 程序Bug
- 缓存击穿
- 用户大量请求
服务雪崩的应对策略
针对造成服务雪崩的不同原因, 可以使用不同的应对策略:
- 服务降级:释放服务器资源以保证核心任务的正常运行
- 服务限流:限制请求访问量
- 服务隔离:避免服务之间相互影响
- 服务容错:Sentinel、Hystrix、Resilience4j
Sentinel 服务容错
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 的主要特性:
Sentinel 的开源生态:
Sentinel 分为两个部分:
- 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
- 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
快速开始
在提供者(provider)添加依赖
<!-- sentinel 服务容错 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency><!-- 服务监控器 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在提供者(provider)添加YAML配置
spring:cloud:# 服务容错sentinel:transport:dashboard: localhost:8080management:endpoints:web:exposure:include: '*'
提供者(provider) YAML 完整配置
server:port: 9000
spring:application:# 服务名称name: springcloud-provider #服务名称,微服务项目中必须设计服务名称cloud:# 服务注册nacos:discovery:server-addr: 127.0.0.1:8848 #Nacos的服务注册中心地址# 服务容错sentinel:transport:dashboard: localhost:8080management:endpoints:web:exposure:include: '*'
注意:运行项目前先启动本地的sentinel-dashboard-1.8.0.jar
包
打开控制台启动命令:
java -jar sentinel-dashboard-1.8.0.jar
启动成功后访问: http://localhost:8080;如图所示
账号密码sentinel sentinel
进入控制台后需要先访问一下接口进行监控
Alibaba Sentinel 流控规则
Sentinel流控模式
流控是Sentinel核心功能之一,流控指的是流量控制。
- 资源名: 唯一名称,默认请求路径
- 针对来源: Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
- 阈值类型/单机阈值:
- QPS(每秒请求数量):当调用该api的QPS达到阈值的时候,进行限流
- 线程数:当调用该api的线程数达到阈值的时候,进行限流
- 是否集群: 不需要集群
- 流控模式:
- 直接:api达到限流条件时,直接限流
- 关联:当关联的资源达到限流阈值时,就限流自己
- 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到峰值,就进行限流)【api级别的针对来源】
- 流控效果:
- 快速失败:直接失败,抛异常
- Warm Up:根据coldFactor(冷加载因子,默认3)的值,从阈值/coldFactor,经过预热时长,才达到设置的QPS阈值
- 排队等待:匀速排队,让请求以匀速通过,阈值类型必须设置为QPS,否则无效
直接限流
点击簇点链路后进行操作
表示1秒内查询2次就是OK,若超过次数2,就直接失败-快速失败,报默认错误。
连续快速访问:
关联限流
当A接口访问到达指定的值,将B接口进行限流
在提供者(provider)定义方法
/*** 测试关联限流* @return*/@GetMapping("/show")public String show(){return "2333333";}
目前提供者(provider)所拥有的方法
package com.cp.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author : CP* @version: 1.0* @program : springcloud-father* @description :* @date : 2021-03-06 10:08**/
@RestController
public class ProviderController {/*** 获取端口号*/@Value("${server.port}")private String port;/*** 被消费者进行调用并输出当前端口号* @return*/@GetMapping("/echo")public String echo(){return "Hello word ------->"+port;}/*** 测试关联限流* @return*/@GetMapping("/show")public String show(){return "2333333";}
}
编写测试类频繁访问提供者(provider)接口 来测试限流
package com.cp;import org.springframework.web.client.RestTemplate;/*** @author : CP* @version: 1.0* @program : springcloud-father* @description :* @date : 2021-03-08 14:46**/
public class ProviderTest {public static void main(String[] args) {RestTemplate restTemplate = new RestTemplate();for (int i = 0; i < 500; i++) {String forObject = restTemplate.getForObject("http://localhost:9010/show", String.class);try {//0.1秒延迟Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}
}
通过关联/show接口;当接口每秒访问超过2时,/echo接口限流
添加限流规则后去确定测试类进行测试
访问结果:
链路限流
B和C都访问A接口,当B或C其中一个接口到达限流要求后将A接口限流
在提供者(provider)添加依赖
<!-- 链路限流所需以下三个依赖 -->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-core</artifactId><version>1.8.0</version> <!-- 通过版本统一可以忽略版本号 -->
</dependency><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-web-servlet</artifactId><version>1.8.0</version>
</dependency><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-transport-simple-http</artifactId><version>1.8.0</version>
</dependency>
在提供者(provider) YMAL 中配置添加
spring:cloud: sentinel: filter: enabled: false
提供者(provider) YAML 完整配置
server:port: 9000
spring:application:# 服务名称name: springcloud-provider #服务名称,微服务项目中必须设计服务名称cloud:# 服务注册nacos:discovery:server-addr: 127.0.0.1:8848 #Nacos的服务注册中心地址# 熔断器sentinel:transport:dashboard: localhost:8080filter:enabled: falsemanagement:endpoints:web:exposure:include: '*'
在提供者(provider)添加配置类
package com.cp.config;import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author : CP* @version: 1.0* @program : springcloud-father* @description :* @date : 2021-03-10 09:35**/
@Configuration
public class FilterConfiguration {@Beanpublic FilterRegistrationBean registrationBean(){FilterRegistrationBean registrationBean = new FilterRegistrationBean();registrationBean.setFilter(new CommonFilter());registrationBean.addUrlPatterns("/*");registrationBean.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY,"false");registrationBean.setName("sentinelFilter");return registrationBean;}
}
提供者(provider) 添加 ProviderServiceImpl 类
package com.cp.service.impl;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.stereotype.Service;/*** @author : CP* @version: 1.0* @program : springcloud-father* @description :* @date : 2021-03-10 07:56**/
@Service
public class ProviderServiceImpl {//必须添加 @SentinelResource 才有流控效果@SentinelResource("/link")public String link(){return "链路访问结果";}
}
在提供者(provider) ProviderController 添加方法
@Autowiredprivate ProviderServiceImpl providerService;/*** 链路限流测试* @return*/@GetMapping("/link1")public String link1(){providerService.link();return "link1";}@GetMapping("/link2")public String link2(){providerService.link();return "link2";}
打开Sentinel 控制台,查看相关链路
进行链路限流
选择好资源名后,流控模式选择链路
根据自己选择的资源名查看他的拥有哪些入口资源,添加一个入口资源,可添加多个用逗号隔开
当入口资源达到自己定义的阈值后选择的资源进行限流
修改之前编写过的测试类进行测试
package com.cp;import org.springframework.web.client.RestTemplate;/*** @author : CP* @version: 1.0* @program : springcloud-father* @description :* @date : 2021-03-08 14:46**/
public class ProviderTest {public static void main(String[] args) {RestTemplate restTemplate = new RestTemplate();for (int i = 0; i < 500; i++) {String forObject = restTemplate.getForObject("http://localhost:9000/link2", String.class);try {//0.5秒延迟Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}
}
运行测试类后访问/link1得到结果
资源成功的被限流了
消息驱动-RocketMQ
消息队列概述
消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ
核心概念
- Topic:消息主题,一级消息类型,生产者向其发送消息。
- 生产者:也称为消息发布者,负责生产并发送消息至Topic。
- 消费者:也称为消息订阅者,负责从Topic接收并消费消息。
- 消息:生产者向Topic发送并最终传送给消费者的数据和(可选)属性的组合。
- 消息属性:生产者可以为消息定义的属性,包含Message Key和Tag。
- Group:一类生产者或消费者,这类生产者或消费者通常生产或消费同一类消息,且消息发布或订阅的逻辑一致。
Linux 安装和部署RocketMQ
Linux 配置环境:传送门
JDK: jdk-8u271-linux-x64.tar.gz
RocketMQ: rocketmq-all-4.7.1-bin-release
RocketMQ控制台: rocketmq-externals
Spring Boot 整合 RocketMQ
创建 dao 模块统一公共的依赖
pom.xml 依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!-- Lombok -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>
创建 Order 类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {private Integer id;private String buyerName;private String buyerTel;private String address;private Date createDate;
}
提供者(provider) 继承dao模块
提供者(provider)添加依赖
<dependency><groupId>com.cp</groupId><artifactId>dao</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency><!-- Spring Boot Rocketmq -->
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.1.0</version>
</dependency><!-- Rocketmq 可视化连接 -->
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version>4.7.1</version>
</dependency>
提供者(provider)目前依赖
<dependency><groupId>com.cp</groupId><artifactId>dao</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency><!-- Nacos -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency><!-- sentinel 服务容错 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency><!-- 服务监控器 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency><!-- 链路限流所需以下三个依赖 -->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-core</artifactId><version>1.8.0</version>
</dependency><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-web-servlet</artifactId><version>1.8.0</version>
</dependency><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-transport-simple-http</artifactId><version>1.8.0</version>
</dependency><!-- Spring Boot Rocketmq -->
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.1.0</version>
</dependency><!-- Rocketmq 可视化连接 -->
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version>4.7.1</version>
</dependency>
提供者(provider) 添加 application.yml 配置
rocketmq:name-server: 192.168.64.135:9876producer:group: myprovider
提供者(provider) 现在 YAML 配置
server:port: 9000
spring:application:# 服务名称name: springcloud-provider #服务名称,微服务项目中必须设计服务名称cloud:# 服务注册nacos:discovery:server-addr: 127.0.0.1:8848 #Nacos的服务注册中心地址# 熔断器sentinel:transport:dashboard: localhost:8080filter:enabled: falsemanagement:endpoints:web:exposure:include: '*'rocketmq:name-server: 192.168.64.135:9876producer:group: myprovider
在提供者(provider) 控制器中 定义方法
@Autowired
private RocketMQTemplate rocketMQTemplate;@GetMapping("/create")
public Order create(){Order order = new Order(1,"张三","123123","软件园",new Date());this.rocketMQTemplate.convertAndSend("orderTopic",order);return order;
}
目前提供者(provider) 控制器所拥有的方法
package com.cp.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author : CP* @version: 1.0* @program : springcloud-father* @description :* @date : 2021-03-06 10:08**/
@RestController
public class ProviderController {/*** 获取端口号*/@Value("${server.port}")private String port;/*** 被消费者进行调用并输出当前端口号* @return*/@GetMapping("/echo")public String echo(){return "Hello word ------->"+port;}/*** 测试关联限流* @return*/@GetMapping("/show")public String show(){return "2333333";}@Autowiredprivate RocketMQTemplate rocketMQTemplate;/*** 消息队列进行消息发送*/@GetMapping("/create")public Order create(){Order order = new Order(1,"张三","123123","软件园",new Date());this.rocketMQTemplate.convertAndSend("orderTopic",order);return order;}
}
启动前要保证nacos、ES、以及 [服务器/虚拟机] 端口号开放和打开
访问: http://localhost:9000/create 得到结果
消费者(consumer) 继承dao模块
消费者(consumer) 模块添加依赖和提供者(provider)添加依赖一致
<dependency><groupId>com.cp</groupId><artifactId>dao</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency><!-- Spring Boot Rocketmq -->
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.1.0</version>
</dependency><!-- Rocketmq 可视化连接 -->
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version>4.7.1</version>
</dependency>
消费者(consumer) 目前拥有的依赖
<dependency><groupId>com.cp</groupId><artifactId>dao</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency><!--nacos-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency><!-- Spring Boot Rocketmq -->
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.1.0</version>
</dependency><!-- Rocketmq 可视化连接 -->
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version>4.7.1</version>
</dependency><!-- OpenFeign -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
消费者(consumer) 添加 application.yml 配置
rocketmq:name-server: 192.168.64.138:9876
消费者(consumer) 现在 YAML 配置
spring:application:name: springcloud-consumercloud:nacos:discovery:server-addr: 127.0.0.1:8848server:port: 9001rocketmq:name-server: 192.168.64.135:9876
消费者(consumer) 创建 ConsumeService 类 进行消息消费
消费者(consumer)会实时监控提供者(provider)是否产生消息来通过消费
package com.cp.service;import com.cp.enitiy.Order;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;/*** @author : CP* @version: 1.0* @program : spring-cloud-alibaba* @description :* @date : 2021-03-16 20:13**/
@Slf4j
@Service
@RocketMQMessageListener(consumerGroup = "myConsumer",topic = "orderTopic")
public class ConsumeService implements RocketMQListener<Order> {@Overridepublic void onMessage(Order order) {log.info("新订单{},发短信",order);}
}
无论先启动提供者(provider)还是消费者(consumer)都没有关系
提供者(provider) 用于提供消息
消费者(consumer)实时监控提供者(provider)
启动前要保证nacos、ES、以及 [服务器/虚拟机] 端口号开放和打开
每次刷新提供者提供消息的接口,消费者都会立刻进行消费
打开 RocketMQ控制台也可以查看消费记录
java -jar rocketmq-console-ng-1.0.0.jar 启动jar包 访问自己定义的端口号
API网关-Gateway
微服务网关概述
不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题:
- 客户端会多次请求不同的微服务,增加了客户端的复杂性
- 存在跨域请求,在一定场景下处理相对复杂
- 认证复杂,每个服务都需要独立认证
- 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施
- 某些微服务可能使用了防火墙 / 浏览器不友好的协议,直接访问会有一定的困难
以上这些问题可以借助网关解决。
Gateway特性
- 基于Spring Framework 5, Project Relactor 和 Spring Boot 2.0 进行构建;
- 动态路由:能够匹配任何请求属性;
- 可以对路由指定 Predicate (断言)和 Filter (过滤器) ;
- 集成 Hystrix 的断路器功能;
- 集成 Spring Cloud 服务发现功能;
- 易于编写的 Predicate (断言)和Filter (过滤器) ;
- 请求限流功能;
- 支持路径重写;
Gateway工作流程
客户端向Spring Cloud GateWay发出请求,然后在GateWay Handler Mapping中找到与请求相匹配的路由,将其发送到GateWay Web Handler;Handler再通过指定的过滤器链来将请求发送到我们实际的服务执⾏业务逻辑,然后返回。过滤器之
间⽤虚线分开是因为过滤器可能会在发送代理请求之前(pre)或者之后(post)执⾏业务逻辑。
Filter在“pre”类型过滤器中可以做参数校验、权限校验、流量监控、⽇志输出、协议转换等,在“post”类型的过滤器中可以做响应内容、响应头的修改、⽇志的输出、流量监控等。
快速开始
创建Gateway模块
项目名为 springcloud-gateway
添加依赖
<!-- Nacos -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency><!-- OpenFeign -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency><!-- gateway -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
特别注意
Spring Cloud Gateway 不使用 Web 作为服务器,而是 使用 WebFlux 作为服务器,Gateway 项目已经依赖了 starter-webflux
,所以这里千万不要依赖starter-web
创建Gateway主启动类
package com.cp;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;/*** @author : CP* @version: 1.0* @program : spring-cloud-alibaba* @description :* @date : 2021-03-19 09:35**/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class,args);}
}
创建application.yml
在resources创建YAML文件
server:port: 9010
spring:application:# 服务名称name: springcloud-gateway #服务名称,微服务项目中必须设计服务名称cloud:gateway:# 开启本地能使用服务访问路由discovery:locator:enabled: trueroutes:#springcloud-provider 提供者模块- id: SPRINGCLOUD-PROVIDERuri: lb://springcloud-providerpredicates:- Method=GET,POST #请求方式#springcloud-consumer 消费者模块- id: SPRINGCLOUD-CONSUMERuri: lb://springcloud-consumerpredicates:- Method=GET,POST#其他服务可继续添加
传送门: 官方文档
启动 Gateway 模块、提供者(provider)模块、消费者(consumer)模块
访问提供者(provider)模块
访问消费者(consumer)模块
鉴权过滤器
添加后访问必须携带请求头token才能进行访问
package com.cp.filter;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.Map;/*** 鉴权过滤器*/
@Component
public class AuthFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String token = exchange.getRequest().getQueryParams().getFirst("token");if (token == null || token.isEmpty()) {ServerHttpResponse response = exchange.getResponse();// 封装错误信息Map<String, Object> responseData = Maps.newHashMap();responseData.put("code", 401);responseData.put("message", "非法请求");responseData.put("cause", "Token is empty");try {// 将信息转换为 JSONObjectMapper objectMapper = new ObjectMapper();byte[] data = objectMapper.writeValueAsBytes(responseData);// 输出错误信息到页面DataBuffer buffer = response.bufferFactory().wrap(data);response.setStatusCode(HttpStatus.UNAUTHORIZED);response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");return response.writeWith(Mono.just(buffer));} catch (JsonProcessingException e) {e.printStackTrace();}}return chain.filter(exchange);}/*** 设置过滤器的执行顺序* @return*/@Overridepublic int getOrder() {return Ordered.LOWEST_PRECEDENCE;}
}
配置管理-Nacos
什么是配置
我们应用程序在运行过程中需要读取一切配置信息,这些信息会伴随程序的整个生命周期。例如:数据库的配置
什么是配置中心
随着微服务的兴起,配置文件也随之增加并且分散冗余,配置中心就是将配置文件从应用中剥离出来进行统一的管理,不需要我们的服务自己去管理配置。
配置中心流程
- 用户在配置中心更新配置信息。
- 服务A和服务B得到配置更新的通知,从配置中心获取配置
主流配置中心对比
目前市面上用的比较多的配置中心有:Spring Cloud Config、Apollo(携程)和Nacos(阿里)等。
对比项目 | Spring Could Confi | 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 |
- 从配置中心角度来看,性能方面Nacos的读写性能最高,Apollo次之,Spring Cloud Config依赖Git场景不适合开 放的大规模自动化运维API。
- 功能方面Apollo最为完善,nacos具有Apollo大部分配置管理功能,而Spring Cloud Config不带运维管理界面,需要自行开发。Nacos的一大优势是整合了注册中心、配置中心功能,部署和操作相比 Apollo都要直观简单,因此它简化了架构复杂度,并减轻运维及部署工作。
快速开始
发布配置
1、需要在 Nacos Server 中创建配置文件,采用YAML的方式部署配置文件,操作流程如下:
浏览器打开 http://127.0.0.1:8848/nacos,访问 Nacos Server
2、修改提供者(provider) resources 目录下的配置文件
添加bootstrap.properties
# 这里的应用名对应 Nacos Config 中的 Data ID,实际应用名称以配置中心的配置为准
spring.application.name=springcloud-provider-config
# 指定查找名为 nacos-provider-config.yaml 的配置文件
spring.cloud.nacos.config.file-extension=yaml
# Nacos Server 的地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
为了避免出现问题将提供者(provider)application.yml删除或注释
3、修改提供者(provider) ProviderController 类
在类上添加@RefreshScope可以达到服务端修改配置后立刻得到反应
注入ConfigurableApplicationContext方式将要以applicationContext.getEnvironment().getProperty(“user.name”);来取值
package com.cp.controller;import com.cp.service.impl.ProviderServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author : CP* @version: 1.0* @program : springcloud-father* @description :* @date : 2021-03-06 10:08**/
@RefreshScope //范围刷新
@RestController
public class ProviderController {@Autowiredprivate ProviderServiceImpl providerService;/*** 获取端口号*/@Value("${server.port}")private String port;/*** 获取自定义名称*/@Value("${user.name}")private String name;/*** 被消费者进行调用并输出当前端口号* @return*/@GetMapping("/echo")public String echo(){return "Hello word ------->"+port;}/*** 测试关联限流* @return*/@GetMapping("/show")public String show(){return "2333333";}/*** 链路限流测试* @return*/@GetMapping("/link1")public String link1(){providerService.link();return "link1";}@GetMapping("/link2")public String link2(){providerService.link();return "link2";}// /**
// * 注入配置文件上下文
// */
// @Autowired
// private ConfigurableApplicationContext applicationContext;@GetMapping("/getName")public String getName(){// return applicationContext.getEnvironment().getProperty("user.name");return name;}}
ableApplicationContext方式将要以applicationContext.getEnvironment().getProperty(“user.name”);来取值
package com.cp.controller;import com.cp.service.impl.ProviderServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author : CP* @version: 1.0* @program : springcloud-father* @description :* @date : 2021-03-06 10:08**/
@RefreshScope //范围刷新
@RestController
public class ProviderController {@Autowiredprivate ProviderServiceImpl providerService;/*** 获取端口号*/@Value("${server.port}")private String port;/*** 获取自定义名称*/@Value("${user.name}")private String name;/*** 被消费者进行调用并输出当前端口号* @return*/@GetMapping("/echo")public String echo(){return "Hello word ------->"+port;}/*** 测试关联限流* @return*/@GetMapping("/show")public String show(){return "2333333";}/*** 链路限流测试* @return*/@GetMapping("/link1")public String link1(){providerService.link();return "link1";}@GetMapping("/link2")public String link2(){providerService.link();return "link2";}// /**
// * 注入配置文件上下文
// */
// @Autowired
// private ConfigurableApplicationContext applicationContext;@GetMapping("/getName")public String getName(){// return applicationContext.getEnvironment().getProperty("user.name");return name;}}
搭建 Spring Cloud Alibaba 微服务框架相关推荐
- 从0到1 手把手搭建spring cloud alibaba 微服务大型应用框架(三) (mini-cloud) 搭建认证服务(认证/资源分离版) oauth2.0 (中)
本文承接上文<从0到1 手把手搭建spring cloud alibaba 微服务大型应用框架(三) (mini-cloud) 搭建认证服务(认证/资源分离版) oauth2.0 (上)> ...
- 从0到1手把手搭建spring cloud alibaba 微服务大型应用框架(十五) swagger篇 : gateway 集成swagger 与 knife4j实现在线api文档并嵌入到自己项目内
背景 我们日常开发中基本都是协同开发的,当然极个别的项目整体前后端都是一个人开发的,当多人协作时,尤其是前后端人员协同开发时 必然会面临着前端需要了解后端api接口的情况,两个选择,提前设计好文档,然 ...
- 从0到1带大家把手搭建spring cloud alibaba 微服务大型应用框架(八) saas平台篇-解决不同租户针定制化开发问题 -完整代码以及案例方案(1)
问题描述 平台越做越大到多租户时,经常会遇见一种情况,就是某些用户希望自己的功能是定制化的,有可能是完全的新功能,也有可能压根就是同样的功能但是A和B两个用户的实现前后台展示和逻辑就压根不同 不可能在 ...
- 防止内卷和被潜规则,Spring Cloud Alibaba微服务架构实战派(上下册)|35岁程序员那些事
目录 1 写书缘由 2 本书上册核心内容 2.1 Spring Cloud Alibaba基础实战 2.1.1 主要内容 2.1.2 MyBatis-Plus实现多租户架构的核心原理 2.2 分布式服 ...
- Spring Cloud Alibaba 微服务开发实践
作者:禅与计算机程序设计艺术 1.简介 Spring Cloud Alibaba 是阿里巴巴开源的基于 Spring Cloud 的微服务框架.该项目从最初孵化到现在已经历经十多年的发展,得到了广泛的 ...
- Spring Cloud Alibaba 微服务详细笔记
文章目录 SpringCloud 一.微服务概述 1.1.什么是微服务? 1.2.为什么是微服务? 1.3.架构演变 1.4.微服务的解决方案 二.什么是SpringCloud 2.1.官方定义 2. ...
- Spring Cloud Alibaba微服务项目中集成Redis实现分布式事务锁实践
引言 我们知道同一个进程里面为了解决资源共享而不出现高并发的问题可以通过高并发编程解决,通过给变量添加volatile关键字实现线程间变量可见:通过synchronized关键字修饰代码块.对象或者方 ...
- Spring Cloud Alibaba微服务组件快速上手
文章目录 Nacos 什么是Nacos Nacos的启动 将项目注册到Nacos 项目pom依赖 yaml配置 Nacos心跳机制 Dubbo 什么是RPC 什么是Dubbo Dubbo服务的注册与发 ...
- 开源,阿里内部Spring Cloud Alibaba微服务神仙文档(全彩版)
Spring Cloud Alibaba概述 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案.此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring C ...
- Spring Cloud Alibaba 微服务生态基础实践,线程池的底层原理
content longtext NOT NULL COMMENT 'content', md5 varchar(32) DEFAULT NULL COMMENT 'md5', gmt_create ...
最新文章
- Java知识汇总-思维导图
- docker 错误 request canceled while waiting for connection 或 TLS handshake timeout 解决方案
- opencl高斯源码整理
- 支持向量机libsvm实战入门
- python中奇数怎么表示_如何在python输出数据中的奇数
- MySQL—用户和权限管控
- Unity web player无法正常使用
- rx560d linux 图形设计,RX 560D对比RX 560哪个好?RX560D与560的区别对比详细评测
- oracle12c启动ODM,Oracle 12c impdp 导入ORA-17500: ODM err:Communication error on send 错误处理方法...
- 系统—怎么关闭windows自带的安全中心
- 关于DevExpress XtraReport 表格单合并单元格完整教程
- 引起内存不能“read”的原因及“written”的解决方案
- 计算机考试题 实操,计算机考试实操题.doc
- CSS用flex布局两端对齐,列不满左对齐
- 活动预告:美团、Envoy、网易杭研、微博大咖齐聚,多角度剖析云原生实践
- 简约好看的自适应导航页源码
- 小微企业如何实现数字化转型?应该从哪一步开始?
- discuz论坛(discuz论坛官网)
- 波浪理论与伦敦金价走势分析
- 电子商务公司运营流程是什么怎样绘制
热门文章
- 转载《五大免费采集器哪个好,火车头,海纳,ET,三人行,狂人采集 》
- 网站ssl证书错误是为什么?要怎么解决ssl证书错误
- Excelize 发布 2.6.0 版本,功能强大的 Excel 文档基础库
- JavaScript getMonth() 函数用法
- 进化算法和深度强化学习的关系?
- svn: E230001: Server SSL certificate verification failed: certificate issued for a different hostnam
- 影响世界的100条管理励志名言
- 授课型英硕申请Ph.D (带奖)历程
- 数字图像处理基础——图像空间操作的3种形式
- 程序员出身的史玉柱,曾写了50万行代码,他的编程水平怎样?