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…...
基于Geotools的PostGIS原始操作之CQL过滤及按属性名称生成面属性时间-以湖北省地级市行政区划为例
目录 前言 背景与意义 技术方法概述 一、CQL查询实现 1、CQL查询原理 2、Geotools中的CQL实现 二、SLD编程式样式生成 1、获取唯一的分类值 2、生成不同颜色分类 3、集成生成SLD的Style文件 三、总结 前言 随着地理信息系统(GIS)技术的快速发展…...
Linux内核中struct net_protocol的early_demux字段解析
背景问题 在内核版本4.19.0-25的头文件中,struct net_protocol结构体的定义未显式包含early_demux字段。然而,在内核版本4.19的源代码中可以看到tcp_protocol实例化时却对该字段进行了赋值: static struct net_protocol tcp_protocol = {.early_demux = tcp_v4_earl…...
TLS协议四次握手原理详解,密钥套件采用DH密钥交换算法
目录 1.TLS协议握手概述 2.TLS协议握手具体步骤 2.1.TLS第一次握手 2.2.TLS第二次握手 2.3.TLS第三次握手 2.4.TLS第四次握手 3.DH密钥交换算法 1.TLS协议握手概述 第一步客户端会发起一个消息,携带了TLS的版本号,客户端随机数,密码套…...
React 更新state中的对象
更新 state 中的对象 state 中可以保存任意类型的 JavaScript 值,包括对象。但是,你不应该直接修改存放在 React state 中的对象。相反,当你想要更新一个对象时,你需要创建一个新的对象(或者将其拷贝一份)…...
祁连山国家公园shp格式数据
地理位置:祁连山国家公园位于中国西北部,横跨甘肃省与青海省交界处,主体处于青藏高原东北边缘。总面积约5.02万平方公里,是中国首批设立的10个国家公园之一。 设立背景 试点启动:2017年,祁连山国家公园体制…...
电梯设备与电源滤波器:现代建筑中的安全守护者与电力净化师
在现代都市的钢铁森林中,电梯作为垂直交通的动脉,承载着无数人的日常出行。与此同时,在电气系统的隐秘角落,电源滤波器则默默扮演着“电力净化师”的角色,保障着各类电子设备的稳定运行。电梯设备与电源滤波器…...
Qt样式表(窗口、按钮之类,有图片和代码详细注释)
Qt样式表 1、前言2、QWdiget窗口添加背景图片2.1使用Frame解决 3、主题1(黑色背景发光边框冷色调)3.1 QWidget3.2 QPushButton3.3QLineEdit3.4 QTextEdit 4、主题二(极简冰川蓝)4.1QWidget4.2 QLineEdit4.3QTextEdit4.4QPushButto…...
在Ubuntu下进行单片机开发是否需要关闭Secure Boot
1. Secure Boot的作用 功能:Secure Boot是UEFI的安全功能,旨在阻止未经验证的驱动或操作系统启动,防止恶意软件篡改引导过程。 影响范围:它主要限制的是操作系统启动阶段加载的内核级驱动(如显卡驱动、虚拟化模块&…...
【Python爬虫】简单案例介绍4
本文继续接着我的上一篇博客【Python爬虫】简单案例介绍3-CSDN博客 目录 3.4 完整代码 3.4 完整代码 此小节给出上述案例的完整代码, # encodingutf-8 import re, json, requests, xlwt, csv import pandas as pd from lxml import etree from bs4 import Beauti…...
农民剧团的春天与改变之路
杨天义,男,1966年9月生,中共党员,江西省吉安市吉水县水南农民剧团团长。 杨天义从废品收购起家,凭借自身的努力和奋斗,自筹资金100余万元建设了水南镇的第一座影剧院,组建了江西省吉安市吉水县…...
网页防篡改与盗链防护:实时监控与自动化修复实践
摘要:针对网页内容篡改与盗链问题,本文基于群联AI云防护系统,详解如何通过哈希校验、实时监控与CDN联动实现秒级修复,并提供Python与AWS S3集成代码。 一、网页安全的核心需求 防篡改:保障页面内容完整性,…...
【密码学——基础理论与应用】李子臣编著 第五章 序列密码 课后习题
免责声明 这里都是自己搓或者手写的。 里面不少题目感觉有问题或者我的理解有偏颇,请大佬批评指正! 不带思考抄作业的请自动退出,我的并非全对,仅仅提供思维! 题目 逐题解析 5.1 我们先要知道三阶LFSR函数的表达式…...
【uni-app】页面跳转传参
一、EventChannel 的核心作用 替代全局事件总线 相比传统的 uni.$emit 和 uni.$on,EventChannel 无需手动移除监听(如 uni.$off),避免内存泄漏风险。解决 URL 传参限制 当需要传递大量数据时,URL 拼接参数可能超出长度…...
【MySQL】表的增删改查
前言 前面我们对表结构做了介绍,本期我们对表的内容操作机增删改查进行介绍! 目录 前言 一、insert 插入 1.1 单行数据 全列插入 1.2 多行数据 指定列插入 1.3 插入否则更新 1.4 插入否则替换 二、select 查询 2.1 select 列 2.1.1 全列查询…...
AQchat
在当前项目里,Handler 类主要用于处理不同类型的命令或者消息,下面按照不同功能模块为你详细介绍各 Handler 的作用。 命令处理 Handler(位于 com.howcode.aqchat.handler.impl 包) SyncRoomMembersCmdHandler:处理同…...
Profibus DP转ModbusTCP网关通讯案例解析
Profibus DP转ModbusTCP网关通讯案例解析 Profibus DP和Modbus TCP都是工业自动化领域中常见的通信协议,各自在不同的应用场景中发挥着重要作用。然而,由于不同设备、系统之间的兼容性需求,常常需要进行这两种协议的转换。本文将介绍一个典型…...
将你的 Rust + WebAssembly 项目发布到 npm
一、准备工作:登录 npm 在发布之前,你需要: 拥有一个 npm 账号 没有的话可前往 https://www.npmjs.com/signup 免费注册。 登录本地 npm 账户 使用 wasm-pack 自带的登录命令: wasm-pack login它会提示你输入 npm token…...
RGBD惯性SLAM
介绍 本篇介绍一种基于视觉光流法的RGBD惯性SLAM算法,该算法的前身是DEMO算法。 相对于原始版本: 更新了相对较老的IplImage 相关接口 加入了GTSAM后端;滑动窗口后端;3D-3Dbatch优化;点到面batch后端。分别对应不同的…...
linuxbash原理
3417 1647 0 04:17 ? 00:00:21 /usr/libexec/gnome-terminal-server yangang 3425 3417 0 04:17 pts/0 00:00:00 bash yangang 4524 3417 0 04:26 pts/1 00:00:00 bash 控制台创建是通过/usr/libexec/gnome-terminal-server 进行创建 rea…...
ctfshow做题笔记—栈溢出—pwn75~pwn79
目录 前言 一、pwn75(栈空间不够怎么办?) 二、pwn76 三、pwn77(Ez ROP or Mid ROP ?) 四、pwn79(你需要注意某些函数,这是解题的关键!) 前言 嘿嘿,隔了一段时间没有做pwn题了(主播脱单了)࿰…...
C++ 标准库中的 <algorithm> 头文件算法总结
C 常用 <algorithm> 算法概览 C 标准库中的 <algorithm> 头文件提供了大量有用的算法,主要用于操作容器(如 vector, list, array 等)。这些算法通常通过迭代器来操作容器元素。 1. 非修改序列操作 std::all_of, std::any_of, s…...
leecode Hot100之回溯算法【C++速查】
文章目录 [46. 全排列](https://leetcode.cn/problems/permutations/)[78. 子集](https://leetcode.cn/problems/subsets/)[17. 电话号码的字母组合](https://leetcode.cn/problems/letter-combinations-of-a-phone-number/)[39. 组合总和](https://leetcode.cn/problems/combi…...
前端 main.js能做哪些事?
前端 main.js 的从入门到进阶 摘要 在前端开发中,main.js 文件是项目启动的关键入口,它承担着初始化应用、引入依赖、配置全局设置等重要职责。本文将全面介绍 main.js 的基础知识,包括其基本结构和作用,并深入探讨如何进行进阶开…...
JAVA Web_定义Servlet2_学生登录验证Servlet
题目 页面StudentLogin.html中有一HTML的表单代码如下: <form action"studentLogin" method"post">学生姓名:<input type"text" name"stuName" value""><br>登录密码:…...
【信息系统项目管理师】高分论文:论信息系统项目的范围管理(电网公司保供电可视化系统)
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 论文1、规划范围管理2、收集需求3、定义范围4、创建工作分解结构(WBS)5、确认范围6、控制范围论文 2017年5月,我作为项目经理参加XX省电网公司保供电可视化系统应用项目的建设,该项目是2017年XX省电网信息化…...
如何高效查询订单销售情况与售罄率:从SQL到架构优化的全流程设计
在电商平台、SaaS多租户系统中,订单数据作为核心数据之一,承载了关键的运营指标,如销售额、商品售罄率、订单转化等。随着数据量的持续增长,如何在大数据量条件下快速、稳定地获取统计信息,成为系统设计的重点之一。 本文将从查询目标分析入手,结合数据库设计优化与典型…...
RTT添加一个RTC时钟驱动,以DS1307为例
添加一个外部时钟芯片 这里多了一个选项 复制drv_rtc.c,重命名为drv_rtc_ds1307.c 添加到工程中 /*** @file drv_rtc_ds1307.c* @brief * @author jiache (wanghuan3037@fiberhome.com)* @version 1.0* @date 2025-01-08* * @copyright Copyright (c) 2025 58* */ #...
Leetcode 独一无二的出现次数
可以通过哈希集来判断是否独一无二,如果set中已经包含了count,那么set.add(count)会返回false class Solution {public boolean uniqueOccurrences(int[] arr) {Map<Integer, Integer> map new HashMap<>();for(int i 0; i < arr.leng…...
ubuntu上,e1000e,i1210有线网卡驱动安装
1,下载附属资源,解压对应的压缩包 tar zxf e1000e-<x.x.x>.tar.gz 2,进入压缩包src目录下 cd e1000e-<x.x.x>/src/ 3,安装 sudo make install 4,重启 reboot e1000e Intel官网下载地址 https://www.i…...
Xmind 2025 中文思维导图
Xmind 2025 中文思维导图 一、介绍 Xmind ,是一款出色的思维导图和头脑风暴软件,拥有美观的智能配色方案,便于你轻松理清思路捕捉创意。丰富的导图模板及多种创意整合工具,可助力导图迸发更多活力。还拥有强大演说模式ÿ…...
搭载DeepSeek|暴雨AI教育一体机加速AI教育普及
近日,在全国智算大会上,暴雨公司展示了新一代 AI 教育一体机,通过全栈国产化技术与 DeepSeek 模型的深度适配,打造低成本、高性能的人工智能教育解决方案,助力 AI 教育普及与教育数字化转型。 暴雨AI教育一体机&#…...
【字节跳动AI论文】Seaweed-7B:视频生成基础模型的高成本效益培训
摘要:本技术报告介绍了一种经济有效的视频生成基础模型训练策略。 我们提出了一种中等规模的研究模型,大约有70亿个参数(7B),称为Seaweed-7B,使用665,000个H100 GPU小时从头开始训练。 尽管使用适度的计算资…...
java 线程池:IO密集型的任务(CPU核数 * 2 + 1),为什么这么设置,计算密集型任务( CPU核数+1 ),为什么这么设置
文章目录 1. IO密集型任务:`CPU核数 2 + 1`为什么这样设置?示例场景:2. CPU密集型任务:`CPU核数 + 1`为什么这样设置?示例场景:3. 两者的核心差异4. 实际应用中的注意事项5. 总结在Java线程池的配置中, IO密集型和 CPU密集型任务的线程数设置逻辑存在显著差异,核心原…...
RabbitMQ消息的可靠性
生产者的可靠 首先,我们一起分析一下消息丢失的可能性有哪些。 消息从发送者发送消息,到消费者处理消息,需要经过的流程是这样的: 消息从生产者到消费者的每一步都可能导致消息丢失: ● 发送消息时丢失:…...
涵盖通算、智算、超算、量算!“四算合一”算力网络投入使用,效率提升20%
近日,由中国移动承建的全国首个“四算合一”算力网络调度平台日前正式投入使用。这座“数字三峡”的诞生,标志着我国算力基建完成从“单兵作战”到“军团协同”的跃迁。 什么是“四算合一”? “四算合一”是指将通用算力、智能算力、超级算…...
【Redis】数据结构和内部编码
先来复习一下之前学过的几个基本的全局命令: keys:用来查看匹配规则的keyexists:用来判定执行key是否存在del:删除指定的keyexpire:给key设置过期时间ttl:查询key的过期时间type:查询key对应的…...
考研数据结构之二叉树(一)(包含真题及解析)
考研数据结构之二叉树(一) 下期预告:后续文章将深入探讨二叉树的遍历算法与高频考点(如平衡二叉树、线索二叉树)。 二叉树是数据结构中的核心内容之一,也是考研高频考点。本文将从定义和存储结构两方面展开…...
linux多线(进)程编程——番外1:内存映射与mmap
前言 在修真世界之外,无数异世界,其中某个叫地球的异世界中,一群人对共享内存的第二种使用方式做出了讲解。 内核空间与用户空间 内存空间的划分 Linux操作系统下一个进程的虚拟地址空间被分为用户空间与内核空间 Linux 内核空间在内存管…...
旧版 VMware 虚拟机迁移至 KVM 平台-案例2
项目背景 需将一台旧版 VMware 虚拟机(VMDK 格式)迁移至 KVM 虚拟化平台,具体要求如下: 格式转换:将 VMDK 转换为 QCOW2 格式。磁盘扩容:将原 40GB 磁盘扩展至 60GB。密码重置:修改 aiden 用户…...
六、adb通过Wifi连接
背景 收集是荣耀X40,数据线原装全新的,USB连上之后,老是断,电脑一直叮咚叮咚的响个不停,试试WIFI 连接是否稳定,需要手机和电脑用相同的WIFI. 连接 1.通过 USB 连接手机和电脑(打开USB调试等这些都略过) adb device…...
Kafka使用方式与底层原理解析
一、Kafka简介 Apache Kafka是一个分布式流处理平台,由LinkedIn开发并开源,现已成为实时数据管道和流应用的核心组件。它具备高吞吐量、低延迟、高可扩展性等特点,广泛应用于日志收集、消息系统、流处理等领域。 1.1 Kafka核心概念 Topic&…...
【Python内置函数的深度解析与应用】id
目录 前言:技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解关键技术模块技术选型对比 二、实战演示环境配置要求核心代码实现1. 基础身份验证2. 不可变对象优化3. 对象生命周期追踪 运行结果验证 三、性能对比测试方法论量化数据…...
【Pandas】pandas DataFrame keys
Pandas2.2 DataFrame Indexing, iteration 方法描述DataFrame.head([n])用于返回 DataFrame 的前几行DataFrame.at快速访问和修改 DataFrame 中单个值的方法DataFrame.iat快速访问和修改 DataFrame 中单个值的方法DataFrame.loc用于基于标签(行标签和列标签&#…...
探索QEMU-KVM虚拟化:麒麟系统下传统与云镜像创建虚拟机的最佳实践
随着云计算和虚拟化技术的不断进步,虚拟化在管理服务器、隔离资源以及提升性能方面的好处越来越明显。麒麟操作系统Kylin OS是我们国家自己开发的操作系统,在政府机构和企业中用得很多。这篇文章会教你如何在麒麟操作系统上设置QEMU-KVM虚拟化环境&#…...
pycharm中调试功能讲解
一、调试前的准备工作 1. 准备一段测试代码 先写一个简单的Python脚本(比如计算阶乘),故意留点问题: def factorial(n):result 1for i in range(n):result * ireturn resultprint(factorial(5)) # 预期输出120࿰…...
SimpleITK (sitk) 中查看 DICOM 文件的像素位深(8位或16位)
在 SimpleITK (sitk) 中查看 DICOM 文件的像素位深(8位或16位),可以通过以下方法实现: 方法一:通过 图像像素数组的数据类型 判断 读取 DICOM 文件: 使用 sitk.ReadImage() 加载文件,生成图像对…...
day28图像处理OpenCV
文章目录 一、图像预处理4 边缘填充4.1 边界复制(BORDER_REPLICATE)4.2 边界反射(BORDER_REFLECT)4.3 边界反射101(BORDER_REFLECT_101)4.4 边界常数(BORDER_CONSTANT)4.5 边界包裹&…...
【NLP】 自然语言处理笔记
NLP的全称是Natuarl Language Processing,中文意思是自然语言处理,是人工智能领域的一个重要方向。自然语言处理(NLP)就是在机器语言和人类语言之间沟通的桥梁,以实现人机交流的目的。 人类语言是抽象的信息符号,其中蕴含着丰富的语义信息,人类可以很轻松地理解其中的含…...
LaTeX 的pstricks-add宏绘图练习
练习。 \documentclass[10pt]{article} \usepackage{pstricks-add} \pagestyle{empty} \begin{document} \psset{xunit1.0cm,yunit1.0cm,algebraictrue,dimenmiddle,dotstyleo,dotsize5pt 0,linewidth2.pt,arrowsize3pt 2,arrowinset0.25} \begin{pspicture*}(-16.5581463…...