3.Spring Cloud LoadBalancer 入门与使用

3.Spring Cloud LoadBalancer 入门与使用

  • 1.什么是 LoadBalancer?
    • 1.1负载均衡分类
    • 1.2 常见负载均衡策略
  • 2.为什么要学 LoadBalancer?
  • 3.如何使用?
  • 4.默认负载均衡策略
  • 5.随机负载均策略
    • 5.1 创建随机负载均衡器
    • 5.2 设置随机负载均衡器 (局部设置)
    • 5.3 设置全局负载均衡器
  • 6.Nacos 权重负载均器
    • 6.1 创建 Nacos 负载均衡器
    • 6.2 设置负载均衡器
  • 7.自定义负载均衡器
    • 7.1 创建自定义负载均衡器
    • 7.2 封装自定义负载均衡器
    • 7.3 设置自定义负载均器
  • 8.缓存
    • 关闭缓存
  • 9.执行原理
      • 底层执行原理
        • 1. `ServiceInstanceListSupplier`
        • 2. `LoadBalancerClient`
        • 3. `LoadBalancer`
      • 执行流程
      • 源码示例
      • 总结

1.什么是 LoadBalancer?

LoadBalancer(负载均衡器)是一种网络设备或软件机制,用于分发传入的网络流量负载(请求)到多个后端目标服务器上,从而实现系统资源的均衡利用和提高系统的可用性和性能。

1.1负载均衡分类

负载均衡分为服务器端负载均衡和客户端负载均衡。

  1. 服务器端负载均衡指的是存放在服务器端的负载均衡器,例如 Nginx、HAProxy、F5 等.
  2. 客户端负载均衡指的是嵌套在客户端的负载均衡器,例如 Ribbon、Spring Cloud LoadBalancer。

1.2 常见负载均衡策略

在这里插入图片描述
但无论是服务器端负载均衡和客户端负载均衡,它们的负载均衡策略都是相同的,因为负载均衡策略本质上是一种思想。
常见的负载均衡策略有以下几个:

  1. 轮询(Round Robin):轮询策略按照顺序将每个新的请求分发给后端服务器,依次循环。这是一种最简单的负载均衡策略,适用于后端服务器的性能相近,且每个请求的处理时间大致相同的情况。
  2. 随机选择(Random):随机选择策略随机选择一个后端服务器来处理每个新的请求。这种策略适用于后端服2务器性能相似,且每个请求的处理时间相近的情况,但不保证请求的分发是均的。
  3. 最少连接(Least Connections):最少连接策略将请求分发给当前连接数最少的后端服务器。这可以确保负载均衡在后端服务器的连接负载上均衡,但需要维护连接计数。
  4. IP 哈希(IP Hash):IP 哈希策略使用客户端的 IP 地址来计算哈希值,然后将请求发送到与哈希值对应的后端服务器。这种策略可用于确保来自同一客户端的请求都被发送到同一台后端服务器,适用于需要会话保持的情况。
  5. 加权轮询(Weighted Round Robin):加权轮询策略给每个后端服务器分配一个权重值,然后按照权重值比例来分发请求。这可以用来处理后端服务器性能不均衡的情况,将更多的请求分发给性能更高的服务器。
  6. 加权随机选择(Weighted Random):加权随机选择策略与加权轮询类似,但是按照权重值来随机选择后端服务器。这也可以用来处理后端服务器性能不均衡的情况,但是分发更随机。
  7. 最短响应时间(Least Response Time):最短响应时间策略会测量每个后端服务器的响应时间,并将请求发送到响应时间最短的服务器。这种策略可以确保客户端获得最快的响应,适用于要求低延迟的应用。

2.为什么要学 LoadBalancer?

作为早期版本中内置的负载均衡器 Ribbon,在 Spring Cloud 2020.0.0 中已经被移除了,更新日志详见,https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2020.0-Release-Notes取而代之的是 Spring Cloud LoadBalancer,并日它也是 Spring cloud 官方提供的负载均衛器,所以咱们的课程就要学习最新最主流的机制栈,而 Spring Cloud LoadBalancer 则是绕不过去的必学知识。

3.如何使用?

在项目中添加 Spring Cloud OpenFeign 和注册中心如 Nacos 之后,再添加 Spring Cloud LoadBalancer 则会在进行接口调用时直接使用 Spring Cloud LoadBalancer。

4.默认负载均衡策略

Spring Cloud LoadBalancer 负载均衡策略默认的是轮询,这一点可以通过 Spring Cloud LoadBalancer 的配置类LoadBalancerClientConfiguration 中发现,它的部分源码如下:

public class LoadBalancerClientConfiguration {

	private static final int REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER = 193827465;

	@Bean
	@ConditionalOnMissingBean
	public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,
			LoadBalancerClientFactory loadBalancerClientFactory) {
		String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
		return new RoundRobinLoadBalancer(
				loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
	}

继续查看 RoundRobinLoadBalancer 核心实现源码如下:

	private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
		if (instances.isEmpty()) {
			if (log.isWarnEnabled()) {
				log.warn("No servers available for service: " + serviceId);
			}
			return new EmptyResponse();
		}

		// Do not move position when there is only 1 instance, especially some suppliers
		// have already filtered instances
		if (instances.size() == 1) {
			return new DefaultResponse(instances.get(0));
		}

		// Ignore the sign bit, this allows pos to loop sequentially from 0 to
		// Integer.MAX_VALUE
		int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;

		ServiceInstance instance = instances.get(pos % instances.size());

		return new DefaultResponse(instance);
	}

在这里插入图片描述

5.随机负载均策略

Spring Cloud LoadBalancer 内置了两种负载均衡策略

  1. 轮询负载均衡策略,默认负载均衡策略。
  2. 随机负载均衡策略

而要实现随机负载均衡策略的步骤如下:

  1. 创建随机负载均衡策略。
  2. 设置随机负载均衡策略。
    在这里插入图片描述
    在这里插入图片描述

5.1 创建随机负载均衡器

public class RandomLoadBalancerConfig {
    @Bean
    public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(
            Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty("loadbalancer.client.name");
        return new RandomLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name,
                        ServiceInstanceListSupplier.class), name);
    }
}

5.2 设置随机负载均衡器 (局部设置)

package com.example.consumer.service;

import com.example.consumer.config.CustomLoadBalancerConfig;
import com.example.consumer.config.NacosLoadBalancerConfig;
import com.example.consumer.config.RandomLoadBalancerConfig;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Service
@FeignClient("loadbalancer-service")
// 设置局部负载均衡策略
@LoadBalancerClient(name = "loadbalancer-service",
        configuration = RandomLoadBalancerConfig.class)
public interface UserService {
    @RequestMapping("/user/getname")
    String getName(@RequestParam("id") Integer id);
}

5.3 设置全局负载均衡器

package com.example.consumer;

import com.example.consumer.config.CustomLoadBalancerConfig;
import com.example.consumer.config.RandomLoadBalancerConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients // 开启 Openfeign
// 设置全局的负载均衡策略
@LoadBalancerClients(defaultConfiguration =
        RandomLoadBalancerConfig.class)
public class ConsumerApplication {

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

}

6.Nacos 权重负载均器

Nacos 中支持两种负载均衡器,一种是权重负载均衡器,另一种是第三方 CMDB(地域就近访问)标签负载均後器,我们可以将 Spring Cloud Loadbalancer 直接配置为 Nacos 的负载均衡器,它默认就是权重负载均衡策略。它的配置有以下两步:

  1. 创建 Nacos 负载均衡器
  2. 设置负载均衡器
    在这里插入图片描述

6.1 创建 Nacos 负载均衡器

@LoadBalancerClients(defaultConfiguration = NacosLoadBalancerConfig.class)
public class NacosLoadBalancerConfig {
    @Resource
    private NacosDiscoveryProperties nacosDiscoveryProperties;
    @Bean
    public ReactorLoadBalancer<ServiceInstance> nacosLoadBalancer(
            Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty("loadbalancer.client.name");
        return new NacosLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name,
                        ServiceInstanceListSupplier.class), name
                ,nacosDiscoveryProperties);
    }
}

6.2 设置负载均衡器

@SpringBootApplication
@EnableFeignClients // 开启 Openfeign
// 设置全局的负载均衡策略
@LoadBalancerClients(defaultConfiguration =
        NacosLoadBalancerConfig.class)
public class ConsumerApplication {

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

}

7.自定义负载均衡器

实现自定义负载均衡策略需要以下 3步:

  1. 创建自定义负载均衡器
  2. 封装自定义负载均衡器
  3. 为服务设置自定义负载均衡器

7.1 创建自定义负载均衡器

package com.example.consumer.config;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.DefaultResponse;
import org.springframework.cloud.client.loadbalancer.EmptyResponse;
import org.springframework.cloud.client.loadbalancer.Request;
import org.springframework.cloud.client.loadbalancer.Response;
import org.springframework.cloud.loadbalancer.core.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import reactor.core.publisher.Mono;

import java.util.List;

public class CustomLoadBalancer implements ReactorServiceInstanceLoadBalancer {
    private static final Log log = LogFactory.getLog(RandomLoadBalancer.class);
    private final String serviceId;
    private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;

    public CustomLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId) {
        this.serviceId = serviceId;
        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
    }

    public Mono<Response<ServiceInstance>> choose(Request request) {
        ServiceInstanceListSupplier supplier = (ServiceInstanceListSupplier)this.serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);
        return supplier.get(request).next().map((serviceInstances) -> {
            return this.processInstanceResponse(supplier, serviceInstances);
        });
    }

    private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier, List<ServiceInstance> serviceInstances) {
        Response<ServiceInstance> serviceInstanceResponse = this.getInstanceResponse(serviceInstances);
        if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {
            ((SelectedInstanceCallback)supplier).selectedServiceInstance((ServiceInstance)serviceInstanceResponse.getServer());
        }

        return serviceInstanceResponse;
    }

    private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
        if (instances.isEmpty()) {
            if (log.isWarnEnabled()) {
                log.warn("No servers available for service: " + this.serviceId);
            }

            return new EmptyResponse();
        } else {
            // 核心:自定义随机策略
            // 获取 Request 对象
            ServletRequestAttributes attributes = (ServletRequestAttributes)
                    RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            String ipAddress = request.getRemoteAddr();
            System.out.println("用户 IP:" + ipAddress);
            int hash = ipAddress.hashCode();
            // 自定义负载均衡策略【这行代码是关键】
            int index = hash % instances.size();
            // 得到服务实例方法
            ServiceInstance instance = (ServiceInstance) instances.get(index);
            return new DefaultResponse(instance);
        }
    }
}

7.2 封装自定义负载均衡器

public class CustomLoadBalancerConfig {
    @Bean
    public ReactorLoadBalancer<ServiceInstance> customLoadBalancer(
            Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty("loadbalancer.client.name");
        return new CustomLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name,
                        ServiceInstanceListSupplier.class), name);
    }
}

7.3 设置自定义负载均器

@SpringBootApplication
@EnableFeignClients // 开启 Openfeign
// 设置全局的负载均衡策略
@LoadBalancerClients(defaultConfiguration =
        CustomLoadBalancerConfig.class)
public class ConsumerApplication {

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

}

8.缓存

Spring Cloud LoadBalancer 在获取实例时有两种选择:

  1. 即时获取:每次从注册中心得到最新健康的实例,效果好、开销太大。
  2. 缓存服务列表:每次得到服务列表之后,缓存一段时间,这样既能保证性能,同时也能兼容一定的及时性。而 Spring Cloud LoadBalancer 中默认开启了缓存服务列表的功能。Spring

Cloud LoadBalancer 默认缓存的重要特性有两项:

  1. 缓存的过期时间为 35s。
  2. 缓存保存个数为 256 个
    我们可以通过以下配置来改变这些配置:

关闭缓存

    loadbalancer:
      cache:
        enabled: true # 关闭 loadbalancer 缓存
        ttl: 10 # 缓存存活时间
        capacity: 1000 # 缓存存储容量

9.执行原理

OpenFeign 底层是通过 HTTP 客户端对象 RestTemplate 实现接口请求的,而负载均衡器的作用只是在请求客户端发送请求之前,得到一个服务的地址给到 RestTemplate 对象,而 Spring Cloud LoadBalancer 的整体类图如下:
在这里插入图片描述

通过查看 Spring Cloud LoadBalancer 源码我们可以发现,@LoadBalanced 注解出 spring-cloud-commons 实现查看实现逻辑我们发现, spring-cloud-commons 存在自动配置类 LoadBalancerAutoConfiquration,当满足条件时将自动创建 LoadBalancerInterceptor 并注入到 RestTemplate 中,部分源码如下:

Spring Cloud LoadBalancer 是 Spring Cloud 提供的一种客户端负载均衡解决方案,用于替代 Netflix Ribbon。它通过将负载均衡逻辑从服务端移到客户端,使得每个客户端实例都可以独立地选择要调用的服务实例,从而实现更灵活和高效的负载均衡。

底层执行原理

Spring Cloud LoadBalancer 的核心组件包括 ServiceInstanceListSupplierLoadBalancerClientLoadBalancer。下面结合源码来详细说明其执行原理。

1. ServiceInstanceListSupplier

ServiceInstanceListSupplier 是一个接口,用于提供服务实例列表。它的实现类负责从服务注册中心(如 Eureka、Consul 等)获取可用的服务实例列表。

public interface ServiceInstanceListSupplier {
    Flux<List<ServiceInstance>> get();
}

Flux 是 Reactor 库中的一个类,表示一个异步序列。ServiceInstanceListSupplierget 方法返回一个 Flux,它会异步地提供服务实例列表。

2. LoadBalancerClient

LoadBalancerClient 是一个接口,定义了负载均衡客户端的基本操作。它的主要方法是 choose,用于选择一个服务实例。

public interface LoadBalancerClient {
    <T> ServiceInstance choose(String serviceId, Request<T> request);
}

choose 方法接受服务 ID 和请求信息,返回一个 ServiceInstance 对象,表示选择的服务实例。

3. LoadBalancer

LoadBalancer 是负载均衡的核心接口,定义了负载均衡的策略。它的主要方法是 choose,用于根据负载均衡策略选择一个服务实例。

public interface LoadBalancer<T> {
    Mono<Response<T>> choose(Request request);
}

choose 方法返回一个 Mono<Response<T>>,其中 Mono 是 Reactor 库中的另一个类,表示一个异步的单值序列。

执行流程

  1. 获取服务实例列表

    • ServiceInstanceListSupplier 从服务注册中心获取可用的服务实例列表,并返回一个 Flux<List<ServiceInstance>>
  2. 选择服务实例

    • LoadBalancer 使用负载均衡策略(如轮询、随机等)从服务实例列表中选择一个服务实例。
    • LoadBalancerClient 调用 LoadBalancerchoose 方法,获取选择的服务实例。
  3. 执行请求

    • LoadBalancerClient 使用选择的服务实例执行请求,并返回结果。

源码示例

以下是一个简单的 ServiceInstanceListSupplier 实现示例:

public class SimpleServiceInstanceListSupplier implements ServiceInstanceListSupplier {

    private final List<ServiceInstance> instances;

    public SimpleServiceInstanceListSupplier(List<ServiceInstance> instances) {
        this.instances = instances;
    }

    @Override
    public Flux<List<ServiceInstance>> get() {
        return Flux.just(instances);
    }
}

以下是一个简单的 LoadBalancer 实现示例:

public class RoundRobinLoadBalancer implements LoadBalancer<ServiceInstance> {

    private final AtomicInteger position;
    private final ServiceInstanceListSupplier supplier;

    public RoundRobinLoadBalancer(ServiceInstanceListSupplier supplier) {
        this.supplier = supplier;
        this.position = new AtomicInteger(0);
    }

    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
        return supplier.get().next().map(instances -> {
            if (instances.isEmpty()) {
                return new EmptyResponse();
            }
            int pos = Math.abs(this.position.incrementAndGet());
            ServiceInstance instance = instances.get(pos % instances.size());
            return new DefaultResponse(instance);
        });
    }
}

总结

Spring Cloud LoadBalancer 通过 ServiceInstanceListSupplier 获取服务实例列表,通过 LoadBalancer 选择服务实例,并通过 LoadBalancerClient 执行请求。其核心思想是将负载均衡逻辑从服务端移到客户端,使得每个客户端实例都可以独立地选择要调用的服务实例,从而实现更灵活和高效的负载均衡。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Codeforces Round 946 (Div. 3) A~G

A.Phone Desktop (枚举) 题意&#xff1a; 小 A A A的手机有一个桌面&#xff08;或称启动器&#xff09;。桌面可以由多个屏幕组成。每个屏幕表示为大小为 5 3 5 \times 3 53 的网格&#xff0c;即五行三列。 有 x x x 个应用程序的图标大小为 1 1 1 \times 1 11 个单…

C51单片机开发--库函数

知不足而奋进 望远山而前行 目录 系列文章目录 文章目录 前言 目标 内容 开发过程回顾 使用库函数点灯 什么是库函数? 面向库函数和面向寄存器开发 使用delay模块延时 总结 前言 在嵌入式系统开发中&#xff0c;使用库函数是提高开发效率、简化编程的重要手段之一…

学习Uni-app开发小程序Day21

学习了评分组件、自定义导航栏 评分组件uni-rate 这是需要达到的效果图&#xff0c;这里先分析下效果图&#xff0c; 1、图片是从布局中间弹出的&#xff0c;那这里就要用到uni-popup &#xff0c;设置type从中间弹出 2、这个弹出的顶部和上一张的顶部布局是一样的&#xff0c…

Axios的使用简单说明

axios 请求方式和参数 axios 可以发送 ajax 请求&#xff0c;不同的方法可以发送不同的请求: axios.get&#xff1a;发送get请求 axios.post&#xff1a;发送post请求 axios.put&#xff1a;发送put请求 axios.delete&#xff1a;发送delete请求 无论哪种方法&#xff0c;第一…

怎么使用Stable diffusion中的models

Stable diffusion中的models Stable diffusion model也可以叫做checkpoint model&#xff0c;是预先训练好的Stable diffusion权重&#xff0c;用于生成特定风格的图像。模型生成的图像类型取决于训练图像。 如果训练数据中从未出现过猫的图像&#xff0c;模型就无法生成猫的…

应急响应-网页篡改-典型处置案例

内部系统主页被篡改 事件背景 2019年11月13日&#xff0c;某单位发现其内部系统的主页被篡改&#xff0c;应急响应工程师到达现场后对被入侵服务器进行检查&#xff0c;发现对方采用某开源CMS和第三方phpstudy进行环境部署。由于phpstudy默认不开启Web日志记录&#xff0c;因…

【Pandas】深入解析`pd.read_json()`函数

【Pandas】深入解析pd.read_json()函数 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我深耕Python编程、机器学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;并乐于分享知识与经验的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#x…

SQL面试题练习 —— 计算次日留存率

题目 现有用户登录记录表&#xff0c;已经按照用户日期进行去重处理。以用户登录的最早日期作为新增日期&#xff0c;请计算次日留存率是多少。 样例数据 ----------------------- | user_id | login_date | ----------------------- | aaa | 2023-12-01 | | bbb …

负载箱:充电桩测试利器

随着新能源汽车的普及&#xff0c;充电桩的需求也在不断增长。为了保证充电桩的安全、稳定和高效运行&#xff0c;对其进行严格的测试是必不可少的。在这个过程中&#xff0c;负载箱就成为了充电桩测试的重要工具。 负载箱模拟电动汽车充电的设备&#xff0c;它可以模拟真实的充…

轻兔推荐 —— 一个好用的软件服务推荐平台

给大家推荐一个好用的的软件服务推荐平台&#xff1a;轻兔推荐 网站界面简洁大方&#xff0c;没有太多杂七杂八的功能和页面&#xff0c;有明暗主题色可以选择&#xff0c;默认为亮色&#xff0c;可在网站上方手动切换。 每工作日都会推荐一款软件&#xff0c;有时会加更&…

高铁Wifi是如何接入的?

使用PC端的朋友&#xff0c;请将页面缩小到最小比例&#xff0c;阅读最佳&#xff01; 在飞驰的高铁上&#xff0c;除了窗外一闪而过的风景&#xff0c;你是否好奇过&#xff0c;高铁Wifi信号如何连接的呢&#xff1f; 远动的火车可不能连接光纤吧&#xff0c;难道是连接的卫星…

深入理解python列表遍历:两种方法详解与实例

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、使用索引遍历列表 三、直接使用元素遍历列表 四、总结 一、引言 在编程过程…

python-数据可视化(总)

python-数据可视化 ** 数据可视化 指的是通过可视化表示来探索数据&#xff0c;它与数据挖掘**紧密相关&#xff0c;而数据挖掘指的是使用代码来探索数据集的规律和关联。数据集可以是用一行代码就能表示的小型数字列表&#xff0c;也可以是数以吉字节的数据 最流行的工具之一…

智慧冶金:TSINGSEE青犀AI+视频技术助力打造高效、安全的生产环境

一、建设背景 冶金行业因其特殊的生产环境和工艺要求&#xff0c;对安全生产、环境保护以及质量监控等方面有着极高的要求。因此&#xff0c;将视频智能监控技术引入冶金行业&#xff0c;不仅有助于提升生产效率&#xff0c;更能有效保障生产安全&#xff0c;降低事故风险。 …

[ARM-2D 专题] arm-2d项目简介

Arm-2D 是一个用于 Cortex-M 处理器上的 2.5D 图像处理的开源项目。 由ARM公司开发和维护&#xff0c;属于官方性质的项目&#xff0c;目前最新版本为V1.1.6. 2022年7月发布1.0的预览版&#xff0c; 2023年2月发布第一个正式版V1.1.1&#xff0c;近一年来快速迭代和功能增强&a…

基于序列深度学习模型的向量海岸线形状分类方法 2024.05

本文中提出了一个数据驱动的方法来分类的形状矢量海岸线&#xff0c;该方法利用基于序列的深度学习算法对海岸线矢量分段进行建模和分类。具体而言&#xff0c;首先将复杂的海岸线划分为一系列弯曲&#xff0c;并进一步提出了一组不同的特征来描述每个弯曲的形态特征。然后&…

基于Spring 框架中的@Async 注解实现异步任务

Async 是 Spring 框架中的一个注解&#xff0c;用于实现方法级别的异步执行。使用 Async 可以让你的代码在非当前线程中执行&#xff0c;从而提高应用的并发性能。 1、 启用异步支持 在 Spring 应用的主配置类或任何其他配置类上添加 EnableAsync 注解来开启异步任务的支持 …

WordPress中借助Table of Contents Plus+Widget Options插件,实现仅在文章侧边栏显示文章目录的功能

本文转自博主的个人博客&#xff1a;https://blog.zhumengmeng.work,欢迎大家前往查看。 原文链接&#xff1a;点我访问 序言&#xff1a;今天心血来潮&#xff0c;写了一篇文章&#xff0c;忽然发现自己的文章极少有目录&#xff0c;这对于长文章的阅读来说是十分不利的&#…

Android14 WMS-窗口添加流程(一)-Client端

窗口布局在onCreate方法中通过setContentView(R.layout.xxx)加载&#xff0c;但窗口的显示并不是在wm_on_create_called中, 而是在wm_on_resume_called后&#xff0c;也就是说应用onResume时此窗口是不可见的&#xff0c;真正可见是当此window窗口的mDrawState变化状态从NO_SUR…

2024年社会发展、人文艺术与文化国际会议(ICSDHAC 2024)

2024年社会发展、人文艺术与文化国际会议&#xff08;ICSDHAC 2024&#xff09; 会议简介 2024年国际社会发展、人文、艺术和文化会议&#xff08;ICSDHAC 2024&#xff09;将在广州举行。会议旨在为从事社会发展、人文、艺术和文化研究的专家学者提供一个平台&#xff0c;分…