Feign、Ribbon、Hystrix(铁三角)以及三者超时时间配置

news2024/12/24 21:45:13

在微服务架构中很多功能都需要调用多个服务才能完成某一项功能,一个成熟的微服务集群,内部调用必然依赖一个好的 RPC 框架,比如:基于 Http 协议的 Feign,基于私有 tcp 协议的 Dubbo 

1. Feign 是什么
Feign 是Spring Cloud Netflix组件中的轻量级Restful的 HTTP 服务客户端,实现了负载均衡和 Rest 调用的开源框架,封装了Ribbon和RestTemplate, 实现了WebService的面向接口编程,进一步降低了项目的耦合度。

Feign 通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,封装了 Http 调用流程。
 

1、Robbin
(1)客户端的软负载

Robbin是springcloud的LB调用组件,提供客户端的软件负载均衡。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。

Robbin 提供的客户端软负载,是SpringCloud微服务的典型特征之一。

2)负载均衡策略

  • 轮询(RoundRobin),以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。
  • 随机(Random),随机选择状态为UP的Server。
  • 加权响应时间(WeightedResponseTime),根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。
  • 区域感知轮询(ZoneAvoidanceRule),复合判断server所在区域的性能和server的可用性选择server。

(3)核心组件

Ribbon的核心组件(均为接口类型)有以下几个,

  • ServerList,用于获取地址列表。它既可以是静态的(提供一组固定的地址),也可以是动态的(从注册中心中定期查询地址列表)。
  • ServerListFilter,仅当使用动态ServerList时使用,用于在原始的服务列表中使用一定策略过虑掉一部分地址。
  • IRule,选择一个最终的服务地址作为LB结果。选择策略有轮询、根据响应时间加权、断路器(当Hystrix可用时)等。

Ribbon在工作时首选会通过ServerList来获取所有可用的服务列表,然后通过ServerListFilter过虑掉一部分地址,最后在剩下的地址中通过IRule选择出一台服务器作为最终结果。
 

2、Fegin

Fegin是一个声明式Http端调用,集成了Robbin的负载均衡功能,同时声明式调用更加方便(只需要简单的注解即可)。简单的可以理解为:Spring Cloud Feign 的出现使得Eureka和Ribbon的使用更加简单。

(1)Fegin接口示例

a、启动类@EnableFeignClients 注解

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients // 启用fegin声明式调用
public class FeginComsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeginComsumerApplication.class, args);
    }

}

b、声明一个调用的Feign接口,

@Service
@FeignClient(name = "name-service")
public interface NameService {

    @RequestMapping(value = "/getName", method = RequestMethod.GET)
    public String getName();

}

c、服务端提供接口实现

@RequestMapping(value = "/getName", method = RequestMethod.GET)
public String getName(){
    return "hello world";
}

d、fegin声明是调用

@Autowired
private NameServiceClient feginNameServiceClient;

@RequestMapping(value = "/getName", method= RequestMethod.GET)
public String getName(){
    return feginNameServiceClient.getName();
}

(2)Fegin 的类加载流程

  • 通过主类上的EnableFeignClients 注解开启FeignClient;
  • 根据Feign 的规则实现接口,并加上FeignClient注解,供调用的地方注入调用;
  • 程序启动后,会扫描所有FeignClient 注解的类,并将这些信息注入到IOC 容器中;
  • 当b中接口被调用时,通过jdk代理,以及反射(Spring处理注解的方式),来生成具体的RequestTemplate
  • RequestTemplate 生成Reqest
  • Request 交给httpclient处理,这里的httpclient 可以是OkHttp,也可以是HttpUrlConnection 或者HttpClient
  • 最后Client被封装到LoadBalanceClient类,这个类结合Ribbon 实现负载均衡。
     

(3)Fegin的原理

3、Hystrix

Hystrix 是springcloud生态的断路器(隔离、限流、降级),主要是用来预防服务雪崩的现象,剔除掉分布式系统中某些挂掉或请求过慢的服务节点。Hystrix是一个帮助解决分布式系统中超时处理和容错的类库, 拥有保护系统的能力。

(1)隔离、限流、降级

Hystrix断路器有两种隔离策略:信号量隔离(默认)和线程池隔离。

信号量模式从始至终都只有请求线程自身,是同步调用模式,不支持超时调用,不支持直接熔断,由于没有线程的切换,开销非常小。
线程池模式可以支持异步调用,支持超时调用,支持直接熔断,存在线程切换,开销大。

信号量隔离:常用于获取共享资源的场景中,比如计算机连接了两个打印机,那么初始的信号量就是2,被某个进程或线程获取后减1,信号量为0后,需要获取的线程或进程进入资源等待状态。Hystrix的处理有些不同,其不等待,直接返回失败。

线程池隔离:采用的就是jdk的线程池,其默认选用不使用阻塞队列的线程池,例如线程池大小为10,如果某时刻10个线程均被使用,那么新的请求将不会进入等待队列,而是直接返回失败,起到限流的作用。

此外,其还引入了一个断路器机制,当断路器处于打开状态时,直接返回失败或进入降级流程。断路器打开和关闭的触发流程为:当总的请求数达到可阈值HystrixCommandProperties.circuitBreakerRequestVolumeThreshold(),或总的请求失败百分比达到了阈值HystrixCommandProperties.circuitBreakerErrorThresholdPercentage(),这时将断路器的状态由关闭设置为打开。当断路器打开时,所有的请求均被短路,在经过指定休眠时间窗口后,让下一个请求通过(断路器被认为是半开状态)。如果请求失败,断路器进入打开状态,并进入新的休眠窗口;否则进入关闭状态。

 流程如上图所示,Hystrix框架通过命令模式来实现方法粒度上的服务保障,主要涉及HystrixCommand和HystrixObservableCommand类,前者提供同步的execute和异步的queue方法,后者提供立即执行observe和延迟执行toObservable的回调方法。此外,实际项目中通常不会使用Hystrix集成的本地缓存。
 

配置问题

Feign 如何设置超时时间(connectionTimeout、readTimout

对于这个问题网上有很多相关资料,大体上有两种方案,一种是通过设置 ribbon 的超时时间(因为 Feign 是基于 ribbon 来实现的,所以通过 ribbon 的超时时间设置也能达到目的),一种是直接设置 Feign 的超时时间,我将会在下边的篇幅里分别说一下如何通过application.yml 配置文件来设置超时时间

1、Ribbon

对于 ribbon 又分为全局配置和指定服务配置:

  • 全局配置
    对所有的服务该配置都生效
    ribbon:  
        ReadTimeout: 30000 #单位毫秒
        ConnectTimeout: 30000 #单位毫秒

  • 指定服务配置
    下边代码中的 jettopro-basic 是服务的名称,意思是该配置只针对名为 annoroad-beta 的服务有效,根据实际的需要替换成你自己的服务名
    jettopro-basic:
      ribbon:
        ReadTimeout: 30000 #单位毫秒
        ConnectTimeout: 30000 #单位毫秒

    2、Feign

    与 Ribbon 一样,Feign 也分为全局配置和指定服务配置:

  • 全局配置
    下边代码中使用的 feign.client.config.default ,意思是所有服务都采用该配置
feign:
  client:
    config:
      default:
        connectTimeout: 10000 #单位毫秒
        readTimeout: 10000 #单位毫秒
  • 指定服务配置
    下边代码中使用的 feign.client.config.jettopro-basic,意思是该配置只针对名为 jettopro-basic 的服务有效,可以根据实际的需要替换成你自己的服务名
feign:
  client:
    config:
      jettopro-basic:
        connectTimeout: 10000 #单位毫秒
        readTimeout: 10000 #单位毫秒

3、总结
如果同时配置了Ribbon、Feign,那么 Feign 的配置将生效
Ribbon 的配置要想生效必须满足微服务相互调用的时候通过注册中心,如果你是在本地通过 @FeignClient 注解的 url 参数进行服务相互调用的测试,此时 ribbon 设置的超时时间将会失效,但是通过 Feign 设置的超时时间不会受到影响(仍然会生效)
综上所述建议使用 Feign 的来设置超时时间
 

基本介绍
1. Feign 是什么
Feign 是Spring Cloud Netflix组件中的轻量级Restful的 HTTP 服务客户端,实现了负载均衡和 Rest 调用的开源框架,封装了Ribbon和RestTemplate, 实现了WebService的面向接口编程,进一步降低了项目的耦合度。

Feign 通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,封装了 Http 调用流程。

2. 为什么要使用 Feign
如果不使用 RPC 框架,那么调用服务需要走 Http 的话,配置请求 head、body,然后才能发起请求。获得响应体后,还需解析等操作,十分繁琐。

Feign 旨在使编写 JAVA HTTP 客户端变得更加简单,Feign 简化了RestTemplate代码,实现了Ribbon负载均衡,使代码变得更加简洁,也少了客户端调用的代码,使用 Feign 实现负载均衡是首选方案,只需要你创建一个接口,然后在上面添加注解即可。

Feign 是声明式服务调用组件,其核心就是:像调用本地方法一样调用远程方法,无感知远程 HTTP 请求。让开发者调用远程接口就跟调用本地方法一样的体验,开发者完全无感知这是远程方法,无需关注与远程的交互细节,更无需关注分布式环境开发。

3. OpenFeign
Feign 内置了Ribbon,用来做客户端负载均衡调用服务注册中心的服务。
Feign 支持的注解和用法参考官方文档:https://github.com/OpenFeign/feign官方文档,使用 Feign 的注解定义接口,然后调用这个接口,就可以调用服务注册中心的服务。

Feign本身并不支持Spring MVC的注解,它有一套自己的注解,为了更方便的使用Spring Cloud孵化了OpenFeign。并且支持了Spring MVC的注解,如@RequestMapping,@PathVariable等等。
OpenFeign的@FeignClient可以解析Spring MVC的@RequestMapping注解下的接口,并通过动态代理方式产生实现类,实现类中做负载均衡调用服务。

  • Feign 采用的是基于接口的注解
  • Feign 整合了 Ribbon,具有负载均衡的能力
  • 整合了 Hystrix,具有熔断的能力

一、Feign 和 Ribbon

1. 设置 OpenFeign 的超时时间

我们首先来看一下 OpenFeign 自己的请求超时配置,直接在 yml 文件中配置:

eign:
  # 设置 feign 超时时间
  client:
    config:
      # default 设置的全局超时时间,指定服务名称可以设置单个服务的超时时间
      default:
        connectTimeout: 5000
        readTimeout: 5000

default 默认是全局的,将 default 换成某个服务的名称可以设置单个服务的超时时间

2. 设置 Ribbon 的超时时间

ribbon:
  # 建立链接所用的时间,适用于网络状况正常的情况下, 两端链接所用的时间
  ReadTimeout: 5000
  # 指的是建立链接后从服务器读取可用资源所用的时间
  ConectTimeout: 5000

注意这两个参数设置的时候没有智能提示

ConnectTimeout:

指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间。
在java中,网络状况正常的情况下,例如使用 HttpClient 或者 HttpURLConnetion 连接时设置参数 connectTimeout=5000 即5秒,如果连接用时超过5秒就是抛出 java.net.SocketException: connetct time out 的异常。
 

ReadTimeout:

指的是建立连接后从服务器读取到可用资源所用的时间。
在这里我们可以这样理解ReadTimeout:正常情况下,当我们发出请求时可以收到请求的结果,也就是页面上展示的内容,但是当网络状况很差的时候,就会出现页面上无法展示出内容的情况。另外当我们使用爬虫或者其他全自动的程序时,无法判断当前的网络状况是否良好,此时就有了ReadTimeout的用武之地了,通过设置ReadTimeout参数,例:ReadTimeout=5000,超过5秒没有读取到内容时,就认为此次读取不到内容并抛出Java.net.SocketException: read time out的异常。
 

源码分析

可以发现 OpenFeign 的默认的 connectTimeout 是 10 秒,readTimeout 是 60 秒

此时,我们是要验证 OpenFeign 的默认超时时间,所以在 application.yml 中 feign 和 ribbon 的超时时间都没有设置。报错了,连接超时,可是我们代码里睡 5 秒,明明还在超时时间范围内,怎么就连接超时了呐?其实 OpenFeign 集成了 RibbonRibbon 的默认超时连接时间、读超时时间都是 1 秒

如果 OpenFeign 没有设置对应得超时时间,那么将会采用 Ribbon 的默认超时时间

  • 设置 OpenFeign 超时时间
    feign:
      client:
        config:
          default:
            connectTimeout: 8000
            readTimeout: 8000

  • 设置 Ribbon 超时时间
  • ribbon:
      ReadTimeout: 7000
      ConectTimeout: 7000

重复上面步骤,断点进去一看 ??? 怎么还是 8000

原因是 OpenFeign 和 Ribbon 的超时时间只会有一个生效两者是二选一的,且 OpenFeign 优先

注掉 OpenFeign 超时时间配置之后,就变成了使用设置的 Ribbon 的超时时间

4. 结论
Feign 和 Ribbon 的超时时间只会有一个生效,规则:如果没有设置过 feign 超时,也就是等于默认值的时候,就会读取 ribbon 的配置,使用 ribbon 的超时时间和重试设置。否则使用 feign 自身的设置。两者是二选一的,且 feign 优先。


二、Ribbon 和 Hystrix

1. Hystrix 设置超时时间


# 设置 hystrix 超时时间
feign:
  hystrix:
    enabled: true
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 6000

@FeignClient(contextId = "remoteUserService", value = "cloud-system", fallbackFactory = RemoteUserFallbackFactory.class)

 注意:如果没有配置 fallback,那么 hystrix 的超时就不会生效,而是由 ribbon 来控制。

hystrix 的默认超时时间是 1s,这个配置在 HystrixCommandProperties 类

设置 hystrix 超时时间比 ribbon 大(OpenFign 的超时时间注掉)

ribbon:
  ReadTimeout: 2000
  ConectTimeout: 2000

访问地址 http://localhost:9203/test/getUserInfo?userId=2 发现请求 2s 左右就返回了,这个值刚好是 ribbon.ReadTimeout 的时间。表示此时 ribbon 超时触发了。然后进入了 hystrix 的熔断过程。

2. 结论:

  • 如果请求时间超过 ribbon 的超时配置,会触发重试;
  • 在配置 fallback 的情况下,如果请求的时间(包括 ribbon 的重试时间),超出了 ribbon 的超时限制,或者 hystrix 的超时限制,那么就会熔断。

一般来说,会设置 ribbon 的超时时间 < hystrix, 这是因为 ribbon 有重试机制。(这里说的 ribbon 超时时间是包括重试在内的,即,最好要让 ribbon 的重试全部执行,直到 ribbon 超时被触发)。
 

由于 connectionTime 一般比较短,可以忽略。那么,设置的超时时间应该满足:

(1 + MaxAutoRetries) * (1 + MaxAutoRetriesNextServer)* ReadTimeOut < hystrix 的 *timeoutInMillisecond

微服务系列:服务调用 Spring Cloud 之 OpenFeign 详细入门_程序猿秃头之路的博客-CSDN博客

微服务系列:服务调用 Spring Cloud 之 OpenFeign 性能优化_程序猿秃头之路的博客-CSDN博客

微服务系列:Spring Cloud 之 Feign、Ribbon、Hystrix 三者超时时间配置_feign和ribbon超时时间设置_程序猿秃头之路的博客-CSDN博客

错误1:springcloud异常:timed-out and no fallback available,failed and no fallback available的问题解决 

timed-out and no fallback available:

这个错误基本是出现在Hystrix熔断器,熔断器的作用是判断该服务能不能通,如果通了就不管了,调用在指定时间内超时时,就会通过熔断器进行错误返回。

一般设置如下配置的其中一个即可:

1、把时间设长

这里设置5秒

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000  

2、把超时发生异常属性关闭

hystrix.command.default.execution.timeout.enabled=false  

3、禁用feign的hystrix 

feign.hystrix.enabled: false  

failed and no fallback available:

而通过上面设置只是针对熔断器的错误关闭,并不能解决根本问题,比如Feign客户端调用远程服务时,默认为8秒超时时间,如果在规定时间内没有返回,同样会跳转到熔断器进行处理。即使关闭了熔断器的错误,但是总的错误处理还会是有这个问题出现。

那么要解决根本问题,就要从请求超时时间入手,因为有些服务可能存在调用时间长的问题,所以直接配置:

ribbon.ReadTimeout=60000

ribbon.ConnectTimeout=60000

这些才是真正解决请求超时的问题,如果不设置这个,被调用接口很慢时,会出现Read Timeout on Request。

而针对调用失败重试的次数也可以设置:

ribbon.maxAutoRetries=0

参考:

  1. https://github.com/spring-cloud/spring-cloud-netflix/issues/321

  2. https://stackoverflow.com/questions/38080283/how-to-solve-timeout-feignclient

  3. http://www.itmuch.com/spring-cloud-feign-ribbon-first-request-fail/

  4. https://github.com/spring-cloud/spring-cloud-netflix/issues/696

  5. http://www.jianshu.com/p/0eb13fd033a8

  6. http://blog.csdn.net/qwlzxx/article/details/77163268

  7. http://blog.csdn.net/clementad/article/details/54315805

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

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

相关文章

Consul 理解

Consul是google开源的一个使用go语言开发的服务发现、配置管理中心服务。内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案&#xff0c;不再需要依赖其他工具&#xff08;比如ZooKeeper等&#xff09;。服务部署简单&#xff0c;只有一…

SpringBoot实现自定义配置属性提示

前言 我们在使用SpringBoot开发项目时&#xff0c;常常需要编写一些属性配置类&#xff0c;用来完成自定义或特定的属性配置。在配置文件application.yml中&#xff0c;IDEA会自动提示官方默认的相关配置且可以点击属性自动跳转到属性对应的配置类中&#xff0c;实现快速查看属…

力扣387:字符串中的第一个唯一字符

题目描述&#xff1a;给定一个字符串s&#xff0c;找到它的第一个不重复字符&#xff0c;并返回索引&#xff0c;如果不存在&#xff0c;则返回-1. 提示&#xff1a;s 不为空且 s 只包含小写字母 思路&#xff1a; 将字符串中的每个字符遍历一次&#xff0c;将其中每个字符以…

基于Java斗车交易系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

centos下的Nginx, tar安装不能使用systemctl启动问题

1.systemctl start nginx启动报错 2.报错原因 解压方式nginx&#xff0c;系统服务内没有nginx的服务&#xff0c;所以报错 3.配置nginx系统服务 1)/etc/init.d/目录下创建nginx 2)nginx文件内容 #!/bin/sh # nginx - this script starts and stops the nginx daemin # # c…

【漏洞案例】云上攻防之云主机中web应用自身漏洞

0x00 前言 最近在做项目的时候&#xff0c;测到了一个部署在云上的存在 Laravel UEditor SSRF 漏洞的站点&#xff0c;并且发现这个 SSRF 漏洞可以读取到临时凭证&#xff0c;这不巧了&#xff0c;正好最近写了一个云环境利用的工具。 开始之前这里先简单介绍一下这个工具&am…

(三)R-studio调度

1、准备测试脚本 from datetime import datetime print(111) print(datetime.now()) 2、设置定时调度 如果crontab没有安装&#xff0c;需要在root用户下安装&#xff0c;并启动&#xff0c;可参考&#xff1a;Ubuntu下crontab的安装和使用 (base) rstudio5abc0fae5cff:~/p…

JVM的OOM问题定位解决

1、生成dump文件&#xff08;错误日志文件&#xff09;&#xff0c;MAT可以进行解读 &#xff08;1&#xff09;参数 -XX:HeapDumpOnOutOfMemoryErrorOOM时导出堆到文件。 -Xms1m -Xmx8m -XX:HeapDumpOnOutOfMemoryError&#xff08;2&#xff09;设置参数 -Xms1m -Xmx8m -…

【Python】 Windows上通过git bash执行python卡住的解决方法

解决方法 编辑 C:\Program Files\Git\etc\profile.d\aliases.sh&#xff0c;将python2.7改成python 编辑完成后&#xff0c;重启git bash, 输入python即可 参考 https://blog.csdn.net/ofreelander/article/details/112058975

Linux网络环境配置

第一种方式&#xff08;自动获取&#xff09;&#xff1a; 说明&#xff1a;登陆后&#xff0c;通过界面的来设置自动获取IP 特点&#xff1a;Linux启动后会自动获取IP 缺点&#xff1a;是每次自动获取的IP地址可能不一样 第二种方法&#xff08;指定IP)&#xff1a; 1、说明…

kettle文件资源库之Show hidden folders

版本7.1 在创建文件资源库时&#xff0c;有一个选项“show hidden folders”。从字面上理解&#xff0c;是“显示隐藏文件夹”的意思&#xff0c;其实不然。 通过repositories.xml文件我们可以看到&#xff0c;其实这个选项在配置文件中对应的标签是&#xff1a;<hides_hi…

计算机视觉:3*3卷积核的优势

本文重点 如果你了解卷积神经网络,那么你一定会注意到大多数卷积神经网络模型经常使用3*3的卷积核,甚至是1*1的,而5*5的都少用,这是为什么呢?本文对3*3的卷积神经网络的好处进行总结。 参数量少 在卷积神经网络中,卷积核的大小决定了模型的参数量。3*3的卷积核比5*5…

leetcode 102. 二叉树的层序遍历

2023.6.28 二叉树的层序遍历&#xff0c;需要用到的数据结构是队列。有几个核心点&#xff1a; 初始化变量 size&#xff0c;用于记录每层节点的数量。不能直接用que.size()&#xff0c;因为队列的大小是会随时变化的。在内层while循环中&#xff0c;每次先将队头节点的值保存…

HDLbits--Bugs mux4

用二选一多路选择器创建4选一多路选择器 说先修改编译问题&#xff1a;mux0&#xff0c;mux1变量重复使用&#xff0c;并且位宽只有一位&#xff0c;修改后编译 结果&#xff1a; 可知&#xff1a;00-a&#xff0c;01-b,10-c,11-d 可知sel[0]区分a和b&#xff0c;c和d &…

vue2项目Vant组件Dialog 弹出框异步关闭的坑

vue2项目使用vant&#xff0c;我这边是全局引入的&#xff0c;引入插件官方文档中有&#xff0c;这边就不介绍了。 安装&#xff1a;Vant 2 - Mobile UI Components built on Vue 话不多说直接说坑&#xff0c;当时写这个的时候真的给我气到了~~~ 先看一下官方文档&#xff1…

VS2019 Python连接Sql server2008

安好后&#xff1a; 测试代码&#xff1a; import pymssqltry:conn pymssql.connect(host127.0.0.1,usersa,password123456,databasehotel,charsetutf8)# 连接并执行Sql语句cursor conn.cursor()sql select * from odercursor.execute(sql)# 获取数据集rs cursor.fetchal…

【UCOS-III】自我学习笔记→第37讲→内存管理实验

文章目录 前言实验步骤1.复制消息队列工程&#xff0c;并创建OS内存区句柄和内存地址&#xff0c;并删除task2\task3及其相关内容2.修改task1任务函数3.查看串口现象 测试代码工程文件总结 前言 无&#xff0c;仅作记录&#xff0c;不具有参考价值&#xff0c;所用开发板为STM…

记一次docker-compose的坎坷安装经历

最近公司在做一个kafka项目&#xff0c;所以想用docker来安装kafka集群&#xff0c;所以安装完docker后就准备安装docker-compose&#xff0c;但在安装过程中确碰到了各种问题&#xff0c;搞了两个半天再通过翻墙工具才终于搞定。 首先看了篇文章显示安装前要对应docker版本。 …

Spring Boot 中的 @Transactional 注解是什么,原理,如何使用

Spring Boot 中的 Transactional 注解是什么&#xff0c;原理&#xff0c;如何使用 简介 在 Spring Boot 中&#xff0c;Transactional 注解是非常重要的一个注解&#xff0c;用于实现数据库事务的管理。通过使用 Transactional 注解&#xff0c;我们可以很方便地对事务进行控…

用Docker部署Nginx

部署步骤&#xff1a; 1.拉取镜像 docker pull nginx 2.创建并进入容器 docker run -d --name nginx01 -p 3344:80 nginx #注意nginx01是起的名字&#xff0c;3344是公网访问的端口&#xff0c;80是Nginx的默认端口 3.启动Nginx curl localhost:3344 4.在我的windows系统访…