自定義責任鏈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.pswp.cn/news/166393.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166393.shtml
英文地址,請注明出處:http://en.pswp.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…