当前位置: 首页 > news >正文

SpringBoot 整合 Avro 与 Kafka

优质博文:IT-BLOG-CN

【需求】:生产者发送数据至 kafka 序列化使用 Avro,消费者通过 Avro 进行反序列化,并将数据通过 MyBatisPlus 存入数据库。

一、环境介绍

【1】Apache Avro 1.8;【2】Spring Kafka 1.2;【3】Spring Boot 1.5;【4】Maven 3.5;

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.codenotfound</groupId><artifactId>spring-kafka-avro</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-kafka-avro</name><description>Spring Kafka - Apache Avro Serializer Deserializer Example</description><url>https://www.codenotfound.com/spring-kafka-apache-avro-serializer-deserializer-example.html</url><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.4.RELEASE</version></parent><properties><java.version>1.8</java.version><spring-kafka.version>1.2.2.RELEASE</spring-kafka.version><avro.version>1.8.2</avro.version></properties><dependencies><!-- spring-boot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- spring-kafka --><dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId><version>${spring-kafka.version}</version></dependency><dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka-test</artifactId><version>${spring-kafka.version}</version><scope>test</scope></dependency><!-- avro --><dependency><groupId>org.apache.avro</groupId><artifactId>avro</artifactId><version>${avro.version}</version></dependency></dependencies><build><plugins><!-- spring-boot-maven-plugin --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><!-- avro-maven-plugin --><plugin><groupId>org.apache.avro</groupId><artifactId>avro-maven-plugin</artifactId><version>${avro.version}</version><executions><execution><phase>generate-sources</phase><goals><goal>schema</goal></goals><configuration><sourceDirectory>${project.basedir}/src/main/resources/avro/</sourceDirectory><outputDirectory>${project.build.directory}/generated/avro</outputDirectory></configuration></execution></executions></plugin></plugins></build>
</project>

二、Avro 文件

【1】Avro 依赖于由使用JSON定义的原始类型组成的架构。对于此示例,我们将使用Apache Avro入门指南中的“用户”模式,如下所示。该模式存储在src / main / resources / avro下的 user.avsc文件中。我这里使用的是 electronicsPackage.avsc。namespace 指定你生成 java 类时指定的 package 路径,name 表时生成的文件。

{"namespace": "com.yd.cyber.protocol.avro","type": "record","name": "ElectronicsPackage","fields": [{"name":"package_number","type":["string","null"],"default": null},{"name":"frs_site_code","type":["string","null"],"default": null},{"name":"frs_site_code_type","type":["string","null"],"default":null},{"name":"end_allocate_code","type":["string","null"],"default": null},{"name":"code_1","type":["string","null"],"default": null},{"name":"aggregat_package_code","type":["string","null"],"default": null}]
}

【2】Avro附带了代码生成功能,该代码生成功能使我们可以根据上面定义的“用户”模式自动创建Java类。一旦生成了相关的类,就无需直接在程序中使用架构。这些类可以使用 avro-tools.jar 或项目是Maven 项目,调用 Maven Projects 进行 compile 自动生成 electronicsPackage.java 文件:如下是通过 maven 的方式

【3】这将导致生成一个 electronicsPackage.java 类,该类包含架构和许多 Builder构造 electronicsPackage对象的方法。

三、为 Kafka 主题生成 Avro消息

Kafka Byte 在其主题中存储和传输数组。但是,当我们使用 Avro对象时,我们需要在这些 Byte数组之间进行转换。在0.9.0.0版之前,Kafka Java API使用 Encoder/ Decoder接口的实现来处理转换,但是在新API中,这些已经被 Serializer/ Deserializer接口实现代替。Kafka附带了许多 内置(反)序列化器,但不包括Avro。为了解决这个问题,我们将创建一个 AvroSerializer类,该类Serializer专门为 Avro对象实现接口。然后,我们实现将 serialize() 主题名称和数据对象作为输入的方法,在本例中,该对象是扩展的 Avro对象 SpecificRecordBase。该方法将Avro对象序列化为字节数组并返回结果。这个类属于通用类,一次配置多次使用。

package com.yd.cyber.web.avro;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;import org.apache.avro.io.BinaryEncoder;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.specific.SpecificDatumWriter;
import org.apache.avro.specific.SpecificRecordBase;
import org.apache.kafka.common.errors.SerializationException;
import org.apache.kafka.common.serialization.Serializer;/***  avro序列化类* @author zzx* @creat 2020-03-11-19:17*/
public class AvroSerializer<T extends SpecificRecordBase> implements Serializer<T> {@Overridepublic void close() {}@Overridepublic void configure(Map<String, ?> arg0, boolean arg1) {}@Overridepublic byte[] serialize(String topic, T data) {if(data == null) {return null;}DatumWriter<T> writer = new SpecificDatumWriter<>(data.getSchema());ByteArrayOutputStream byteArrayOutputStream  = new ByteArrayOutputStream();BinaryEncoder binaryEncoder  = EncoderFactory.get().directBinaryEncoder(byteArrayOutputStream , null);try {writer.write(data, binaryEncoder);binaryEncoder.flush();byteArrayOutputStream.close();}catch (IOException e) {throw new SerializationException(e.getMessage());}return byteArrayOutputStream.toByteArray();}
}

四、AvroConfig 配置类

Avro 配置信息在 AvroConfig 配置类中,现在,我们需要更改,AvroConfig 开始使用我们的自定义 Serializer实现。这是通过将“ VALUE_SERIALIZER_CLASS_CONFIG”属性设置为 AvroSerializer该类来完成的。此外,我们更改了ProducerFactory 和KafkaTemplate 通用类型,使其指定 ElectronicsPackage 而不是 String。当我们有多个序列化的时候,这个配置文件需要多次需求,添加自己需要序列化的对象。

package com.yd.cyber.web.avro;/*** @author zzx* @creat 2020-03-11-20:23*/
@Configuration
@EnableKafka
public class AvroConfig {@Value("${spring.kafka.bootstrap-servers}")private String bootstrapServers;@Value("${spring.kafka.producer.max-request-size}")private String maxRequestSize;@Beanpublic Map<String, Object> avroProducerConfigs() {Map<String, Object> props = new HashMap<>();props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);props.put(ProducerConfig.MAX_REQUEST_SIZE_CONFIG, maxRequestSize);props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, AvroSerializer.class);return props;}@Beanpublic ProducerFactory<String, ElectronicsPackage> elProducerFactory() {return new DefaultKafkaProducerFactory<>(avroProducerConfigs());}@Beanpublic KafkaTemplate<String, ElectronicsPackage> elKafkaTemplate() {return new KafkaTemplate<>(elProducerFactory());}
}

五、通过 kafkaTemplate 发送消息

最后就是通过 Controller类调用 kafkaTemplate 的 send 方法接受一个Avro electronicsPackage对象作为输入。请注意,我们还更新了 kafkaTemplate 泛型类型。

package com.yd.cyber.web.controller.aggregation;import com.yd.cyber.protocol.avro.ElectronicsPackage;
import com.yd.cyber.web.vo.ElectronicsPackageVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;/*** <p>* InnoDB free: 4096 kB 前端控制器* </p>** @author zzx* @since 2020-04-19*/
@RestController
@RequestMapping("/electronicsPackageTbl")
public class ElectronicsPackageController {//日誌private static final Logger log = LoggerFactory.getLogger(ElectronicsPackageController.class);@Resourceprivate KafkaTemplate<String,ElectronicsPackage> kafkaTemplate;@GetMapping("/push")public void push(){ElectronicsPackageVO electronicsPackageVO = new ElectronicsPackageVO();electronicsPackageVO.setElectId(9);electronicsPackageVO.setAggregatPackageCode("9");electronicsPackageVO.setCode1("9");electronicsPackageVO.setEndAllocateCode("9");electronicsPackageVO.setFrsSiteCodeType("9");electronicsPackageVO.setFrsSiteCode("9");electronicsPackageVO.setPackageNumber("9");ElectronicsPackage electronicsPackage = new ElectronicsPackage();BeanUtils.copyProperties(electronicsPackageVO,electronicsPackage);//发送消息kafkaTemplate.send("Electronics_Package",electronicsPackage);log.info("Electronics_Package TOPIC 发送成功");}
}

六、从 Kafka主题消费 Avro消息反序列化

收到的消息需要反序列化为 Avro格式。为此,我们创建一个 AvroDeserializer 实现该 Deserializer接口的类。该 deserialize()方法将主题名称和Byte数组作为输入,然后将其解码回Avro对象。从 targetType类参数中检索需要用于解码的模式,该类参数需要作为参数传递给 AvroDeserializer构造函数。

package com.yd.cyber.web.avro;import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.BinaryDecoder;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificRecordBase;
import org.apache.kafka.common.errors.SerializationException;
import org.apache.kafka.common.serialization.Deserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.xml.bind.DatatypeConverter;/***  avro反序列化* @author fuyx* @creat 2020-03-12-15:19*/
public class AvroDeserializer<T extends SpecificRecordBase> implements Deserializer<T> {//日志系统private static final Logger LOGGER = LoggerFactory.getLogger(AvroDeserializer.class);protected final Class<T> targetType;public AvroDeserializer(Class<T> targetType) {this.targetType = targetType;}@Overridepublic void close() {}@Overridepublic void configure(Map<String, ?> arg0, boolean arg1) {}@Overridepublic T deserialize(String topic, byte[] data) {try {T result = null;if(data == null) {return null;}LOGGER.debug("data='{}'", DatatypeConverter.printHexBinary(data));ByteArrayInputStream in = new ByteArrayInputStream(data);DatumReader<GenericRecord> userDatumReader = new SpecificDatumReader<>(targetType.newInstance().getSchema());BinaryDecoder decoder = DecoderFactory.get().directBinaryDecoder(in, null);result = (T) userDatumReader.read(null, decoder);LOGGER.debug("deserialized data='{}'", result);return result;} catch (Exception ex) {throw new SerializationException("Can't deserialize data '" + Arrays.toString(data) + "' from topic '" + topic + "'", ex);} finally {}}
}

七、反序列化的配置类

我将反序列化的配置和序列化的配置都放置在 AvroConfig 配置类中。在 AvroConfig 需要被这样更新了AvroDeserializer用作值“VALUE_DESERIALIZER_CLASS_CONFIG”属性。我们还更改了 ConsumerFactory 和 ConcurrentKafkaListenerContainerFactory通用类型,以使其指定 ElectronicsPackage 而不是 String。将 DefaultKafkaConsumerFactory 通过1个新的创造 AvroDeserializer 是需要 “User.class”作为构造函数的参数。需要使用Class<?> targetType,AvroDeserializer 以将消费 byte[]对象反序列化为适当的目标对象(在此示例中为 ElectronicsPackage 类)。

@Configuration
@EnableKafka
public class AvroConfig {@Value("${spring.kafka.bootstrap-servers}")private String bootstrapServers;@Value("${spring.kafka.producer.max-request-size}")private String maxRequestSize;@Beanpublic Map<String, Object> consumerConfigs() {Map<String, Object> props = new HashMap<>();props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, AvroDeserializer.class);props.put(ConsumerConfig.GROUP_ID_CONFIG, "avro");return props;}@Beanpublic ConsumerFactory<String, ElectronicsPackage> consumerFactory() {return new DefaultKafkaConsumerFactory<>(consumerConfigs(), new StringDeserializer(),new AvroDeserializer<>(ElectronicsPackage.class));}@Beanpublic ConcurrentKafkaListenerContainerFactory<String, ElectronicsPackage> kafkaListenerContainerFactory() {ConcurrentKafkaListenerContainerFactory<String, ElectronicsPackage> factory =new ConcurrentKafkaListenerContainerFactory<>();factory.setConsumerFactory(consumerFactory());return factory;}}

八、消费者消费消息

消费者通过 @KafkaListener 监听对应的 Topic ,这里需要注意的是,网上直接获取对象的参数传的是对象,比如这里可能需要传入 ElectronicsPackage 类,但是我这样写的时候,error日志总说是返回序列化的问题,所以我使用 GenericRecord 对象接收,也就是我反序列化中定义的对象,是没有问题的。然后我将接收到的消息通过 mybatisplus 存入到数据库。

package com.zzx.cyber.web.controller.dataSource.intercompany;import com.zzx.cyber.web.service.ElectronicsPackageService;
import com.zzx.cyber.web.vo.ElectronicsPackageVO;
import org.apache.avro.generic.GenericRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Controller;import javax.annotation.Resource;/*** @desc:* @author: zzx* @creatdate 2020/4/1912:21*/
@Controller
public class ElectronicsPackageConsumerController {//日志private static final Logger log  = LoggerFactory.getLogger(ElectronicsPackageConsumerController.class);//服务层@Resourceprivate ElectronicsPackageService electronicsPackageService;/*** 扫描数据测试* @param genericRecordne*/@KafkaListener(topics = {"Electronics_Package"})public void receive(GenericRecord genericRecordne) throws Exception {log.info("数据接收:electronicsPackage + "+  genericRecordne.toString());//业务处理类,mybatispuls 自动生成的类ElectronicsPackageVO electronicsPackageVO = new ElectronicsPackageVO();//将收的数据复制过来BeanUtils.copyProperties(genericRecordne,electronicsPackageVO);try {//落库log.info("数据入库");electronicsPackageService.save(electronicsPackageVO);} catch (Exception e) {throw new Exception("插入异常"+e);}}
}

相关文章:

SpringBoot 整合 Avro 与 Kafka

优质博文&#xff1a;IT-BLOG-CN 【需求】&#xff1a;生产者发送数据至 kafka 序列化使用 Avro&#xff0c;消费者通过 Avro 进行反序列化&#xff0c;并将数据通过 MyBatisPlus 存入数据库。 一、环境介绍 【1】Apache Avro 1.8&#xff1b;【2】Spring Kafka 1.2&#xf…...

支持JT1078和GB28181的流媒体服务器-LKM启动配置文件参数说明

流媒体服务器地址&#xff1a;https://github.com/lkmio/lkm GB28181信令&#xff0c;模拟多个国标设备工具&#xff1a;https://github.com/lkmio/gb-cms 文章目录 gop_cachegop_buffer_sizeprobe_timeoutwrite_timeoutmw_latencylisten_ippublic_ipidle_timeoutreceive_timeo…...

什么是隐式类型转换?隐式类型转换可能带来哪些问题? 显式类型转换(如强制类型转换)有哪些风险?

C 中的隐式类型转换 定义&#xff1a;在 C 中&#xff0c;隐式类型转换是指由编译器自动执行的类型转换&#xff0c;不需要程序员显式地进行操作。这种转换在很多情况下会自动发生&#xff0c;比如在表达式求值、函数调用传参等过程中。常见场景 算术运算中的转换&#xff1a;…...

量化交易新利器:阿布量化(AbuQuant)——金融研究者的得力助手

&#x1f680; 量化交易新利器&#xff1a;阿布量化&#xff08;AbuQuant&#xff09;——金融研究者的得力助手 &#x1f680; 文章目录 &#x1f680; 量化交易新利器&#xff1a;阿布量化&#xff08;AbuQuant&#xff09;——金融研究者的得力助手 &#x1f680;&#x1f3…...

UI设计从入门到进阶,全能实战课

课程内容&#xff1a; ├── 【宣导片】从入门到进阶!你的第一门UI必修课!.mp4 ├── 第0课&#xff1a;UI知识体系梳理 学习路径.mp4 ├── 第1课&#xff1a;IOS设计规范——基础规范与切图.mp4 ├── 第2课&#xff1a;IOS新趋势解析——模块规范与设计原则(上).mp4…...

Uniapp自动调整元素高度

获取设备的像素 如果你想让元素的高度相对于整个屏幕的高度占用一定的比例&#xff0c;可以通过获取屏幕的高度&#xff0c;然后计算出你想要的比例来设置元素的高度。以下是如何实现的示例&#xff1a; <script setup> import { ref, onMounted } from vue;// 定义一个…...

软考高项经验分享:我的备考之路与实战心得

软考&#xff0c;尤其是信息系统项目管理师&#xff08;高项&#xff09;考试&#xff0c;对于众多追求职业提升与专业认可的人士来说&#xff0c;是一场充满挑战与机遇的征程。我在当年参加软考高项的经历&#xff0c;可谓是一波三折&#xff0c;其中既有成功的喜悦&#xff0…...

安全关系型数据库查询新选择:Rust 语言的 rust-query 库深度解析

在当今这个数据驱动的时代&#xff0c;数据库作为信息存储和检索的核心组件&#xff0c;其重要性不言而喻。然而&#xff0c;对于开发者而言&#xff0c;如何在保证数据安全的前提下&#xff0c;高效地进行数据库操作却是一项挑战。传统的 SQL 查询虽然强大&#xff0c;但存在诸…...

《C++ 模型训练之早停法:有效预防过拟合的关键策略》

在 C 模型开发的复杂世界里&#xff0c;过拟合犹如一个潜藏的陷阱&#xff0c;常常使我们精心构建的模型在实际应用中表现大打折扣。而早停法&#xff08;Early Stopping&#xff09;作为一种行之有效的策略&#xff0c;能够帮助我们及时察觉模型训练过程中的异常&#xff0c;避…...

5.11【数据库】第一次实验

民宿预定&#xff0c;至少有不同的民宿&#xff0c;民宿下面有不同的房间&#xff08;面积&#xff0c;房间编号&#xff09; 房间类型&#xff0c;单价&#xff0c; 可预订以及不可预订 游客信息 订单信息 公司有很多课程&#xff0c; 学生&#xff0c;课程 每位学生每期…...

【CSS in Depth 2 精译_062】第 10 章 CSS 中的容器查询(@container)概述 + 10.1 容器查询的一个简单示例

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 【第十章 CSS 容器查询】 ✔️ 10.1 容器查询的一个简单示例 ✔️ 10.1.1 容器尺寸查询的用法 ✔️ 10.2 深入理解容器10.3 与容器相关的单位10.4 容器样式查询的用法10.5 本章小结 文章目录 第 10…...

蓝桥杯每日真题 - 第23天

题目&#xff1a;&#xff08;直线&#xff09; 题目描述&#xff08;12届 C&C B组C题&#xff09; 解题思路&#xff1a; 题目理解: 在平面直角坐标系中&#xff0c;从给定的点集中确定唯一的直线。 两点确定一条直线&#xff0c;判断两条直线是否相同&#xff0c;可通过…...

# Vue 入门级教程三

在前两篇 Vue 入门教程中&#xff0c;我们已经熟悉了 Vue 的基础语法、数据绑定、指令以及组件化开发等核心概念。在本教程中&#xff0c;我们将进一步探索 Vue 的高级特性&#xff0c;包括过滤器、自定义指令、过渡效果以及 Vue 与后端数据交互等内容&#xff0c;让你能够构建…...

hint: Updates were rejected because the tip of your current branch is behind!

问题 本地仓库往远段仓库推代码时候提示&#xff1a; error: failed to push some refs to 192.168.2.1:java-base/java-cloud.git hint: Updates were rejected because the tip of your current branch is behind! refs/heads/master:refs/heads/master [rejected] (…...

PHP 方头像转为圆图

业务需要把创建海报上的用户头像由方形转为圆形&#xff0c;前端的样式设置不能用。 故采用GD的函数来对方图进行裁剪处理为圆图。 目录 裁剪函数 本地图片 远程图片 效果 参考文章 总结 裁剪函数 从网上找的一个裁剪图片的函数。 代码如下&#xff1a; /* * 将图片切…...

centos 7 离线安装postgis插件

前一段时间记录了下如何在centos7中离线安装postgresql&#xff0c;因为工作需要&#xff0c;我不仅要安装postgresql&#xff0c;还需要安装postgis插件&#xff0c;这篇文章记录下postgis插件的安装过程。 1. 安装前的参考 如下的链接都是官网上的链接&#xff0c;对你安装p…...

pyinstaller打包的时候将ffmpeg也加进包中(包括打包文件夹的方法)

在使用 PyInstaller 打包包含 pydub 的 Python 应用程序时&#xff0c;由于 pydub 需要依赖 ffmpeg&#xff0c;你需要确保 ffmpeg 被正确包含进打包后的程序。以下是操作步骤&#xff1a; 1. 准备 ffmpeg 首先&#xff0c;确保你已经下载并安装了 ffmpeg。可以通过以下方式获取…...

JVM面试知识点1

内存结构&#xff08;掌握内存结构划分、熟知各区域结构功能&#xff09; 经典的JVM内存结构&#xff1a; 按照线程是否共享来划分&#xff1a; Heap (堆区&#xff09; 1. 堆区的介绍 堆是 OOM 故障最主要的发生区域。它是内存区域中最大的一块区域&#xff0c;被所有线程共…...

wordpress

2024年自己建网站的步骤&#xff0c;新手自学建站教程 – 奶爸建站笔记 超详细图解&#xff1a;从 0 搭建一个个人网站&#xff0c;也太简单了吧 - 王一白 - 博客园 如何使用插件或者自定义页面创建一个WordPress着陆页 - 闪电博...

Day33 动态规划part02

62.不同路径 本题大家掌握动态规划的方法就可以。 数论方法 有点非主流,很难想到。 代码随想录 视频讲解:动态规划中如何初始化很重要!| LeetCode:62.不同路径_哔哩哔哩_bilibili class Solution {public int uniquePaths(int m, int n) {int dp[][] = new int[m][n];//初…...

渗透测试之Web基础之Linux病毒编写——泷羽sec

声明&#xff1a; 学习视频来自B站UP主泷羽sec,如涉及侵权马上删除文章。本文只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 泷羽sec的个人空间-泷羽sec个人主页-哔哩哔哩视频 (bilibili.com)https://space.bilibili.com/350329294 导读&#xff1a; 时刻…...

jmeter基础07_组件的层级

课程大纲 1. 优先级/执行顺序&#xff08;一般情况&#xff09; 同级组件&#xff1a;按组件先后顺序执行。如&#xff1a;同一层的线程组、同一层的http请求。 上下级组件&#xff1a;先执行外层&#xff08;上级&#xff09;&#xff0c;再执行内层&#xff08;下级&#xff…...

Nginx反向代理和负载均衡配置

一、疑问 在苍穹外卖里&#xff0c;浏览器发送的请求&#xff0c;比如登录&#xff0c;其url为http://localhost/api/employee/login&#xff0c; 而后端的路径是http://localhost:8080/admin/employee/login 两者不一致&#xff0c;数据是如何准确传输的呢&#xff1f; 二、…...

【379】基于springboot的防疫物资管理信息系统

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装防疫物资管理信息系统软件来发挥其高效地信息处理的作用&am…...

Linux 各个目录作用

刚毕业的时候学习Linux基础知识&#xff0c;发现了一份特别好的文档快乐的 Linux 命令行&#xff0c;翻译者是happypeter&#xff0c;作者当年也在慕课录制了react等前端相关的视频&#xff0c;通俗易懂&#xff0c;十分推荐 关于Linux的目录&#xff0c;多数博客已有详细介绍…...

【Linux】文件操作的艺术——从基础到精通

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长&#xff0c;行则将至 目录 &#x1f4da;前言&#xff1a;一切皆文件 &#x1f4da;一、C语言的文件接口 &#x1f4d6;1.文件打…...

java中的运算符

大家好&#xff0c;今天来看看java中运算符的一些知识点&#xff0c;理解好运算符是我们在写代码的一大重点&#xff0c;那么我们就来看看吧。 运算符:对操作数进行操作时的符号.,不同运算筹操作的含义不同. 一、算术算片. 1、基本四则运算符:加减乘除模(一*/%) 注意:都是二元…...

全面解析 C++ STL 中的 set 和 map

C 标准模板库&#xff08;STL&#xff09;中的关联式容器以其强大的功能和高效性成为开发者解决复杂数据组织问题的重要工具。其中&#xff0c;set 和 map 是最常用的两类关联容器。本篇博客将从基本特性、底层实现、用法详解、高级案例以及性能优化等多个角度&#xff0c;详细…...

css:怎么设置div背景图的透明度为0.6不影响内部元素

目录 1.前言 2.解决思路 3.具体实例 4.另外一种实例 5.总结 1.前言 div背景图为project-bg.png&#xff0c;设置div透明度为0.6&#xff1b;div内的名称、数值受透明度影响颜色显示不正常&#xff1b;怎么设置背景图的透明度为0.6不影响内部元素&#xff1b; 2.解决思路 …...

Kubernetes ConfigMaps

文章目录 简介创建ConfigMaps通过命令行使用字面值创建 ConfigMap。从文件创建ConfigMaps从多个文件创建 ConfigMap从目录创建 ConfigMap使用 YAML 创建 ConfigMap 使用ConfigMaps使用 ConfigMaps作为环境变量使用 ConfigMap 作为卷挂载使用 ConfigMap 中的特定的key ConfigMap…...

wordpress页面加载慢/国内10大搜索引擎

PHP 8.1&#xff1a;初始化器&#xff08;new in initializers&#xff09; PHP 8.1 添加了一个看似很小的细节&#xff0c;但我认为它会对许多人产生重大的日常影响。那么这个“初始化器 RFC 中的新内容”是关于什么的&#xff1f;我们来看一个例子&#xff1b;我们都写过这样…...

建设银行官方网站诚聘英才/优化公司组织架构

很多资料是看到的&#xff0c;大家可以参考下 Image2Lcd 是一款工具软件&#xff0c;它能使你把各种来源的图片转换成特定的数据格式以用来匹配单片机系统所需要的显示数据格式。Image2Lcd支持的输入图像格式包括&#xff1a; BMP, WBMP, JPG, GIF, WMF, EMF, ICO, 等等。Imag…...

可不可以用帝国cms做企业网站/爬虫搜索引擎

所谓延时队列就是延时的消息队列&#xff0c;下面说一下一些业务场景实践场景订单支付失败&#xff0c;每隔一段时间提醒用户用户并发量的情况&#xff0c;可以延时2分钟给用户发短信先来看看Redis实现普通的消息队列我们知道&#xff0c;对于专业的消息队列中间件&#xff0c;…...

百度做的网站后台怎么建设/网站seo优化多少钱

前言 大家应该看过不少人分享的面试成功的面经&#xff0c;是不是觉得自己“说不定也可以”呢&#xff1f; 这里重提一个理论&#xff1a;幸存者偏差。当取得资讯的渠道&#xff0c;仅来自于幸存者时&#xff08;因为死人不会说话&#xff09;&#xff0c;此资讯可能会存在与…...

互联网站建设维护需要做什么/上海网站排名优化

问题描述&#xff1a; 让导航栏重叠在轮播图上面&#xff0c;并且导航栏要是透明的状态&#xff0c;功能实现了&#xff0c;但是出现拖到分屏宽度就变了。 代码&#xff1a; 开始用的宽度设置都是px单位&#xff0c;后来改成百分比就可以自适应了。 原因分析&#xff1a;…...

台州网站建设公司./农村电商平台有哪些

default Comparator<T> reversed() {return Collections.reverseOrder(this); } 上面是reversed方法&#xff0c;可见&#xff0c;这里用到了Java8的新特性&#xff0c;接口里面的方法可以有默认的实现。接下来我们分析下Collectionsde的静态方法&#xff1a;public stat…...