【Hystrix技术指南】(7)故障切换的运作流程原理分析(含源码)
背景介绍
目前对于一些非核心操作,如增减库存后保存操作日志发送异步消息时(具体业务流程),一旦出现MQ服务异常时,会导致接口响应超时,因此可以考虑对非核心操作引入服务降级、服务隔离。
Hystrix说明
官方文档
Hystrix是Netflix开源的一个容灾框架,解决当外部依赖故障时拖垮业务系统、甚至引起雪崩的问题。
为什么需要Hystrix?
- 在大中型分布式系统中,通常系统很多依赖(HTTP,hession,Netty,Dubbo等),在高并发访问下,这些依赖的稳定性与否对系统的影响非常大,但是依赖有很多不可控问题:如网络连接缓慢,资源繁忙,暂时不可用,服务脱机等。
- *当依赖阻塞时,大多数服务器的线程池就出现阻塞(BLOCK),影响整个线上服务的稳定性,在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败。高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。
例如:一个依赖30个SOA服务的系统,每个服务99.9999.990.3换算成时间大约每月有2个小时服务不稳定.随着服务依赖数量的变多,服务不稳定的概率会成指数性提高.解决问题方案:对依赖做隔离。
复制代码
Hystrix设计理念
想要知道如何使用,必须先明白其核心设计理念,Hystrix基于命令模式,通过UML图先直观的认识一下这一设计模式。
- 可见,Command是在 Receiver和 Invoker之间添加的中间层, Command实现了对Receiver的封装。
- API既可以是Invoker又可以是reciever,通过继承Hystrix核心类HystrixCommand来封装这些API(例如,远程接口调用,数据库查询之类可能会产生延时的操作)。
- *就可以为API提供弹性保护了。
Hystrix如何解决依赖隔离
- Hystrix使用命令模式HystrixCommand(Command)包装依赖调用逻辑,每个命令在单独线程中/信号授权下执行。
- 可配置依赖调用超时时间,超时时间一般设为比99.5%平均时间略高即可。当调用超时时,直接返回或执行fallback逻辑。
- 为每个依赖提供一个小的线程池(或信号),如果线程池已满调用将被立即拒绝,默认不采用排队,加速失败判定时间。
- 依赖调用结果分,成功,失败(抛出异常),超时,线程拒绝,短路。 请求失败(异常,拒绝,超时,短路)时执行fallback(降级)逻辑。
- 提供熔断器组件,可以自动运行或手动调用,停止当前依赖一段时间(10秒),熔断器默认错误率阈值为50%,超过将自动运行。
- 提供近实时依赖的统计和监控
Hystrix流程结构解析
、
流程说明:
- 每次调用构建HystrixCommand或者HystrixObservableCommand对象,把依赖调用封装在run()方法中.
- 结果是否有缓存如果没有执行execute()/queue做sync或async调用,对应真正的run()/construct()
- 判断熔断器(circuit-breaker)是否打开,如果打开跳到步骤8,进行降级策略,如果关闭进入步骤.
- 判断线程池/队列/信号量是否跑满,如果跑满进入降级步骤8,否则继续后续步骤.
- 使用HystrixObservableCommand.construct()还是HystrixCommand.run(),运行依赖逻辑
- 依赖逻辑调用超时,进入步骤8
- 判断逻辑是否调用成功
- 6a 返回成功调用结果
- 6b 调用出错,进入步骤8.
- 计算熔断器状态,所有的运行状态(成功, 失败, 拒绝,超时)上报给熔断器,用于统计从而判断熔断器状态.
- getFallback()降级逻辑. a. 没有实现getFallback的Command将直接抛出异常 b. fallback降级逻辑调用成功直接返回 c. 降级逻辑调用失败抛出异常
- 返回执行成功结果
以下四种情况将触发getFallback调用:
- run()方法抛出非HystrixBadRequestException异常。
- run()方法调用超时
- 熔断器开启短路调用
- 线程池/队列/信号量是否跑满
熔断器:Circuit Breaker
每个熔断器默认维护10个bucket,每秒一个bucket,每个bucket记录成功,失败,超时,拒绝的状态,默认错误超过50%且10秒内超过20个请求进行中断短路。
Hystrix隔离分析
Hystrix隔离方式采用线程/信号的方式,通过隔离限制依赖的并发量和阻塞扩散.
线程隔离
- 执行依赖代码的线程与请求线程(如:jetty线程)分离,请求线程可以自由控制离开的时间(异步过程)。
- 通过线程池大小可以控制并发量,当线程池饱和时可以提前拒绝服务,防止依赖问题扩散。
- *线上建议线程池不要设置过大,否则大量堵塞线程有可能会拖慢服务器。
实际案例:
Netflix公司内部认为线程隔离开销足够小,不会造成重大的成本或性能的影响。Netflix 内部API 每天100亿的HystrixCommand依赖请求使用线程隔,每个应用大约40多个线程池,每个线程池大约5-20个线程。
信号隔离
信号隔离也可以用于限制并发访问,防止阻塞扩散, 与线程隔离最大不同在于执行依赖代码的线程依然是请求线程(该线程需要通过信号申请),如果客户端是可信的且可以快速返回,可以使用信号隔离替换线程隔离,降低开销。
信号量的大小可以动态调整, 线程池大小不可以。
线程隔离与信号隔离区别如下图:
fallback故障切换降级机制
有兴趣的小伙伴可以看看:官方参考文档
源码分析
hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/AbstractCommand.java
executeCommandAndObserve
private Observable executeCommandAndObserve(final AbstractCommand _cmd) {final Func1> handleFallback = new Func1>() {public Observable call(Throwable t) {circuitBreaker.markNonSuccess();Exception e = getExceptionFromThrowable(t);executionResult = executionResult.setExecutionException(e);if (e instanceof RejectedExecutionException) {return handleThreadPoolRejectionViaFallback(e);} else if (t instanceof HystrixTimeoutException) {return handleTimeoutViaFallback();} else if (t instanceof HystrixBadRequestException) {return handleBadRequestByEmittingError(e);} else {if (e instanceof HystrixBadRequestException) {eventNotifier.markEvent(HystrixEventType.BAD_REQUEST, commandKey);return Observable.error(e);}return handleFailureViaFallback(e);}}};Observable execution;if (properties.executionTimeoutEnabled().get()) {execution = executeCommandWithSpecifiedIsolation(_cmd).lift(new HystrixObservableTimeoutOperator(_cmd));} else {execution = executeCommandWithSpecifiedIsolation(_cmd);}return execution.doOnNext(markEmits).doOnCompleted(markOnCompleted).onErrorResumeNext(handleFallback).doOnEach(setRequestContext);}
复制代码
使用Observable的onErrorResumeNext,里头调用了handleFallback,handleFallback中区分不同的异常来调用不同的fallback。
- RejectedExecutionException调用handleThreadPoolRejectionViaFallback
- HystrixTimeoutException调用handleTimeoutViaFallback
- *非HystrixBadRequestException的调用handleFailureViaFallback
applyHystrixSemantics
private Observable applyHystrixSemantics(final AbstractCommand _cmd) {executionHook.onStart(_cmd);if (circuitBreaker.attemptExecution()) {final TryableSemaphore executionSemaphore = getExecutionSemaphore();final AtomicBoolean semaphoreHasBeenReleased = new AtomicBoolean(false);final Action0 singleSemaphoreRelease = new Action0() {public void call() {if (semaphoreHasBeenReleased.compareAndSet(false, true)) {executionSemaphore.release();}}};final Action1 markExceptionThrown = new Action1() {public void call(Throwable t) {eventNotifier.markEvent(HystrixEventType.EXCEPTION_THROWN, commandKey);}};if (executionSemaphore.tryAcquire()) {try {executionResult = executionResult.setInvocationStartTime(System.currentTimeMillis());return executeCommandAndObserve(_cmd).doOnError(markExceptionThrown).doOnTerminate(singleSemaphoreRelease).doOnUnsubscribe(singleSemaphoreRelease);} catch (RuntimeException e) {return Observable.error(e);}} else {return handleSemaphoreRejectionViaFallback();}} else {return handleShortCircuitViaFallback();}}
复制代码
- applyHystrixSemantics方法针对executionSemaphore.tryAcquire()没通过的调用
- handleSemaphoreRejectionViaFallback
- applyHystrixSemantics方法针对circuitBreaker.attemptExecution()没通过的调用handleShortCircuitViaFallback()
ViaFallback方法
private Observable handleSemaphoreRejectionViaFallback() {Exception semaphoreRejectionException = new RuntimeException("could not acquire a semaphore for execution");executionResult = executionResult.setExecutionException(semaphoreRejectionException);eventNotifier.markEvent(HystrixEventType.SEMAPHORE_REJECTED, commandKey);logger.debug("HystrixCommand Execution Rejection by Semaphore.");return getFallbackOrThrowException(this, HystrixEventType.SEMAPHORE_REJECTED, FailureType.REJECTED_SEMAPHORE_EXECUTION,"could not acquire a semaphore for execution", semaphoreRejectionException);}private Observable handleShortCircuitViaFallback() {eventNotifier.markEvent(HystrixEventType.SHORT_CIRCUITED, commandKey);Exception shortCircuitException = new RuntimeException("Hystrix circuit short-circuited and is OPEN");executionResult = executionResult.setExecutionException(shortCircuitException);try {return getFallbackOrThrowException(this, HystrixEventType.SHORT_CIRCUITED, FailureType.SHORTCIRCUIT,"short-circuited", shortCircuitException);} catch (Exception e) {return Observable.error(e);}}private Observable handleThreadPoolRejectionViaFallback(Exception underlying) {eventNotifier.markEvent(HystrixEventType.THREAD_POOL_REJECTED, commandKey);threadPool.markThreadRejection();return getFallbackOrThrowException(this, HystrixEventType.THREAD_POOL_REJECTED, FailureType.REJECTED_THREAD_EXECUTION, "could not be queued for execution", underlying);}private Observable handleTimeoutViaFallback() {return getFallbackOrThrowException(this, HystrixEventType.TIMEOUT, FailureType.TIMEOUT, "timed-out", new TimeoutException());}private Observable handleFailureViaFallback(Exception underlying) {logger.debug("Error executing HystrixCommand.run(). Proceeding to fallback logic ...", underlying);eventNotifier.markEvent(HystrixEventType.FAILURE, commandKey);executionResult = executionResult.setException(underlying);return getFallbackOrThrowException(this, HystrixEventType.FAILURE, FailureType.COMMAND_EXCEPTION, "failed", underlying);}
复制代码
- handleSemaphoreRejectionViaFallback、handleShortCircuitViaFallback、handleThreadPoolRejectionViaFallback、handleTimeoutViaFallback、handleFailureViaFallback这几个方法调用了getFallbackOrThrowException
- 其eventType分别是SEMAPHORE_REJECTED、SHORT_CIRCUITED、THREAD_POOL_REJECTED、TIMEOUT、FAILURE
- AbstractCommand.getFallbackOrThrowException
hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/AbstractCommand.java
private Observable getFallbackOrThrowException(final AbstractCommand _cmd, final HystrixEventType eventType, final FailureType failureType, final String message, final Exception originalException) {final HystrixRequestContext requestContext = HystrixRequestContext.getContextForCurrentThread();long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();executionResult = executionResult.addEvent((int) latency, eventType);if (isUnrecoverable(originalException)) {logger.error("Unrecoverable Error for HystrixCommand so will throw HystrixRuntimeException and not apply fallback. ", originalException);Exception e = wrapWithOnErrorHook(failureType, originalException);return Observable.error(new HystrixRuntimeException(failureType, this.getClass(), getLogMessagePrefix() + " " + message + " and encountered unrecoverable error.", e, null));} else {if (isRecoverableError(originalException)) {logger.warn("Recovered from java.lang.Error by serving Hystrix fallback", originalException);}if (properties.fallbackEnabled().get()) {final Action1super R>> setRequestContext = new Action1super R>>() {public void call(Notificationsuper R> rNotification) {setRequestContextIfNeeded(requestContext);}};final Action1 markFallbackEmit = new Action1() {public void call(R r) {if (shouldOutputOnNextEvents()) {executionResult = executionResult.addEvent(HystrixEventType.FALLBACK_EMIT);eventNotifier.markEvent(HystrixEventType.FALLBACK_EMIT, commandKey);}}};final Action0 markFallbackCompleted = new Action0() {public void call() {long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();eventNotifier.markEvent(HystrixEventType.FALLBACK_SUCCESS, commandKey);executionResult = executionResult.addEvent((int) latency,HystrixEventType.FALLBACK_SUCCESS);}};final Func1> handleFallbackError = new Func1>() {public Observable call(Throwable t) {Exception e = wrapWithOnErrorHook(failureType, originalException);Exception fe = getExceptionFromThrowable(t);long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();Exception toEmit;if (fe instanceof UnsupportedOperationException) {logger.debug("No fallback for HystrixCommand. ", fe);eventNotifier.markEvent(HystrixEventType.FALLBACK_MISSING, commandKey);executionResult = executionResult.addEvent((int) latency, HystrixEventType.FALLBACK_MISSING);toEmit = new HystrixRuntimeException(failureType, _cmd.getClass(), getLogMessagePrefix() + " " + message + " and no fallback available.", e, fe);} else {logger.debug("HystrixCommand execution " + failureType.name() + " and fallback failed.", fe);eventNotifier.markEvent(HystrixEventType.FALLBACK_FAILURE, commandKey);executionResult = executionResult.addEvent((int) latency, HystrixEventType.FALLBACK_FAILURE);toEmit = new HystrixRuntimeException(failureType, _cmd.getClass(), getLogMessagePrefix() + " " + message + " and fallback failed.", e, fe);}if (shouldNotBeWrapped(originalException)) {return Observable.error(e);}return Observable.error(toEmit);}};final TryableSemaphore fallbackSemaphore = getFallbackSemaphore();final AtomicBoolean semaphoreHasBeenReleased = new AtomicBoolean(false);final Action0 singleSemaphoreRelease = new Action0() {public void call() {if (semaphoreHasBeenReleased.compareAndSet(false, true)) {fallbackSemaphore.release();}}};Observable fallbackExecutionChain;if (fallbackSemaphore.tryAcquire()) {try {if (isFallbackUserDefined()) {executionHook.onFallbackStart(this);fallbackExecutionChain = getFallbackObservable();} else {fallbackExecutionChain = getFallbackObservable();}} catch (Throwable ex) {fallbackExecutionChain = Observable.error(ex);}return fallbackExecutionChain.doOnEach(setRequestContext).lift(new FallbackHookApplication(_cmd)).lift(new DeprecatedOnFallbackHookApplication(_cmd)).doOnNext(markFallbackEmit).doOnCompleted(markFallbackCompleted).onErrorResumeNext(handleFallbackError).doOnTerminate(singleSemaphoreRelease).doOnUnsubscribe(singleSemaphoreRelease);} else {return handleFallbackRejectionByEmittingError();}} else {return handleFallbackDisabledByEmittingError(originalException, failureType, message);}}}
复制代码
- fallbackExecutionChain的onErrorResumeNext,调用了handleFallbackError
- fallbackExecutionChain的doOnCompleted,调用了markFallbackCompleted
- AbstractCommand.getFallbackSemaphore
hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/AbstractCommand.java
protected TryableSemaphore getFallbackSemaphore() {if (fallbackSemaphoreOverride == null) {TryableSemaphore _s = fallbackSemaphorePerCircuit.get(commandKey.name());if (_s == null) {fallbackSemaphorePerCircuit.putIfAbsent(commandKey.name(), new TryableSemaphoreActual(properties.fallbackIsolationSemaphoreMaxConcurrentRequests()));return fallbackSemaphorePerCircuit.get(commandKey.name());} else {return _s;}} else {return fallbackSemaphoreOverride;}}
复制代码
针对每个commandKey获取或创建TryableSemaphoreActual
fallback源码分析小结
hystrix的fallback主要分为5种类型:
- SEMAPHORE_REJECTED对应handleSemaphoreRejectionViaFallback
- SHORT_CIRCUITED对应handleShortCircuitViaFallback
- THREAD_POOL_REJECTED对应handleThreadPoolRejectionViaFallback
- TIMEOUT对应handleTimeoutViaFallback
- FAILURE对应handleFailureViaFallback
- 这几个方法最后都调用了getFallbackOrThrowException方法。
分享资源
获取以上资源请访问开源项目 点击跳转
相关文章:

【Hystrix技术指南】(7)故障切换的运作流程原理分析(含源码)
背景介绍 目前对于一些非核心操作,如增减库存后保存操作日志发送异步消息时(具体业务流程),一旦出现MQ服务异常时,会导致接口响应超时,因此可以考虑对非核心操作引入服务降级、服务隔离。 Hystrix说明 官方…...

Springboot 整合MQ实现延时队列入门
延时队列 添加依赖配置文件队列TTL代码架构图交换机、队列、绑定配置文件代码生产者代码消费者代码延时队列优化添加普通队列配置代码生产者发送消息是进行设置消息的ttl 通过MQ 插件实现延时队列代码架构图配置交换机生产者代码消费者代码测试发送 添加依赖 <!-- rabbitMQ …...

前端基础(Vue框架)
前言:前端开发框架——Vue框架学习。 准备工作:添加Vue devtools扩展工具 具体可查看下面的这篇博客 添加vue devtools扩展工具添加后F12不显示Vue图标_MRJJ_9的博客-CSDN博客 Vue官方学习文档 Vue.js - 渐进式 JavaScript 框架 | Vue.js 目录 MV…...

【实用插件】ArcGIS for AutoCAD插件分享下载
ArcGIS包含一系列功能,其中ArcGIS for AutoCAD一个免费的可下载的AutoCAD插件,它可简化将CAD和GIS数据整合在一起的过程提供互操作性。 ArcGIS for AutoCAD互操作性平台将连接AutoCAD和 ArcGIS,以增强使用地理环境设计CAD工程图时的用户体验…...

GaussDB数据库SQL系列-子查询
目录 一、前言 二、GaussDB SQL子查询表达式 1、EXISTS/NOT EXISTS 2、IN/NOT IN 3、ANY/SOME 4、ALL 三、GaussDB SQL子查询实验示例 1、创建实验表 2、EXISTS/NOT EXISTS示例 3、IN/NOT IN 示例 4、ANY/SOME 示例 5、ALL示例 四、注意事项及建议 五、小结 一、…...

Kafka 什么速度那么快
批量发送消息 Kafka 采用了批量发送消息的方式,通过将多条消息按照分区进行分组,然后每次发送一个消息集合,看似很平常的一个手段,其实它大大提升了 Kafka 的吞吐量。 消息压缩 消息压缩的目的是为了进一步减少网络传输带宽。而…...

环形链表笔记(自用)
环形链表 不管怎么样slow最多走半圈了, 快慢指针slow走一步,fast走两步最合适,因为假设fast和slow相差n每一次他们前进,就会相差n-1步,这样他们一定会相遇,如果是环形链表的话。 代码 /*** Definition for…...

js循环中发起请求数据不一致问题
项目场景: 在公司的一个项目中需要使用循环更改查询条件,然后查询子表数据,但是在查询过程中for下面的key变化了之后,查询中的key却并没有变化,导致查询的参数不一致,从未结果数据出错 for(let i 0;i<…...
工作流自动化:提升效率、节约成本的重要工具
在现代社会中,软件和技术的运用使得我们的日常活动变得更加简单和高效。然而,这些技术也有自身的特点和独特之处。尽管我们使用这些工具来简化工作,但有时仍需要一些人工干预,比如手动数据录入。在工作场所中,手动数据…...

仿牛客论坛项目day7|Kafka
一、阻塞队列 创建了一个生产者线程和一个消费者线程。生产者线程向队列中放入元素,消费者线程从队列中取出元素。我们可以看到,当队列为空时,消费者线程会被阻塞,直到生产者线程向队列中放入新的元素。 二、Kafka入门 发布、订阅…...

[SpringCloud] 组件性能优化技巧
Feign 配置优化hystrix配置 优化ribbon 优化Servlet 容器 优化Zuul配置 优化 文章目录 1.Servlet 容器 优化2.Feign 配置优化3.Zuul配置 优化4.hystrix配置 优化5.ribbon 优化 1.Servlet 容器 优化 默认情况下, Spring Boot 使用 Tomcat 来作为内嵌的 Servlet 容器, 可以将 We…...

okhttp下载文件 Java下载文件 javaokhttp下载文件 下载文件 java下载 okhttp下载 okhttp
okhttp下载文件 Java下载文件 javaokhttp下载文件 下载文件 java下载 okhttp下载 okhttp 1、引入Maven1.1、okhttp发起请求官网Demo 2、下载文件3、扩充,读写 txt文件内容3.1读写内容 示例 http客户端 用的是 okhttp,也可以用 UrlConnetcion或者apache …...

Oracle/PL/SQL奇技淫巧之Json转表
在Oracle中,有些时候我们需要在一个json文档中查数据 这个时候我们可以通过JSON_TABLE函数来把 json文档 提取成一张可以执行正常查询操作的表 先看JSON_TABLE函数的基础用法: JSON_TABLE(json_data, $.json_path COLUMNS (column_definitions))其中&a…...

每日一学——网络安全
网络安全设计、原则、审计等知识点的精讲如下: 网络安全设计与原则: 网络安全设计是指在系统或网络的设计过程中考虑到安全性,并采取相应的安全措施来保护系统或网络不受威胁。安全设计原则包括最小权限原则(Least Privilege Prin…...

python中的lstm:介绍和基本使用方法
python中的lstm:介绍和基本使用方法 未使用插件 LSTM(Long Short-Term Memory)是一种循环神经网络(RNN)的变体,专门用于处理序列数据。LSTM 可以记忆序列中的长期依赖关系,这使得它非常适合于各…...

【Flink】Flink窗口触发器
数据进入到窗口的时候,窗口是否触发后续的计算由窗口触发器决定,每种类型的窗口都有对应的窗口触发机制。WindowAssigner 默认的 Trigger通常可解决大多数的情况。我们通常使用方式如下,调用trigger()方法把我们想执行触发器传递进去: SingleOutputStreamOperator<Produ…...

深度云化时代,什么样的云网络才是企业的“心头好”?
科技云报道原创。 近年来企业上云的快速推进,对云网络提出了更多需求。 最初,云网络只是满足互联网业务公网接入。 随着移动互联网的发展,企业对云上网络安全隔离能力和互访能力、企业数据中心与云上网络互联、构建混合云的能力࿰…...

【快应用】快应用广告学习之激励视频广告
【关键词】 快应用、激励视频广告、广告接入 【介绍】 一、关于激励视频广告 定义:用户通过观看完整的视频广告,获得应用内相关的奖励。适用场景:游戏/快游戏的通关、继续机会、道具获取、积分等场景中,阅读、影音等应用的权益体系…...

国产化系统中遇到的视频花屏、卡顿以及延迟问题的记录与总结
目录 1、国产化系统概述 1.1、国产化操作系统与国产化CPU 1.2、国产化服务器操作系统 1.3、当前国产化系统的主流配置 2、视频解码花屏与卡顿问题 2.1、视频解码花屏 2.2、视频解码卡顿 2.3、关于I帧和P帧的说明 3、国产显卡处理速度慢导致图像卡顿问题 3.1、视频延…...

go内存管理机制
golang内存管理基本是参考tcmalloc来进行的。go内存管理本质上是一个内存池,只不过内部做了很多优化:自动伸缩内存池大小,合理切割内存块。 基本概念: Page:页,一块 8 K大小的内存空间。Go向操作系统申请和…...

【Python】Web学习笔记_flask(5)——会话cookie对象
HTTP是无状态协议,一次请求响应结束后,服务器不会留下对方信息,对于大部分web程序来说,是不方便的,所以有了cookie技术,通过在请求和响应保温中添加cookie数据来保存客户端的状态。 html代码: …...

用友U8+CRM 任意文件上传+读取漏洞复现
0x01 产品简介 用友U8 CRM客户关系管理系统是一款专业的企业级CRM软件,旨在帮助企业高效管理客户关系、提升销售业绩和提供优质的客户服务。 0x02 漏洞概述 用友 U8 CRM客户关系管理系统 getemaildata.php 文件存在任意文件上传和任意文件读取漏洞,攻击…...

【量化课程】08_1.机器学习量化策略基础实战
文章目录 1. 常用机器学习模型1.1 回归模型1.2 分类模型1.2.1 SVC介绍1.2.2 SVC在量化策略中的应用 2. 机器学习量化策略实现的基本步骤3. 策略实现 1. 常用机器学习模型 1.1 回归模型 线性回归多层感知器回归自适应提升树回归随机森林回归 1.2 分类模型 线性分类支持向量机…...

Mongodb 更新集合的方法到底有几种 (中) ?
更新方法 Mongodb 使用以下几种方法来更新文档 , Mongodb V5.0 使用 mongosh 客户端: db.collection.updateOne(<filter>, <update>, <options>) db.collection.updateMany(<filter>, <update>, <options>) db.c…...

预演攻击:谁需要网络靶场,何时需要
"网络演习 "和 "网络靶场 "几乎是当今信息安全领域最流行的词汇。与专业术语不同的是,这些词对于企业和高级管理人员来说早已耳熟能详:法律要求他们进行演习,包括网络演习,而网络射击场也经常在企业界和媒体上…...

【Linux】IO多路转接——poll接口
目录 poll初识 poll函数 poll服务器 poll的优点 poll的缺点 poll初识 poll也是系统提供的一个多路转接接口。 poll系统调用也可以让我们的程序同时监视多个文件描述符上的事件是否就绪,和select的定位是一样的,适用场景也是一样的。 poll函数 po…...

系统架构设计师---OSI七层协议
目录 OSI七层协议 各层主要功能和详细说明 Internet协议的主要协议及其层次关系...

Next.js - Route Groups(路由组)
路由组的作用 在应用程序目录中,嵌套文件夹通常会映射到 URL 路径。不过,您可以将文件夹标记为路由组,以防止该文件夹包含在路由的 URL 路径中。 这样就可以在不影响 URL 路径结构的情况下,将路由段和项目文件组织到逻辑组中。 …...

musl libc ldso 动态加载研究笔记:01
前言 musl 是一个轻量级的标准C库,建立在系统调用之上,可以认为是【用户态】的C 库,与 glibc 或者 uClibc 属于同一类。 基于 musl 的 gcc 工具链包括交叉编译工具链,可以用于编译 Linux 或者其他的操作系统,如当前 L…...

2023 年 4 款适用于安卓手机的最佳 PDF 转 Word 转换器
尝试在 Android 上将 PDF 文档转换为 Word 文件?好吧,您可能会发现要让它发挥作用几乎是不可能的,至少在没有任何额外工具的情况下是这样。Web 上有用于此类转换的选项,但本地不一定会发生任何情况(可能除了一个应用程…...