简介
Spring Cloud Alibaba是阿里巴巴结合自身的微服务实践开源的微服务全家桶,我个人以为其组件比Spring Cloud 中的组件更加好用和强大。并且对的Spring Cloud组件做了很好的兼容。比如在Spirng Cloud Alibaba中依然可以利用Feign作为服务调用方式,利用Eureak做服务注册发现等等。
重要功能
1.服务注册和发现(nacos):可以注册服务,并且客户可以利用Spring托管的bean(自动集成功能区)发现实例。注册中央。
2.分布式配置(nacos):支持分布式系统中的外部配置,配置更改时自动革新。 配置中央
3.流控制和服务降级(Sentinel ):支持WebServlet,WebFlux-->(比Springmvc更高级)OpenFeign,RestTemplate,Dubbo访问限制和降级流的功能。它可以在运行时通过控制台实时修改限制和降级流的规则,并且还支持监视限制和降级度量标准。 - 服务熔断限流hystrix
4.Rpc服务:扩展Spring Cloud客户端RestTemplate(ribbon)和OpenFeign以支持调用Dubbo RPC服务。
5.分布式事务(seata):支持高性能且易于利用的分布式事务办理方案。
6.事件驱动:支持构建与共享消息系统毗连的高度可扩展的事件驱动微服务。
7.阿里云对象存储:大规模,安全,低成本,高度可靠的云存储服务。支持随时随地在任何应用程序中存储和访问任何类型的数据。
8.阿里云SchedulerX:准确,高度可靠,高可用性的计划作业调度服务,响应时间在几秒钟内。
9.阿里云短信:阿里云短信服务覆盖环球,提供便捷,高效,智能的通讯功能,帮助企业快速联系客户。
与奈飞对比
注册中央nacos
什么是nacos
Nacos致力于帮助您发现,配置和管理微服务。它提供了一组简单有用的功能,使您能够实现动态服务发现,服务配置,服务元数据和流量管理。Nacos使构建,交付和管理微服务平台变得更容易,更快捷。它是通过微服务或云原生方法支持以服务为中央的现代应用程序体系结构的底子架构。说的通俗一些,就是负担了奈飞框架中的Eureka的功能,相当于注册中央,但比Eureka更加智能与便捷。
如何安装nacos
官方提供了Nacos的服务端供我们下载利用,我们启动Nacos后将我们的微服务注册进入Nacos即可。
下载地址:[https://github.com/alibaba/nacos/releases]
启动nacos
nacos的启动也十分方便,在下载好的jar包目录下实行
- windows实行bin目录下的startup命令 :startup.cmd -m standalone
- linux 实行 :sh startup.sh -m standalone
启动成功页面如下所示
nacos的默认端口为8848,在启动成功后,用户即可访问nacos,访问地址为 本地单机模式)http://127.0.0.1:8848/nacos/index.html
登录的账号和暗码均为:nacos
登录成功页面如图所示(笔者这里已经注册好了几个服务,故会有信息,第一次登录且未将服务注册到nacos的话,这里是没有信息的)
服务架构简单搭建
举例服务项目结构
微服务调用流程
Order-Service-20010提供订单的查询服务,Order-Client-30010调用Order-Service-20010提供的服务查询自身的订单信息,Order-Common作为公共服务,提供了相干实体类以及对应的无参有参构造方法
项目搭建
父工程的pom.xml
- <!--公共的一些配置-->
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <java.version>1.8</java.version>
-
- </properties>
- <!--SpringBoot-->
- <parent>
- <groupId> org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.2.5.RELEASE</version>
- </parent>
- <!--SpringCloud-->
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-alibaba-dependencies</artifactId>
- <version>2.2.1.RELEASE</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-dependencies</artifactId>
- <version>Hoxton.SR3</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- </dependency>
- <!--导入lombok-->
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.12</version>
- </dependency>
- </dependencies>
复制代码 服务注册到nacos
Order-Service-20010配置
添加依靠
- <dependency>
- <groupId>com.alibaba.cloud </groupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
- </dependency>
复制代码 编写启动类
- @SpringBootApplication
- @EnableDiscoveryClient
- public class OrderServerStart {
- public static void main(String[] args) {
- SpringApplication.run(OrderServerStart.class);
- }
- }
复制代码 编写配置文件yml
- server:
- port: 20010
- spring:
- application:
- name: Order-server
- cloud:
- nacos:
- discovery:
- server-addr: 127.0.0.1:8848
-
复制代码 Order-Client-30010配置
添加依靠
- <dependency>
- <groupId>com.alibaba.cloud </groupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
- </dependency>
复制代码 编写启动类
- @SpringBootApplication
- @EnableDiscoveryClient
- @EnableFeignClients
- public class OrderClientStart
- {
- public static void main( String[] args )
- {
- SpringApplication.run(OrderClientStart.class);
- }
- }
复制代码 编写配置文件yml
- server:
- port: 30010
- spring:
- application:
- name: Order-client
- cloud:
- nacos:
- discovery:
- server-addr: 127.0.0.1:8848
复制代码 启动成功后,nacos当中便会看见注册成功的服务
Nacos配置中央
客户端接入配置中央
概述
在《SpringCloud极简入门》中我们通过Spring Cloud Config作为同一配置文件管理中央,其实我们总结一下发现Spring Cloud Config利用起来总归比较麻烦。Nacos作为Spring Cloud Alibaba的一个重要组件,它不仅可以用作服务注册与发现,也可以用来替代Spring Cloud Config作为同一配置文件管理,而且他的利用更为简单和人性化。
如何实现
点击页面左上角的"+"按钮即可添加新的配置,不过需要注意的是,编写的后缀改为yaml,在项目中要将application.yml,修改为bootstrap.yml,并在内部举行相干的配置
导入依靠
- <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.example</groupId>
- <artifactId>springcloudalibaba-user-common</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
复制代码 配置Controller
- @RefreshScope //刷新配置
- @RestController
- public class UserController {
- @Value("${temp.notify}")
- private String notify;
- @GetMapping("/user/{id}")
- public User getById(@PathVariable Long id){
- User user = new User(id,"root"+notify ,null);
- return user;
- }
- }
复制代码 修改yml配置
以修改order-client的yml为例
- server:
- port: 30010
- spring:
- application:
- name: Order-client
- profiles:
- active: dev
- cloud:
- nacos:
- discovery:
- server-addr: 127.0.0.1:8848
- config:
- server-addr: 127.0.0.1:8848
- file-extension: yaml
- prefix: application-user
- group: DEFAULT_GROUP
复制代码 测试
root后多了一个1234,为什么呢?
因为笔者在nacos当中的配置文件中,界说了notify的值为1234,这样就表示配置中央配置成功
Sentinel限流控制
Sentinel和Hystrix
限流和熔断
限流 , 限制流量,这里的流量我们可以理解成请求数目,其实就是限制服务器的请求并发数目,为什么要这么做?如果不做限流,那么在大量并发请求下我们的服务器会慢慢的变慢然后顶不住压力而挂掉(类似堵车)。并不是说并发越大越好,有的时候我们的项目规模和业务决定了我们不需要那么大的并发性,当大量的并发请求访问到服务器时我们需要把部分请求拒绝在外,这个是流量限制 - 限流。
熔断机制在在[《Spring Cloud 极简入门》)中有具体的表明,熔断机制是对服务调用链路的保护机制,如果链路上的某个服务不可访问,调用超时,发生异常等,服务会举行发熔断,触发降级返回托底数据。简单理解就是当服务器不可访问,可以返回一些预先准备好的兜底数据给用户,比如友爱的提示信息,不至于直接向客户抛出异常。
Hystrix的熔断和资源隔离
其着实[《Spring Cloud 极简入门》]中我们已经学习过Hystrix的熔断和资源隔离机制,它的资源隔离可以通过线程池隔离和信号量隔离两种方式来实现对流量的控制。Hystrix相比Sentinel来说它的线程池隔离(限流)会造成线程上下切换对资源的斲丧比较大;Hystrix利用的信号量举行资源的隔离效果不错,但是无法对慢调用举行自动降级。
Sentinel界说
Sentinel诞生于阿里巴巴,其重要目的是流量控制和服务熔断,2018年,Sentinel演变为一个开源项目现现在成为了Spring Cloud Alibaba的一个子项目。Sentinel是通过限制并发线程的数目来减少不稳固资源的影响,而不是利用线程池,省去了线程切换的性能开销。
当资源的响应时间变长时,线程将开始被占用。当线程数累积到肯定数目时,新的传入请求将被拒绝。反之亦然,当资源恢复并变得稳固时,占用的线程也将被开释,新请求将被接受。
除了限制并发性外,Sentinel可以根据响应时间降级不稳固资源也是包管可靠性的有效方法。当资源的响应时间太大时,将在指定的时间窗口中拒绝所有对该资源的访问。-- 熔断机制
别的,Sentinel支持的熔断降级维度更多,可对多种指标举行流控、熔断,且提供了实时监控和控制面板,功能更为强大。
Sentinel客户端接入
导入依靠
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
- </dependency>
复制代码 添加yml配置
- spring:
- cloud:
- sentinel:
- transport:
- dashboard: localhost:1111
复制代码 资源限流实现
在Controller中添加一个Sentinelresource注解
- @SentinelResource(value = "getUser",blockHandler = "LimitResource")
复制代码 value表示要举行限流的方法,blockHandler表示限流之后系统调用的方法
完整代码:
- @RefreshScope
- @RestController
- @RequestMapping("/user")
- public class UserController {
- @Value("${temp.notify}")
- private String notify;
- @Autowired
- private OrderOpenFeignClient feignClient;
- //限制的资源
- @SentinelResource(value = "getUser",blockHandler = "LimitResource")
- // 给资源取名user,后续通过名字来进行限流
- @GetMapping("/{id}")
- public User getUser(@PathVariable("id") Long id){
- //发起远程调用
- List<Order> orders =feignClient.getList(id);
- int i=new Random().nextInt(2);
- System.out.println(1/i);
- User user = new User(id,"root"+notify ,orders);
- return user;
- }
-
- public User LimitResource(@PathVariable("id") Long id,BlockException e){
- e.printStackTrace();
- return new User(-1L,"限流了",null);
- }
-
- }
复制代码 如何设置限流
在sentinel的当前页面,点击对应资源的流控按钮,举行流控计谋的配置。
这里单机阈值设置为1,表示1s内的访问量超过一次,则会触发限流效果。 系统便会实行本身设定的LimitResource方法,笔者这里便不附上运行截图了,配置十分简单,配置完成也不需要重启服务,直接举行接口访问压测即可。
Sentinel流控效果
快速失败
快速失败 RuleConstant.CONTROL_BEHAVIOR_DEFAULT)是默认的流控方式,当流量达到阀值直接返回异常,QPS达到任何规则阈值后,后续请求就会立即拒绝,并抛出FlowException 异常。简单理解:并发太高,直接请求拒绝
warmup预热
Warm Up预热 RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,根据codeFactor(默认3)的值,从(阀值/codeFactor)为初始阀值,经过预热时长,才到达设置的QPS的阀值,即预热/冷启动方式。简单理解:慢慢的增大处理并发的本领
排队等候
排队等候(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER),突然增加的请求并发量达到了限流阈值后续请求会被拒绝,偶然候我们大概更希望后续的请求可以参加队列举行排队,慢慢实行,而不是直接拒绝请求,这种方式后严酷控制请求通过的时间隔断,也即是让请求以匀称的速率通过,对应的是漏桶算法,这种方式重要用于处理隔断性突发的流量,例如消息队列。 简单理解:突发流量处理不过来,让请求排队。
Sentinel熔断
概述
什么是熔断
Sentinel除了流控还提供了服务熔断和降级机制,服务之间的调用关系错综复杂,微服务的调用链上的某些服务资源不稳固(宕机,异常,超时)大概会导致大概请求的失败和请求的堆积,调用链产生连锁反应大概会导致整个微服务架构瘫痪。服务熔断降级机制是保障高可用的重要措施之一。
Sentinel熔断
Sentinel的服务熔断机制会对调用链上的某个不稳固(宕机,异常,超时)的资源,做出请求限制,快速失败,避免影响到别的的服务而导致级联错误。资源熔断后,在后续的肯定时间(时间窗口)之内,对该服务的请求都自动熔断,抛出 DegradeException异常。Sentinel拥有比Hystrix更强大和丰富的功能,能满足我们的各种应用场景,并且经历过淘宝双十一的磨练,是微服务架构中熔断机制的不二选择。
熔断规则
均匀响应RT
均匀响应时间 (DEGRADE_GRADE_RT):当资源的均匀响应时间超过阈值(DegradeRule 中的 count,以 ms 为单位)之后,资源进入准降级状态。如果接下来 1s 内连续进入 5 个请求(即 QPS >= 5),它们的 RT 都连续超过这个阈值,那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作 4900 ms,若需要变更此上限可以通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置。
异常比例
异常比例(DEGRADE_GRADE_EXCEPTION_RATIO):每秒请求量 > 5 ,当资源的每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
异常数
异常数 (DEGRADE_GRADE_EXCEPTION_COUNT):当资源近 1 分钟的异常数目超过阈值之后会举行熔断。注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则竣事熔断状态后仍大概再进入熔断状态。
慢调用比例
熔断计谋慢调用比例是以慢调用数目的比例作为阈值,首先需要设置最大 RT(即最大的响应时间,用于鉴定是否是慢调用),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数大于设置的最小请求数,并且慢调用的比例大于比例阈值,则接下来的请求会自动熔断,熔断时间为设置的熔断时长。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若在HALF-OPEN状态下有一个请求响应时间小于 最大RT 则竣事熔断,否则继续熔断。
熔断实战示例
导入依靠
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-openfeign</artifactId>
- </dependency>
复制代码 配置yml
- feign:
- sentinel:
- enabled: true #熔断
复制代码 配置OpenFeign
接口
- @FeignClient(value = "Order-server")
- public interface OrderOpenFeignClient {
- @GetMapping("/order/{id}")
- public List<Order> getList(@PathVariable("id") Long id);
- }
复制代码 熔断返回fallback
- @Component
- public class UserFallBack implements FallbackFactory<OrderOpenFeignClient> {
- @Override
- public OrderOpenFeignClient create(Throwable throwable) {
- return id ->Arrays.asList(new Order(-2L,"服务暂时不可用","请您稍后再试"));
- }
- }
复制代码 修改Controller
在SentinelResource中添加相干属性值
Controller完整代码
- @RefreshScope
- @RestController
- @RequestMapping("/user")
- public class UserController {
- @Value("${temp.notify}")
- private String notify;
- @Autowired
- private OrderOpenFeignClient feignClient;
- //限制的资源
- @SentinelResource(value = "getUser",blockHandler = "LimitResource",blockHandlerClass = UserFallback.class,
- fallback = "Error")
- // 给资源取名user,后续通过名字来进行限流
- @GetMapping("/{id}")
- public User getUser(@PathVariable("id") Long id){
- //发起远程调用
- List<Order> orders =feignClient.getList(id);
- int i=new Random().nextInt(2);
- System.out.println(1/i);
- User user = new User(id,"root"+notify ,orders);
- return user;
- }
- //方案1
- // public User LimitResource(@PathVariable("id") Long id,BlockException e){
- // e.printStackTrace();
- // return new User(-1L,"限流了",null);
- // }
- public User Error(@PathVariable("id") Long id){
- return new User(-1L,"熔断数据集",null);
- }
- }
复制代码 因为在这里,写了一个Error方法,并且在SentinelResource中添加了fallback="Error"以是fallback返回的将是Error的内容。
测试效果:
写在末了:
SpringCloudAlibaba是一款优秀的微服务架构,在市面上有着广泛的应用。这篇文章介绍了SpringCloudAlibaba的一些根本利用,适合初学者,希望能够给各人带来帮助。笔者小,中,大厂均有面试履历,现在正在从事全栈开发工作,对峙逐日分享java全栈开发知识与相干的面试真题,希望能够给各人带来帮助,同各人共同进步
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |