当前位置: 首页 > article >正文

Sentinel源码—1.使用演示和简介二

大纲

1.Sentinel流量治理框架简介

2.Sentinel源码编译及Demo演示

3.Dashboard功能介绍

4.流控规则使用演示

5.熔断规则使用演示

6.热点规则使用演示

7.授权规则使用演示

8.系统规则使用演示

9.集群流控使用演示

5.熔断规则使用演示

(1)案例说明熔断和降级

(2)Sentinel Dashboard中熔断规则的配置项

(3)熔断策略之慢调用比例

(4)熔断策略之异常比例和异常数

(1)案例说明熔断和降级

一.熔断

假设电商平台有多个库存服务实例,用于处理商品库存查询。有一个库存服务实例可能由于网络问题等原因而变得不稳定,为了避免该库存服务实例异常而影响整个服务,可以对该实例实施熔断。

在这种情况下,可以设定一个阈值。如果在一段时间内发现对该库存服务实例的请求有50%+是失败的,那么会触发熔断器,在一段时间内停止对该库存服务实例进行调用。这样这个异常的库存服务实例便不会影响到商品的库存查询业务了。

二.降级

假设电商平台有个商品推荐功能,它会根据用户浏览记录推荐相关商品。在大促期间,平台可能会遭受巨大流量冲击,导致服务响应时间变慢。为了避免影响核心功能,可以在高峰期间对商品推荐功能进行降级。这意味着系统只会提供基本的商品推荐,而不会使用复杂的推荐算法。这样虽然会降低用户体验,但可以确保平台的核心功能仍然可用。

通过熔断和降级机制,系统可以在节点不稳定或高负载情况下保持稳定。从而避免系统崩溃或性能下降,这是分布式系统中流量治理的重要实践。

熔断和降级往往都是结合一起使用的。针对单节点进行熔断的时候,适合单独使用熔断规则。针对所有节点进行熔断的时候,适合熔断 + 降级一起使用。

假设整个库存查询服务都出了问题,各个服务实例都触发了熔断。这时就可以考虑结合降级策略,确保系统依然能够提供基本的功能。

比如在库存查询的情况下,可选择的降级方案有:

方案一:降级到可靠介质

可以将查询库存的请求切换到查询备份数据库或其他可靠介质,这样虽然可能会降低性能,但仍然可以为用户提供基本的服务。

方案二:降级到限流方法

可以实施限流,即控制并发请求数,以避免过多的请求加重故障状况。例如实现一个每秒只允许处理一定数量的库存查询请求的方法,从而保护系统免受过载的影响。

(2)Sentinel Dashboard中熔断规则的配置项

资源名:就是通过SphU.entry("xxx")或@SentinelResource("xxx")定义的名称。

熔断策略:比如慢调用比例、异常比例、异常数。

最大RT:RT就是Response Time,即响应时间。当熔断策略为慢调用比例时会出现此选项,其他两种策略不会显示此选项,也就是当请求时间超出多少RT后会进行熔断。

比例阈值:当熔断策略配置慢调用比例时,该值为慢调用占所有请求的比例上限。当熔断策略配置异常比例时,该值为请求异常所占比例的上限。取值范围:0.0 ~ 1.0,小数其实就是百分比。比如配置0.1,则为10%,最大为1.0,也就是100%。

异常数:当熔断策略选择异常数时才会出现异常数选项,含义就是请求的异常数量。值得注意的是:Sentinel中异常降级的统计是仅针对业务异常,而Sentinel本身的异常也就是BlockException是不生效的。比如触发流控报异常了,那么是不会统计到异常数当中。

熔断时长:当达到熔断阈值后,会进入熔断状态。超出配置的熔断时长后会恢复到Half Open状态。也就是说当超出熔断时长后不会立即恢复,而是看新进入的请求是否正常。如果还是不正常,则继续熔断,反之恢复。

最小请求数:请求数目大于该值时才会根据配置的熔断策略进行降级。比如配置该值为10 ,但是请求一共才3个。那么即使比例阈值设置的100% ,熔断策略也不会生效的,因为没达到最小请求数。

统计时长:就是统计慢调用比例、异常比例、异常数时的时长。

(3)熔断策略之慢调用比例

慢调用比例,就是一个用于度量系统中慢速或延迟调用所占比例的指标。即在一定时间窗口内,慢速调用的数量与总调用数量的比例。

例如在过去的10秒内(统计时长),系统总共处理了100个调用,其中有10个调用的响应时间超过了1000毫秒(最大RT),那么慢调用比例就是10%。

下面的配置要达到的效果是:当资源testSlowCall在10秒(统计时长)内请求数达10个(最小请求数)以上,且响应时长超过1秒(最大RT)的请求数量大于1(10 * 0.1)个时进行熔断,熔断5秒后资源testSlowCall会变成Half Open状态。即5秒后的第一个请求如果没有问题则恢复正常,否则继续熔断。

同时针对上述配置会新增一个接口如下:即提供一个RT为3s的接口。接下来就可以实现慢调用比例的效果了,只需要在10s内(统计时长)请求testSlowCall资源10次(最小请求数)即可。由于第10次请求时发现RT已超1s,此时就会触发熔断并熔断时长为5s。这次请求被熔断后就不会进入主方法了,会直接返回默认的异常页。

@GetMapping("testSlowCall")
@SentinelResource(value = "testSlowCall")
public String testSlowCall() throws InterruptedException {//业务逻辑处理TimeUnit.SECONDS.sleep(3000);return "ok";
}

当然,被熔断后也可以通过@SentinelResource指定执行自定义的方法。其中@SentinelResource注解的fallback属性,就能指定执行自定义方法。但该属性有很多限制,比如其方法必须和接口在同一个类中等。

@GetMapping("testSlowCall")
@SentinelResource(value = "testSlowCall", fallback = "testSlowCallFallback")
public String testSlowCall() throws InterruptedException {// select dbTimeUnit.SECONDS.sleep(3);return "ok";
}public String testSlowCallFallback() {//降级return "fallBack";
}

(4)熔断策略之异常比例和异常数

这里的异常指业务异常,不包括Sentinel的流控异常BlockedException。

一.异常比例

下面为了测试异常比例的熔断策略创建一个接口,这个接口的资源名为testErrorRate,降级方法为testErrorRateFallback。

@GetMapping("testErrorRate")
@SentinelResource(value = "testErrorRate", fallback = "testErrorRateFallback")
public String testErrorRate(Integer id) {if (null == id) {throw new NullPointerException("id is null");}return "ok";
}public String testErrorRateFallback(Integer id) {//降级return "fallBack";
}

这个接口的熔断规则如下:当10秒(统计时长)内达到10个请求(最小请求数)以上,而且请求异常比例超过20%时,就会触发熔断并熔断时长为5秒。熔断5秒后资源testErrorRate会变成Half Open状态。即5秒后的第一个请求如果没有问题则恢复正常,否则就继续熔断。

二.异常数

异常数就是在单位时间内超出错误数则触发熔断,和异常比例唯一不同的就是异常比例是计算百分比,而异常数是直接计算错误数量。

(5)总结

一.熔断策略总结

策略一:慢调用比例

衡量在一定时间内,响应时间超过阈值的调用占总调用数量的比例。比如在一分钟内,有10%的调用响应时间超过1秒。

策略二:异常比例

衡量在一定时间内,发生异常的调用占总调用数量的比例。比如在一小时内,有5%的调用发生异常。

策略三:异常数

计算在一定时间内发生的异常调用的绝对数量。例如,过去一天中,发生了100次调用异常。

二.实际应用场景总结

一个在线支付系统有一个接口用于处理支付请求:

场景一:慢调用比例

过去10分钟内有20%的支付请求的响应时间超过了3秒,超过预设的阈值。

场景二:异常比例

在过去一小时内,有2%的支付请求发生了异常,可能是由于网络问题或支付平台故障引起的。

场景三:异常数

昨天共有30次支付请求发生了异常,可能是由于无效的订单号或者连接超时导致的。

6.热点规则使用演示

(1)参数限流的意思

(2)参数限流的实战

(1)参数限流的意思

传统的流量控制,一般是通过资源维度来限制某接口或方法的调用频率。但有时需要更细粒度地控制不同参数条件下的访问速率,即参数限流。

参数限流允许根据不同的参数条件设置不同的流量控制规则,这种方式非常适合处理特定条件下的请求,能更加精细地管理流量。

场景一:假设有一个在线电影订票系统,某个接口允许用户查询电影的放映时间。但只希望每个用户每10秒只能查询接口1次,以避免过多的查询请求。这时如果直接将接口的QPS限制为5是不能满足要求的。因为需求是每个用户每5分钟只能查询1次,而不是每秒一共只能查询5次。

因此可以使用参数限流设置一个规则,根据用户ID来限制每个用户的查询频率。将限流的维度从资源维度细化到参数维度,从而实现每个用户每10秒只能查询接口1次。

场景二:一个SAAS服务/中台服务,希望能根据不同的商家/业务方来做限流规则。比如规模大的商家/业务方,允许调用的QPS是1000,而小的只能是50。

(2)参数限流的实战

下面实现每个用户每10秒只能查询一次电影票信息,首先在pom.xml添加依赖:

<!-- 可以使用热点参数限流功能 -->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-parameter-flow-control</artifactId><version>1.8.6</version>
</dependency>

然后新增一个接口:

@RestController
@RequestMapping("/hotKey")
public class TestHotKeyController {@GetMapping("/testMovieTicket")@SentinelResource(value = "testMovieTicket", fallback = "testMovieTicketFallback")public String testMovieTicket(String userId, Integer movieId) {return "testMovieTicketSuccess";}public String testMovieTicketFallback(String userId, Integer movieId) {return "testMovieTicketFail";}
}

接着针对该接口配置如下规则:相同参数值(第一个参数)每隔10秒只能请求一次。

新增热点规则之后,就可以对热点规则进行编辑。在编辑框里,提供了高级选项进行进一步的选择。

假如希望影院工作人员可以每秒查询10次,老板可以每秒查询100次,而购票者则只能每10秒查询一次。其中工作人员的userId值为100和200,老板的userId值为9999。那么可以如下配置:注意限流阈值是以秒为单位的,需要乘以统计窗口时长10。

(3)总结

参数限流允许基于不同参数条件来限制不同请求的访问速率。在实际应用中,参数限流可以适用于各种场景。例如秒杀系统、订票系统、广告点击等。通过合理设置参数限流规则,可以有效地保护系统免受过多请求的影响。

7.授权规则使用演示

(1)授权规则的核心概念

(2)授权规则的实战

(1)授权规则的核心概念

有时只允许特定用户或IP地址才能访问系统,这时可以使用Sentinel的授权规则(黑白名单)功能。授权规则功能有两个核心概念:黑名单和白名单。

一.黑名单

一种限制性授权规则,用于限制某些用户、操作或资源的访问权限。

二.白名单

一种授予性授权规则,允许特定用户、操作或资源访问受限制的功能。

授权规则适用的场景:

场景一:用户身份认证

当用户登录系统时,系统会验证其身份,确保用户是合法用户。例如,只有登录的管理员才能发布新的电影信息。

场景二:角色和权限分配

系统会为不同角色的用户分配不同的权限。例如,管理员可管理电影信息,编辑可编辑但不能发布,访客只能浏览。

场景三:操作访问控制

某些操作可能只能被特定角色的用户执行。例如,只有管理员可以删除电影信息。

场景四:数据保护

系统需要保护敏感数据,确保只有授权的用户可以访问。例如,用户只能访问自己的个人信息。

场景五:安全访问

限制只有特定用户或特定IP地址可以访问系统,防止恶意用户或恶意IP地址对系统进行攻击或滥用资源。

(2)授权规则的实战

首先需要定义授权规则,Sentinel授权规则配置类是AuthorityRule。因此自己定义一个类,初始化Sentinel授权规则配置,代码如下:

这里没有借助Sentinel Dashboard来配置规则,而是通过代码方式实现。配置规则并不一定要借助Sentinel Dashboard,通过代码也可以完成。如下代码就设置了一个白名单策略,且白名单的值只能是user1或user2。这意味着只有user1和user2这两个用户才能访问"authority-demo"资源。

@Component
public class SentinelAuthorityRule {@PostConstructpublic void init() {doInit();}private void doInit() {//定义资源名称String resource = "authority-demo";//定义授权规则,此类为 Sentinel 内部类,并非自己定义的AuthorityRule rule = new AuthorityRule();rule.setResource(resource);//白名单rule.setStrategy(RuleConstant.AUTHORITY_WHITE);//限制user1/user2能访问rule.setLimitApp("user1,user2");//注册授权规则AuthorityRuleManager.loadRules(Collections.singletonList(rule));}
}

当然,对应于Sentinel Dashboard中进行授权规则配置如下:

接着添加接口应用授权规则:

@RestController
@RequestMapping("/sentinelAuthority")
public class SentinelAuthorityController {//资源名称private static final String RESOURCE_NAME = "authority-demo";//userId此处当参数传递仅仅是为了模拟,实际生产环境中还需符合自身公司规范,比如放到header里,从header获取等@GetMapping("/demo")public String demo(String userId) {//进行授权规则验证ContextUtil.enter(RESOURCE_NAME, userId);Entry entry = null;try {entry = SphU.entry(RESOURCE_NAME);//执行业务逻辑return "ok";} catch (BlockException ex) {//授权验证未通过//处理授权验证失败的逻辑return "fail";} finally {if (entry != null) {entry.exit();}}}
}

最后启动服务进行验证便可发现:

http://localhost:19966/sentinelAuthority/demo?userId=user1返回ok;
http://localhost:19966/sentinelAuthority/demo?userId=user2返回ok;
http://localhost:19966/sentinelAuthority/demo?userId=user3返回fail;

8.系统规则使用演示

(1)什么是系统规则

(2)系统规则实战

(1)什么是系统规则

系统规则是针对整个系统进行流量控制的,是操作系统级别或服务器级别的,不是应用级别或资源级别的。一台服务器可以部署很多应用(资源),虽然可为每个资源设置流控规则,但是服务器也可能被压爆。如果因为一个服务导致服务器垮了,那么也会对其他服务产生影响。所以,服务器本身也需要可靠性,也需要做一些流控规则配置。比如入口QPS阈值指的是当前服务器上所有接口的入口流量。

它提供多种阈值类型,当触发这些阈值时,系统便会拒绝新的流量请求。

一.Load(负载)阈值

Load阈值可以限制系统的负载。当系统负载过高时,限制新的请求进入系统,以避免系统崩溃。

应用场景: 电商平台在大促活动期间,大量用户涌入平台使得系统资源紧张。此时可以使用设置Load阈值,当系统负载过高时,限制新请求进入系统。

二.RT(平均响应时间)阈值

RT阈值可限制系统的平均响应时间,即请求从接收到响应的平均耗时,RT高可能表示系统负载或性能存在问题。

应用场景:在一个即时消息应用中,确保用户能及时收到消息非常重要。此时可以设置RT阈值,限制消息接口的平均响应时间,保障用户体验。

三.线程数阈值

线程数阈值可限制系统的并发线程数,避免过多线程竞争资源影响性能。

应用场景:在一个高并发的在线游戏中,每个用户都可能占用一个独立线程。此时可以设置线程数阈值,限制并发线程数,避免过多的线程占用资源。

四.入口QPS(每秒查询数)阈值

入口QPS阈值用于限制所有接口的入口流量,防止短时间内大量请求涌入。

应用场景: 在一个热门的抢购活动中,用户可能频繁刷新页面以获取商品信息。可以使用入口QPS阈值,限制商品详情接口的访问频率。

五.CPU使用率阈值

CPU使用率阈值用于限制系统的CPU使用率,避免CPU负载过高。

应用场景:在一个图像渲染应用中,每个任务需要大量计算资源。可以设置CPU使用率规则,限制渲染任务的CPU使用率。

(2)系统规则实战

如下是官网的Demo:通过系统规则管理类SystemRuleManager加载initSystemRule()的阈值。一旦超出initSystemRule()中配置的阈值,新进来的请求将被直接拒绝。

package com.alibaba.csp.sentinel.demo.system;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import com.alibaba.csp.sentinel.util.TimeUtil;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;public class SystemGuardDemo {private static AtomicInteger pass = new AtomicInteger();private static AtomicInteger block = new AtomicInteger();private static AtomicInteger total = new AtomicInteger();private static volatile boolean stop = false;private static final int threadCount = 100;private static int seconds = 60 + 40;public static void main(String[] args) throws Exception {//打印测试结果tick();//初始化系统规则配置initSystemRule();//启动多线程进行测试for (int i = 0; i < threadCount; i++) {Thread entryThread = new Thread(new Runnable() {@Overridepublic void run() {while (true) {Entry entry = null;try {entry = SphU.entry("methodA", EntryType.IN);pass.incrementAndGet();try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {}} catch (BlockException e1) {block.incrementAndGet();try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {}} catch (Exception e2) {} finally {total.incrementAndGet();if (entry != null) {entry.exit();}}}}});entryThread.setName("working-thread");entryThread.start();}}//初始化系统规则配置private static void initSystemRule() {List<SystemRule> rules = new ArrayList<SystemRule>();SystemRule rule = new SystemRule();//max load is 3,系统最高负载为3.0rule.setHighestSystemLoad(3.0);//max cpu usage is 60%,系统CPU最大使用率为60%rule.setHighestCpuUsage(0.6);//max avg rt of all request is 10 ms,系统最大平均响应时间为10毫秒rule.setAvgRt(10);//max total qps is 20,系统最大QPS为20rule.setQps(20);//max parallel working thread is 10,系统最大并行线程数为10rule.setMaxThread(10);rules.add(rule);//通过系统规则配置管理类SystemRuleManager将规则配置注册进去,一旦超出上述阈值,新进来的请求将被直接拒绝SystemRuleManager.loadRules(Collections.singletonList(rule));}private static void tick() {Thread timer = new Thread(new TimerTask());timer.setName("sentinel-timer-task");timer.start();}static class TimerTask implements Runnable {@Overridepublic void run() {System.out.println("begin to statistic!!!");long oldTotal = 0;long oldPass = 0;long oldBlock = 0;while (!stop) {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}long globalTotal = total.get();long oneSecondTotal = globalTotal - oldTotal;oldTotal = globalTotal;long globalPass = pass.get();long oneSecondPass = globalPass - oldPass;oldPass = globalPass;long globalBlock = block.get();long oneSecondBlock = globalBlock - oldBlock;oldBlock = globalBlock;System.out.println(seconds + ", " + TimeUtil.currentTimeMillis() + ", total:" + oneSecondTotal + ", pass:" + oneSecondPass + ", block:" + oneSecondBlock);if (seconds-- <= 0) {stop = true;}}System.exit(0);}}
}

9.集群流控使用演示

(1)部署集群环境

(2)集群流控实战

(1)部署集群环境

Sentinel源码中就有一个实现了集群流控的Demo。

因此为了演示集群效果,可以直接启动:

com.alibaba.csp.sentinel.demo.cluster.app.ClusterDemoApplication;

接下来会启动三次此项目,分别指定不同的端口。启动之前,需要在IDEA中分别添加如下JVM参数。

第一次启动项目时添加的参数:

 -Dcsp.sentinel.log.use.pid=true -Dproject.name=sentinle.cluster.demo.embedded -Dserver.port=8081 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dcsp.sentinel.api.port=8881

对应的截图如下:

第二次启动项目时添加的参数:

 -Dcsp.sentinel.log.use.pid=true -Dproject.name=sentinle.cluster.demo.embedded -Dserver.port=8082 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dcsp.sentinel.api.port=8882

对应的截图如下:

第三次启动项目时添加的参数:

 -Dcsp.sentinel.log.use.pid=true -Dproject.name=sentinle.cluster.demo.embedded -Dserver.port=8083 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dcsp.sentinel.api.port=8883

对应的截图如下:

分别启动三个ClusterDemoApplication项目,然后再分别访问如下地址:

http://localhost:8081/hello/sentinel
http://localhost:8082/hello/sentinel
http://localhost:8083/hello/sentinel

接着打开Sentinel Dashboard机器列表,便会发现注册进来了三个服务。

(2)集群流控实战

首先,需要新增Token Server和Token Client。可以随意选择一个服务作为Token Server,另外两个作为Token Client。

接着,新建一个集群规则:集群QPS阈值为1。这也就意味着三台服务加起来的QPS为1,即整个集群内1s只能访问一次。配置如下图所示:

至此,就完成了集群限流的配置。

相关文章:

Sentinel源码—1.使用演示和简介二

大纲 1.Sentinel流量治理框架简介 2.Sentinel源码编译及Demo演示 3.Dashboard功能介绍 4.流控规则使用演示 5.熔断规则使用演示 6.热点规则使用演示 7.授权规则使用演示 8.系统规则使用演示 9.集群流控使用演示 5.熔断规则使用演示 (1)案例说明熔断和降级 (2)Sentin…...

IDEA的常用设置(更新中......)

文章目录 1. 自动导包2. 忽略大小写3. 设置项目文件编码格式4. 设置方法之间分割线5. 设置字体大小6. 设置IDEA默认不打开项目持续更新中...... 1. 自动导包 File->Settings->Editor->General>Auto Import 2. 忽略大小写 File->Editor->General->Code…...

SQL注入之时间盲注攻击流程详解

目录 一、时间盲注原理 二、完整攻击流程 1. 注入点确认 2. 基础条件判断 3. 系统信息收集 &#xff08;1&#xff09;获取数据库版本 &#xff08;2&#xff09;获取当前数据库名 4. 数据提取技术 &#xff08;1&#xff09;表名枚举 &#xff08;2&#xff09;列名猜…...

【ROS2】行为树 BehaviorTree(三):异步操作

【ROS】郭老二博文之:ROS目录 1、简述 前面的例子中,使用过同步节点 SyncActionNode,当调用到该节点时,成功返回SUCCESS,失败返回FAILURE,并且线程会等待该节点执行完毕。 如果需要异步操作,比如节点执行需要很长时间,不能立刻返回结果,可以先去执行其它任务,等该…...

比特币不是solidity编写吗,比特币不是基于 Solidity

对&#xff01;你这个问题问得非常精准——比特币不是基于 Solidity 的&#xff0c;而且它和以太坊智能合约的设计思路也完全不同。我们来讲清楚&#x1f447; ❌ 比特币不是 Solidity 的&#xff01; &#x1f4cc; 原因如下&#xff1a; 项目智能合约语言说明比特币&#x…...

c# Kestrel

Kestrel 是 .NET 中用于 ASP.NET Core 应用程序的跨平台 Web 服务器。它是轻量级且高性能的&#xff0c;能够处理大量并发连接&#xff0c;常被用作 ASP.NET Core 应用的默认服务器。以下为你介绍 Kestrel 的基本使用和配置&#xff1a; 基本使用 创建一个简单的 ASP.NET Cor…...

x86 保护模式中的GDT表是什么?

GDT&#xff08;全局描述符表&#xff0c;Global Descriptor Table&#xff09;是 x86 保护模式下用于描述不同类型内存段的一个重要数据结构。在保护模式下&#xff0c;GDT 用于管理和保护系统内存&#xff0c;它通过提供一组段描述符来定义内存的访问权限、大小、类型等属性 …...

筛选条件在on和where中的区别(基于hivesql)

理解筛选条件在on和where中的区别&#xff0c;最好先理解sql的执行顺序&#xff0c;尽管实际执行时不同的物理执行引擎可能会有特定的优化&#xff0c;但是逻辑执行顺序必须遵循&#xff1a; 1&#xff09;from&#xff1a;确定数据源是什么&#xff0c;from后可以是单表&#…...

自然语言处理Hugging Face Transformers

Hugging Face Transformers 是一个基于 PyTorch 和 TensorFlow 的开源库&#xff0c;专注于 最先进的自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;如 BERT、GPT、RoBERTa、T5 等。它提供了 预训练模型、微调工具和推理 API&#xff0c;广泛应用于文本分类、机器翻…...

vue3+vite+ts使用daisyui/tailwindcss

vite创建vue3脚手架 npm init vitelatest myVue3 – --template vue cd .\myVue3\ npm i npm run dev 安装tailwindcss/daisyui 依赖安装 npm install -D tailwindcss postcss autoprefixer daisyui npx tailwindcss init -p 这条命令将生成postcss.config.js(因为加了…...

Android常见界面控件、程序活动单元Activity练习

第3章 Android常见界面控件、第4章程序活动单元Activity 一. 填空题 1. (填空题)Activity的启动模式包括standard、singleTop、singleTask和_________。 正确答案&#xff1a; (1) singleInstance 2. (填空题)启动一个新的Activity并且获取这个Activity的返回数据&#xff…...

大模型在直肠癌诊疗全流程预测及应用研究报告

目录 一、引言 1.1 研究背景与目的 1.2 国内外研究现状 1.3 研究方法与创新点 二、大模型预测直肠癌的原理与技术基础 2.1 大模型技术概述 2.2 用于直肠癌预测的数据来源 2.3 模型构建与训练过程 三、术前预测 3.1 肿瘤分期预测 3.1.1 基于影像组学的 T 分期预测模型…...

大联盟(特别版)双端互动平台完整套件分享:含多模块源码+本地部署环境

这是一套结构清晰、功能完整的互动平台组件&#xff0c;适合有开发经验的技术人员进行模块参考、结构研究或本地部署实验使用。 该平台覆盖前端展示、后端服务、移动端资源以及完整数据库&#xff0c;采用模块化架构&#xff0c;整体部署流程简单清晰&#xff0c;适合自研团队参…...

设计模式:迪米特法则 - 最少依赖,实现高内聚低耦合

一、迪米特法则简介 迪米特法则&#xff08;Law of Demeter&#xff0c;简称 LoD&#xff09;&#xff0c;也称为“最少知识法则”&#xff0c;核心思想是&#xff1a;一个对象应当对其他对象有最少的了解&#xff0c;仅与直接相关的对象交互。通过减少对象之间的耦合度&#…...

Spark-SQL

Spark-SQL 概述 Spark SQL 是 Spark 用于结构化数据(structured data)处理的 Spark 模块 Shark 是伯克利实验室 Spark 生态环境的组件之一&#xff0c;是基于 Hive 所开发的工具&#xff0c;它修改了内存管理、物理计划、执行三个模块&#xff0c;并使之能运行在 Spark 引擎上…...

多任务响应2(Qt)

多任务响应2 扩展方案1. 设计思路2. 示例代码3. 说明 在多任务响应1的基础上&#xff0c;当任务响应比较复杂时&#xff0c;需要整合多个模块的信息。 扩展方案 利用【中介者模式】或【系统上下文】来整合多个模块的信息&#xff0c;并在命令对象中通过依赖注入&#xff08;D…...

【MySQL】MVCC工作原理、事务隔离机制、undo log回滚日志、间隙锁

一、什么是MVCC&#xff1f; MVCC&#xff0c;即 Multiversion Concurrency Control&#xff08;多版本并发控制&#xff09;&#xff0c;它是数据库实现并发控制的一种方式。 MVCC 的核心思想是&#xff1a; 为每个事务提供数据的“快照”版本&#xff0c;从而避免加锁&…...

无人机气动-结构耦合技术要点与难点

一、技术要点 1. 多学科耦合建模 气动载荷与结构响应的双向耦合&#xff1a;气动力&#xff08;如升力、阻力、力矩&#xff09;导致结构变形&#xff0c;而变形改变气动外形&#xff0c;进一步影响气流分布&#xff0c;形成闭环反馈。 建模方法&#xff1a; 高精度C…...

七大数据库全面对比:ClickHouse、ES、MySQL等特性、优缺点及使用场景

七大数据库全面对比:ClickHouse、ES、MySQL等特性、优缺点及使用场景 引言 在数字化时代,数据库的选择对于业务的成功至关重要。本文将通过表格形式,对ClickHouse、Elasticsearch(ES)、MySQL、SQL Server、MongoDB、HBase、Cassandra这七大数据库进行特性、优缺点及使用…...

element-ui plus 中 filter-method 函数多次触发问题解决

前情提要 点进这个文章的小伙伴&#xff0c;应该都是为了解决一个需求&#xff0c;把原本的前端过滤改为后端过滤&#xff0c;但是将filter-method修改为后端取数据后&#xff0c;发现其触发了很多次。博主也是在修改表格过滤时用到了这个坑&#xff0c;本篇文章为大家解决一下…...

基于【Lang Chain】构建智能问答系统的实战指南

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《深度探秘&#xff1a;AI界的007》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、什么是Lang Chain 2、LangChain在问答系统中的核心优…...

idea的快捷键使用以及相关设置

文章目录 快捷键常用设置 快捷键 快捷键作用ctrlshift/注释选中内容Ctrl /注释一行/** Enter文档注释ALT SHIFT ↑, ALT SHIFT ↓上下移动当前代码Ctrl ALT L格式化代码Ctrl X删除所在行并复制该行Ctrl D复制当前行数据到下一行main/psvm快速生成入口程序soutSystem.o…...

TestHubo安装及入门指南

TestHubo是一款开源免费的测试管理工具&#xff0c;提供一站式测试解决方案&#xff0c;涵盖功能测试、接口测试、性能测试以及 Web 和 App 测试等多个维度。TestHubo 整合了全面的测试能力&#xff0c;使团队可以在一个平台内完成所有测试需求。本文将介绍如何快速安装配置及入…...

react tailwindcss最简单的开始

参考教程&#xff1a; Install Tailwind CSS with Vite - TailwindCSS中文文档 | TailwindCSS中文网https://www.tailwindcss.cn/docs/guides/vite操作过程&#xff1a; Microsoft Windows [版本 10.0.26100.3476] (c) Microsoft Corporation。保留所有权利。D:\gitee\tailwi…...

openGauss新特性 | 自动参数化执行计划缓存

目录 自动化参数执行计划缓存简介 SQL参数化及约束条件 一般常量参数化示例 总结 自动化参数执行计划缓存简介 执行计划缓存用于减少执行计划的生成次数。openGauss数据库会缓存之前生成的执行计划&#xff0c;以便在下次执行该SQL时直接使用&#xff0c;可…...

3、组件:魔法傀儡的诞生——React 19 组件化开发全解析

一、开篇&#xff1a;魔法傀儡的觉醒 "每个React组件都像一具魔法傀儡&#xff0c;"邓布利多校长挥动魔杖&#xff0c;空中浮现出闪烁的代码字符&#xff0c;"它们能自主思考、协同工作&#xff0c;甚至能跨越时空&#xff08;服务器与客户端&#xff09;执行任…...

使用Python实现矢量路径的压缩、解压与可视化

引言 在图形设计和Web开发中&#xff0c;矢量路径数据的高效存储与传输至关重要。本文将通过一个Python示例&#xff0c;展示如何将复杂的矢量路径命令序列压缩为JSON格式&#xff0c;再将其解压还原&#xff0c;并通过matplotlib进行可视化。这一过程可应用于字体设计、矢量图…...

达梦数据库迁移问题总结

更多技术博客&#xff0c;请关注微信公众号&#xff1a;运维之美 问题一、DTS工具运行乱码 开启图形化 [rootlocalhost ~]# xhost #如果命令不存在执行sudo yum install xorg-x11-server-utils xhost: unable to open display "" [rootlocalhost ~]# su - dmd…...

OpenHarmony荷兰研习会回顾 | 仓颉语言赋能原生应用开发实践

近日&#xff0c;由全球顶级学术峰会EuroSys/ASPLOS和OpenHarmony社区在荷兰鹿特丹合办的操作系统深度研习会圆满收官&#xff0c;本次研习会以"架构探秘-开发实践-创新实验"三位一体的进阶模式&#xff0c;为全球开发者构建了沉浸式技术探索平台。其中&#xff0c;由…...

【远程工具】0 std::process::Command 介绍

std::process::Command 是 Rust 标准库中用于创建和配置子进程的主要类型。它允许你启动新的进程、设置其参数和环境变量、重定向输入/输出等。 基本用法 use std::process::Command;let output Command::new("echo").arg("Hello, world!").output().ex…...