【Springcloud】Sentinel熔断和降级

news2024/11/27 10:44:15

【Springcloud】Sentinel熔断和降级

  • 【一】基本介绍
    • 【1】什么是熔断和降级
    • 【2】为什么使用熔断和降级
    • 【3】Sentinel熔断和降级
    • 【4】核心概念
  • 【二】下载方式
    • 【1】Windows平台安装包下载
    • 【2】打开控制台
  • 【三】使用案例
    • 【1】添加依赖
    • 【2】添加Sentinel配置
    • 【3】添加TestUserController.java,模拟接口返回用户信息。
    • 【4】启动服务
  • 【四】定义资源
    • 【1】代码定义
    • 【2】属性说明
  • 【五】流量规则
    • 【1】控制台定义
    • 【2】代码定义
    • 【3】属性说明
  • 【五】降级规则
    • 【1】控制台定义
    • 【2】代码定义
    • 【3】属性说明
  • 【五】动态配置规则
    • 【1】文件配置规则
    • 【2】Nacos配置规则
  • 【六】RestTemplate 支持
  • 【七】RestTemplate 支持
    • 【1】添加依赖
    • 【2】feign开启sentinel支持
    • 【3】测试用户服务类RemoteUserService.java
    • 【4】降级用户服务类处理RemoteUserFallbackFactory.java
    • 【5】启动类扫描配置

【一】基本介绍

【1】什么是熔断和降级

服务的稳定是公司可持续发展的重要基石,随着业务量的快速发展,一些平时正常运行的服务,会出现各种突发状况,而且在分布式系统中,每个服务本身又存在很多不可控的因素,比如线程池处理缓慢,导致请求超时,资源不足,导致请求被拒绝,又甚至直接服务不可用、宕机、数据库挂了、缓存挂了、消息系统挂了…对于一些非核心服务,如果出现大量的异常,可以通过技术手段,对服务进行降级并提供有损服务,保证服务的柔性可用,避免引起雪崩效应。

(1)服务熔断
一般是指软件系统中,由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保护措施。

(2)服务降级
是在服务器压力陡增的情况下,利用有限资源,根据当前业务情况,关闭某些服务接口或者页面,以此释放服务器资源以保证核心任务的正常运行。

【2】为什么使用熔断和降级

在一个分布式系统里,一个服务依赖多个服务,可能存在某个服务调用失败,比如超时、异常等,需要保证在一个依赖出问题的情况下,不会导致整体服务失败。

【3】Sentinel熔断和降级

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性。

sentinel具有以下特征:
(1)丰富的应用场景
Sentinel承接了阿里巴巴近十年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围),消息削峰填谷,集群流量控制,实时熔断下游不可用应用等

(2)完美的实时监控
Sentinel同时提供实时的监控功能,您可以在控制台看到接入应用的单台机器秒级数据,甚至500台一下规模的集群的汇总运行情况

(3)广泛的开源生态
Sentinel提供开箱即用的与其他框架/库的整合模块,例如与SpringCloud,Dubbo,gRPC的整合,您只需要引入响应的依赖并进行简单的配置即可快速接入Sentinel

(4)完美的SPI扩展点
Sentinel提供简单易用的,完美的SPI扩展接口,可以通过实现扩展接口来快速定制逻辑,例如定制规则管理,适配动态数据源等

【4】核心概念

(1)核心库
不依赖任何框架/库,能够允许在jdk7以上的版本运行时环境,同时对Dubbo、SpringCloud等框架也有比较好的支持。

(2)控制台
主要负责管理推送规则、监控、集群限流分配管理、机器发现等。

【二】下载方式

注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。

【1】Windows平台安装包下载

可以从https://github.com/alibaba/Sentinel/releases下载sentinel-dashboard-$version.jar包。

使用如下命令启动控制台:

java -Dserver.port=8718 -Dcsp.sentinel.dashboard.server=localhost:8718 -Dproject.name=sentinel-dashboard -Dcsp.sentinel.api.port=8719 -jar D:\sentinel\sentinel-dashboard-1.8.0.jar

其中-Dserver.port=8718用于指定Sentinel控制台端口为8718,F:\software\sentinel\sentinel-dashboard-1.8.0.jar为下载的包路径地址。

如果觉得官网下载慢,可以使用我分享的网盘地址: https://pan.baidu.com/s/1E9J52g6uW_VFWY34fHL6zA 提取码: vneh

【2】打开控制台

Sentinel提供了一个可视化的操作平台,安装好之后,在浏览器中输入(http://localhost:8718 (opens new window))就可以访问了,默认的用户名和密码都是sentinel(我使用的是1.8.0版本)
在这里插入图片描述

【三】使用案例

【1】添加依赖

<!-- springcloud alibaba sentinel -->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<!-- SpringBoot Web -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

【2】添加Sentinel配置

spring: 
  application:
    # 应用名称
    name: ruoyi-xxxx 
  cloud:
    sentinel:
      # 取消控制台懒加载
      eager: true
      transport:
        # 控制台地址
        dashboard: 127.0.0.1:8718

【3】添加TestUserController.java,模拟接口返回用户信息。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestUserController
{
    @GetMapping("/user/info")
    public Object info()
    {
        return "{\"username\":\"admin\",\"password\":\"admin123\"}";
    }
}

【4】启动服务

查看Sentinel控制台的请求数据

【四】定义资源

资源是Sentinel中的核心概念之一。我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。最常用的资源是我们代码中的Java方法。Sentinel提供了@SentinelResource注解用于定义资源,并提供了AspectJ的扩展用于自动定义资源、处理BlockException等。

【1】代码定义

@SentinelResource用于定义资源,并提供可选的异常处理和fallback配置项。

接口定义IUserService.java

/**
 * 用户接口
 * 
 * @author ruoyi
 */
public interface IUserService
{
    public Object selectUserByName(String username);
}

接口实现IUserServiceImpl.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;

/**
 * 用户实现
 * 
 * @author ruoyi
 */
@Service
public class IUserServiceImpl implements IUserService
{
    @Autowired
    private RestTemplate restTemplate;

    @Bean
    public RestTemplate restTemplate()
    {
        return new RestTemplate();
    }

    @SentinelResource(value = "selectUserByName", blockHandler = "selectUserByNameBlockHandler", fallback = "selectUserByNameFallback")
    @Override
    public Object selectUserByName(String username)
    {
        return restTemplate.getForObject("http://localhost:9201/user/info/" + username, String.class);
    }

    // 服务流量控制处理,参数最后多一个 BlockException,其余与原函数一致。
    public Object selectUserByNameBlockHandler(String username, BlockException ex)
    {
        System.out.println("selectUserByNameBlockHandler异常信息:" + ex.getMessage());
        return "{\"code\":\"500\",\"msg\": \"" + username + "服务流量控制处理\"}";
    }

    // 服务熔断降级处理,函数签名与原函数一致或加一个 Throwable 类型的参数
    public Object selectUserByNameFallback(String username, Throwable throwable)
    {
        System.out.println("selectUserByNameFallback异常信息:" + throwable.getMessage());
        return "{\"code\":\"500\",\"msg\": \"" + username + "服务熔断降级处理\"}";
    }

}

测试接口请求TestUserController.java

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.RestController;

@RestController
public class TestUserController
{
    @Autowired
    private IUserService userService;

    @GetMapping("/info/{username}")
    public Object info(@PathVariable("username") String username)
    {
        return userService.selectUserByName(username);
    }
}

【2】属性说明

@SentinelResource注解包含以下属性:

value:资源名称,必需项(不能为空)
entryType:资源调用方向,可选项(默认为EntryType.OUT)
resourceType:资源的分类
blockHandler:对应处理BlockException的函数名称
blockHandlerClass:处理类的Class对象,函数必需为static函数
fallback:用于在抛出异常的时候提供fallback处理逻辑
defaultFallback:用作默认的回退的方法
fallbackClass:异常类的Class对象,函数必需为static函数
exceptionsToTrace:异常类跟踪列表(默认为Throwable.class)
exceptionsToIgnore:排除掉的异常类型

注意:注解方式埋点不支持 private 方法。

【五】流量规则

【1】控制台定义

选择流控规则,新增流控规则,填入对应信息
在这里插入图片描述

(1)资源名: 唯一名称,默认请求路径
(2)针对来源: Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
(3)阈值类型/单机阈值:
1-QPS(每秒请求数量):当调用该api的QPS达到阈值的时候,进行限流
2-线程数:当调用该api的线程数达到阈值的时候,进行限流
(4)是否集群: 不需要集群
(5)流控模式:
1-直接:api达到限流条件时,直接限流
2-关联:当关联的资源达到限流阈值时,就限流自己
3-链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到峰值,就进行限流)【api级别的针对来源】
(6)流控效果:
1-快速失败:直接失败,抛异常
2-Warm Up:根据coldFactor(冷加载因子,默认3)的值,从阈值/coldFactor,经过预热时长,才达到设置的QPS阈值
3-排队等待:匀速排队,让请求以匀速通过,阈值类型必须设置为QPS,否则无效

【2】代码定义

理解上面规则的定义之后,我们可以通过调用FlowRuleManager.loadRules()方法来用硬编码的方式定义流量控制规则,比如:

private void initFlowQpsRule() {
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule(resourceName);
    // set limit qps to 20
    rule.setCount(20);
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule.setLimitApp("default");
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}

【3】属性说明

流量控制规则(FlowRule)重要属性

resource:资源名,资源名是限流规则的作用对象
limitApp:流控针对的调用来源,若为 default 则不区分调用来源 default,代表不区分调用来源
grade:限流阈值类型,QPS 模式(1)或并发线程数模式(0) QPS 模式
count:限流阈值
strategy:调用关系限流策略:直接、链路、关联 根据资源本身(直接)
controlBehavior:流量控制效果(直接拒绝、Warm Up、匀速排队) 直接拒绝
clusterMode:是否集群限流 否

同一个资源可以同时有多个限流规则,检查规则时会依次检查。

从1.6.3版本开始,Sentinel Web filter默认收敛所有URL的入口context,因此链路限流不生效。1.7.0版本开始(对应SCA 2.1.1.RELEASE),我们在CommonFilter引入了WEB_CONTEXT_UNIFY这个init parameter,用于控制是否收敛context。将其配置为false即可根据不同的URL进行链路限流。 参考:https://github.com/alibaba/sentinel/issues/1213

【五】降级规则

现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。

【1】控制台定义

选择降级规则,新增降级规则,填入对应信息。

在这里插入图片描述

【2】代码定义

private void initDegradeRule() {
    List<DegradeRule> rules = new ArrayList<>();
    DegradeRule rule = new DegradeRule();
    rule.setResource(KEY);
    // set threshold RT, 10 ms
    rule.setCount(10);
    rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
    rule.setTimeWindow(10);
    rules.add(rule);
    DegradeRuleManager.loadRules(rules);
}

【3】属性说明

熔断降级规则(DegradeRule)重要属性

resource:资源名,即规则的作用对象
grade:熔断策略,支持慢调用比例/异常比例/异常数策略 慢调用比例
count:慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
timeWindow:熔断时长,单位为 s
minRequestAmount:熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入) 5
statIntervalMs:统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入) 1000 ms
slowRatioThreshold:慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)

同一个资源可以同时有多个降级规则。

【五】动态配置规则

上面的规则配置,都是存在内存中的。即如果应用重启,这个规则就会失效,可以整合动态配置系统,如ZooKeeper、Nacos、Apollo等,动态地实时刷新配置规则。

【1】文件配置规则

Sentinel支持通过本地文件加载规则配置,使用方式如下(限流规则作为演示)

spring:
  cloud:
    sentinel:
      datasource:
        ds1:
          file:
            file: classpath:flowRule.json
            data-type: json
            rule-type: flow

flowRule.json对应com.alibaba.csp.sentinel.slots.block.flow.FlowRule各属性。

[
  {
    "resource": "selectUserByName",
    "count": 1,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0,
    "controlBehavior": 0
  }
]

【2】Nacos配置规则

当sentinel重新启动时,sentinel dashboard中原来的数据将会全部消失,这样就需要重新定义限流规则,无疑是不可取的。所以需要将sentinel中定义的限流规则保存到配置中心里面。

具体的实现方法如下:
(1)在nacos中定义自定义限流策略sentinel-ruoyi-xxxx

[
  {
    "resource": "selectUserByName",
    "count": 2,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0,
    "controlBehavior": 0
  }
]

(2)添加依赖

<!-- springcloud alibaba nacos config -->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

<!-- sentinel datasource nacos -->
<dependency>
	<groupId>com.alibaba.csp</groupId>
	<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

(3)添加相关配置,sentinel下面的dataSource中配置nacos

spring: 
  application:
    # 应用名称
    name: ruoyi-xxxx 
  cloud:
    nacos:
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
    sentinel:
      # 取消控制台懒加载
      eager: true
      transport:
        # 控制台地址
        dashboard: 127.0.0.1:8718
      # nacos配置持久化
      datasource:
        ds1:
          nacos:
            server-addr: 127.0.0.1:8848
            dataId: sentinel-ruoyi-gateway
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

(4)启动sentinel应用,可以看到我们在nacos中配置的限流规则

【六】RestTemplate 支持

Spring Cloud Alibaba Sentinel支持对RestTemplate调用的服务进行服务保护。需要在构造RestTemplate Bean时添加@SentinelRestTemplate注解。

RestTemplate添加@SentinelRestTemplate注解保护支持。

@Bean
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class, fallback = "fallback", fallbackClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
	return new RestTemplate();
}

服务熔断处理类ExceptionUtil.java,必须使用静态方法。

import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpResponse;

public class ExceptionUtil
{
    // 服务流量控制处理
    public static ClientHttpResponse handleException(HttpRequest request, byte[] body,
            ClientHttpRequestExecution execution, BlockException exception)
    {
        exception.printStackTrace();
        return new SentinelClientHttpResponse("{\"code\":\"500\",\"msg\": \"服务流量控制处理\"}");
    }

    // 服务熔断降级处理
    public static ClientHttpResponse fallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution,
            BlockException exception)
    {
        exception.printStackTrace();
        return new SentinelClientHttpResponse("{\"code\":\"500\",\"msg\": \"服务熔断降级处理\"}");
    }
}

【七】RestTemplate 支持

其实不管是Hystrix还是Sentinel对于Feign的支持,核心代码基本上是一致的,只需要修改依赖和配置文件即可。

【1】添加依赖

<!-- SpringCloud Alibaba Nacos -->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!-- spring cloud openfeign 依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

【2】feign开启sentinel支持

spring: 
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
		
feign:
  sentinel:
    enabled: true

【3】测试用户服务类RemoteUserService.java

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * 用户服务
 * 
 * @author ruoyi
 */
@FeignClient(contextId = "remoteUserService", value = "ruoyi-system", fallbackFactory = RemoteUserFallbackFactory.class)
public interface RemoteUserService
{
    /**
     * 通过用户名查询用户信息
     *
     * @param username 用户名
     * @return 结果
     */
    @GetMapping(value = "/user/info/{username}")
    public Object getUserInfo(@PathVariable("username") String username);
}

【4】降级用户服务类处理RemoteUserFallbackFactory.java

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import feign.hystrix.FallbackFactory;

/**
 * 用户服务降级处理
 * 
 * @author ruoyi
 */
@Component
public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserService>
{
    private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class);

    @Override
    public RemoteUserService create(Throwable throwable)
    {
        log.error("用户服务调用失败:{}", throwable.getMessage());
        return new RemoteUserService()
        {
            @Override
            public Object getUserInfo(String username)
            {
                return "{\"code\":\"500\",\"msg\": \"用户服务熔断降级处理\"}";
            }
        };
    }
}

【5】启动类扫描配置

@EnableFeignClients(basePackages = "com.ruoyi")

创建的类需要在resources\META-INF下的spring.factories配置加载自动装配类

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  .....
  com.ruoyi.system.api.factory.RemoteUserFallbackFactory

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/978182.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络类型+二层封装技术

一、网络类型分类 1、点到点网络 在一个网段中&#xff0c;只能部署两个节点&#xff08;两个IP&#xff09;&#xff0c;如GRE环境就属于虚拟的点到点网络类型&#xff0c;通常是串线连接。 如下图当前只存在两个节点&#xff0c;但并不是点到点&#xff0c;因为它中间网段…

简易版人脸识别qt opencv

1、配置文件.pro #------------------------------------------------- # # Project created by QtCreator 2023-09-05T19:00:36 # #-------------------------------------------------QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsTARGET 01_face TEMP…

【trie树】CF Edu12 E

Problem - E - Codeforces 题意&#xff1a; 思路&#xff1a; 这其实是一个套路题 区间异或转化成前缀异或&#xff0c;然后枚举 i 对于每一个 i&#xff0c;ai ^ x k&#xff0c;对 x 计数 先建一棵字典树&#xff0c;然后在字典树上计数 先去对 > k 的部分计数&a…

m8130kt GPS模块测试

m8130kt GPS模块测试 ✨在某宝捡电子垃圾&#xff0c;10块钱的价格&#xff0c;就是没有资料可以提供的。上面携带有u-blox UBX-M8130-KT芯片&#xff0c;是肯定的&#xff0c;至于HMC5883芯片不确定&#xff0c;拆了屏蔽罩&#xff0c;芯片实在是太小&#xff0c;使用40倍放大…

SpringCloud实战项目(1)---创建空项目 jdk17

创建空项目 New ProjectAdd Jdk17创建空白标准Maven项目不要选择Create from archetype选项填写相关项目信息创建项目得到一个标准的maven项目&#xff0c;作为一个Parent project存在的&#xff0c;需删除src文件夹。 New Project 使用Idea, File -> New ->Project Add …

语音特征提取与预处理

导入相关包 import librosa import librosa.display import soundfile as sf import numpy as np import matplotlib.pyplot as plt from playsound import playsound 语音读取与显示 file_path test1.wav data, fs librosa.load(file_path, srNone, monoTrue) librosa.d…

word如何插入图片?3种常用的方法

word作为一款常用的办公软件&#xff0c;不仅可以处理文本内容&#xff0c;还能够轻松地插入图片以丰富文档内容。插入图片可以使文档更具吸引力、可读性和信息传达能力。本文将为您介绍word如何插入图片的3种方法&#xff0c;帮助您在文档中灵活、高效地添加图像元素。 word插…

SLAM从入门到精通(矩阵的使用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 学习SLAM&#xff0c;离开了矩阵肯定是玩不转的。大学数学里面除了微积分&#xff0c;剩下的就是线性代数和概率论。而矩阵就是线性代数的一部分。…

selenium 动态爬取页面使用教程以及使用案例

Selenium 介绍 概述 Selenium是一款功能强大的自动化Web浏览器交互工具。它可以模拟真实用户在网页上的操作&#xff0c;例如点击、滚动、输入等等。Selenium可以爬取其他库难以爬取的网站&#xff0c;特别是那些需要登录或使用JavaScript的网站。Selenium可以自动地从Web页面…

在多机多卡训练时,保存的文件无法读取,报错文件已经损坏

问题描述&#xff1a;多机多卡训练保存了optimizer.pt文件&#xff0c;但是该文件在被读取时显示已经损坏。 原来的报错&#xff1a; Traceback (most recent call last):File "/mnt/petrelfs/tongjingqi/train-moe/smoe/entrypoint/cpt_fpt.py", line 280, in <…

Android Aidl跨进程通讯(三)--进阶使用

学更好的别人&#xff0c; 做更好的自己。 ——《微卡智享》 本文长度为2478字&#xff0c;预计阅读6分钟 前言 Android的AIDL使用和异常报错都已经介绍过了&#xff0c;今天这篇还是在原来的Demo基础上加入几个AIDL的进阶使用方法。 】 AIDL进阶使用 微卡智享 in,out,inout的使…

定时线程池原理解析

基本使用 ScheduledThreadPoolExecutor继承自ThreadPoolExecutor。它主要用来在给定的延迟之后运行任务&#xff0c;或者定期执行任务。 public class ScheduledThreadPoolExecutorTest {public static void main(String[] args) {ScheduledThreadPoolExecutor threadPoolExecu…

QT DAY7

主要完成多人聊天室&#xff0c;注册与登录使用sql3数据库进行对密码的保存&#xff0c;避免了用户重复登录、错误密码登录、重复注册的问题&#xff0c;之后使用TCP通信&#xff0c;连接上服务器后可在聊天室多人交流

怎么处理zk或redis脑裂

很极端场景会出现脑裂 什么是分布式的脑裂 怎么理解zk脑裂 就是ZK&#xff0c;与客户端可能因为网络原因&#xff0c;客户端A还在跑着后续程序&#xff0c;而zk与客户端之前的心跳断了&#xff0c;此zk就把这节点给删除了&#xff0c;这时另一个客户会加锁成功&#xff0c;就样…

[Java]异常

目录 1.异常的概念与体系结构 1.1异常的概念 1.1.1算术异常 1.1.2数组越界异常 1.1.3空指针异常 1.2异常的体系结构 1.3异常的分类 2.异常的处理 2.1 防御式编程 2.2异常的抛出 2.3异常的捕获 2.3.1 异常声明throws 将光标放在抛出异常方法上&#xff0c;alt Insert …

咖啡店小程序:吸引顾客的创新营销手段

近日&#xff0c;“酱香拿铁”的大火让大家再次把目标聚焦在年轻人都喜欢的咖啡上。现在咖啡已经成为年轻一代的社交硬通货&#xff0c;咖啡店也遍地开花。而随着移动互联网的快速发展&#xff0c;咖啡店小程序已经成为了各大咖啡店主的选择&#xff0c;因为它提供了便捷的方式…

【Leetcode-面试经典150题-day22】

目录 97. 交错字符串 97. 交错字符串 题意&#xff1a; 给定三个字符串 s1、s2、s3&#xff0c;请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 两个字符串 s 和 t 交错 的定义与过程如下&#xff0c;其中每个字符串都会被分割成若干 非空 子字符串&#xff1a; s s1 s2 …

便捷、快速、稳定、高性能!以 GPU 实例演示 Alibaba Cloud Linux 3 对 AI 生态的支持 | 龙蜥技术

编者按&#xff1a;日前&#xff0c;Alibaba Cloud Linux 3 为使 AI 开发体验更高效&#xff0c;提供了一些优化升级&#xff0c;本文为“Alibaba Cloud Linux 3 AI 能力介绍”系列文章预告篇&#xff0c;以 GPU 实例为例&#xff0c;为大家演示 Alibaba Cloud Linux 3 对 AI 生…

Vue + Element UI 前端篇(五):国际化实现

Vue Element UI 实现权限管理系统 前端篇&#xff08;五&#xff09;&#xff1a;国际化实现 国际化支持 1.安装依赖 执行以下命令&#xff0c;安装 i18n 依赖。 yarn add vue-i18n $ yarn add vue-i18n yarn add v1.9.4 warning package-lock.json found. Your project …

数据分析必知的统计知识——区间估计(其四)

4. 区间估计 还以为你被上节课的内容唬住了~终于等到你&#xff0c;还好没放弃&#xff01; 本节我们将说明两个问题&#xff1a;总体均值 μ \mu μ 的区间估计和总体比例 p ˉ \bar{p} pˉ​ 的区间估计。 区间估计经常用于质量控制领域来检测生产过程是否正常运行或者在…