sentinel-1.8.7与nacos-2.3.0实现动态规则配置、双向同步

😊 @ 作者: 一恍过去
💖 @ 主页: https://blog.csdn.net/zhuocailing3390
🎊 @ 社区: Java技术栈交流
🎉 @ 主题: sentinel-1.8.7与nacos-2.3.0实现动态规则配置、双向同步
⏱️ @ 创作时间: 2024年04月2日

目录

  • 1、为什么整合Nacos
  • 2、源码拉取
  • 3、创建公共配置
  • 4、控制台规则配置
    • 4.1、流控规则
    • 4.2、熔断降级规则
    • 4.3、热点规则
    • 4.4、系统规则
    • 4.5、授权规则
  • 5、网关控制台规则配置
    • 5.1、API管理
    • 5.2、流程规则
    • 5.3、降级规则
    • 5.4、系统规则
  • 6、效果测试
  • 7、整合Cloud使用
  • 8、打包部署
  • 9、源码包下载

1、为什么整合Nacos

默认情况下Sentinel配置的规则是储存的内存中,在重新Sentinel服务后,配置会显示,我们通过整合第三方中间件实现,配置的持久化,比如使用Nacos

我们要实现SentinelNacos的双向同步持久化,就需要对sentinel-dashboard的源码包进行修改。

2、源码拉取

1、下载源码压缩包
在Sentinel-github下载需要版本的压缩包,比如Sentinel-1.8.7.zip,或者直接从Git上将代码Clone

2、加载源码
将下载好的Sentinel-1.8.7.zip解压,使用IDE工具,打开sentinel-dashboard工程,或者直接从Git上将代码Clone
在这里插入图片描述

3、创建公共配置

在进行规则代码修改之前需要创建Nacos配置文件,在com.alibaba.csp.sentinel.dashboard.rule包下创建nacos包,并且在包下创建四个类:RuleNacosConfigRuleNacosProviderRuleNacosPublisherNacosConfigUtil
在这里插入图片描述

RuleNacosConfig:

package com.alibaba.csp.sentinel.dashboard.rule.nacos;import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigFactory;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.Properties;@Configuration
public class NacosConfig {@Beanpublic ConfigService nacosConfigService() throws Exception {Properties properties = new Properties();properties.put(PropertyKeyConst.SERVER_ADDR, "localhost:8848");// properties.put(PropertyKeyConst.NAMESPACE, "xxx");properties.put(PropertyKeyConst.USERNAME, "nacos");properties.put(PropertyKeyConst.PASSWORD, "nacos");return ConfigFactory.createConfigService(properties);}
}

RuleNacosProvider:

package com.alibaba.csp.sentinel.dashboard.rule.nacos;import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class RuleNacosProvider {@Autowiredprivate ConfigService configService;public String getRules(String dataId) throws Exception {// 将服务名称设置为GroupIdreturn configService.getConfig(dataId, NacosConfigUtil.GROUP_ID, 3000);}
}

RuleNacosPublisher:

package com.alibaba.csp.sentinel.dashboard.rule.nacos;import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class RuleNacosPublisher {@Autowiredprivate ConfigService configService;public void publish(String dataId, String rules) {try {if (rules == null) {return;}configService.publishConfig(dataId, NacosConfigUtil.GROUP_ID, rules);} catch (NacosException e) {throw new RuntimeException(e);}}
}

NacosConfigUtil:

package com.alibaba.csp.sentinel.dashboard.rule.nacos;/*** @author Eric Zhao* @since 1.4.0*/
public final class NacosConfigUtil {public static final String GROUP_ID = "SENTINEL_GROUP";public static final String FLOW_DATA_ID_POSTFIX = "-flow-rules";public static final String GATEWAY_FLOW_DATA_ID_POSTFIX = "-gateway-rules";public static final String AUTHORITY_FLOW_DATA_ID_POSTFIX = "-authority-rules";public static final String SYSTEM_FLOW_DATA_ID_POSTFIX = "-system-rules";public static final String DEGRADE_FLOW_DATA_ID_POSTFIX = "-degrade-rules";public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-rules";public static final String CLUSTER_MAP_DATA_ID_POSTFIX = "-cluster-map";/*** cc for `cluster-client`*/public static final String CLIENT_CONFIG_DATA_ID_POSTFIX = "-cc-config";/*** cs for `cluster-server`*/public static final String SERVER_TRANSPORT_CONFIG_DATA_ID_POSTFIX = "-cs-transport-config";public static final String SERVER_FLOW_CONFIG_DATA_ID_POSTFIX = "-cs-flow-config";public static final String SERVER_NAMESPACE_SET_DATA_ID_POSTFIX = "-cs-namespace-set";private NacosConfigUtil() {}
}

4、控制台规则配置

通过修改源码,实现流控规则、降级规则、热点规则、系统规则、授权规则的持久化操作;

4.1、流控规则

修改FlowControllerV1:
RuleNacosPublisherRuleNacosProvider注入到FlowControllerV1

// 加入以下代码:
@Autowired
private RuleNacosProvider ruleProvider;
@Autowired
private RuleNacosPublisher rulePublisher;

修改读取逻辑:

// 修改位置如下:
List<FlowRuleEntity> rules = sentinelApiClient.fetchFlowRuleOfMachine(app, ip, port);// 将上面代码修改为以下代码:
String ruleStr = ruleProvider.getRules(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX);
List<FlowRuleEntity> rules = new ArrayList<>();
if (ruleStr != null) {rules = JSON.parseArray(ruleStr, FlowRuleEntity.class);if (rules != null && !rules.isEmpty()) {for (FlowRuleEntity entity : rules) {entity.setApp(app);}}
}

修改推送逻辑:

// 1、修改位置如下:
private CompletableFuture<Void> publishRules(String app, String ip, Integer port) {List<FlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));return sentinelApiClient.setFlowRuleOfMachineAsync(app, ip, port, rules);
}// 将上面代码修改为以下代码:
private void publishRules(String app) {List<FlowRuleEntity> rules = repository.findAllByApp(app);String ruleStr = JSON.toJSONString(rules);rulePublisher.publish(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX, ruleStr);
}
=======================================================================================// 2、修改位置如下:有两处
publishRules(entity.getApp(), entity.getIp(), entity.getPort()).get(5000, TimeUnit.MILLISECONDS);// 将上面代码修改为以下代码:
publishRules(entity.getApp());
=======================================================================================// 3、修改位置如下:
publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort()).get(5000, TimeUnit.MILLISECONDS);// 将上面代码修改为以下代码:
publishRules(oldEntity.getApp());

4.2、熔断降级规则

修改DegradeController:
RuleNacosProviderRuleNacosPublisher注入到DegradeController

// 加入以下代码:
@Autowired
private RuleNacosProvider ruleProvider;
@Autowired
private RuleNacosPublisher rulePublisher;

修改读取逻辑:

// 修改位置如下:
List<DegradeRuleEntity> rules = sentinelApiClient.fetchDegradeRuleOfMachine(app, ip, port);// 将上面代码修改为以下代码:
String ruleStr = ruleProvider.getRules(app + NacosConfigUtil.DEGRADE_FLOW_DATA_ID_POSTFIX);
List<DegradeRuleEntity> rules = new ArrayList<>();
if (ruleStr != null) {rules = JSON.parseArray(ruleStr, DegradeRuleEntity.class);if (rules != null && !rules.isEmpty()) {for (DegradeRuleEntity entity : rules) {entity.setApp(app);}}
}
rules = repository.saveAll(rules);
return Result.ofSuccess(rules);

修改推送逻辑:

// 1、修改位置如下:
private boolean publishRules(String app, String ip, Integer port) {List<DegradeRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));return sentinelApiClient.setDegradeRuleOfMachine(app, ip, port, rules);
}// 将上面代码修改为以下代码:
private boolean publishRules(String app) {List<DegradeRuleEntity> rules = repository.findAllByApp(app);String ruleStr = JSON.toJSONString(rules);rulePublisher.publish(app + NacosConfigUtil.DEGRADE_FLOW_DATA_ID_POSTFIX, ruleStr);return true;
}
=======================================================================================// 2、修改位置如下:有两处
if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {logger.warn("Publish degrade rules failed, app={}", entity.getApp());
}// 将上面代码修改为以下代码:
if (!publishRules(entity.getApp())){logger.warn("Publish degrade rules failed, app={}", entity.getApp());
}
=======================================================================================// 3、修改位置如下:
if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {logger.warn("Publish degrade rules failed, app={}", oldEntity.getApp());
}// 将上面代码修改为以下代码:
if (!publishRules(oldEntity.getApp())){logger.warn("Publish degrade rules failed, app={}", entity.getApp());
}

4.3、热点规则

修改ParamFlowRuleController:
RuleNacosProviderRuleNacosPublisher注入到ParamFlowRuleController

// 加入以下代码:
@Autowired
private RuleNacosProvider ruleProvider;
@Autowired
private RuleNacosPublisher rulePublisher;

修改读取逻辑:

// 修改位置如下:
return sentinelApiClient.fetchParamFlowRulesOfMachine(app, ip, port).thenApply(repository::saveAll).thenApply(Result::ofSuccess).get();// 将上面代码修改为以下代码:
String ruleStr = ruleProvider.getRules(app + NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX);
List<ParamFlowRuleEntity> rules = new ArrayList<>();
if (ruleStr != null) {rules = JSON.parseArray(ruleStr, ParamFlowRuleEntity.class);if (rules != null && !rules.isEmpty()) {for (ParamFlowRuleEntity entity : rules) {entity.setApp(app);}}
}
rules = repository.saveAll(rules);
return Result.ofSuccess(rules);

修改推送逻辑:

// 1、修改位置如下:
private CompletableFuture<Void> publishRules(String app, String ip, Integer port) {List<ParamFlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));return sentinelApiClient.setParamFlowRuleOfMachine(app, ip, port, rules);
}// 将上面代码修改为以下代码:
private void publishRules(String app) {try {List<ParamFlowRuleEntity> rules = repository.findAllByApp(app);String ruleStr = JSON.toJSONString(rules);rulePublisher.publish(app + NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX, ruleStr);} catch (Exception e) {e.printStackTrace();}
}
=======================================================================================// 2、修改位置如下:有两处
try {entity = repository.save(entity);publishRules(entity.getApp(), entity.getIp(), entity.getPort()).get();return Result.ofSuccess(entity);
} catch (ExecutionException ex) {....
}
// 将上面代码修改为以下代码:
try {entity = repository.save(entity);publishRules(entity.getApp());return Result.ofSuccess(entity);
} catch (Exception ex) {....
}
=======================================================================================// 3、修改位置如下:
try {repository.delete(id);publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort()).get();return Result.ofSuccess(id);
} catch (ExecutionException ex) {....
}// 将上面代码修改为以下代码:
try {repository.delete(id);publishRules(oldEntity.getApp());return Result.ofSuccess(id);
} catch (Exception ex) {....
}

4.4、系统规则

修改SystemController:
RuleNacosProviderRuleNacosPublisher注入到SystemController

// 加入以下代码:
@Autowired
private RuleNacosProvider ruleProvider;
@Autowired
private RuleNacosPublisher rulePublisher;

修改读取逻辑:

// 修改位置如下:
List<SystemRuleEntity> rules = sentinelApiClient.fetchSystemRuleOfMachine(app, ip, port);// 将上面代码修改为以下代码:
String ruleStr = ruleProvider.getRules(app + NacosConfigUtil.SYSTEM_FLOW_DATA_ID_POSTFIX);
List<SystemRuleEntity> rules = new ArrayList<>();
if (ruleStr != null) {rules = JSON.parseArray(ruleStr, SystemRuleEntity.class);if (rules != null && !rules.isEmpty()) {for (SystemRuleEntity entity : rules) {entity.setApp(app);}}
}

修改推送逻辑:

// 1、修改位置如下:
private boolean publishRules(String app, String ip, Integer port) {List<SystemRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));return sentinelApiClient.setSystemRuleOfMachine(app, ip, port, rules);
}// 将上面代码修改为以下代码:
private boolean publishRules(String app) {List<SystemRuleEntity> rules = repository.findAllByApp(app);String ruleStr = JSON.toJSONString(rules);rulePublisher.publish(app + NacosConfigUtil.SYSTEM_FLOW_DATA_ID_POSTFIX, ruleStr);return true;
}
=======================================================================================// 2、修改位置如下
if (!publishRules(app, ip, port)) {logger.warn("Publish system rules fail after rule add");
}// 将上面代码修改为以下代码:
if (!publishRules(entity.getApp())) {logger.warn("Publish system rules fail after rule add");
}
=======================================================================================// 3、修改位置如下
if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {logger.info("publish system rules fail after rule update");
}// 将上面代码修改为以下代码:
if (!publishRules(entity.getApp())) {logger.warn("Publish system rules fail after rule add");
}
=======================================================================================// 4、修改位置如下:
if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {logger.info("publish system rules fail after rule delete");
}// 将上面代码修改为以下代码:
if (!publishRules(oldEntity.getApp())) {logger.info("publish system rules fail after rule delete");
}

4.5、授权规则

修改AuthorityRuleController:
RuleNacosPublisherRuleNacosProvider注入到AuthorityRuleController

// 加入以下代码:
@Autowired
private RuleNacosProvider ruleProvider;
@Autowired
private RuleNacosPublisher rulePublisher;

修改读取逻辑:

// 修改位置如下:
List<AuthorityRuleEntity> rules = sentinelApiClient.fetchAuthorityRulesOfMachine(app, ip, port);// 将上面代码修改为以下代码:
String ruleStr = ruleProvider.getRules(app + NacosConfigUtil.SYSTEM_FLOW_DATA_ID_POSTFIX);
List<AuthorityRuleEntity> rules = new ArrayList<>();
if (ruleStr != null) {rules = JSON.parseArray(ruleStr, AuthorityRuleEntity.class);if (rules != null && !rules.isEmpty()) {for (AuthorityRuleEntity entity : rules) {entity.setApp(app);}}
}

修改推送逻辑:

// 1、修改位置如下:
private boolean publishRules(String app, String ip, Integer port) {List<AuthorityRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));return sentinelApiClient.setAuthorityRuleOfMachine(app, ip, port, rules);
}// 将上面代码修改为以下代码:
private boolean publishRules(String app) {List<AuthorityRuleEntity> rules = repository.findAllByApp(app);String ruleStr = JSON.toJSONString(rules);rulePublisher.publish(app + NacosConfigUtil.AUTHORITY_FLOW_DATA_ID_POSTFIX, ruleStr);return true;
}
=======================================================================================// 2、修改位置如下:有两处
if (!publishRules(entity.getApp(), entity.getIp(), entity.getPort())) {logger.info("Publish authority rules failed after rule update");
}// 将上面代码修改为以下代码:
if (!publishRules(entity.getApp())) {logger.info("Publish authority rules failed after rule update");
}
=======================================================================================// 3、修改位置如下:
if (!publishRules(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {logger.error("Publish authority rules failed after rule delete");
}// 将上面代码修改为以下代码:
if (!publishRules(oldEntity.getApp())) {logger.error("Publish authority rules failed after rule delete");
}

5、网关控制台规则配置

配置网关控制台规则,在启动网关时需要加上参数:-Dcsp.sentinel.app.type=1

本次源码修改中暂时没有做处理,如果需要可以参照下面的代码示例。

5.1、API管理

修改GatewayApiController:
RuleNacosPublisherRuleNacosProvider注入到GatewayApiController

// 加入以下代码:
@Autowired
private RuleNacosProvider ruleProvider;
@Autowired
private RuleNacosPublisher rulePublisher;

修改读取逻辑:

// 修改位置如下:
List<ApiDefinitionEntity> apis = sentinelApiClient.fetchApis(app, ip, port).get();// 将上面代码修改为以下代码:
String ruleStr = ruleProvider.getRules(app + NacosConfigUtil.GATEWAY_FLOW_DATA_ID_POSTFIX);
List<ApiDefinitionEntity> apis = new ArrayList<>();
if (ruleStr != null) {apis = JSON.parseArray(ruleStr, ApiDefinitionEntity.class);if (apis != null && !apis.isEmpty()) {for (ApiDefinitionEntity entity : apis) {entity.setApp(app);}}
}

修改推送逻辑:

// 1、修改位置如下:
private boolean publishApis(String app, String ip, Integer port) {List<ApiDefinitionEntity> apis = repository.findAllByMachine(MachineInfo.of(app, ip, port));return sentinelApiClient.modifyApis(app, ip, port, apis);
}// 将上面代码修改为以下代码:
private boolean publishApi(String app) {List<ApiDefinitionEntity> apis= repository.findAllByApp(app);
String ruleStr = JSON.toJSONString(apis);
rulePublisher.publish(app + NacosConfigUtil.GATEWAY_FLOW_DATA_ID_POSTFIX, ruleStr);
return true;
}
=======================================================================================// 2、修改位置如下
if (!publishApis(app, ip, port)) {logger.warn("publish gateway apis fail after add");
}// 将上面代码修改为以下代码:
if (!publishApis(entity.getApp())) {logger.warn("publish gateway apis fail after add");
}
=======================================================================================// 3、修改位置如下
if (!publishApis(app, entity.getIp(), entity.getPort())) {logger.warn("publish gateway apis fail after update");
}// 将上面代码修改为以下代码:
if (!publishApis(entity.getApp())
=======================================================================================// 4、修改位置如下:
if (!publishApis(oldEntity.getApp(), oldEntity.getIp(), oldEntity.getPort())) {logger.warn("publish gateway apis fail after delete");
}// 将上面代码修改为以下代码:
if (!publishApis(oldEntity.getApp())) {logger.warn("publish gateway apis fail after delete");
}

5.2、流程规则

使用的是控制台规则配置中的流控规则接口,无需在做操作,参考《4.1、流控规则》。

5.3、降级规则

使用的是控制台规则配置中的降级规则接口,无需在做操作,参考《4.2、降级规则》。

5.4、系统规则

使用的是控制台规则配置中的系统规则接口,无需在做操作,参考《4.4、系统规则》。

6、效果测试

我们以流控规则为例,演示一个数据同步持久化的操作;

1、nacos同步到sentinel:

需要注意的是,nacos中的分组必须为SENTINEL_GROUP

在nacos中,新增配置文件,文件的DataId为user-service-flow-rules,内容为:

[{"app":"user-service",// 服务名称"resource": "/list", //资源名称"count": 1, //阀值"grade": 1, //阀值类型,0表示线程数,1表示QPS;"limitApp": "default", //来源应用	"strategy": 0,// 流控模式,0表示直接,1表示关联,2表示链路;"controlBehavior": 0 //流控效果,0表示快速失败,1表示Warm Up,2表示排队等待}
]

在这里插入图片描述

查看Sentinel控制台:数据已经实现了同步
在这里插入图片描述

2、sentinel同步到nacos:

我们在sentinel控制台,建立任意流控规则,如下:
在这里插入图片描述

查看Nacos控制台:配置数据已经实现了同步
在这里插入图片描述

7、整合Cloud使用

整合cloud使用时,需要调整配置文件,以流控规则热点规则为例,其他的规则可以参考着进行配置,配置中的rule-typegroupIddataId需要写对(与nacos匹配)

spring:cloud:sentinel:transport:port: 9999 #跟控制台交流的端口,随意指定一个未使用的端口即可dashboard: 127.0.0.1:8080 # 指定控制台服务的地址#添加Nacos数据源配置datasource:#名字自定义即可,配置流控规则sentinel-flow:nacos:server-addr: 127.0.0.1:8848username: nacospassword: nacosrule-type: flowgroupId: SENTINEL_GROUP#namespace: publicdataId: user-service-flow-rules#名字自定义即可,配置热点规则sentinel-param:nacos:server-addr: 127.0.0.1:8848username: nacospassword: nacosrule-type: param-flowgroupId: SENTINEL_GROUP#namespace: publicdataId: user-service-param-rules

8、打包部署

进入到sentinel-dashboard所在目的,通过mvn clean install package -DskipTests=true进行打包。

部署jar参考:
《Linux搭建Sentinel 控制台环境》
《Docker搭建Sentinel 控制台环境》

9、源码包下载

对于上述修改的代码,源码下载地址:
https://gitee.com/lhzlx/sentinel-nacos.git

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

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

相关文章

unity的特性AttriBute详解

unity的特性AttriBute曾经令我大为头疼。因为不动使用的法则&#xff0c;但是教程都是直接就写&#xff0c;卡住就不能继续学下去。令我每一次看到&#xff0c;直接不敢看了。 今天使用文心一言搜索一番&#xff0c;发现&#xff0c;恐惧都是自己想象的&#xff0c;实际上这个…

Kotlin泛型之 循环引用泛型(A的泛型是B的子类,B的泛型是A的子类)

IDE(编辑器)报错 循环引用泛型是我起的名字&#xff0c;不知道官方的名字是什么。这个问题是我在定义Android 的MVP时提出来的。具体是什么样的呢&#xff1f;我们看一下我的基础的MVP定义&#xff1a; interface IPresenter<V> { fun getView(): V }interface IVie…

Nodejs 第六十八章(远程桌面)

远程桌面 远程桌面&#xff08;Remote Desktop&#xff09;是一种技术&#xff0c;允许用户通过网络远程连接到另一台计算机&#xff0c;并在本地计算机上控制远程计算机的操作。通过远程桌面&#xff0c;用户可以在不同地点的计算机之间共享屏幕、键盘和鼠标&#xff0c;就像…

宝塔面板安装教程(linux)

宝塔官网地址 宝塔官网linux安装地址 针对Ubuntu系统的安装命令&#xff1a; wget -O install.sh https://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh ed8484bec 安装过程中&#xff0c;中途会出现一个 Y&N ? 的选项&#xf…

OpenCV如何模板匹配

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV如何实现背投 下一篇 &#xff1a;OpenCV在图像中寻找轮廓 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 使用 OpenCV 函数 matchTemplate()搜索图像贴片和输入图像之间…

如何下载AndroidStudio旧版本

文章目录 1. Android官方网站2. 往下滑找到历史版本归档3. 同意软件下载条款协议4. 下载旧版本Androidstudio1. Android官方网站 点击 Android官网AS下载页面 https://developer.android.google.cn/studio 进入AndroidStuido最新版下载页面,如下图: 2. 往下滑找到历史版本归…

一本书了解AI的下一个风口:AI Agent

在数字化浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;已成为推动现代社会前进的强劲引擎。 从智能手机的智能助手到自动驾驶汽车的精准导航&#xff0c;AI技术的应用已经渗透到生活的方方面面。 随着技术的飞速发展&#xff0c;我们正站在一个新的转折点上&#xff…

构建本地大语言模型知识库问答系统

MaxKB 2024 年 4 月 12 日&#xff0c;1Panel 开源项目组正式对外介绍了其官方出品的开源子项目 ——MaxKB&#xff08;github.com/1Panel-dev/MaxKB&#xff09;。MaxKB 是一款基于 LLM&#xff08;Large Language Model&#xff09;大语言模型的知识库问答系统。MaxKB 的产品…

[论文笔记]GAUSSIAN ERROR LINEAR UNITS (GELUS)

引言 今天来看一下GELU的原始论文。 作者提出了GELU(Gaussian Error Linear Unit,高斯误差线性单元)非线性激活函数&#xff1a; GELU x Φ ( x ) \text{GELU} x\Phi(x) GELUxΦ(x)&#xff0c;其中 Φ ( x ) \Phi(x) Φ(x)​是标准高斯累积分布函数。与ReLU激活函数通过输入…

网盘—上传文件

本文主要讲解网盘里面关于文件操作部分的上传文件&#xff0c;具体步骤如下 目录 1、实施步骤&#xff1a; 2、代码实现 2.1、添加上传文件协议 2.2、添加上传文件槽函数 2.3、添加槽函数定义 2.4、关联上传槽函数 2.5、服务器端 2.6、在服务器端添加上传文件请求的ca…

算法学习(5)-图的遍历

目录 什么是深度和广度优先 图的深度优先遍历-城市地图 图的广度优先遍历-最少转机 什么是深度和广度优先 使用深度优先搜索来遍历这个图的过程具体是&#xff1a; 首先从一个未走到过的顶点作为起始顶点&#xff0c; 比如以1号顶点作为起点。沿1号顶点的边去尝试访问其它未…

提升编码技能:学习如何使用 C# 和 Fizzler 获取特价机票

引言 五一假期作为中国的传统节日&#xff0c;也是旅游热门的时段之一&#xff0c;特价机票往往成为人们关注的焦点。在这个数字化时代&#xff0c;利用爬虫技术获取特价机票信息已成为一种常见的策略。通过结合C#和Fizzler库&#xff0c;我们可以更加高效地实现这一目标&…

2024年---蓝桥杯网络安全赛道部分WP

一、题目名称&#xff1a;packet 1、下载附件是一个流量包 2、用wireshark分析&#xff0c;看到了一个cat flag的字样 3、追踪http数据流&#xff0c;在下面一行看到了base64编码。 4、解码之后得到flag 二、题目名称&#xff1a;cc 1、下载附件&#xff0c;打开是一个html …

Docker构建LNMP部署WordPress

前言 使用容器化技术如 Docker 可以极大地简化应用程序的部署和管理过程&#xff0c;本文将介绍如何利用 Docker 构建 LNMP 环境&#xff0c;并通过部署 WordPress 来展示这一过程。 目录 一、环境准备 1. 项目需求 2. 安装包下载 3. 服务器环境 4. 规划工作目录 5. 创…

CAPS Wizard for Mac:打字输入辅助应用

CAPS Wizard for Mac是一款专为Mac用户设计的打字输入辅助应用&#xff0c;以其简洁、高效的功能&#xff0c;为用户带来了全新的打字体验。 CAPS Wizard for Mac v5.3激活版下载 该软件能够智能预测用户的输入内容&#xff0c;实现快速切换和自动大写锁定&#xff0c;从而大大…

OmniReader Pro for Mac:强大且全面的阅读工具

OmniReader Pro for Mac是一款专为Mac用户设计的强大且全面的阅读工具&#xff0c;它集阅读、编辑、管理等多种功能于一身&#xff0c;为用户提供了卓越的阅读体验。 OmniReader Pro for Mac v2.9.5激活版下载 该软件支持多种文件格式的阅读&#xff0c;包括PDF、Word、Excel、…

pycharm配置wsl开发环境(conda)

背景 在研究qanything项目的过程中&#xff0c;为了进行二次开发&#xff0c;需要在本地搭建开发环境。然后根据文档说明发现该项目并不能直接运行在windows开发环境&#xff0c;但可以运行在wsl环境中。于是我需要先创建wsl环境并配置pycharm。 wsl环境创建 WSL是“Windows Su…

新时代写作与互动:《一本书讲透 Elasticsearch》读者群的创新之路

1、《一本书讲透 Elasticsearch》销售最近进展汇报 给大家同步一下《一本书讲透 Elasticsearch》图书的进展情况&#xff0c;本周五&#xff08;2024年4月26日&#xff09;&#xff0c;出版社编辑老师反馈图书相关销量进展&#xff1a; 预计全网销量 1000 册&#xff0c;发货量…

OpenHarmony语言基础类库【@ohos.xml (xml解析与生成)】

将XML文本转换为JavaScript对象、以及XML文件生成和解析的一系列接口。 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import xml from ohos.xml; XmlSerializer XmlSerializer接口…

FPGA实现图像处理之【直方图均衡-寄存器版】

FPGA实现直方图统计 一、图像直方图统计原理 直方图的全称为灰度直方图&#xff0c;是对图像每一灰度间隔内像素个数的统计。即对一张图片中每隔二灰度值的像素数量做统计&#xff0c;然后以直方图的形式展现出来。图下的亮暗分布在直方图中就可以一目了然&#xff0c;直方图…