自定义责任链Filter实现

核心接口

Filter

package com.xxx.arch.mw.nbp.common.extension;import com.xxx.commons.data.domain.Result;/*** @date 2023/08/25*/
public interface Filter {Result invoke(final Invoker invoker, final Invocation invocation);
}

Invoker

package com.xxx.arch.mw.nbp.common.extension;import com.xxx.commons.data.domain.Result;/*** @date 2023/08/25*/
public interface Invoker {Result invoke(Invocation invocation);
}

Invocation

package com.xxx.arch.mw.nbp.common.extension;import com.xxx.arch.mw.nbp.share.dto.PropertyDTO;/*** @date 2023/08/25*/
public interface Invocation<T> {T getDetail();PropertyDTO getProperty();boolean isAsync();}

关键类

FilterChain

package com.xxx.arch.mw.nbp.common.extension;import com.xxx.arch.mw.nbp.common.annotation.DispatchFilter;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;/*** @date 2023/08/28*/
public class FilterChain {private final List<Filter> filters = new ArrayList<>();public FilterChain() {}public void addFilter(Filter filter) {if (filter == null || filter.getClass().getAnnotation(DispatchFilter.class) == null) {return;}if (this.filters.stream().noneMatch(existFilter -> existFilter.getClass().equals(filter.getClass()))) {this.filters.add(filter);}}public void removeFilter(String filterName) {this.filters.removeIf(filter -> filter.getClass().getAnnotation(DispatchFilter.class).value().equals(filterName));}public void removeFilter(Filter filter) {this.filters.removeIf(aFilter -> aFilter.getClass().equals(filter.getClass()));}public Invoker buildInvokerChain(final Invoker invoker) {Invoker last = invoker;if (!filters.isEmpty()) {this.sort();for (int i = filters.size() - 1; i >= 0; i--) {final Filter filter = filters.get(i);final Invoker next = last;last = invocation -> filter.invoke(next, invocation);}}return last;}public void sort() {Collections.sort(this.filters, FilterComparator.COMPARATOR);}public List<Filter> getFilters() {return filters;}
}

FilterComparator

package com.xxx.arch.mw.nbp.common.extension;import com.xxx.arch.mw.nbp.common.annotation.DispatchFilter;import java.util.Comparator;/*** @date 2023/08/28*/
public class FilterComparator implements Comparator<Object>  {public static final Comparator<Object> COMPARATOR = new FilterComparator();@Overridepublic int compare(Object o1, Object o2) {if (o1 == null && o2 == null) {return 0;}if (o1 == null) {return -1;}if (o2 == null) {return 1;}if (o1.equals(o2)) {return 0;}DispatchFilter a1 = o1.getClass().getAnnotation(DispatchFilter.class);DispatchFilter a2 = o2.getClass().getAnnotation(DispatchFilter.class);int n1 = a1 == null ? 0 : a1.order();int n2 = a2 == null ? 0 : a2.order();// never return 0 even if n1 equals n2, otherwise, o1 and o2 will override each other in collection like HashSetreturn n1 > n2 ? 1 : -1;}
}

SingleInvocation

package com.xxx.arch.mw.nbp.common.extension;import com.xxx.arch.mw.nbp.share.dto.PropertyDTO;
import com.xxx.arch.mw.nbp.share.dto.SingleDetailDTO;/*** @date 2023/08/28*/
public class SingleInvocation implements Invocation<SingleDetailDTO> {private final SingleDetailDTO singleDetailDTO;private final PropertyDTO propertyDTO;private final boolean async;public SingleInvocation(SingleDetailDTO singleDetailDTO, PropertyDTO propertyDTO) {this.singleDetailDTO = singleDetailDTO;this.propertyDTO = propertyDTO;this.async = false;}public SingleInvocation(SingleDetailDTO singleDetailDTO, PropertyDTO propertyDTO, boolean async) {this.singleDetailDTO = singleDetailDTO;this.propertyDTO = propertyDTO;this.async = async;}@Overridepublic SingleDetailDTO getDetail() {return singleDetailDTO;}@Overridepublic PropertyDTO getProperty() {return propertyDTO;}@Overridepublic boolean isAsync() {return this.async;}
}

MultiInvocation

package com.xxx.arch.mw.nbp.common.extension;import com.xxx.arch.mw.nbp.share.dto.PropertyDTO;
import com.xxx.arch.mw.nbp.share.dto.SingleDetailDTO;import java.util.List;/*** @date 2023/08/28*/
public class MultiInvocation implements Invocation<List<SingleDetailDTO>> {private final List<SingleDetailDTO> singleDetailDTOS;private final PropertyDTO propertyDTO;private final boolean async;public MultiInvocation(List<SingleDetailDTO> singleDetailDTOS, PropertyDTO propertyDTO) {this.singleDetailDTOS = singleDetailDTOS;this.propertyDTO = propertyDTO;this.async = false;}public MultiInvocation(List<SingleDetailDTO> singleDetailDTOS, PropertyDTO propertyDTO, boolean async) {this.singleDetailDTOS = singleDetailDTOS;this.propertyDTO = propertyDTO;this.async = async;}@Overridepublic List<SingleDetailDTO> getDetail() {return singleDetailDTOS;}@Overridepublic PropertyDTO getProperty() {return propertyDTO;}@Overridepublic boolean isAsync() {return this.async;}
}

自定义Filter

选取几个经典实现

ValidationFilter

package com.xxx.arch.mw.nbp.client.extension;import com.xxx.arch.mw.nbp.common.annotation.DispatchFilter;
import com.xxx.arch.mw.nbp.common.constant.FilterConstants;
import com.xxx.arch.mw.nbp.common.domain.NbpCode;
import com.xxx.arch.mw.nbp.common.exception.NbpException;
import com.xxx.arch.mw.nbp.common.extension.*;
import com.xxx.arch.mw.nbp.share.dto.SingleDetailDTO;
import com.xxx.commons.data.domain.Result;import java.util.List;/*** @date 2023/08/28*/
@DispatchFilter(group = {FilterConstants.PUBLISHER, FilterConstants.EXECUTOR}, value = "validation", order = 20)
public class ValidationFilter implements Filter {@Overridepublic Result invoke(final Invoker invoker, final Invocation invocation) {if (invoker == null) {throw new NbpException(NbpCode.ILLEGAL_PARAM.getCode(), "invoker can't be null");}if (invocation == null) {throw new NbpException(NbpCode.ILLEGAL_PARAM.getCode(), "invocation can't be null");}if (invocation.getDetail() == null) {throw new NbpException(NbpCode.ILLEGAL_PARAM.getCode(), "detail can't be null");}if (invocation.getProperty() == null) {throw new NbpException(NbpCode.ILLEGAL_PARAM.getCode(), "property can't be null");}if (invocation instanceof SingleInvocation) {this.validate(((SingleInvocation) invocation).getDetail());} else if (invocation instanceof MultiInvocation) {List<SingleDetailDTO> singleDetailDTOList = ((MultiInvocation) invocation).getDetail();if (singleDetailDTOList.isEmpty()) {throw new NbpException(NbpCode.ILLEGAL_PARAM.getCode(), "singleDetailList can't be null or empty");}for (SingleDetailDTO singleDetail : singleDetailDTOList) {this.validate(singleDetail);}}return invoker.invoke(invocation);}private void validate(SingleDetailDTO singleDetail) {if (singleDetail == null) {throw new NbpException(NbpCode.ILLEGAL_PARAM.getCode(), "singleDetail can't be null");}if (singleDetail.getTemplateCode() == null) {throw new NbpException(NbpCode.ILLEGAL_PARAM.getCode(), "templateCode can't be null");}if (singleDetail.getUserContext() == null || singleDetail.getUserContext().size() == 0) {throw new NbpException(NbpCode.ILLEGAL_PARAM.getCode(), "userContext can't be null or empty");}}
}

PublishMetricFilter

package com.xxx.arch.mw.nbp.client.extension;import com.xxx.arch.mw.nbp.client.util.EnvUtils;
import com.xxx.arch.mw.nbp.client.util.VersionUtils;
import com.xxx.arch.mw.nbp.common.annotation.DispatchFilter;
import com.xxx.arch.mw.nbp.common.constant.FilterConstants;
import com.xxx.arch.mw.nbp.common.constant.InstanceKey;
import com.xxx.arch.mw.nbp.common.constant.TraceKey;
import com.xxx.arch.mw.nbp.common.domain.NbpCode;
import com.xxx.arch.mw.nbp.common.exception.NbpException;
import com.xxx.arch.mw.nbp.common.extension.*;
import com.xxx.arch.mw.nbp.common.util.TraceUtil;
import com.xxx.arch.mw.nbp.share.dto.MultiResult;
import com.xxx.arch.mw.nbp.share.dto.SingleDetailDTO;
import com.xxx.commons.data.domain.Result;
import com.xxx.commons.data.exception.ServiceException;
import org.apache.commons.lang3.time.StopWatch;import java.util.List;
import java.util.Map;import static com.xxx.arch.mw.nbp.client.logger.LoggerInit.LOGGER_PUBLISH;/*** @date 2023/08/28*/
@DispatchFilter(group = {FilterConstants.PUBLISHER}, value = "publishMetric", order = 200)
public class PublishMetricFilter implements Filter {@Overridepublic Result invoke(final Invoker invoker, final Invocation invocation) {if (Boolean.TRUE.equals(invocation.getProperty().getPublisher().getMetricDisabled())) {return invoker.invoke(invocation);}Result result;StopWatch stopWatch = new StopWatch();try {stopWatch.start();result = invoker.invoke(invocation);stopWatch.stop();if (result.isSuccess()) {MultiResult<SingleDetailDTO> resultData = (MultiResult<SingleDetailDTO>) result.getData();for (SingleDetailDTO singleDetail : resultData.getSuccessList()) {this.log(singleDetail, true, stopWatch, null);}for (SingleDetailDTO singleDetail : resultData.getFailureList()) {this.log(singleDetail, false, stopWatch, null);}} else {// 仅PublishExceptionFilter被禁用才会走该分支if (invocation instanceof SingleInvocation) {this.log(((SingleInvocation) invocation).getDetail(), false, stopWatch,new NbpException(result.getCode(), result.getMessage(), result.getCause()));} else if (invocation instanceof MultiInvocation) {List<SingleDetailDTO> singleDetailDTOList = ((MultiInvocation) invocation).getDetail();for (SingleDetailDTO singleDetail : singleDetailDTOList) {this.log(singleDetail, false, stopWatch,new NbpException(result.getCode(), result.getMessage(), result.getCause()));}}}} catch (Throwable e) {if (stopWatch.isStarted()) {stopWatch.stop();}if (invocation instanceof SingleInvocation) {this.log(((SingleInvocation) invocation).getDetail(), false, stopWatch, e);} else if (invocation instanceof MultiInvocation) {List<SingleDetailDTO> singleDetailDTOList = ((MultiInvocation) invocation).getDetail();for (SingleDetailDTO singleDetail : singleDetailDTOList) {this.log(singleDetail, false, stopWatch, e);}}throw e;}return result;}private void log(SingleDetailDTO singleDetail, boolean success, StopWatch stopWatch,Throwable throwable) {Map<String, Object> systemContext = singleDetail.getSystemContext();LOGGER_PUBLISH.info("NBP-CLIENT METRIC PUBLISH","success={},elapsed={},env={},shadow={},traceId={},rpcId={},version={},"+ "code={},id={},bizKey={},triggerTime={},strategyId={},ruleId={},msgId={},"+ "publishedTime={},publishedIp={},receivedTime={},receivedIp={},"+ "errorCode={}",success, stopWatch.getTime(), EnvUtils.getCurrentEnv().name(),TraceUtil.isShadow(), TraceUtil.getTraceId(), TraceUtil.getRpcId(),VersionUtils.VERSION, singleDetail.getTemplateCode(), singleDetail.getInstanceId(),singleDetail.getBizKey(), singleDetail.getTriggerTime(),systemContext.get(InstanceKey.STRATEGY_ID),systemContext.get(InstanceKey.RULE_ID),singleDetail.getUserContext().get(InstanceKey.DISASTER_MSG_ID),systemContext.get(TraceKey.PUBLISHED_TIME),systemContext.get(TraceKey.PUBLISHED_IP),systemContext.get(TraceKey.RECEIVED_TIME),systemContext.get(TraceKey.RECEIVED_IP),throwable == null ? null : throwable instanceof ServiceException ?((ServiceException) throwable).getCode() : NbpCode.UNKNOWN.getCode(),throwable == null ? null : throwable);}}

PublishTraceFilter

package com.xxx.arch.mw.nbp.client.extension;import com.xxx.arch.mw.nbp.common.annotation.DispatchFilter;
import com.xxx.arch.mw.nbp.common.constant.CommonConstants;
import com.xxx.arch.mw.nbp.common.constant.FilterConstants;
import com.xxx.arch.mw.nbp.common.extension.Filter;
import com.xxx.arch.mw.nbp.common.extension.Invocation;
import com.xxx.arch.mw.nbp.common.extension.Invoker;
import com.xxx.arch.mw.nbp.common.util.TraceUtil;
import com.xxx.arch.mw.nbp.share.dto.PropertyDTO;
import com.xxx.arch.mw.nbp.share.facade.DispatchPublishService;
import com.xxx.commons.data.domain.Result;
import com.xxx.arch.mw.util.RequestCtxUtil;import static com.xxx.arch.mw.nbp.common.util.TraceUtil.*;
import static com.xxx.arch.mw.nbp.common.util.TraceUtil.NBP_RPC_PUB_NAME;/*** @date 2023/08/28*/
@DispatchFilter(group = {FilterConstants.PUBLISHER}, value = "publishTrace", order = 100)
public class PublishTraceFilter implements Filter {@Overridepublic Result invoke(final Invoker invoker, final Invocation invocation) {final PropertyDTO property = invocation.getProperty();if (Boolean.TRUE.equals(property.getPublisher().getEagleEyeDisabled())) {return invoker.invoke(invocation);}Result result;try {TraceUtil.startRpc(String.join(CommonConstants.COLON, DispatchPublishService.class.getCanonicalName(),invocation.getProperty().getTemplateCode()), NBP_PUB_SEND_METHOD_NAME, NBP_RPC_PUB_TYPE);TraceUtil.rpcClientSend();result = invoker.invoke(invocation);final String remoteIp = RequestCtxUtil.getProviderIp();if (remoteIp != null) {TraceUtil.remoteIp(remoteIp);}if (result.isSuccess()) {TraceUtil.attribute(RPC_NAME_KEY, NBP_RPC_PUB_NAME);TraceUtil.rpcClientRecv(RPC_RESULT_SUCCESS, "success");} else {TraceUtil.attribute(RPC_NAME_KEY, NBP_RPC_PUB_NAME);TraceUtil.rpcClientRecv(RPC_RESULT_FAILED, result.getMessage());}} catch (Throwable e) {TraceUtil.attribute(RPC_NAME_KEY, NBP_RPC_PUB_NAME);TraceUtil.rpcClientRecv(RPC_RESULT_FAILED, e.getMessage());throw e;}return result;}
}

PublishExceptionFilter

package com.xxx.arch.mw.nbp.client.extension;import com.xxx.arch.mw.nbp.common.annotation.DispatchFilter;
import com.xxx.arch.mw.nbp.common.constant.FilterConstants;
import com.xxx.arch.mw.nbp.common.domain.NbpCode;
import com.xxx.arch.mw.nbp.common.exception.DegradeException;
import com.xxx.arch.mw.nbp.common.exception.FlowException;
import com.xxx.arch.mw.nbp.common.exception.NbpException;
import com.xxx.arch.mw.nbp.common.exception.RpcException;
import com.xxx.arch.mw.nbp.common.extension.Filter;
import com.xxx.arch.mw.nbp.common.extension.Invocation;
import com.xxx.arch.mw.nbp.common.extension.Invoker;
import com.xxx.commons.data.domain.Result;
import com.xxx.arch.mw.exception.RpcException;/*** @date 2023/08/28*/
@DispatchFilter(group = {FilterConstants.PUBLISHER}, value = "publishException", order = 300)
public class PublishExceptionFilter implements Filter {@Overridepublic Result invoke(final Invoker invoker, final Invocation invocation) {try {Result result = invoker.invoke(invocation);if (!result.isSuccess()) {if (NbpCode.FLOW_CONTROL_DENIED.getCode().equals(result.getCode())) {throw new FlowException(NbpCode.FLOW_CONTROL_DENIED.getCode(), result.getMessage(), result.getCause());} else if (NbpCode.BLACKLIST_DENIED.getCode().equals(result.getCode())) {throw new FlowException(NbpCode.BLACKLIST_DENIED.getCode(), result.getMessage(), result.getCause());} else if (NbpCode.DEGRADED_DENIED.getCode().equals(result.getCode())) {throw new DegradeException(NbpCode.DEGRADED_DENIED.getCode(), result.getMessage(), result.getCause());} else {throw new NbpException(result.getCode(), result.getMessage(), result.getCause());}}return result;} catch (NbpException e) {throw e;} catch (RpcException e) {throw new RpcException(NbpCode.RPC_ERROR.getCode(), e.getMessage(), e.getCause());} catch (Throwable e) {throw new NbpException(NbpCode.UNKNOWN.getCode(), e.getMessage(), e.getCause());}}}

PublishCompressFilter

package com.xxx.arch.mw.nbp.client.extension;import com.xxx.arch.mw.nbp.common.annotation.DispatchFilter;
import com.xxx.arch.mw.nbp.common.constant.CommonConstants;
import com.xxx.arch.mw.nbp.common.constant.FilterConstants;
import com.xxx.arch.mw.nbp.common.converter.ConverterUtil;
import com.xxx.arch.mw.nbp.common.csp.Compressor;
import com.xxx.arch.mw.nbp.common.csp.CompressorEnum;
import com.xxx.arch.mw.nbp.common.csp.CompressorFactory;
import com.xxx.arch.mw.nbp.common.extension.*;
import com.xxx.arch.mw.nbp.share.dto.PropertyDTO;
import com.xxx.arch.mw.nbp.share.dto.SingleDetailDTO;
import com.xxx.commons.data.domain.Result;import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import static com.xxx.arch.mw.nbp.common.constant.InstanceKey.COMPRESSED_ALGORITHM_KEY;
import static com.xxx.arch.mw.nbp.common.constant.InstanceKey.COMPRESSED_CONTEXT_KEY;/*** @date 2023/08/28*/
@DispatchFilter(group = {FilterConstants.PUBLISHER}, value = "publishCompress", order = 700)
public class PublishCompressFilter implements Filter {@Overridepublic Result invoke(final Invoker invoker, final Invocation invocation) {final PropertyDTO propertyDTO = invocation.getProperty();final boolean compressEnabled = propertyDTO.getPublisher().getCompressDisabled() != null ?!propertyDTO.getPublisher().getCompressDisabled() : CommonConstants.USER_CONTEXT_COMPRESS_ENABLED;if (compressEnabled) {final int userContextCompressSizeThreshold = propertyDTO.getPublisher().getCompressSizeThreshold() != null ?propertyDTO.getPublisher().getCompressSizeThreshold() : CommonConstants.USER_CONTEXT_COMPRESS_SIZE_THRESHOLD;final CompressorEnum compressorEnum = CompressorEnum.toEnumFromName(propertyDTO.getPublisher().getCompressAlgorithm());final Compressor compressor = compressorEnum != null ?CompressorFactory.getCompressor(compressorEnum) : CompressorFactory.getDefaultCompressor();if (invocation instanceof SingleInvocation) {this.doProcess(((SingleInvocation) invocation).getDetail(), propertyDTO,userContextCompressSizeThreshold, compressorEnum, compressor);} else if (invocation instanceof MultiInvocation) {List<SingleDetailDTO> singleDetailDTOList = ((MultiInvocation) invocation).getDetail();for (SingleDetailDTO singleDetail : singleDetailDTOList) {this.doProcess(singleDetail, propertyDTO,userContextCompressSizeThreshold, compressorEnum, compressor);}}}return invoker.invoke(invocation);}private void doProcess(SingleDetailDTO singleDetail,PropertyDTO propertyDTO,int userContextCompressSizeThreshold,CompressorEnum compressorEnum,Compressor compressor) {byte[] body = ConverterUtil.toBody(singleDetail.getUserContext());if (body.length > userContextCompressSizeThreshold) {final Map<String, String> remainUnchangedFields = new HashMap<>();propertyDTO.getPublisher().getRemainUnchangedFields().forEach(filed -> {if (singleDetail.getUserContext().containsKey(filed)) {remainUnchangedFields.put(filed, singleDetail.getUserContext().remove(filed));}});if (remainUnchangedFields.size() > 0) {body = ConverterUtil.toBody(singleDetail.getUserContext(), Map.class);}final byte[] compressedBody = compressor.compress(body);final String compressedContext = Base64.getEncoder().encodeToString(compressedBody);if (body.length - compressedContext.length() > CommonConstants.USER_CONTEXT_COMPRESS_REVENUE_THRESHOLD) {singleDetail.getUserContext().clear();singleDetail.getUserContext().put(COMPRESSED_CONTEXT_KEY, compressedContext);if (compressorEnum != null && compressorEnum != Compressor.DEFAULT_COMPRESSOR_ALGORITHM) {singleDetail.getUserContext().put(COMPRESSED_ALGORITHM_KEY, compressorEnum.getName());}}singleDetail.getUserContext().putAll(remainUnchangedFields);}}
}

自定义Invoker

PublishInvoker

package com.xxx.arch.mw.nbp.client.invoker;import com.xxx.arch.mw.nbp.client.configuration.DispatchProperty;
import com.xxx.arch.mw.nbp.common.extension.Invocation;
import com.xxx.arch.mw.nbp.common.extension.Invoker;
import com.xxx.arch.mw.nbp.common.extension.MultiInvocation;
import com.xxx.arch.mw.nbp.common.extension.SingleInvocation;
import com.xxx.arch.mw.nbp.share.dto.SingleDetailDTO;
import com.xxx.arch.mw.nbp.share.facade.DispatchPublishService;
import com.xxx.commons.data.domain.Result;import java.util.ArrayList;
import java.util.List;/*** @date 2023/08/30*/
public class PublishInvoker implements Invoker {private DispatchPublishService publishService;private DispatchProperty dispatchProperty;public PublishInvoker(DispatchPublishService publishService, DispatchProperty dispatchProperty) {this.publishService = publishService;this.dispatchProperty = dispatchProperty;}@Overridepublic Result invoke(Invocation invocation) {List<SingleDetailDTO> singleDetailDTOS = new ArrayList<>();if (invocation instanceof SingleInvocation) {singleDetailDTOS.add(((SingleInvocation) invocation).getDetail());} else if (invocation instanceof MultiInvocation) {singleDetailDTOS = ((MultiInvocation) invocation).getDetail();}return this.publishService.publish(singleDetailDTOS);}public DispatchProperty getDispatchProperty() {return dispatchProperty;}}

Invoker构建与使用

public static final List<Filter> PUBLISH_FILTERS = new ArrayList<Filter>() {{add(new ValidationFilter());add(new PublishMetricFilter());add(new PublishExceptionFilter());add(new PublishTraceFilter());add(new PublishCompressFilter());}
};FilterChain publishChain = new FilterChain();
for (Filter filter : ClientFilterConstants.PUBLISH_FILTERS) {publishChain.addFilter(filter);
}Invoker invoker = publishChain.buildInvokerChain(new PublishInvoker(publishService, this.property));Invocation invocation = singleDetailDTOList.size() == 1 ?new SingleInvocation(singleDetailDTOList.get(0), propertyDTO) :new MultiInvocation(singleDetailDTOList, propertyDTO);Result<MultiResult<SingleDetailDTO>> result = invoker.invoke(invocation);

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

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

相关文章

修改mysql的密码(每一步都图文解释哦)

当你想要连接本机数据库时&#xff0c;是不是有可能突然忘记了自己的数据库密码? 在此文中&#xff0c;我们来详细解决一下如何去修改自己的数据库密码&#xff0c;并使用Navicat来连接测试 1.停止mysql服务 打开终端&#xff0c;键入命令,将mysql服务先停止掉&#xff0c;…

设置滚动条样式

滚动条样式&#xff1a; 下面是代码&#xff1a; <!doctype html> <html lang"en"><head><meta charset"UTF-8"><title>CSS3自定义滚动条</title><style>header {font-family: Lobster, cursive;text-align: c…

亚马逊云科技向量数据库助力生成式AI成功落地实践探秘(二)

向量数据库选择哪种近似搜索算法&#xff0c;选择合适的集群规模以及集群设置调优对于知识库的读写性能也十分关键&#xff0c;主要需要考虑以下几个方面&#xff1a; 向量数据库算法选择 在 OpenSearch 里&#xff0c;提供了两种 k-NN 的算法&#xff1a;HNSW (Hierarchical…

基于STM32设计的智能防盗单车锁(马蹄锁)设计_升级版

1. 前言 随着共享单车和自行车的普及,人们对自行车的安全和便利性提出了更高的要求。智能防盗马蹄锁是一种基于 STM32 单片机的智能锁,可以通过手机蓝牙实现开锁和关锁控制,同时具备 GPRS 防盗预警功能,提高了自行车的安全性和使用便利性。 通过智能防盗马蹄锁,用户可以…

YOLOv5和改进后模型的result.csv文件对比

import pandas as pd import matplotlib.pyplot as plt# 读取CSV文件 df1 pd.read_csv(rE:\xianyu\yolo.csv) df2 pd.read_csv(rE:\xianyu\final.csv)# 获取列名 columns df1.columns# 循环绘制每一列的对比图 for column in columns:plt.figure(figsize(8, 5))plt.plot(df1…

技术分享 | 在 IDE 插件开发中接入 JCEF 框架

项目背景 当前的开发环境存在多种不同语言的 IDE&#xff0c;如 JetBrains 全家桶、Eclipse、Android Studio 和 VS Code 等等。由于每个 IDE 各有其特定的语言和平台要求&#xff0c;因此开发 IDE 插件时&#xff0c;需要投入大量资源才能尽可能覆盖大部分工具。同时&#xf…

数据结构算法-贪心算法

引言 贪心&#xff1a;人只要有 “需求“ &#xff0c;都会有有点“贪“&#xff0c; 这种“贪“是一种选择&#xff0c;或者“”取舍“ RTS&#xff08;即时战略&#xff09;游戏&#xff1a; 帝国时代里 首先确保拥有足够的人口 足够的粮食&#xff0c;足够的战略资源 足够的…

干货科普 | 不同类型的机器人及其在工作中的应用

原创 | 文 BFT机器人 制造商在其操作中使用各种类型的机器人&#xff0c;每种机器人都具有特定的能力和功能。我们将讨论制造业中使用的一些最常见类型的机器人&#xff0c;以及哪种机器人可能最适合您的应用。 01 关节机器人 关节式机器人是一种工业机器人&#xff0c;具有一…

npm,yarn,pnpm 清理缓存

目录 1&#xff0c;为什么要清理缓存1&#xff0c;缓存文件太多&#xff0c;影响系统运行2&#xff0c;不同源会有区别 2&#xff0c;命令2.1&#xff0c;npm2.2&#xff0c;yarn2.3&#xff0c;pnpm 1&#xff0c;为什么要清理缓存 1&#xff0c;缓存文件太多&#xff0c;影响…

关于easy-es的聚合问题

es实体类&#xff1a; public class ChemicalES {IndexId(type IdType.CUSTOMIZE)private Long id;HighLightIndexField(fieldType FieldType.TEXT, analyzer "ik_max_word")private String name;IndexField(fieldType FieldType.KEYWORD)private List<Stri…

三数之和 Java版

题目描述&#xff1a;给你一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a&#xff0c;b&#xff0c;c &#xff0c;使得 a b c 0 请你找出所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 输入&#xff1a;nums …

“土味出海”,屡试不爽!短剧出海引来新一轮爆发?

土味和“钱途”并存的短剧不仅在国内迅猛爆发&#xff0c;今年下半年以来海外市场多部爆火短剧出现&#xff0c;“短剧出海”的话题热度不断攀升&#xff0c;丝毫不差2021年网文出海的盛况。 “霸总的爱&#xff0c;日入千万刀”&#xff0c;是真实存在的&#xff01; 据统计…

tp8 使用rabbitMQ(1)简单队列

php8.0 使用 rabbitmq 要使用 3.6版本以上的&#xff0c; 并且还要开启 php.ini中的 socket 扩展 php think make:command SimpleMQProduce //创建一个生产者命令行 php think make:command SimpleMQConsumer //创建一个消费者命令行 代码中的消息持久化的说明 RabbitMQ 消息持…

#Js篇:var、let和 const

var 声明的变量具有函数作用域或者全局作用域&#xff1b;存在变量提升&#xff0c;即在执行上下文中&#xff0c;变量会被提升到函数或全局作用域的顶部&#xff0c;但初始化的赋值不会提升&#xff1b;可以重复声明同一个变量不会报错&#xff1b;可以被重新赋值&#xff1b…

vue3 + Ant Design Vue国际化,组件默认显示中文

官网 写入App.vue <template><ConfigProvider :locale"zhCN"><router-view :key"$route.fullPath"></router-view></ConfigProvider> </template><script setup> import { ConfigProvider } from "ant-de…

某上市证券公司:管控文件交换行为 保护核心数据资产

客户简介 某上市证券公司成立于2001年&#xff0c;经营范围包括&#xff1a;证券经纪、证券投资咨询、证券承销与保荐、证券自营等。经过多年发展&#xff0c;在北京、上海、深圳、重庆、杭州、厦门等国内主要中心城市及甘肃省内各地市设立了15家分公司和80余家证券营业部。20…

软文推广中如何提炼好产品卖点,媒介盒子分享

内容同质化的时代下&#xff0c;企业应该如何让用户留下印象&#xff0c;并且成功将产品卖出去&#xff0c;核心思维就在于提炼产品卖点&#xff0c;产品卖点是销量提升的关键&#xff0c;相信企业在推广产品时都会有点困惑&#xff0c;感觉自家产品和竞品比起来只是logo、外观…

压缩与解压缩

核心接口 Compressor package com.xxx.arch.mw.nbp.common.csp;import com.xxx.arch.mw.nbp.common.constant.CommonConstants; import com.xxx.arch.mw.nbp.common.exception.NbpException;import static com.xxx.arch.mw.nbp.common.csp.CompressorEnum.ZSTD;/*** */ publi…

【mybatis】使用<foreach>报错parameter ‘id‘ not found

程序其他sql都执行正常&#xff0c;也写了param注解&#xff0c;但是还是一直报parameter ‘id’ not found。最后发现是调用sql的实现类里ids的入参对象名称不叫ids&#xff0c;叫idList 代码如下&#xff1a; List<Map<String,String>> resultmapper.sql(date,…

【攻防世界-misc】pure_color

1.方法一&#xff1a;用画图工具打开图片&#xff0c;将图片拷贝至虚拟机win7桌面&#xff0c; 点“属性”&#xff0c;颜色设置为“黑白”&#xff0c; 出现flag值。 2.方法二&#xff1a;使用Stegsilve打开&#xff0c;分析图片 将图片打开&#xff0c;按左右键查找&#xff…