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

【Sentinel】Sentinel簇点链路的形成

说明

一切节点的跟是 machine-root,同一个资源在不同链路会创建多个DefaultNode,但是在全局只会创建一个 ClusterNode

                machine-root/\/    \EntranceNode1   EntranceNode2/          \/              \DefaultNode(nodeA)         DefaultNode(nodeA)|                  |- - - - - - + - - - - - - - - - +- - - - - - -> ClusterNode(nodeA);

如我们所见,在两个上下文中为“nodeA”创建了两个 DefaultNode,但只创建了一个 ClusterNode

一切的开始

DispatcherServlet是Spring MVC框架中的核心组件,它作为前置控制器,它拦截匹配的请求,并根据相应的规则分发到目标Controller来处理。当请求进入后,首先会执行DispatcherServlet 的 doDispatch 方法

public class DispatcherServlet extends FrameworkServlet {protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {···try {try {···// 执行preHandle方法 // 会进入AbstractSentinelInterceptor 的 preHandle// 会为当前访问的controller接口创建资源if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// Actually invoke the handler.// 最终会执行SentinelResourceAspect#invokeResourceWithSentinel(pjp);// 为所有添加注解的方法创建资源mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}···}catch (Exception ex) {···}}catch (Exception ex) {···}}
}

因此,从这里就可以知道,簇点链路中,默认使用 controller 创建的资源一定在使用注解创建的资源之前创建,也就是说,使用注解创建的资源只能作为使用 controller 创建的资源的子节点。

链路创建过程分析

创建 EntranceNode

上面说到,执行会进入AbstractSentinelInterceptor 的 preHandle,进行资源创建

public abstract class AbstractSentinelInterceptor implements HandlerInterceptor {public static final String SENTINEL_SPRING_WEB_CONTEXT_NAME = "sentinel_spring_web_context";@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {try {// 获取资源名,也就是 /order/{orderId}String resourceName = getResourceName(request);if (StringUtil.isEmpty(resourceName)) {return true;}if (increaseReferece(request, this.baseWebMvcConfig.getRequestRefName(), 1) != 1) {return true;}// Parse the request origin using registered origin parser.String origin = parseOrigin(request);// contextName默认是sentinel_spring_web_context,// 如果不想使用这个,而是使用Controller接口路径作为contextName,则需要在application.yml文件中关闭context整合// spring.cloud.sentinel.web-context-unify=falseString contextName = getContextName(request);// 创建context// Context初始化的过程中,会创建EntranceNode,contextName就是EntranceNode的名称ContextUtil.enter(contextName, origin);// 创建资源,簇点链路的形成就在里面Entry entry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_WEB, EntryType.IN);request.setAttribute(baseWebMvcConfig.getRequestAttributeName(), entry);return true;} catch (BlockException e) {···}}
}

在获取 contextName 时,会先判断有没有关闭 context 整合,然后选择返回默认的sentinel_spring_web_contex还是从接口中获取url

@Override
protected String getContextName(HttpServletRequest request) {if (config.isWebContextUnify()) {return super.getContextName(request);}return getResourceName(request);
}@Override
protected String getResourceName(HttpServletRequest request) {// Resolve the Spring Web URL pattern from the request attribute.Object resourceNameObject = request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);if (resourceNameObject == null || !(resourceNameObject instanceof String)) {return null;}String resourceName = (String) resourceNameObject;UrlCleaner urlCleaner = config.getUrlCleaner();if (urlCleaner != null) {resourceName = urlCleaner.clean(resourceName);}// Add method specification if necessaryif (StringUtil.isNotEmpty(resourceName) && config.isHttpMethodSpecify()) {resourceName = request.getMethod().toUpperCase() + ":" + resourceName;}return resourceName;
}

然后会进行 context 的创建

protected static Context trueEnter(String name, String origin) {// 第一次肯定为空Context context = contextHolder.get();if (context == null) {// contextNameNodeMap 有1个值(EntranceNode是DefaultNode的子类,是一种特殊的DefaultNode)//      1. sentinel_default_context -> {EntranceNode@10330} Map<String, DefaultNode> localCacheNameMap = contextNameNodeMap;// 根据传入的contextName选择看有没有这个name的EntranceNodeDefaultNode node = localCacheNameMap.get(name);// 如果没有就创建一个if (node == null) {if (localCacheNameMap.size() > Constants.MAX_CONTEXT_NAME_SIZE) {setNullContext();return NULL_CONTEXT;} else {LOCK.lock();try {node = contextNameNodeMap.get(name);if (node == null) {if (contextNameNodeMap.size() > Constants.MAX_CONTEXT_NAME_SIZE) {setNullContext();return NULL_CONTEXT;} else {// 创建一个新的EntranceNodenode = new EntranceNode(new StringResourceWrapper(name, EntryType.IN), null);// Add entrance node.// Constants.ROOT是一个EntranceNode, id是machine-root// 将当前创建的EntranceNode添加为Constants.ROOT的子节点Constants.ROOT.addChild(node);Map<String, DefaultNode> newMap = new HashMap<>(contextNameNodeMap.size() + 1);newMap.putAll(contextNameNodeMap);newMap.put(name, node);contextNameNodeMap = newMap;}}} finally {LOCK.unlock();}}}// 创建一个新的contextcontext = new Context(node, name);context.setOrigin(origin);contextHolder.set(context);}return context;
}

创建 DefaultNode

创建资源时,首先会创建一个 slot 执行链,然后依次执行。

第一个节点是 NodeSelectSlot,在里面完成 DefaultNode 的创建。

当第一次访问时,NodeSelectorSlot 中

// volatile保证map多线程的可见性
// 非static变量,每次创建对象时都创建一个新的
private volatile Map<String, DefaultNode> map = new HashMap<String, DefaultNode>(10);@Override
public void entry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized, Object... args) throws Throwable {// 第一次一定是空,同一个链路中的资源之后的请求不为空// 不同链路中的资源,后续的请求中,第一次访问还是空DefaultNode node = map.get(context.getName());if (node == null) {synchronized (this) {node = map.get(context.getName());if (node == null) {// 创建一个DefaultNode,将他放入到map中node = new DefaultNode(resourceWrapper, null);HashMap<String, DefaultNode> cacheMap = new HashMap<String, DefaultNode>(map.size());cacheMap.putAll(map);cacheMap.put(context.getName(), node);// 更新mapmap = cacheMap;// Build invocation tree// 将刚创建的node设置为当前node的子节点((DefaultNode) context.getLastNode()).addChild(node);}}}// 设置当前节点为刚创建的节点context.setCurNode(node);fireEntry(context, resourceWrapper, node, count, prioritized, args);
}

下面的图是访问/order/query/{name}接口创建的资源

下面的图是访问/order/query/{name}接口创建的资源,不过在这个 Controller 接口里面又调用了 service 中添加了@SentinelResource注解的方法。根据上面的分析,基于注解的资源后创建,因此它作为基于 Controller 创建的资源的子节点

第二次访问/order/query/{name}接口,在NodeSelectorSlot中,node 会获取到,因此直接执行后边的操作

如果 controller 接口上加了@SentinelResource,还是先创建 controller 资源,然后创建 controller 基于注解的资源,然后是 service 的资源。下面的图中,在/order/query/{name}Controller 接口上添加了@SentinelResource注解。

feign 对 Sentinel 支持

开启 feign 对 Sentinel 的支持后,Sentinel 会将 feign 的请求添加到簇点链路中

feign.sentinel.enabled=true

在 Sentinel 的 jar 中,使用 spi 机制加载了一个类com.alibaba.cloud.sentinel.feign.SentinelFeignAutoConfiguration

SentinelFeignAutoConfiguration 配置类里定义了Feign.Builder 的实现类 SentinelFeign.builder()

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ SphU.class, Feign.class })
public class SentinelFeignAutoConfiguration {@Bean@Scope("prototype")@ConditionalOnMissingBean@ConditionalOnProperty(name = "feign.sentinel.enabled") // 配置项为true时该bean生效public Feign.Builder feignSentinelBuilder() {return SentinelFeign.builder();}}

SentinelFeign.builder( )build( ) 方法

主要作用是: 创建 invocationHandlerFactory,重写create( ) 方法;invocationHandlerFactory 用于创建 SentinelInvocationHandler ,代替前面的 FeignCircuitBreakerInvocationHandler。

public Feign build() {super.invocationHandlerFactory(new InvocationHandlerFactory() {public InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch) {GenericApplicationContext gctx = (GenericApplicationContext)Builder.this.applicationContext;BeanDefinition def = gctx.getBeanDefinition(target.type().getName());FeignClientFactoryBean feignClientFactoryBean = (FeignClientFactoryBean)def.getAttribute("feignClientsRegistrarFactoryBean");// 从BeanDefinition 里获取到 fallback、fallbackFactory Class fallback = feignClientFactoryBean.getFallback();Class fallbackFactory = feignClientFactoryBean.getFallbackFactory();String beanName = feignClientFactoryBean.getContextId();if (!StringUtils.hasText(beanName)) {beanName = feignClientFactoryBean.getName();}if (Void.TYPE != fallback) {// 创建 fallback 实例Object fallbackInstance = this.getFromContext(beanName, "fallback", fallback, target.type());// 创建 SentinelInvocationHandlerreturn new SentinelInvocationHandler(target, dispatch, new org.springframework.cloud.openfeign.FallbackFactory.Default(fallbackInstance));} else if (Void.TYPE != fallbackFactory) {FallbackFactory fallbackFactoryInstance = (FallbackFactory)this.getFromContext(beanName, "fallbackFactory", fallbackFactory, FallbackFactory.class);return new SentinelInvocationHandler(target, dispatch, fallbackFactoryInstance);} else {return new SentinelInvocationHandler(target, dispatch);}}private Object getFromContext(String name, String type, Class fallbackType, Class targetType) {Object fallbackInstance = Builder.this.feignContext.getInstance(name, fallbackType);if (fallbackInstance == null) {throw new IllegalStateException(String.format("No %s instance of type %s found for feign client %s", type, fallbackType, name));} else if (!targetType.isAssignableFrom(fallbackType)) {throw new IllegalStateException(String.format("Incompatible %s instance. Fallback/fallbackFactory of type %s is not assignable to %s for feign client %s", type, fallbackType, targetType, name));} else {return fallbackInstance;}}});super.contract(new SentinelContractHolder(this.contract));return super.build();
}

在 invoke 方法里面为feign请求创建资源创建资源

@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {if ("equals".equals(method.getName())) {try {Object otherHandler = args.length > 0 && args[0] != null? Proxy.getInvocationHandler(args[0]): null;return equals(otherHandler);}catch (IllegalArgumentException e) {return false;}}else if ("hashCode".equals(method.getName())) {return hashCode();}else if ("toString".equals(method.getName())) {return toString();}Object result;MethodHandler methodHandler = this.dispatch.get(method);// only handle by HardCodedTargetif (target instanceof Target.HardCodedTarget) {Target.HardCodedTarget hardCodedTarget = (Target.HardCodedTarget) target;MethodMetadata methodMetadata = SentinelContractHolder.METADATA_MAP.get(hardCodedTarget.type().getName()+ Feign.configKey(hardCodedTarget.type(), method));// resource default is HttpMethod:protocol://urlif (methodMetadata == null) {result = methodHandler.invoke(args);}else {String resourceName = methodMetadata.template().method().toUpperCase()+ ":" + hardCodedTarget.url() + methodMetadata.template().path();Entry entry = null;try {ContextUtil.enter(resourceName);// 为feign请求创建资源entry = SphU.entry(resourceName, EntryType.OUT, 1, args);// 调用服务端接口result = methodHandler.invoke(args);}catch (Throwable ex) {// fallback handleif (!BlockException.isBlockException(ex)) {Tracer.trace(ex);}if (fallbackFactory != null) {try {//异常时 调用熔断逻辑Object fallbackResult = fallbackMethodMap.get(method).invoke(fallbackFactory.create(ex), args);return fallbackResult;}catch (IllegalAccessException e) {····}}else {···}}finally {···}}}else {result = methodHandler.invoke(args);}return result;
}

如果 service 中使用 feign,则 feign 的调用 也会现实在链路中,他和使用注解创建的service 资源是同级的,但是先创建 feign,后创建 service 注解资源

使用注解和 feign 创建的资源,EntryType 都是 OUT,只有 controller 资源的EntryType 是 IN。

EntryType:枚举标记资源调用方向。

创建ClusterNode

在创建 ClusterNode 时,使用 static 变量存储。将创建的 ClusterNode 与当前 node 进行关联。

/*** 请记住,相同的资源(ResourceWrapper.equals(Object))将在全局范围内共享相同的ProcessorSlotChain,而与上下文无关。* 因此,如果代码进入entry(Context,ResourceWrapper,DefaultNode,int,boolean,Object...),* 则资源名称必须相同,但上下文名称可能不同。要获得不同上下文中相同资源的总统计数据,* 相同的资源在全局范围内共享相同的ClusterNode。此映射在应用运行时间越长,就会变得越稳定。* 因此,我们不使用并发映射,而是使用锁。因为此锁仅在开始时发生,而并发映射将始终保持锁定状态。*/
private static volatile Map<ResourceWrapper, ClusterNode> clusterNodeMap = new HashMap<>();@Override
public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count,boolean prioritized, Object... args) throws Throwable {// 如果不是第一次访问这个资源,则clusterNode是一定有的// 所以直接将DefaultNode和ClusterNode进行关联// 因为保存ClusterNode的map是static 的,因此全局共享,且创建后内容一直存在// 因此一个资源只会创建一次ClusterNodeif (clusterNode == null) {synchronized (lock) {if (clusterNode == null) {// Create the cluster node.clusterNode = new ClusterNode(resourceWrapper.getName(), resourceWrapper.getResourceType());HashMap<ResourceWrapper, ClusterNode> newMap = new HashMap<>(Math.max(clusterNodeMap.size(), 16));newMap.putAll(clusterNodeMap);newMap.put(node.getId(), clusterNode);clusterNodeMap = newMap;}}}node.setClusterNode(clusterNode);/** if context origin is set, we should get or create a new {@link Node} of* the specific origin.*/if (!"".equals(context.getOrigin())) {Node originNode = node.getClusterNode().getOrCreateOriginNode(context.getOrigin());context.getCurEntry().setOriginNode(originNode);}fireEntry(context, resourceWrapper, node, count, prioritized, args);
}

说明

如果一个请求中要经过多个资源保护的方法(controller 资源*1,注解资源*n),则上面的流程会进行多次,分别根据资源创建类型执行对应的方法,从而将每次的资源添加到前面资源的字节的中,形成于给完整的簇点链路

后面就是限流的一些 slot

相关文章:

【Sentinel】Sentinel簇点链路的形成

说明 一切节点的跟是 machine-root&#xff0c;同一个资源在不同链路会创建多个DefaultNode&#xff0c;但是在全局只会创建一个 ClusterNode machine-root/\/ \EntranceNode1 EntranceNode2/ \/ \DefaultNode(nodeA) DefaultNode(nodeA)|…...

Elasticsearch之mapping

文章目录 以显式的方式创建一个映射查看某个具体索引的mapping定义向已存在的映射中添加一个新的属性查看映射中指定字段的定义信息更新已存在映射的某个字段 1、 官方文档地址 2、 字段类型 1、定义&#xff1a;映射是定义文档及其包含的字段如何存储和索引的过程。 2、每个…...

6、PostgreSQL 数据类型之一:数字类型和货币类型

PostgreSQL 作为一个强大的开源关系型数据库管理系统&#xff0c;本身支持多种数据类型&#xff0c;包括标准 SQL 数据类型以及一些扩展数据类型。 PostgreSQL 支持多种数据类型的设计理念是为了满足不同应用场景的需求&#xff0c;提供更大的灵活性和数据处理能力。原因如下&…...

计算机视觉与深度学习 | 基于点线融合的视觉惯性SLAM前端

===================================================== github:[https://github.com/MichaelBeechan] CSDN:[https://blog.csdn.net/u011344545] ===================================================== 引言 本文中将介绍视觉惯性SLAM的前端部分,首先是传感器数据处理…...

MDK与keilC51共存的方法

MDK与keilC51共存的方法 在网上搜的资料MDK与KeilC51安装顺序都搞反了&#xff0c;而且大家都没成功过&#xff0c;反倒是转发了很多错误的教程。 用此安装方法解决了MDK与KeilC51的共存问题。所有功能完美运行。 因为MDK功能比KeilC51多&#xff0c;所以要先安装KeilC51 1、先…...

c_指针

文章目录 *(p1)1表示第 1 行第 1 个元素的地址。如何理解呢&#xff1f;下标运算符的规则括号 int a; // 1.一个整数 int *a; // 2.一个指向整数的指针 int **a; // 3.一个指向指针的指针, 它所指向的指针又指向一个整数型数据 ;一个指向 …...

循环队列c语言版

一、循环队列结构体 typedef int QueueDataType; #define CQ_MAX_SIZE 10typedef struct CircularQueue {QueueDataType data[CQ_MAX_SIZE];/**标记队列首*/QueueDataType head;/**标记队列尾部*/QueueDataType rear;} CircularQueue; 二、循环队列操作函数声明 /**创建队…...

SprringMVC拦截器

1、拦截器的配置 SpringMVC中的拦截器用于拦截控制器方法的执行 SpringMVC中的拦截器需要实现HandlerInterceptor SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置&#xff1a; <bean class"com.test.interceptor.FirstInterceptor"></bean> …...

redis的实际使用

Redis是一种内存数据库&#xff0c;常用于缓存、会话管理、消息队列等。在项目中合理使用Redis可以提高系统性能和可扩展性。以下是一些使用Redis的建议&#xff1a; 1. 缓存常用数据&#xff1a;将经常使用的数据缓存在Redis中&#xff0c;以减少数据库的读取次数&#xff0c…...

造车先做三蹦子-之二:自制数据集(5x5数据集)230102

#Jupyter Notebook231001import torch import torch.nn as nn import torch.optim as optim# 定义模型 class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.fc1 = nn.Linear(25, 50)self.fc2 = nn.Linear(50, 6)def forward(self, x):x = x.view(-1, 25…...

JS操作DOM及CSS

JS创造于1994年&#xff0c;其目的是为浏览器显示的文档赋予动态行为。 1 Web编程基础 本节讲解如何编写Web应用中的js程序&#xff0c;如果将这些程序加载到浏览器&#xff0c;以及如何获取输入、产出输出&#xff0c;如何运行响应事件的异步代码。 1.1 js 脚本 虽然现在不…...

Linux内核VFS详解

Linux内核VFS是什么? Linux内核VFS(Virtual File System)是Linux操作系统中的一个关键组件,用于提供文件系统抽象层。它允许用户空间和内核空间的各个部分以一种一致的方式访问不同类型的文件系统,包括磁盘文件系统(如EXT4、XFS、NTFS)、网络文件系统(如NFS、CIFS)、…...

在自己的服务器上部署个人博客和开源项目:实现数字存在感

在数字时代&#xff0c;拥有自己的服务器不再是一项难以实现的任务。通过云计算和开源技术的广泛应用&#xff0c;个人可以轻松地拥有自己的服务器&#xff0c;并在其上部署个人博客以及开源项目&#xff0c;为自己在互联网上创造一个数字存在感。本文将介绍如何在自己的服务器…...

【AI视野·今日Robot 机器人论文速览 第五十九期】Fri, 20 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Fri, 20 Oct 2023 Totally 29 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers CCIL: Continuity-based Data Augmentation for Corrective Imitation Learning Authors Liyiming Ke, Yunchu Zhang, Abhay D…...

Chromium浏览器启动参数

文章目录 Chromium浏览器启动参数1. --disable-web-security2. --disable-gpu3. --incognito4. --no-sandbox5. --disable-infobars6. --disable-notifications7. --disable-extensions8. --disable-translate9. --disable-popup-blocking10. --remote-debugging-port=<port…...

【计算机视觉】MoCo v3 讲解

MoCo v3 论文信息 标题:An Empirical Study of Training Self-Supervised Vision Transformers 作者:Xinlei Chen, Saining Xie, Kaiming He 期刊:ICCV 2021 发布时间与更新时间:2021.04.05 2021.04.08 2021.05.05 2021.08.16 主题:计算机视觉、对比学习、MoCo arXiv:[21…...

MySQL - 对字符串字段创建索引

在数据库中&#xff0c;对字符串字段创建索引可以加速字符串字段的查询&#xff1a; 直接创建完整索引&#xff1a;这是最简单的方式&#xff0c;直接对整个字符串字段创建索引。这种方式占用的空间较大&#xff0c;但查询性能通常较好&#xff0c;特别是在精确匹配的情况下。…...

Qt pro文件中 CONFIG += debug 作用

作用 在 Qt 项目文件&#xff08;.pro 文件&#xff09;中&#xff0c;CONFIG debug 的作用是指定项目以调试模式进行构建。 当在项目文件中添加 debug 到 CONFIG 变量时&#xff0c;Qt 构建系统将使用调试配置来编译项目。 这意味着编译器将生成带有调试信息的可执行文件&a…...

java解析生成定时Cron表达式工具类

Cron表达式工具类CronUtil 构建Cron表达式 /****方法摘要&#xff1a;构建Cron表达式*param taskScheduleModel*return String*/public static String createCronExpression(TaskScheduleModel taskScheduleModel){StringBuffer cronExp new StringBuffer("");if(…...

庆祝1024

在CSDN1024这一天&#xff0c;我不禁回想起自己这几年来在这个平台上的经历。回忆着初来时的稚嫩&#xff0c;如今的迷茫与期待&#xff0c;我深深地感受到自己还需不断努力。 回想起八年前&#xff0c;我刚刚步入计算机科学与技术的领域&#xff0c;满怀激情地加入了CSDN这个高…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...