Apache Camel 简介

相关文档地址

https://camel.apache.org/components/next/index.htmlhttps://camel.apache.org/components/4.10.x/languages/simple-language.htmlhttps://camel.apache.org/manual/exception-clause.htmlhttps://camel.apache.org/manual/index.htmlhttps://camel.apache.org/components/next/http-component.html

null-safe 运算符算

Apache Camel中的null安全导航操作

在Apache Camel的Simple语言中,处理可能为null的属性或嵌套属性时,有几种方法可以避免空指针异常:

  1. 使用空安全操作符(?.)
    Apache Camel的Simple语言支持null安全操作符(?.),可以防止在访问嵌套属性时出现空指针异常:
${exchangeProperty.allData?[${exchangeProperty.loopCount}]?.['业务二级产出线ID']?[0]?.['number']}

这种语法确保当任何中间值为null时,表达式会安全地返回null而不是抛出异常。
2. 使用空值合并操作符(??)
当你想在遇到null值时提供默认值时,可以使用null合并操作符(??):

${exchangeProperty.allData?[${exchangeProperty.loopCount}]?.['业务二级产出线ID']?[0]?.['number'] ?? '默认值'}

这样如果表达式计算结果为null,则会返回指定的默认值。
3. 使用isEmpty或exists函数
在某些情况下,你可能想先检查一个值是否存在,然后再尝试访问它的属性:

${header.foo} == null
${header.foo} != null
  1. 使用条件表达式
    可以使用iif函数来实现条件逻辑:
${iif(exchangeProperty.allData?[${exchangeProperty.loopCount}] != null, exchangeProperty.allData?[${exchangeProperty.loopCount}]?.['业务二级产出线ID']?[0]?.['number'], '默认值')}
  1. 处理Map和List类型
    对于Map或List类型的数据,Camel支持索引和键访问,同样可以使用null安全操作符:
${body.address?.lines?[0]}
${header.foo?[bar]}

最佳实践

尽量使用空安全操作符:在访问嵌套属性时,始终使用?.操作符来避免空指针异常。

提供默认值:在可能的情况下,使用??操作符为可能为null的表达式提供默认值。

简化复杂表达式:对于非常复杂的表达式,可以考虑将其分解为多个步骤,或使用Bean组件在Java代码中处理复杂的null处理逻辑。

使用变量存储中间结果:对于复杂的表达式,可以使用变量存储中间结果,然后在后续步骤中使用这些变量。

在你的具体案例中,可以这样修改表达式:

${exchangeProperty.allData?[${exchangeProperty.loopCount}]?.['业务二级产出线ID']?[0]?.['number'] ?? ''}

这样当任何嵌套属性为null时,表达式会安全地返回空字符串而不是抛出异常。

setVariable、setProperty、setHeader

  1. setVariable

变量范围:变量(Variable)是当前交换(Exchange)的一部分,但与Header和Property不同,它不会被复制到消息中

生命周期:变量的生命周期仅限于当前Exchange的处理过程

访问方式:通过${variable.xxx}访问

用途:适合作为路由内部使用的临时数据,不会影响到消息本身

  1. setProperty(或setExchangeProperty)

属性范围:属性(Property)是附加到Exchange上的,在整个消息处理过程中都可用

生命周期:属性在整个Exchange生命周期内持续存在,即使跨多个路由和端点

访问方式:通过${exchangeProperty.xxx}访问

用途:适合存储需要在整个消息处理流程中使用的数据,如跨路由共享的上下文信息

  1. setHeader

作用范围:Header是消息(Message)级别的,附加在消息上而不是Exchange上

生命周期:Header随消息一起传递,当消息被传递到另一个端点时,Header通常也会被传递(取决于端点实现)

访问方式:通过${header.xxx}访问

端点交互:许多组件(如HTTP、JMS、Kafka等)会读取特定的Header来控制行为

重要特性:当使用EIP(如split、multicast)时,新创建的Exchange会从原始Exchange中复制Header

特性setHeadersetVariablesetProperty
作用范围消息级别Exchange级别,但不复制Exchange级别
生命周期随消息传递,可能被端点消费仅当前Exchange处理过程整个Exchange生命周期
是否传递给目标系统是(通常)
跨路由可见性可能会变化(消息转换时)仅在当前Exchange中可见在整个Exchange中可见

当前时间

date:now如果不指定格式模式,{date:now} 如果不指定格式模式,date:now如果不指定格式模式,{date:now}会返回一个默认格式的日期时间字符串。
默认情况下,Apache Camel会使用java.util.Date对象的toString()方法的格式,即类似于:
Wed Apr 24 10:15:30 CST 2024

${date:now:yyyy-MM-dd}
可以根据需要调整日期时间格式。
例如,如果只需要日期部分,可以使用yyyy-MM-dd格式。

Simple语言中的时间偏移支持的单位:
h:小时
m:分钟
s:秒

注意事项:
Simple语言的时间偏移语法使用+和-操作符表示时间的增减
可以组合多个时间单位,如now+1h30m(当前时间加1小时30分钟) date:now+1h30m在路由中使用时,需要将表达式放在{date:now+1h30m} 在路由中使用时,需要将表达式放在date:now+1h30m在路由中使用时,需要将表达式放在{}内部

Apache Camel onException 完整使用指南

概述

在Apache Camel中,onExceptiononWhenretryWhileredeliveryPolicy可以组合使用来实现复杂的异常处理逻辑。本文档详细说明如何同时使用这些功能。

核心组件说明

1. onException

  • 作用: 定义异常处理器,捕获特定类型的异常
  • 语法: <onException><exception>异常类型</exception></onException>

2. onWhen

  • 作用: 条件判断,决定是否处理特定的异常
  • 语法: <onWhen><simple>条件表达式</simple></onWhen>

3. retryWhile

  • 作用: 定义重试条件,决定是否继续重试
  • 语法: <retryWhile><simple>重试条件</simple></retryWhile>

4. redeliveryPolicy

  • 作用: 定义重试策略,包括重试次数、延迟时间等
  • 语法: <redeliveryPolicy>重试策略配置</redeliveryPolicy>

组合使用示例

基本语法结构

<onException><!-- 1. 定义异常类型 --><exception>java.lang.Exception</exception><!-- 2. 使用onWhen条件判断 --><onWhen><simple>${exception.message} contains 'retryable'</simple></onWhen><!-- 3. 使用retryWhile定义重试条件 --><retryWhile><simple>${header.CamelRedeliveryCounter} &lt; 3</simple></retryWhile><!-- 4. 应用重试策略 --><redeliveryPolicy><maximumRedeliveries>3</maximumRedeliveries><redeliveryDelay>1000</redeliveryDelay><backOffMultiplier>2.0</backOffMultiplier><useExponentialBackOff>true</useExponentialBackOff></redeliveryPolicy><!-- 5. 异常处理逻辑 --><setHeader headerName="ErrorType"><simple>${exception.class.simpleName}</simple></setHeader><handled><constant>true</constant></handled>
</onException>

详细配置说明

1. 异常类型捕获

<!-- 捕获单个异常类型 -->
<exception>java.lang.RuntimeException</exception><!-- 捕获多个异常类型 -->
<exception>java.net.ConnectException</exception>
<exception>java.net.SocketTimeoutException</exception>
<exception>java.net.UnknownHostException</exception>

2. onWhen条件判断

<!-- 基于异常消息内容判断 -->
<onWhen><simple>${exception.message} contains 'retryable'</simple>
</onWhen><!-- 基于异常类型判断 -->
<onWhen><simple>${exception.class.simpleName} == 'BusinessException'</simple>
</onWhen><!-- 复合条件判断 -->
<onWhen><simple>${exception.message} contains 'business' or ${exception.message} contains 'validation'</simple>
</onWhen><!-- 总是处理 -->
<onWhen><constant>true</constant>
</onWhen>

3. retryWhile重试条件

<!-- 基于重试次数判断 -->
<retryWhile><simple>${header.CamelRedeliveryCounter} &lt; 3</simple>
</retryWhile><!-- 基于异常消息和重试次数判断 -->
<retryWhile><simple>${header.CamelRedeliveryCounter} &lt; 5 and ${exception.message} contains 'business'</simple>
</retryWhile><!-- 基于自定义逻辑判断 -->
<retryWhile><simple>${header.CamelRedeliveryCounter} &lt; 10 and ${exception.message} contains 'connection'</simple>
</retryWhile>

4. redeliveryPolicy重试策略

<redeliveryPolicy><!-- 最大重试次数 --><maximumRedeliveries>3</maximumRedeliveries><!-- 重试延迟时间(毫秒) --><redeliveryDelay>1000</redeliveryDelay><!-- 退避倍数 --><backOffMultiplier>2.0</backOffMultiplier><!-- 使用指数退避 --><useExponentialBackOff>true</useExponentialBackOff><!-- 日志配置 --><logRetryAttempted>true</logRetryAttempted><logRetryStackTrace>true</logRetryStackTrace><logHandled>true</logHandled><logNewException>true</logNewException><logExhausted>true</logExhausted><logExhaustedMessageHistory>true</logExhaustedMessageHistory>
</redeliveryPolicy>

实际应用场景

1. 全局异常处理

<onException><exception>java.lang.Exception</exception><onWhen><simple>${exception.message} contains 'retryable' or ${exception.message} contains 'temporary'</simple></onWhen><retryWhile><simple>${header.CamelRedeliveryCounter} &lt; 3 and (${exception.message} contains 'retryable' or ${exception.message} contains 'temporary')</simple></retryWhile><redeliveryPolicy><maximumRedeliveries>3</maximumRedeliveries><redeliveryDelay>1000</redeliveryDelay><backOffMultiplier>2.0</backOffMultiplier><useExponentialBackOff>true</useExponentialBackOff></redeliveryPolicy><handled><constant>true</constant></handled>
</onException>

2. 业务异常处理

<onException><exception>java.lang.RuntimeException</exception><onWhen><simple>${exception.message} contains 'business' or ${exception.message} contains 'validation'</simple></onWhen><redeliveryPolicy><maximumRedeliveries>5</maximumRedeliveries><redeliveryDelay>2000</redeliveryDelay><backOffMultiplier>1.5</backOffMultiplier><useExponentialBackOff>true</useExponentialBackOff></redeliveryPolicy><retryWhile><simple>${header.CamelRedeliveryCounter} &lt; 5 and ${exception.message} contains 'business'</simple></retryWhile><to uri="activemq:dead.letter.queue"/><handled><constant>true</constant></handled>
</onException>

3. 网络异常处理

<onException><exception>java.net.ConnectException</exception><exception>java.net.SocketTimeoutException</exception><exception>java.net.UnknownHostException</exception><onWhen><constant>true</constant></onWhen><redeliveryPolicy><maximumRedeliveries>10</maximumRedeliveries><redeliveryDelay>5000</redeliveryDelay><backOffMultiplier>2.0</backOffMultiplier><useExponentialBackOff>true</useExponentialBackOff></redeliveryPolicy><retryWhile><simple>${header.CamelRedeliveryCounter} &lt; 10</simple></retryWhile><handled><constant>true</constant></handled>
</onException>

重要变量说明

异常相关变量

  • ${exception} - 当前异常对象
  • ${exception.message} - 异常消息
  • ${exception.class.simpleName} - 异常类名

重试相关变量

  • ${header.CamelRedeliveryCounter} - 当前重试次数
  • ${header.CamelRedeliveryMaxCounter} - 最大重试次数
  • ${header.CamelFailureEndpoint} - 失败的端点

消息相关变量

  • ${body} - 消息体
  • ${headers} - 消息头
  • ${exchangeId} - 交换ID

最佳实践

1. 异常处理顺序

  • 将具体的异常处理放在前面
  • 将通用的异常处理放在后面

2. 重试策略设计

  • 根据异常类型设置不同的重试策略
  • 使用指数退避避免系统过载
  • 设置合理的最大重试次数

3. 日志记录

  • 启用重试日志记录
  • 记录异常堆栈信息
  • 记录重试历史

4. 死信队列

  • 对于无法重试的异常,发送到死信队列
  • 实现死信队列处理逻辑

测试示例

<route id="testRoute"><from uri="direct:test"/><choice><when><simple>${body} == 'retryable-error'</simple><throwException exceptionType="java.lang.RuntimeException" message="模拟可重试的临时故障"/></when><when><simple>${body} == 'business-error'</simple><throwException exceptionType="java.lang.RuntimeException" message="模拟业务异常"/></when><when><simple>${body} == 'network-error'</simple><throwException exceptionType="java.net.ConnectException" message="模拟网络连接异常"/></when><otherwise><setBody><simple>处理成功: ${body}</simple></setBody></otherwise></choice><to uri="mock:result"/>
</route>

总结

通过组合使用onExceptiononWhenretryWhileredeliveryPolicy,可以实现:

  1. 精确的异常捕获 - 通过onWhen条件判断
  2. 灵活的重试逻辑 - 通过retryWhile自定义重试条件
  3. 可控的重试策略 - 通过redeliveryPolicy配置重试参数
  4. 完善的异常处理 - 通过异常处理器处理捕获的异常

这种组合使用方式能够满足复杂业务场景下的异常处理需求,提高系统的可靠性和稳定性。

onWhen的作用机制

  1. onWhen=true时
    异常会被onException处理器捕获
    会执行redeliveryPolicy定义的重试策略
    会执行retryWhile定义的重试条件判断
    会执行异常处理逻辑(如setHeader、process等)
  2. onWhen=false时
    异常不会被onException处理器捕获
    不会执行重试逻辑
    不会执行异常处理逻辑
    异常会继续向上传播,可能被其他异常处理器捕获或导致路由失败

maximumRedeliveries 和 retryWhile

  1. maximumRedeliveries=0 - 无论retryWhile如何设置,都不会重试
  2. retryWhile=false - 无论maximumRedeliveries如何设置,都不会重试
  3. 优先级关系 - 两个条件是"与"的关系,不是"或"的关系
  4. 两个条件都必须满足 - 只有maximumRedeliveries>0且retryWhile=true时才会重试

重试逻辑的优先级

Apache Camel的重试逻辑遵循以下优先级:

  1. onWhen - 首先判断是否处理此异常
  2. maximumRedeliveries - 检查是否允许重试
  3. retryWhile - 检查是否满足重试条件

这种设计确保了重试行为的可控性和可预测性,避免了意外的重试行为。

Apache Camel异常处理器注册机制:

  1. 处理器注册时机:onException处理器在路由定义时就会注册到异常处理链中,与它们在路由中的位置无关
  2. 匹配顺序:Camel会按照onException在路由中定义的顺序进行检查
  3. 第一个匹配的处理器生效:找到匹配的处理器后立即执行并停止查找

注意:onException 不能被嵌套,否则会报错类似如下:

The output must be added as top-level on the route. Try moving OnException[[java.lang.Exception] When[simple{ 
${exchangeProperty.mysql_custom_exception}} -> []] -> [process[ref:errorLoggingProcessor]]] to the top of route 

解决办法:将所有的异常单独拿出来,紧挨着 from 放到下面,多个异常的,选放业务自定义异常并使用 onWhen 进行控制,全局异常放到所有异常的最后进行兜底 ,xml示例如下:

<route xmlns="http://camel.apache.org/schema/spring" id="VjCFgbqRdYh4Dc7tSKAzY"><from uri="direct:VjCFgbqRdYh4Dc7tSKAzY"/><!-- 自定义异常 --><onException><exception>java.lang.Exception</exception><onWhen><simple resultType="java.lang.Boolean">${exchangeProperty.VjCFgbqRdYh4Dc7tSKAzYhttp_client_1_custom_exception}</simple></onWhen><log message="===&gt; routeId:VjCFgbqRdYh4Dc7tSKAzY,nodeId:http_client_1,logMessage:执行自定义异常处理"/><process ref="errorLoggingProcessor"/><log message="===&gt; routeId:VjCFgbqRdYh4Dc7tSKAzY,nodeId:http_client_1,logMessage:忽略异常,继续执行"/><continued><constant>true</constant></continued></onException><!-- 全局兜底异常 --><onException><exception>java.lang.Exception</exception><log message="===&gt; routeId:VjCFgbqRdYh4Dc7tSKAzY,nodeId:VjCFgbqRdYh4Dc7tSKAzY,logMessage:执行全局兜底异常处理"/><process ref="errorLoggingProcessor"/><log message="===&gt; routeId:VjCFgbqRdYh4Dc7tSKAzY,nodeId:VjCFgbqRdYh4Dc7tSKAzY,logMessage:发生异常,终止执行"/><handled><constant>true</constant></handled></onException><!-- 其他业务逻辑 --><log message="===&gt; routeId:VjCFgbqRdYh4Dc7tSKAzY,nodeId:end,logMessage:工作流执行结束"/><onCompletion><process ref="completionProcessor"/></onCompletion>
</route>

Apache Camel onCompletion 使用说明

概述

onCompletion是Apache Camel中用于处理路由完成事件的机制,类似于onException,但处理的是路由正常完成或异常完成后的清理工作。

onCompletion vs onException 对比

相似点

  1. 注册机制:两者都在路由定义时注册到处理链中
  2. 位置无关性:在路由中的定义位置不影响其生效
  3. 支持条件判断:都可以使用onWhen条件
  4. 处理器引用:都可以使用<process ref="xxx">引用处理器

不同点

特性onExceptiononCompletion
触发时机异常发生时路由完成时(成功或失败)
处理对象异常对象完成事件
重试机制支持重试策略不支持重试
条件类型异常类型匹配完成状态匹配
使用场景异常处理清理工作、日志记录

onCompletion 基本语法

<onCompletion><process ref="completionProcessor"/>
</onCompletion><!-- 带条件的onCompletion -->
<onCompletion><onWhen><simple>${exchangeProperty.CamelRouteStop} == true</simple></onWhen><process ref="stopCompletionProcessor"/>
</onCompletion><!-- 成功完成时的处理 -->
<onCompletion><onCompleteOnly><process ref="successCompletionProcessor"/></onCompleteOnly>
</onCompletion><!-- 失败完成时的处理 -->
<onCompletion><onFailureOnly><process ref="failureCompletionProcessor"/></onFailureOnly>
</onCompletion>

位置影响分析

关键结论:位置不影响功能

onException类似,onCompletion在路由中的位置不会影响其功能,因为:

  1. 注册时机:在路由启动时就已经注册到完成处理链中
  2. 执行时机:在路由完成时触发,与定义位置无关
  3. 作用范围:对整个路由生效

示例验证

<route id="testRoute"><from uri="direct:start"/><!-- 业务逻辑 --><log message="开始处理"/><process ref="businessProcessor"/><!-- onCompletion定义在中间 --><onCompletion><process ref="completionProcessor"/></onCompletion><!-- 更多业务逻辑 --><to uri="mock:result"/><!-- 路由结束<!-- 即使onCompletion定义在中间,仍然会在路由完成时执行 -->
</route>

常用配置模式

1. 基本完成处理

<onCompletion><log message="路由执行完成: ${exchangeId}"/><process ref="cleanupProcessor"/>
</onCompletion>

2. 条件完成处理

<onCompletion><onWhen><simple>${header.ProcessType} == 'batch'</simple></onWhen><log message="批处理完成,执行清理"/><process ref="batchCleanupProcessor"/>
</onCompletion>

3. 成功/失败分别处理

<!-- 成功完成处理 -->
<onCompletion><onCompleteOnly><log message="路由执行成功"/><setHeader headerName="CompletionStatus"><constant>SUCCESS</constant></setHeader><process ref="successProcessor"/></onCompleteOnly>
</onCompletion><!-- 失败完成处理 -->
<onCompletion><onFailureOnly><log message="路由执行失败"/><setHeader headerName="CompletionStatus"><constant>FAILURE</constant></setHeader><process ref="failureProcessor"/></onFailureOnly>
</onCompletion>

4. 资源清理

<onCompletion><log message="开始清理资源"/><!-- 清理临时文件 --><setHeader headerName="TempFile"><simple>${exchangeProperty.tempFile}</simple></setHeader><process ref="fileCleanupProcessor"/><!-- 清理数据库连接 --><process ref="dbCleanupProcessor"/><!-- 记录完成时间 --><setHeader headerName="CompletionTime"><simple>${date:now:yyyy-MM-dd HH:mm:ss}</simple></setHeader><log message="资源清理完成"/>
</onCompletion>

实际应用示例

1. 工作流完成处理

<route id="workflowRoute"><from uri="direct:workflow"/><onCompletion><process ref="workflowCompletionProcessor"/></onCompletion><!-- 工作流逻辑 --><process ref="workflowProcessor"/><to uri="mock:result"/>
</route>

2. 批处理完成处理

<route id="batchProcessRoute"><from uri="direct:batch"/><onCompletion><onWhen><simple>${header.BatchSize} > 1000</simple></onWhen><log message="大批量处理完成,执行特殊清理"/><process ref="largeBatchCleanupProcessor"/></onCompletion><!-- 批处理逻辑 --><process ref="batchProcessor"/><to uri="mock:result"/>
</route>

3. 事务完成处理

<route id="transactionRoute"><from uri="direct:transaction"/><onCompletion><onCompleteOnly><log message="事务提交成功"/><process ref="commitProcessor"/></onCompleteOnly></onCompletion><onCompletion><onFailureOnly><log message="事务回滚"/><process ref="rollbackProcessor"/></onFailureOnly></onCompletion><!-- 事务逻辑 --><transacted ref="transactionPolicy"/><process ref="transactionProcessor"/><to uri="mock:result"/>
</route>

注意事项

1. 执行顺序

  • 多个onCompletion处理器按定义顺序执行
  • onException不同,onCompletion不会停止后续处理器的执行

2. 异常处理

  • onCompletion中的异常不会触发onException处理器
  • 建议在onCompletion中使用try-catch处理异常

3. 性能考虑

  • onCompletion会在每次路由完成时执行
  • 避免在onCompletion中执行耗时的操作

4. 资源管理

  • 确保在onCompletion中正确清理资源
  • 避免资源泄漏

总结

onCompletion是Apache Camel中重要的完成处理机制,与onException类似,在路由中的位置不影响其功能。它主要用于:

  1. 资源清理:清理临时文件、数据库连接等
  2. 日志记录:记录路由执行结果
  3. 状态更新:更新处理状态
  4. 通知机制:发送完成通知

通过合理使用onCompletion,可以确保路由执行后的清理工作得到正确处理,提高系统的稳定性和可维护性。

特殊符号问题 > 、< 和 &

这三个符号会导致xml解析错误,需要进行转义

换行符 \r 和 \n 问题

如果接口入参或者http请求出参中有换行符,并且使用 simple 设置到引擎内,会导致引擎解析字符串为对象时报错(使用 constant 设置到引擎不会报错),需要对\r 和 \n 进行处理

  1. 在body出参中:自定义Processor,示例代码如下:
public class MyBodyTransProcessor implements Processor {private final DefaultCamelContext camelContext;public MyBodyTransProcessor(DefaultCamelContext camelContext) {this.camelContext = camelContext;}@Overridepublic void process(Exchange exchange) throws Exception {String routeId = exchange.getFromRouteId();String body = null;try {body = exchange.getIn().getBody(String.class);} catch (Exception e) {log.error("==>routeId:{},get body error",routeId, e);}String realBody = "{}";if (StringUtils.isNotBlank(body)) {realBody = body.replace("\\n", "\\\\n");realBody = realBody.replace("\\r", "\\\\r");}log.info("==>routeId:{},oldBody:{},realBody:{}",routeId, body, realBody);exchange.getIn().setBody(realBody, String.class);}
}
  1. 在用户设置的入参中:在 from 下面设置两个setProperty,使用
<setProperty name="_nnn_">
<constant>\n</constant>
</setProperty>
<setProperty name="_rrr_">
<constant>\r</constant>
</setProperty>

然后在set到引擎前进行替换

        real = real.replace("\\n", "${exchangeProperty._nnn_"}");real = real.replace("\\r", "${exchangeProperty._rrr_"}");

开发流程

方式一

如果对 Apache Camel 有一定的了解,熟悉 Apache Camel 相关的 xml 语法,可以使用此方式进行开发。

  1. (非必需)在 processor 中定义相关的处理器,只处理核心的逻辑,并在 CamelConfig 中注册此处理器。
  2. 在 parse 中对前端传过来的json进行解析,拼接成 Apache Camel 的 xml 代码,如果 xml 不能直接完成需求,则引用步骤1中定义的处理器。

方式二

如果对 Apache Camel 了解程度有限或需要快速完成需求,可以使用此方式进行开发。

  1. 在 processor 中定义相关的处理器,处理所有的逻辑,并在 CamelConfig 中注册此处理器。
  2. 在 parse 中对前端传过来的json进行解析,只进行核心的校验,并引用步骤1中定义的处理器。

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

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

相关文章

IP离线库 输入IP地址立即返回IP所在地址信息(支持Java、Python)

描述 本文实现&#xff1a; 1、离线查询IP地址 2、IP地址精确到区域 3、IP地址支持国外IP 此时需要一个创建&#xff0c;比如我输入一个8.8.8.8的IP立马就需要返回给我一个中文地址信息&#xff0c; 类似于百度的IP搜索&#xff1a; 113.111.186.123如果现在离线环境或者在…

解决MySQL删除/var/lib/mysql下的所有文件后无法启动的问题

删除 MySQL 数据目录 /var/lib/mysql 下的所有文件后&#xff0c;MySQL 将无法启动&#xff0c;因为该目录包含了数据库的所有数据文件、配置文件和系统表。当这些文件被删除时&#xff0c;MySQL 无法找到必要的数据和配置&#xff0c;从而无法正常启动。本文将详细介绍解决这个…

苍穹外卖项目学习——day1(项目概述、环境搭建)

文章目录一、软件开发整体介绍1.1 软件开发流程1.2 角色分工1.3 软件环境分类二、苍穹外卖项目介绍2.1 定位2.2 功能架构2.3 技术选型三、开发环境搭建3.1 前端环境3.2 后端环境3.3 前后端联调3.4 登录功能优化四、接口文档管理4.1 YApi4.2 Swagger (Knife4j)一、软件开发整体介…

【QT】Qt信号与槽机制详解信号和槽的本质自定义信号和槽带参数的信号和槽

文章目录前言一、信号的本质二、槽的本质三、 信号和槽的使⽤3.1 连接信号和槽四、使用步骤4.1 通过QtCreator⽣成信号槽代码五、 ⾃定义信号和槽5.1 ⽰例1&#xff1a;信号和槽函数初步使用5.2 ⽰例2 两个类使用5.3 示例3 按钮使用触发信号六、 带参数的信号和槽6.1 ⽰例1&…

【OD机试题解法笔记】文件缓存系统

题目描述 请设计一个文件缓存系统&#xff0c;该文件缓存系统可以指定缓存的最大值&#xff08;单位为字节&#xff09;。 文件缓存系统有两种操作&#xff1a; 存储文件&#xff08;put&#xff09;读取文件&#xff08;get&#xff09; 操作命令为&#xff1a; put fileName …

Python中的sys.path与PYTHONPATH全解析:模块导入路径的底层机制与最佳实践

在Python项目开发中&#xff0c;很多人遇到过类似“模块导入失败”、“路径找不到”、“相对导入与绝对导入混乱”等问题。而这些问题的根源&#xff0c;几乎都绕不开一个核心概念——Python模块搜索路径。 今天&#xff0c;我们围绕sys.path 和 PYTHONPATH环境变量&#xff0…

python:如何调节机器学习算法的鲁棒性,以支持向量机SVM为例,让伙伴们看的更明白

鲁棒性&#xff08;Robustness&#xff09;指模型在噪声数据或异常值干扰下保持性能稳定的能力。想详细了解的可参考本人之前的博文 python机器学习&#xff1a;评价智能学习算法性能与效果的常见术语&#xff1a;不收敛、过拟合、欠拟合、泛化能力、鲁棒性一句话、一张图给您…

号源加锁升级思路(解决高并发问题)

原先逻辑链接&#xff1a;号源预约加锁思路_java 预约 接口加锁-CSDN博客 一、进行治疗项目和号源数据缓存 1.新建一个定时任务&#xff0c;主要在凌晨时缓存治疗项目和号源数据 1.1.类中使用redission获取锁&#xff08;用于分布式系统获取数据&#xff0c;保证原子性&…

MCP革命:AI世界的“USB-C”接口如何重塑智能体与外部工具的连接

> 一条标准化的数据通道,让AI从“对话专家”蜕变为“行动专家”,背后是一场由协议驱动的工具连接革命。 2024年11月,Anthropic公司开源了**Model Context Protocol(MCP)**。在短短9个月内,这项技术彻底改变了AI与外部世界的交互方式。截至2025年8月,MCP服务数量**从…

启用“安全登录”组合键(Ctrl+Alt+Delete)解锁

文章目录背景目标功能操作步骤效果背景 在日常工作中&#xff0c;我们有时需要让电脑长期开机运行&#xff08;如处理长任务、作为服务器等&#xff09;。然而&#xff0c;这其中存在一个潜在风险&#xff1a;当电脑处于锁屏或登录界面时&#xff0c;如果有人无意中触碰键盘比…

【08】C++实战篇——C++ 生成动态库.dll 及 C++调用DLL,及实际项目中的使用技巧

文章目录一、创建动态库dll (方法一)1 生成C 动态库dll1.1 创建项目MyDLL1.2 编写.h 和 .cpp文件1.3 设置 及 生成 DLL2 调用 C 动态库dll2.1 创建C 空项目DLLtest2.2 动态库配置 及代码调用测试3 实际项目中的使用技巧3.1 设置dll输出路径3.2 设置头文件引入路径3.3 改进后 测…

kettle插件-kettle http client plus插件,轻松解决https接口无法调用文件流下载问题

场景&#xff1a;小伙伴在使用kettle调用https接口过程中无法正常调用&#xff0c;程序出错问题&#xff0c;今天演示下用自研插件轻松解决这个问题。1、使用openssl 生成自签名证书openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 3652、使用…

C#中的除法

在C#中&#xff0c;除法操作可以通过使用 / 运算符执行。这个运算符可以进行整数除法或浮点除法&#xff0c;这取决于操作数的类型。整数除法当两个整数相除时&#xff0c;结果将自动向下取整到最接近的整数。这意味着结果是一个整数&#xff0c;而不是小数。int a 10; int b …

PPT文件密码解密工具推荐:Tenorshare PassFab for PPT绿色免安装一键解除密码限制,附详细教程和下载地址

前段时间&#xff0c;我帮朋友做一个商业演示的 PPT&#xff0c;为了防止文件被误操作或者内容泄露&#xff0c;我给 PPT 设置了密码。结果等朋友来拿文件的时候&#xff0c;我居然把密码忘得干干净净&#xff0c;这下可把我俩都急坏了。朋友那边马上就要用这个 PPT 去参加重要…

【数据结构】二叉树接口实现指南:递归方法的高效运用 (附经典算法OJ)

文章目录 1、前置说明 1、定义二叉树结点结构 2、创建新节点 3、手动创建二叉树 2、二叉树的遍历 1、前序&#xff0c;中序和后序遍历 1.1、二叉树前序遍历 1.2、二叉树中序遍历 1.3、二叉树后序遍历 2、二叉树层序遍历 3、二叉树的基础操作 1、二叉树节点总数 2、…

自动驾驶控制算法——LQR控制算法

自动驾驶控制算法——LQR控制算法 文章目录自动驾驶控制算法——LQR控制算法**一、LQR 是什么&#xff1f;**二、LQR 原理2.1 线性状态空间模型 (State–Space Model)2.2 二次型性能指标 JJJ2.3 代数黎卡提方程 (ARE)2.4 特点总结2.5 一句话总结 LQR 原理&#xff1a;2.5.1 场景…

Jotai:React轻量级原子化状态管理,告别重渲染困扰

简介 Jotai 是一个为 React 提供的原子化状态管理库&#xff0c;采用自下而上的方法来进行状态管理。Jotai 受 Recoil 启发&#xff0c;通过组合原子来构建状态&#xff0c;并且渲染基于原子依赖性进行优化。这解决了 React 上下文的额外重新渲染问题&#xff0c;并消除了对 m…

C语言数据结构(7)贪吃蛇项目2.贪吃蛇项目实现

8. 核心逻辑实现分析 8.1 游戏主逻辑 程序开始就设置程序支持本地模式&#xff0c;然后进入程序的主逻辑。 主逻辑分为3个过程&#xff1a; • 游戏开始&#xff08;GameStart&#xff09;完成游戏的初始化。 • 游戏运行&#xff08;GameRun&#xff09;完成游戏运行逻辑的…

知识蒸馏 - 最小化KL散度与最小化交叉熵是完全等价的

知识蒸馏 - 最小化KL散度与最小化交叉熵是完全等价的 flyfish KL散度与交叉熵的数学关系 对于两个概率分布 PPP&#xff08;真实分布&#xff09;和 QQQ&#xff08;模型预测分布&#xff09;&#xff0c;KL散度的定义是&#xff1a; DKL(P∥Q)∑xP(x)log⁡(P(x)Q(x)) D_{KL}(P…

设计心得——网络包的处理

一、介绍 在程序的开发中&#xff0c;网络开发是一个重要的应用场景。毕竟这些年IT行业之所以火&#xff0c;主要还是互联网&#xff08;移动互联网&#xff09;带来的。网络开发&#xff0c;有各种平台、框架以及系统和库提供的API&#xff0c;如果说网络开发是一个特别复杂和…