Springboot应用整合Sentinel实现限流、熔断、降级笔记

news2024/9/21 12:47:19

可以使用官方的sentinel

也可使用进行持久化改造后的Sentinel ,本文基于此进行记录。Sentinel持久化到Nacosicon-default.png?t=N2N8https://blog.csdn.net/chenjian723122704/article/details/130098896

Sentinel版本为 1.8.6 

Nacos版本为 2.2.0

关于网关限流、限流和熔断,我自己总结出来了一套规则,有更好的意见希望大家指正。

  1. 网关只做限流,不做熔断。
  2. 普通服务被请求,比如客户请求我们的api服务,此时做限流。
  3. 普通服务调用内部服务,比如API服务,调用账单查询服务,需要做两部操作。1)在api服务的配置文件打开 feign.sentinel.enable=true;2)账单查询服务需要配置熔断规则。  当api的请求账单服务的接口达到熔断的阈值时,api下次再有请求,就会直接进入降级方法,或者抛出异常。

1.启动 Sentinel 服务

java -jar sentinel-dashboard-1.8.6.jar --server.port=8800

2.普通应用的限流策略

新建一个Springboot应用,创建一个用于测试的Controller

/**
 * 测试
 * @author chenjian
 * @date 2022/12/30
 * @version 1.0
 */
@Slf4j
@RefreshScope
@RestController
@RequestMapping("/test")
public class Test {
    @GetMapping("/test")
    public R test() {
        return R.ok();
    }
}


/**
 * 返回数据
 *
 * @author jianchene0
 */
@Slf4j
public class R extends HashMap<String, Object> {
    private static final long serialVersionUID = 1L;

    public R() {
        put("code", 0);
        put("msg", "success");
    }

    public static R error() {
        return error(500, "未知异常,请联系管理员");
    }

    public static R error(String msg) {
        return error(500, msg);
    }

    public static R error(int code, String msg) {
        R r = new R();
        r.put("code", code);
        r.put("msg", msg);

        log.error("失败信息: "+ code + "  ----  " + msg);
        return r;
    }

    public static R ok(String msg) {
        R r = new R();
        r.put("msg", msg);
        return r;
    }

    public static R ok(Map<String, Object> map) {
        R r = new R();
        r.putAll(map);
        return r;
    }

    public static R ok() {
        return new R();
    }

    @Override
    public R put(String key, Object value) {
        super.put(key, value);
        return this;
    }

    /**
     * 检查是否OK
     * @return
     */
    public boolean isOk() {
        return (int)this.get("code") == 0;
    }
}

pom文件中引入依赖


        <!-- Sentinel流量监控、限流、熔断降级处理 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

若使用改造的支持持久化的Sentinel,还需要引入依赖

        <!-- 引入Nacos数据源 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
            <version>${sentinel.version}</version>
        </dependency>

 yaml引入sentinel配置、nacos配置及其他配置

# Tomcat
server:
  tomcat:
    uri-encoding: UTF-8
  port: 9803
  servlet:
    context-path: /

spring:
  application:
    name: api
  cloud:
    nacos:
      # nacos.core.auth.enabled=true 开启权限验证
      discovery:
        # nacos地址
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
        namespace: 
        group: DEFAULT_GROUP
        metadata:
          management:
            context-path: ${server.servlet.context-path}/actuator
      config:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
        #data-id后缀
        file-extension: yaml
        # 分组名称
        namespace: 
        group: DEFAULT_GROUP
        encode: UTF-8
        # 修改后自动加载
        refresh-enabled: true
        # 允许nacos服务端向本地同步配置
        enable-remote-sync-config: true
    sentinel:
      eager: true  #是否开启网关限流,默认true
      transport:
        # 添加sentinel的控制台地址
        dashboard: 127.0.0.1:8800
        #指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer
        # port: 8719
      web-context-unify: false # 默认将调用链路收敛,导致链路流控效果无效
      # 持久化配置
      datasource:
        flow-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-flow-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: flow
        degrade-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-degrade-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: degrade
        system-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-system-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: system
        param-flow-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-param-flow-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: param-flow
        authority-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-authority-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: authority

feign:
  sentinel:
    enabled: true #sentinel是不会对feign进行监控的,需要开启配置

此外,定义Sentinel的异常处理器,使得当被限流、降级时,可以同一返回异常信息

import com.ah.ums.common.constants.ResCodeEnum;
import com.ah.ums.common.utils.R;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * sentinel 限流降级后异常处理
 * @author jianchen
 */
@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws Exception {
        ResCodeEnum resCodeEnum = null;
        if (ex instanceof FlowException) {
            resCodeEnum = ResCodeEnum.SENTINEL_FLOW_ERROR;
        } else if (ex instanceof DegradeException) {
            resCodeEnum = ResCodeEnum.SENTINEL_DEGRADE_ERROR;
        } else if (ex instanceof ParamFlowException) {
            resCodeEnum = ResCodeEnum.SENTINEL_PARAM_FLOW_ERROR;
        } else if (ex instanceof SystemBlockException) {
            resCodeEnum = ResCodeEnum.SENTINEL_SYSTEM_ERROR;
        } else if (ex instanceof AuthorityException) {
            resCodeEnum = ResCodeEnum.SENTINEL_AUTHORITY_ERROR;
        }
        // http状态码
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Type", "application/json;charset=utf-8");
        response.setContentType("application/json;charset=utf-8");
        String errJson = JSON.toJSONString(R.error(resCodeEnum.getCode(), resCodeEnum.getMsg()));
        new ObjectMapper().writeValue(response.getWriter(), errJson);
    }
}


/**
 * 返回码枚举
 *
 * @author chenjian
 * @version 1.0
 * @date 2022/11/11
 */
public enum ResCodeEnum {
    ok(0, "成功"),
    NO_PARAM(201, "传入参数缺失,请检查"),
    ERR_PARAM(202, "传入参数异常,请检查"),
    VALID_FAIL_PARAM(203, "参数校验异常"),
    SENTINEL_FLOW_ERROR(427, "请求过于频繁,被限流了"),
    SENTINEL_DEGRADE_ERROR(428, "请求过于频繁,被降级了"),
    SENTINEL_PARAM_FLOW_ERROR(429, "热点数据请求过于频繁"),
    SENTINEL_SYSTEM_ERROR(430, "请求过于频繁,触发系统限制"),
    SENTINEL_AUTHORITY_ERROR(431, "授权规则不通过"),
    UNKNOWN(999, "操作失败!!");
    private Integer code;
    private String msg;

    ResCodeEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public static ResCodeEnum getByCode(Integer code) {
        if (code == null) {
            return null;
        }
        for (ResCodeEnum resMsgEnum : values()) {
            if(resMsgEnum.code.equals(code)) {
                return resMsgEnum;
            }
        }
        return UNKNOWN;
    }
}

至此,普通服务改造完成,可以使用Sentinel进行监控了

3.测试

1.分别启动 nacos sentinel 以及SpringBoot应用程序。

2.首先访问Springboot的controller 

http://localhost:9803/test/test

 

访问成功后 ,会在Sentinel的控制台看到有api的请求进来了

3.点击流控新增一条流控规则

 

 此时会发现nacos中会自动增肌了一条配置,里面记录了api的流控规则

 

 我们接着测试,在浏览器不停刷新刚刚的链接,会出现限流的提示,此时,我们的url就被限流了

 

 3.熔断规则

假设有两个服务,都是按照第2节配置了Sentinel的依赖、yaml。:

  • API 服务是对外服务,供第三方调研;
  • service 服务是内部服务,供内部调用;

一般的规则时 API服务通过openFeign调用service提供的服务。使用feign注意的是 API 一定要配置  feign.sentinel.enable=true ,否则熔断效果不会生效

在 Feign定义处,加上fallback。

 对应的fallback

 

在Sentinel增加一条熔断规则,2秒内溢出比例达到0.2就进行熔断。

 

 

我们在服务内部加上 int a = 10/0;然后再让API请求查询用户分页数据。就会出发熔断,进入回调方法。

 

4.网关限流

网关限流与第2节中的配置基本类似,不过需要增加网关相关的依赖和配置,以及增加启动参数。

4.1 网关限流的依赖,增加了一个依赖

       <!-- 引入Nacos数据源 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
            <version>${sentinel.version}</version>
        </dependency>
        <!-- Sentinel流量监控、限流、熔断降级处理 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- gateway网关整合sentinel进行限流降级 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
        </dependency>

4.2 网关需要增加网关规则的持久化依赖

网关持久化依赖

spring:
  cloud:
    sentinel:
      datasource:
        gw-flow-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-gw-flow-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: gw-flow
        gw-api-group: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-gw-api-groups
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: gw-api-group

完整的网关yaml配置

# Tomcat
server:
  tomcat:
    uri-encoding: UTF-8
  port: 9803
  servlet:
    context-path: /

spring:
  application:
    name: api
  cloud:
    gateway:
      # 路由数组:指当请求满足什么样的断言时,转发到哪个服务上
      routes:
        # 配置断言路由到 API 服务中
        # 路由标识,要求唯一,名称任意
        - id: api
          uri: lb://api # 使用了lb形式,从注册中心负载均衡的获取uri
          # 设置断言
          predicates:
            # 断言,满足 /api/** 路径的请求都会被路由到 API 服务中
            - Path=/api/**
          filters:
            - StripPrefix=1 # 去除url的第一个前缀,本规则是去除/api
    nacos:
      # nacos.core.auth.enabled=true 开启权限验证
      discovery:
        # nacos地址
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
        namespace: 
        group: DEFAULT_GROUP
        metadata:
          management:
            context-path: ${server.servlet.context-path}/actuator
      config:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
        #data-id后缀
        file-extension: yaml
        # 分组名称
        namespace: 
        group: DEFAULT_GROUP
        encode: UTF-8
        # 修改后自动加载
        refresh-enabled: true
        # 允许nacos服务端向本地同步配置
        enable-remote-sync-config: true
    sentinel:
      eager: true  #是否开启网关限流,默认true
      #配置限流之后的响应内容
      scg:
        fallback:
          # 两种模式:一种是response返回文字提示信息,一种是redirect,重定向跳转
          mode: response
          # 响应的状态
          response-status: 426
          # 响应体
          response-body: '{"code": 426,"message": "限流了,稍后重试!"}'
      transport:
        # 添加sentinel的控制台地址
        dashboard: 127.0.0.1:8800
        #指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer
        # port: 8719
      web-context-unify: false # 默认将调用链路收敛,导致链路流控效果无效
      # 持久化配置
      datasource:
        flow-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-flow-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: flow
        degrade-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-degrade-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: degrade
        system-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-system-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: system
        param-flow-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-param-flow-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: param-flow
        authority-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-authority-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: authority
        gw-flow-rule: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-gw-flow-rules
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: gw-flow
        gw-api-group: # 唯一名称可自定义
          nacos:
            # 设置Nacos的连接地址、命名空间和Group ID
            server-addr: ${spring.cloud.nacos.discovery.server-addr}
            username: ${spring.cloud.nacos.discovery.username}
            password: ${spring.cloud.nacos.discovery.password}
            namespace: # 为空,使用默认的public
            # 设置Nacos中配置文件的命名规则
            dataId: ${spring.application.name}-gw-api-groups
            groupId: SENTINEL_GROUP
            data-type: json
            # 必填的重要字段,指定当前规则类型是"限流"
            rule-type: gw-api-group



启动网关应用,访问一次路由地址 http://localhost/api/test/test?params=1

在Sentinel的控制台能到网关的请求。

 点击流控,

  • 根据Route Id (也就是yaml中定义的routes下的id)进行限流
  • 根据API 分组进行限流,可以更细化的管理网关的限流

测试根据Route Id进行限流,先设置限流规则

刷新页面,会提示限流 http://localhost/api/test/test?params=1

 

根据API分组限流,首先需要在API管理中设置

 在流控设置中可以选择对应的分组

 删除原来的网关限流规则,使用新的规则,测试限流

 

 

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

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

相关文章

【Step1】Linux Kernel -基础

《Linux内核设计与实现.第3版》1-2章学习笔记 1. 获取内核源码 http://www.kernel.org 2. 内核版本命名规则 内核的版本号主要有四个数字组成。 从版本号&#xff1a; 偶数表示稳定版&#xff08;可用于企业级环境&#xff09;&#xff0c;奇数表示开发版&#xff1b; 修订…

ack应答机制

ACK在 Kafka 中&#xff0c;ack&#xff08;Acknowledgment&#xff09;机制是指用于确认生产者发送的消息已经被成功写入到 Kafka 分区中的一种机制。生产者可以通过 ack 参数来控制这个机制&#xff0c;以便根据自己的需求进行设置。 ACK应答级别0&#xff1a;生产者发送过来…

手机号码归属地 API 实现个性化推荐的思路分析

前言 随着移动互联网和智能手机的普及&#xff0c;越来越多的人使用手机上网和购物&#xff0c;移动营销已成为企业获取用户和提升品牌知名度的重要手段。手机号码归属地 API 作为移动营销的关键工具&#xff0c;具有广阔的应用前景。 本文将探讨如何利用手机号码归属地 API …

IDEA配置MAVEN_OPTS

IDEA配置MAVEN_OPTS​ 解决问题 maven MAVEN_OPTS设置 maven编译优化 maven编译速度慢 maven打包编译很慢 maven多线程编译打包 IDEA Maven配置教程​​测试环境:Win10(64位) i7-7700HQ 16GB​​ 参考文章: ​​ ​JVM参数MetaspaceSize的误解​​ Java HotSpot™ 64-Bit Ser…

【AI浪潮下的挑战和机遇】许多职业即将消失,AI 即将战胜人类了吗?

文章目录前言一、人类科技发展史二、 AI浪潮下的挑战1. 数据安全和隐私保护问题2. 带来新的伦理和道德问题3. 版权和知识产权问题三、对传统行业和就业的冲击1.传统文本编辑行业受到冲击2.就业岗位的变化3.工作流程的变化4.创意版权问题四、AI浪潮下的机遇1.提高效率和创意性2.…

【软考备战·希赛网每日一练】2023年4月12日

文章目录一、今日成绩二、错题总结第一题三、知识查缺题目及解析来源&#xff1a;2023年04月12日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析&#xff1a; 依据题目画出PERT图如下&#xff1a; 关键路径长度&#xff08;从起点到终点的路径中最长的一条&#x…

使用MybatisPlus时注意点的记录

在 MyBatis-Plus 中&#xff0c;默认情况下&#xff0c;实体类的主键属性名必须为 "id"&#xff0c;如果实体类主键属性名为 其他比如"nbid"&#xff0c;则需要进行显式的用FileId配置或者在.XML中配置。 在使用MybatisPlus时,如果主键名是id 实体类属性…

Django REST Framework(DRF)框架之视图类(视图基类、Mixin扩展类、子类视图)

DRF框架之视图类的使用视图类概述视图基类Mixin扩展类子类视图类视图基类APIViewGenericAPIViewMixin扩展类ListModelMixinCreateModelMixinRetrieveModelMixinUpdateModelMixinDestroyModelMixin子类视图ListAPIViewCreateAPIViewRetrieveAPIViewDestoryAPIViewUpdateAPIViewL…

联想集团ESG与社会价值论坛召开,首次发布《联想集团2022社会价值报告》

对企业而言&#xff0c;ESG不再是选择题&#xff0c;而是必答题。 联想集团是ESG的先行者、领军者。 2023年4月11日&#xff0c;“联想集团ESG与社会价值论坛暨《联想集团2022社会价值报告》发布会”在京召开&#xff0c;会议由中国社会责任百人论坛、联想集团联合主办&#xf…

【图像】协议:常见的图像格式协议对比

1. 背景 不知不觉已经大半年没有写博客了。换了工作之后突然变忙了许多&#xff0c;紧张的项目节点一个接一个&#xff0c;高优先级的事一件接一件&#xff0c;让人兴奋的同时也变得很多时候没有时间去复盘去反思去沉淀。 最近在整理产品的feature list&#xff0c;各种各样的…

Yum方式安装Nginx

前言&#xff1a;使用Nginx源码进行安装过程比较繁琐&#xff0c;需要提前下载安装GCC编译器、PCRE兼容正则表达式库、zlib压缩库和OpenSSL安全通信的软件库包&#xff0c;然后才能进行Nginx的安装。采用Yum最简单的安装方式能自动解决这些安装依赖&#xff0c;默认情况Centos7…

C++面试指南——类常用知识点概念总结

构造函数 构造函数可以抛出异常&#xff0c;可以重载&#xff0c;如果在实例化时在类名后面加个括号&#xff0c;只是创建了一个匿名的对象。构造不能是虚函数&#xff0c;因为此时虚函数表还没有初始化。new对象会调解构造函数。没有定义拷贝构造时&#xff0c;IDE会自动生成…

关于编译的重要概念总结

文章目录什么是GNU什么是GCC / Ggcc / g编译的四个阶段gcc和g的主要区别MinGW-w64C语言版本C 98C 11C 14C 17C 20Makefilecmake回想初学编程的时候&#xff0c;大部分人都是从C语言开始学起的&#xff0c;除了一些常见的语法和思想&#xff0c;一些基础知识常常被人们忽略&…

智能汽车进入3.0时代,双目立体视觉「打通」智驾与底盘

每一次软硬件技术更迭&#xff0c;都在重构智能化。 2016年7月&#xff0c;上汽集团与阿里巴巴合作开发的互联网汽车荣威RX5正式上市&#xff0c;这被视为中国乘用车市场首次规模化引入互联网生态&#xff0c;第一次在软件层面实现对传统燃油车的升级。几个月后&#xff0c;英特…

python机器学习数据建模与分析——数据预测与预测建模

文章目录前言一、预测建模1.1 预测建模涉及的方面&#xff1a;1.2 预测建模的几何理解1.3 预测模型参数估计的基本策略1.4 有监督学习算法与损失函数&#xff1a;1.5 参数解空间和搜索策略1.6 预测模型的评价1.6.1 模型误差的评价指标1.6.2 模型的图形化评价工具1.6.3 训练误差…

“绿菜单”2.0发布 数据中心液冷生态建设进入加速期

近年来&#xff0c;随着数字化社会对算力需求的不断增长&#xff0c;数据中心能耗与散热问题日益凸显。液冷作为更加高效、低能耗的制冷技术&#xff0c;逐渐成为了数据中心建设的热门选择。对此&#xff0c;产业上下游企业热情高涨&#xff0c;液冷产品与方案纷纷亮相&#xf…

【Java】数据类型与变量

一、java中的数据类型 Java中数据类型主要分为两类&#xff1a;基本数据类型和引用数据类型。 1.与c语言相同的数据类型 short,int,double,float均与c语言保持相同。 2.与c语言不同的数据类型 byte--字节类型 char--字符类型 java中&#xff0c;byte类型只占一个字节&#xff…

手写简易 Spring(二)

文章目录手写简易 Spring&#xff08;二&#xff09;1. 扩展 BeanFactory 接口2. 实现资源加载器&#xff0c;从 Spring.xml 解析和注册 Bean 对象1. 核心实现类 XmlBeanDefinitionReader3. 实现应用上下文&#xff0c;自动识别、资源加载、扩展机制1. 应用上下文2. 核心实现类…

虚幻图文笔记:Character Creator 4角色通过AutoSetup For Unreal Engine插件导入UE5.1的过程笔记

在UE5端安装AutoSetup For Unreal Engine插件 AutoSetup For Unreal Engine是Reallusion官方提供的免费插件&#xff0c;官方下载地址&#xff0c;下载到的是一个可执行文件&#xff0c;点击安装&#xff0c;记住安装的位置⬇ 看装完毕后会打开一个文件夹&#xff0c;这里就是对…

nginx线程池源码剖析

文章目录nginx线程池1. 问题2. 解决办法 nginx线程池3. 线程池实现模型4. 线程池实现核心组件5.源码实现测试代码main.c封装互斥锁&条件变量线程池实现nginx线程池 1. 问题 处理事件过程“阻塞”怎么办&#xff1f; 忙于漫长的 CPU 密集型处理 读取文件&#xff0c;但文…