首页 > 其他分享 >实战:OpenFeign使用以及易踩坑说明

实战:OpenFeign使用以及易踩坑说明

时间:2024-07-24 11:54:44浏览次数:18  
标签:实战 Feign OpenFeign feign 接口 说明 超时 ribbon

OpenFeign是SpringCloud中的重要组件,它是一种声明式的HTTP客户端。使用OpenFeign调用远程服务就像调用本地方法一样,但是如果使用不当,很容易踩到坑。

Feign 和OpenFeign

Feign

Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。

Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务Feign本身不支持Spring MVC的注解,它有一套自己的注解

OpenFeign

OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等,是一个轻量级的Http封装工具对象,大大简化了Http请求,使得我们对服务的调用转换成了对本地接口方法的调用。

OpenFeign 的 @FeignClient 可以解析SpringMVC的 @RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务

openFeign的优势

  1. 集成了Ribbon的负载均衡功能
  2. 集成Hystrix的熔断器功能
  3. 支持请求压缩
  4. 大大简化了远程调用的代码,同时功能还增强啦
  5. 以更加优雅的方式编写远程调用代码,并简化重复代码

OpenFeign应用

1. 导入依赖
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.2.1.RELEASE</version>
  </dependency>
2. 使用

创建Feign接口

@FeignClient(value = "xx-template-service")//value = "xx-template-service"指定服务的名字
public interface DriverFeign {

  /** 
   * demo feign 接口
   */
  @PutMapping(value = "/driver/status")
  Driver status(String id, Integer status);
}

Feign会通过动态代理,帮我们生成实现类。

注解@FeignClient声明Feign的客户端,注解value指明服务名称接口定义的方法,采用SpringMVC的注解。Feign会根据注解帮我们生成URL地址

FeignClient 注解参数

  • name/value:指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现
  • contextId:指定beanID
  • url: url一般用于调试,可以手动指定@FeignClient调用的地址
  • decode404:当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
  • configuration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
  • fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
  • fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
  • path: 定义当前FeignClient的统一前缀

注意事项

  1. 在使用fallback、fallbackFactory属性时,需要使用@Component注解,保证fallback类被Spring容器扫描到
  2. 在使用FeignClient时,Spring会按name创建不同的ApplicationContext,通过不同的Context来隔离FeignClient的配置信息, 在使用配置类时,不能把配置类放到Spring App Component scan的路径下,否则,配置类会对所有FeignClient生效.

启用OpenFeign

我们需要在服务的启动类上开启 OpenFeign ,只需要在 **Application 启动类上添加 @EnableFeignClients即可。

3. 日志配置
logging:
  level:
    xx.template.cloud.web.service.feign.ServiceServiceFeign: debug

通过loggin.level.xx=debug来设置日志级别。然而这个对Feign客户端不会产生效果。因为@FeignClient注解修饰的客户端在被代理时,都会创建一个新的Feign.Logger实例。我们需要额外指定这个日志的级别才可以。

  /** 
   * feign 日志级别配置
   * @return 
   */
  @Bean
  public Logger.Level feignLoggerLevel(){
    return Logger.Level.FULL;
  }

或者在配置文件中配置

feign: 
  client:
    config:
      # 全局配置
      default:
        loggerLevel: full

Feign支持4种级别:
NONE:不记录任何日志,默认值
BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
HEADERS:在BASIC基础上,额外记录了请求和响应的头信息
FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据

4. 数据压缩

用户在网络请求过程中,如果网络不佳、传输数据过大,会造成体验差的问题,我们需要将传输数据压缩提升体验。SpringCloud OpenFeign支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。

在客户端中配置数据压缩

feign:
  compression:
    request:
     enabled: true # 开启请求压缩
    response:
     enabled: true # 开启响应压缩

也可以对请求的数据类型,以及触发压缩的大小下限进行设置

feign:
  compression:
    request:
      enabled: true # 开启请求压缩
      mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
      min-request-size: 2048 # 设置触发压缩的大小下限
      #以上数据类型,压缩大小下限均为默认值
      response:
        enabled: true # 开启响应压缩

OpenFeign高级应用

OpenFeign熔断降级的两种方式-降级方法和降级工厂

首先在配置文件中配置如下,开启熔断降级

feign.hystrix.enabled=true
  1. Feign 定义降级方法

    feign接口定义

    /**
     * FeignClient 注解的 fallback 属性指定降级类
     */
    @FeignClient(name = "xx-template-cloud-service", fallback = ServiceServiceFeignFallBack.class)
    public interface ServiceServiceFeign {
    
        @GetMapping("/order/getOrder")
        Result getOrder(String id);
    }
    
    

    feign接口降级方法定义

    @Slf4j
    @Component
    class ServiceServiceFeignFallBack implements ServiceServiceFeign {
    
        @Override
        public Result getOrder(String id) {
            log.error("Feign接口熔断 熔断方式:ServiceServiceFeignFallBack");
            return Result.error("500", "Feign接口熔断");
        }
    }
    
  2. Feign 定义降级工厂

    feign接口定义

    /**
     * FeignClient 注解的 fallback 属性指定降级类
     */
    @FeignClient(name = "xx-template-cloud-service", fallback = UserCenterFeignClientFallbackFactory.class)
    public interface ServiceServiceFeign {
    
        @GetMapping("/order/getOrder")
        Result getOrder(String id);
    }
    
    

    feign接口降级工厂定义

    @Component
    @Slf4j
    class UserCenterFeignClientFallbackFactory implements FallbackFactory<ServiceServiceFeign> {
    
        @Override
        public ServiceServiceFeign create(Throwable cause) {
            return new ServiceServiceFeign() {
                @Override
                public Result getOrder(String id) {
                    log.error("Feign接口熔断,熔断方式:UserCenterFeignClientFallbackFactory");
                    return Result.error("500", "Feign接口熔断");
                }
            };
        }
    }

踩坑指南

坑一:用对Http Client

1.1 feign中http client

如果不做特殊配置,OpenFeign默认使用jdk自带的HttpURLConnection,我们知道HttpURLConnection没有连接池、性能和效率比较低,如果采用默认,很可能会遇到性能问题导致系统故障。

可以采用Apache HttpClient,properties文件中增加下面配置:

feign.httpclient.enabled=true

pom文件中增加依赖:

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
    <version>9.3.1</version>
</dependency>

也可以采用OkHttpClient,properties文件中增加下面配置:

feign.okhttp.enabled=true

pom文件中增加依赖:

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
    <version>10.2.0</version>
</dependency>

1.2 ribbon中的Http Client

通过OpenFeign作为注册中心的客户端时,默认使用Ribbon做负载均衡,Ribbon默认也是用jdk自带的HttpURLConnection,需要给Ribbon也设置一个Http client,比如使用okhttp,在properties文件中增加下面配置:

ribbon.okhttp.enabled=true

坑二:全局超时时间

OpenFeign可以设置超时时间,简单粗暴,设置一个全局的超时时间,如下:

feign.client.config.default.connectTimeout=2000
feign.client.config.default.readTimeout=60000

如果不配置超时时间,默认是连接超时10s,读超时60s,在源码feign.Request的内部类Options中定义。

但是如果某个服务的并发量很高,服务的超时时间过长会导致占用大量连接资源,导致系统崩溃,要防止这样的故障发生,最好的做法就是给服务单独设置超时时间。

这个接口设置了最大的readTimeout是60s,这个时间必须大于调用的所有外部接口的readTimeout,否则处理时间大于readTimeout的接口就会调用失败。

当然,如果开启熔断后,不配置hystrix和ribbon的超时时间,那么Hystrix与ribbon的默认请求超时时间都是1秒,建议配置Hystrix的超时时间要大于ribbon的超时时间,否则会在接口调用还未完成的时候直接进入回调方法。

# 开启熔断
feign.hystrix.enabled: true

如下图,在一个系统中使用OpenFeign调用外部三个服务,每个服务提供两个接口,其中serviceC的一个接口需要60才能返回,那上面的readTimeout必须设置成60s。

图片

但是如果serviceA出故障了,表现是接口1超过60s才能返回,这样OpenFeign只能等到读超时,如果调用这个接口的并发量很高,会大量占用连接资源直到资源耗尽系统奔溃。要防止这样的故障发生,就必须保证接口1能fail-fast。最好的做法就是给serviceC单独设置超时时间。

坑三:单服务设置超时时间

从上一节的讲解我们看到,需要对serviceC单独设置一个超时时间,代码如下:

feign.client.config.serviceC.connectTimeout=2000
feign.client.config.serviceC.readTimeout=60000

这个时间会覆盖第一节中默认的超时时间。但是问题又来了,serviceC中又掉了serviceD,因为serviceD的故障导致接口6发生了读超时的情况,为了不让系统奔溃,不得不对serviceC的接口5单独设置超时时间。如下图:

图片

几个组件的关系

hystrix+ribbon。hystrix在最外层,然后再到Ribbon,最后里面的是http请求。所以说。hystrix的熔断时间必须大于ribbon的 ( ConnectTimeout + ReadTimeout )。而如果ribbon开启了重试机制,还需要乘以对应的重试次数(注意这里的重试可以是ribbon的重试也可能是feign的重试),保证在Ribbon里的请求还没结束时,Hystrix的熔断时间不会超时。

遇到的问题

1. 使用Spring MVC注解,但请求方式不正确
  • 参数没有通过注解指定,此时的参数会自动封装到body中,Feign检测到body里面有请求参数就会默认使用POST请求。
  • Feign默认使用的是POST方法,如果想使用GET方法,需要在配置文件中设置spring.cloud.openfeign.client.config.default.method.name=get。
  • 如果使用了Spring Cloud Netflix Feign,那么可能是因为您的应用程序使用了Spring Cloud Netflix Ribbon来处理HTTP负载均衡。在这种情况下,您需要确保Ribbon的配置正确,并且不会影响Feign的GET请求。
2. 使用nacos做注册中心,Feign调用时拉取的服务列表为空

我用的spring cloud版本是Hoxton.SR8

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

原因是Feign 在spring cloud Hoxton.M2版本之后,不再使用ribbon,所以我们在pom文件中还需要导入loadbalancer依赖,并排除掉nacos的ribbon依赖。

        <!--nacos-discovery-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2021.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>

并在配置文件中添加


spring.cloud.loadbalancer.ribbon.enabled: false

坑四:熔断超时时间

怎样给单个接口设置超时时间,查看网上资料,必须开启熔断,配置如下:

feign.hystrix.enabled=true

开启熔断后,就可以给单个接口配置超时了。如果调用serviceC的接口5的声明如下:

@FeignClient(value = "serviceC"configuration = FeignMultipartSupportConfig.class)
public interface ServiceCClient {
    @GetMapping("/interface5")
    String interface5(String param);
}

根据上面interface5接口的声明,在properties文件中增加如下配置:

hystrix.command.ServiceCClient#interface5(param).execution.isolation.thread.timeoutInMilliseconds=60000

网上资料说的并不准确,这个超时时间并没有起作用。为什么不生效呢?

4.1 使用feign超时

最终使用的超时时间来自于Options类。如果我们配置了feign的超时时间,会选择使用feign超时时间,下面代码在FeignClientFactoryBean类的configureUsingProperties方法:

if (config.getConnectTimeout() != null && config.getReadTimeout() != null) {
 builder.options(new Request.Options(config.getConnectTimeout(), config.getReadTimeout()));
}

4.2 使用ribbon超时

如果没有配置feign,但是配置了ribbon的超时时间,会使用ribbon的超时时间。我们看下这段源代码,FeignLoadBalancer里面的execute方法,

public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)
  throws IOException {
 Request.Options options;
 if (configOverride != null) {
  RibbonProperties override = RibbonProperties.from(configOverride);
  options = new Request.Options(
    override.connectTimeout(this.connectTimeout),
    override.readTimeout(this.readTimeout));
 }
 else {
  options = new Request.Options(this.connectTimeout, this.readTimeout);
 }
 //这个request里面的client就是OkHttpClient
 Response response = request.client().execute(request.toRequest(), options);
 return new RibbonResponse(request.getUri(), response);
}

4.3 使用自定义Options

对于单个接口怎么配置超时时间,我这里给出一个方案,如果你有其他方案,欢迎探讨。我的方案是使用RestTemplate来调这个接口,单独配置超时时间,配置代码如下,这里使用OkHttpClient:

public class RestTemplateConfiguration {
 
    @Bean
    public OkHttp3ClientHttpRequestFactory okHttp3RequestFactory(){
        OkHttp3ClientHttpRequestFactory requestFactory = new OkHttp3ClientHttpRequestFactory();
        requestFactory.setConnectTimeout(2000);
        requestFactory.setReadTimeout(60000);
        return requestFactory;
    }
 
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(OkHttp3ClientHttpRequestFactory okHttp3RequestFactory){
        return new RestTemplate(okHttp3RequestFactory);
    }
}

为了使用ribbon负载均衡,上面加了@LoadBalanced

如果使用RestTemplate,就会使用OkHttp3ClientHttpRequestFactory中配置的时间。

坑五:ribbon超时时间

作为负载均衡,ribbon超时时间也是可以配置的,可以在properties增加下面配置:

ribbon.ConnectTimeout=2000
ribbon.ReadTimeout=11000

有文章讲ribbon配置的超时时间必须要满足接口响应时间,其实不然,配置feign的超时时间就足够了,因为它可以覆盖掉ribbon的超时时间。

坑六:重试默认不开启

OpenFeign默认是不支持重试的,可以在源代码FeignClientsConfiguration中feignRetryer中看出。

@Bean
@ConditionalOnMissingBean
public Retryer feignRetryer() {
 return Retryer.NEVER_RETRY;
}

要开启重试,我们可以自定义Retryer,比如下面这行代码:

Retryer retryer = new Retryer.Default(100, 1000, 2);

表示每间隔100ms,最大间隔1000ms重试一次,最大重试次数是1,因为第三个参数包含了第一次请求。

坑七:Ribbon重试

7.1 拉取服务列表

Ribbon默认从服务端拉取列表的时间间隔是30s,这个对优雅发布很不友好,一般我们会把这个时间改短,如下改成3s:

serviceC.ribbon.ServerListRefreshInterval=3

7.2 重试

Ribbon重试有不少需要注意的地方,这里分享4个。

1.同一实例最大重试次数,不包括首次调用,配置如下:

serviceC.ribbon.MaxAutoRetries=1

这个次数不包括首次调用,配置了1,重试策略会先尝试在失败的实例上重试一次,如果失败,请求下一个实例。

2.同一个服务其他实例的最大重试次数,这里不包括第一次调用的实例。默认值为1:

serviceC.ribbon.MaxAutoRetriesNextServer=1

3.是否对所有操作都重试,如果改为true,则对所有操作请求都进行重试,包括post,建议采用默认配置false。

serviceC.ribbon.OkToRetryOnAllOperations=false

4.对指定的http状态码进行重试

serviceC.retryableStatusCodes=404,408,502,500

坑八:hystrix超时

如下图:

图片

hystrix默认不开启,但是如果开启了hystrix,因为hystrix是在Ribbon外面,所以超时时间需要符合下面规则:hystrix超时 >= (MaxAutoRetries + 1) * (ribbon ConnectTimeout + ribbon ReadTimeout)

如果Ribbon不重试,MaxAutoRetries=0

根据上面公式,假如我们配置熔断超时时间如下:

hystrix.command.ServiceCClient#interface5(param).execution.isolation.thread.timeoutInMilliseconds=15000
ribbon.ReadTimeout=8000

这个配置是不会重试一次的。serviceA调用serviceB时,hystrix会等待Ribbon返回的结果,如果Ribbon配置了重试,hystrix会一直等待直到超时。上面的配置,因为第一次请求已经耗去了8s,剩下时间7s不够请求一次了,所以是不会进行重试的。

坑九:使用OpenFeign做http客户端

即使不用注册中心,使用OpenFeign做普通http客户端也是很方便的,但是有三点需要注意:

  • 不用配置ribbon相关参数

  • 使用RestTemplate调用时,不考虑负载均衡

  • 使用过程中OpenFeign要组装出自己的一套请求,跟直接使用http客户端比,会有一定开销

使用OpenFeign有很多配置上的坑,对于没有注册中心的情况,建议直接使用http客户端

坑十  OpenFeign客户端可能会出现反序列化失败的错误

问题描述

SpringBoot通过原生OpenFeign客户端调用HTTP接口,如果返回值中包含LocalDateTime类型(包括其他JSR-310中java.time包的时间类),在客户端可能会出现反序列化失败的错误。错误信息如下:

 Caused by:com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('2020-10-07T11:04:32')

问题分析

从客户端调用fegin,也是相当于URL传参就相当于经过一次JSON转换,数据库取出‘2020-10-07T11:04:32'数据这时是时间类型,进过JSON之后就变成了String类型,T就变成了字符不再是一个特殊字符,因此String的字符串“2020-10-07T11:04:32”反序列化就会失败。

问题解决

在项目中增加依赖。

1

2

3

4

5

<dependency>

    <groupId>com.fasterxml.jackson.datatype</groupId>

    <artifactId>jackson-datatype-jsr310</artifactId>

    <version>2.9.9</version>

</dependency>

注:如果是用的是SpringBoot,并且明确指定了SpringBoot版本,引入jackson-datatype-jsr310时,可以不用指定版本号。

接下来,在POJO类的LocalDateTime类型字段增加如下注解。

1

2

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;

添加后的效果如下所示。

1

2

3

4

5

6

7

8

9

10

11

12

13

import java.time.LocalDateTime;

import com.baomidou.mybatisplus.annotation.FieldFill;

import com.baomidou.mybatisplus.annotation.TableField;

import com.fasterxml.jackson.annotation.JsonFormat;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;

@TableField(value = "CREATE_TIME", fill = FieldFill.INSERT)

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")

@JsonDeserialize(using = LocalDateTimeDeserializer.class)

private LocalDateTime createTime;

此时,再次调用远程接口,问题解决。

坑十  OpenFeign中8个易踩的坑汇总

在OpenFeign中,有一些常见的陷阱和问题,这里列举几个常见的并给出简要的解释和解决方法:

注解配置错误:

解释:如果你没有正确使用@FeignClient注解来指定服务名、配置属性等,OpenFeign将无法正常工作。

解决方法:确保你的@FeignClient注解配置正确。

序列化问题:

解释:如果客户端和服务端使用的序列化方式不一致,可能会导致数据传输失败。

解决方法:确保客户端和服务端使用相同的序列化方式。

超时配置不当:
解释:OpenFeign的超时设置不当可能会导致请求长时间挂起。
解决方法:根据实际需求调整超时时间。

日志配置不当:
解释:如果没有正确配置OpenFeign的日志,可能会导致难以发现问题。
解决方法:集成日志框架,如Logback或SLF4J,来查看详细的请求和响应信息。

断路器未正确配置:
解释:如果没有配置或错误配置了断路器,当服务不可用时,OpenFeign可能会一直尝试请求。
解决方法:集成断路器,如Hystrix,并根据服务的可用性配置合适的断路规则。

版本不兼容问题:
解释:OpenFeign与Spring Cloud版本不匹配可能会导致不可预知的问题。
解决方法:确保OpenFeign与Spring Cloud的版本兼容。

请求方法不匹配:
解释:如果Feign客户端接口中的方法签名与提供服务的接口不匹配,可能会导致无法正确映射请求。
解决方法:确保Feign接口与远程服务接口完全一致。

错误的URL拼接:
解释:如果Feign客户端使用了错误的URL,可能会导致请求发送到错误的地址。
解决方法:确保Feign客户端配置的URL是正确的。

二、踩坑一:401 认证错误
由于我的微服务配置了Oauth2来进行权限访问,直接访问认证后才能访问的接口会报401未授权。

最终,我的解决方法是通过在接口上加上@RequestHeader("Authorization") String token来解决问题:每次调用feign接口时我都将访问携带的请求头给他加上,这样成功解决了认证问题。

三、踩坑二:403 请求方式错误
在我刚解决401后,服务器又报403请求方式错误,这不搞心态吗。解决方案:Feign接口会将接口转换成http形式,这就要我们注意接口上的@RequestParam、@RequestBody这些参数不能少,准确使用。

四、踩坑三:List<Long>不能正常传参
原本的服务提供者需要的参数为 @RequestParam List<Long> ids,但在服务调用者调用此feign接口时出现情况如下:

传入的List数据将接口参数变为这样:

http://my-server/xxxx?ids=100&ids=101&ids=102

这个问题就很离谱,理论上应该是这个格式:

http://my-server/xxxx?ids=100,101,102

最终,我的解决方案是将List<Long>直接改为List<String>

feign传参时也只传长度为1的List参数合并参数:

    for (MGPltTenderComment comment : comments) {
            if (ids.toString().equals("")) {
                ids = new StringBuilder(myId);
            } else {
                ids.append(",").append(myId);
            }
        }
 
        R<List<SysUserDto>> res =      sysUserFeign.queryPublicList(Collections.singletonList(String.valueOf(ids)), token);
关键:Collections.singletonList(String.valueOf(ids))



这些问题是OpenFeign使用中可能遇到的常见问题,开发者在遇到问题时可以根据这些点进行排查。

这些问题是OpenFeign使用中可能遇到的常见问题,开发者在遇到问题时可以根据这些点进行排查。

标签:实战,Feign,OpenFeign,feign,接口,说明,超时,ribbon
From: https://blog.csdn.net/Rookie_CEO/article/details/140624242

相关文章

  • Aspose项目实战!pdf、cells for java
    Aspose实战使用:Excel与PDF转换工具类在这篇博客中,我将分享如何使用Aspose库来实现Excel文件与PDF文件之间的转换。我会重点分析一个工具类AsposeOfficeUtil,这个类封装了多个与Excel和PDF相关的操作方法,帮助开发者高效地进行文件转换和数据处理。此外,还将提......
  • 【云原生】Kubernetes 中的 PV 和 PVC 介绍、原理、用法及实战案例分析
    ✨✨欢迎大家来到景天科技苑✨✨......
  • 数字量输入模块:功能与选型及安装说明
    Profinet远程IO模块:数字量输入模块_功能与选型及安装说明XD系列插片式远程I/O模块是兴达易控技术研发的分布式扩展模块。XD系列成套系统主要由耦合器、各种功能I/O模块、电源辅助模块以及终端模块组成。有多种通讯协议总线的耦合器,例如PROFINET、EtherCAT、Ethernet/IP、Cclink......
  • OpenFeign
    ♥️作者:小宋1021......
  • Profinet远程IO模块:模拟量模块_软件组态说明
    本章主要介绍Profinet远程IO模块XD系列与PLC配置步骤。该文举例介绍模拟量模块输入输出的组态方法。1、通信连接图,如图4-1所示。图4-1通信连接图2、硬件配置如表4-1所示3、安装XML描述文件安装XML描述文件到Twin0AT3中,如图4-2所示。示例默认文件夹为(0:\Twin0AT\3.1\0onf......
  • 零基础STM32单片机编程入门(十九) 4位数码管显示模块实战含源码
    文章目录一.概要二.4位数码管主要参数三.数码管显示器的工作原理四.74HC595芯片介绍1.74HC595芯片内部框图2.74HC595通讯时序五.4位数码管原理图六.4位数码管显示实验七.CubeMX工程源代码下载八.小结一.概要数码管显示器是一类价格便宜、使用简单,通过对其不同的管......
  • pytest实战技巧之参数化应用
    pytest是Python中最流行的测试框架之一。它提供了丰富的功能,可以帮助我们编写高效、可靠的测试用例。其中一个重要的功能就是参数化,它可以让我们用不同的数据组合来运行同一个测试用例,从而提高测试覆盖率和效率。本文将介绍pytest参数化的基本用法和一些高级技巧,帮助读者更好地......
  • 计算机编程—IT实战课堂 Springboot 电竞兴趣论坛系统
    计算机编程—IT实战课堂:Springboot电竞兴趣论坛系统随着电子竞技行业的迅猛发展,电竞爱好者对于交流平台的需求日益增长。结合IT实战课堂的教学实践,我们利用SpringBoot框架开发了一款集讨论、资源共享、赛事追踪于一体的电竞兴趣论坛系统。本文将深入探讨该项目的构思背景、......
  • 计算机作业—IT实战营 核酸检测管理系统
    计算机作业—IT实战营:核酸检测管理系统设计与实现在疫情防控常态化的今天,高效、准确的核酸检测管理系统成为了保障公共卫生安全的重要一环。本篇博客将详细介绍一个基于IT实战营项目的核酸检测管理系统,涵盖系统的设计思路、关键技术选型、核心功能模块,以及实战训练中的教育意......
  • 计算机项目设计—IT实战课堂 个人医疗健康管理平台小程序
    计算机项目设计—IT实战课堂:个人医疗健康管理平台小程序在数字化时代背景下,个人健康管理成为公众日益关注的焦点。结合IT实战课程,我们设计并实现了一款基于微信小程序的个人医疗健康管理平台,旨在为用户提供便捷的健康数据记录、医疗咨询、预约挂号及日常健康提醒服务。本文将......