使用Apache Kafka作为消息系统的发布-订阅通信中的微服务,并通过集成测试进行了验证...

发布-订阅消息系统在任何企业体系结构中都起着重要作用,因为它可以实现可靠的集成而无需紧密耦合应用程序。 在解耦的系统之间共享数据的能力并不是一个容易解决的问题。

考虑一个企业,其中具有使用不同语言和平台独立构建的多个应用程序。 它需要以响应方式共享数据和流程。 我们可以使用Messaging通过使用可自定义的格式频繁,立即,可靠且异步地传输数据包来实现此目的。 从根本上说,异步消息传递是对分布式系统问题的务实反应。 发送消息不需要两个系统同时启动和就绪。

发布-订阅频道

从简单的角度来看,通过添加用于传达事件通知的事件通道的概念,对这种模式的理解依赖于它对观察者模式的扩展。 观察者模式描述了将观察者与他们的主题脱钩的必要性,这样,无论有多少观察者,主题都可以轻松地向所有感兴趣的观察者提供事件通知。

每个订阅者都需要一次被通知特定事件,但不应重复通知同一事件。 在通知所有订户之前,不能认为事件已消耗。 但是,一旦所有订户都得到通知,该事件就可以视为已消耗,应该从通道中消失[2]。

代理,队列,主题和订阅

代理消息传递支持真实时间解耦系统的场景,在这种情况下,不能保证消息生产者或使用者的可用性。 对于代理消息传递,队列是保留由生产者创建的消息的代理,并且消费者在准备就绪时可以在其中检索消息。

队列提供了最简单的邮件传递选项。 队列中的消息是按照先进先出(FIFO)进行组织的,并且每个消息都应由单个使用者处理。 但是,主题和订阅构成了一种发布/订阅模式,允许N个消费者处理同一条消息。

5-发布-订阅

可以将单个消息添加到主题,并且对于满足的每个订阅规则,将消息的副本添加到该订阅。 在这种情况下,每个订阅都会成为队列,消费者可以在其中单独处理订阅上的消息。

行业领先者正在使用的可靠且成熟的项目之一是Apache Kafka,它为我们提供了每秒处理大量消息的能力,而不是传统的消息传递系统,该系统在传统场景中非常有用,但效率和价值却不高在处理大数据场景中。

除消息传递外,Apache Kafka还可以应用于流处理,网站活动跟踪,日志聚合,指标,基于时间的消息存储,提交日志和事件源。 在下一节中,我们将深入介绍Apache Kafka的组件和特征。

卡夫卡

Kafka是一个分布式的发布-订阅消息系统,通过其设计,分区和复制的提交日志服务,其本质上是快速,可伸缩的并且分布式的。 它与传统消息传递系统的不同之处在于,它非常易于扩展,提供高吞吐量,支持多订户并在故障期间自动平衡使用者,并具有允许实时应用程序或ETL将其用作批处理消耗的能力磁盘上的持久消息数。

4-发布-订阅

组件[1]

  • 生产者 –生产者是将消息发布给Kafka经纪人的任何应用程序/程序。
  • 使用者 -使用者是使用来自Kafka经纪人的消息的应用程序。 这些使用者可以是简单的应用程序,实时流处理引擎等。
  • 主题和分区 – Apache Kafka支持消息主题的概念,这些主题允许对消息进行分类。 它使我们能够为不同类型的消息创建不同的主题,并让不同的消费者使用消息。 此外,Apache Kafka允许在一个Topic中创建多个分区,以允许并行使用消息,因为我们可以同时从不同的分区中消费不同的使用者。 每个分区都有一个领导节点,负责处理来自消费者/生产者对该分区的读/写请求。
3-发布-订阅
  • 代理 – Kafka代理通常是指安装了Kafka的计算机。 但是,可以在非生产设置中在一台计算机上设置多个代理。 Kafka经纪人负责管理消息日志并接受生产者/消费者的请求。 卡夫卡经纪人是无国籍的。 这意味着消费者必须保持已经消费了多少。 消费者自己维护它,经纪人不会做任何事情。
  • 存储 – Kafka具有非常简单的存储布局。 主题的每个分区都对应一个逻辑日志。 从物理上讲,日志是作为一组大小相等的段文件实现的。 每次生产者将消息发布到分区时,代理都将消息简单地附加到最后一个段文件。 在发布了可配置数量的消息或经过一定时间后,段文件将刷新到磁盘。 消息在清除后会暴露给使用者。
  • 集群 – Kafka集群是Kafka经纪人的集合。 集群中的所有Kafka经纪人共同工作,以管理已配置的消息及其副本。

动物园管理员

ZooKeeper用于管理和协调Kafka经纪人。 每个Kafka经纪人都使用ZooKeeper与其他Kafka经纪人进行协调。 ZooKeeper服务会通知生产者和消费者有关Kafka系统中是否存在新代理或代理失败的信息。 从Zookeeper收到的有关经纪人存在或失败的通知中,生产者和消费者做出决定并开始与其他经纪人协调工作。 同样,它负责为分区选择新的领导者。

案例分析

稍作调整后,专注于练习。 因此,我们的案例研究使用Apache Kafka 2.3.1作为消息系统,在发布-订阅上下文中模拟了使用Spring Boot微框架v2.1.8.RELEASE构建的两个微服务之间的通信。 为了验证我们的研究,我们将设置并执行一个集成测试,该测试重点在于使用JUnit 4/5测试框架在端到端场景中集成应用程序的不同层。

生产者API是一个模块,用于实现业务实体服务的操作,以协调和协调与企业,机构和实体组有关的经济信息。 消费者API是同一解决方案中的另一个模块,旨在集中所有业务实体统计信息,并接收来自不同来源的数据输入。

为了简单起见,API使用H2内存数据库。 项目结构由三个模块组成。 Producer和Consumer这两个主要模块都具有Common模块的依赖性,在Common模块中,它与系统的其余部分共享诸如错误处理和辅助类之类的内容。

可从GitHub存储库访问该示例; 要下载它,请点击此链接 。

1-发布-订阅

让我们开始吧。

将Spring Kafka与Apache Kafka消息系统集成

用于Apache Kafka的Spring项目将核心Spring概念应用于基于Kafka的消息传递解决方案的开发。 它提供了一个“模板”作为发送消息的高级抽象。 它还通过@KafkaListener批注和“侦听器容器”为消息驱动的POJO提供支持。 这些库促进了依赖注入和声明性[3]的使用。

生产者API

我们需要两个步骤来配置生产者。 第一个是config类,其中定义生产者Map对象,生产者工厂和Kafka模板。 当我们将消息生成器设置为在Kafka代理中发布时,第二种尊重服务类。

生产者配置

在配置类中,在application.properties中设置了常数“ bootstrapServers” (即Kafka服务器)。 使用@Value(“ $ {spring.kafka.bootstrap-servers}”)批注表示受影响参数的默认值表达式。

要创建Kafka生产者,我们定义一些属性,这些属性将传递给Kafka生产者的构造函数。 在“ producerconfigs ” @Bean中,我们将BOOTSTRAP_SERVERS_CONFIG属性设置为我们先前在application.properties中定义的代理地址列表。 BOOTSTRAP_SERVERS_CONFIG值是主机/端口对的逗号分隔列表,生产者用来建立与Kafka群集的初始连接。

package com.BusinessEntityManagementSystem;import ...@Configuration
public class KafkaProducerConfig {@Value("${spring.kafka.bootstrap-servers}")private String bootstrapServers;@Beanpublic Map<String, Object> producerConfigs() {Map<String, Object> props = new HashMap<>();props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);return props;}@Beanpublic ProducerFactory<String, BusinessEntity> producerFactory() {return new DefaultKafkaProducerFactory<>(producerConfigs());}@Beanpublic KafkaTemplate<String, BusinessEntity> kafkaTemplate() {return new KafkaTemplate<String, BusinessEntity>(producerFactory());}
}

KEY_SERIALIZER_CLASS_CONFIG是用于Kafka记录键的Kafka序列化器类,该类实现了Kafka序列化器接口。 注意,我们将其设置为StringSerializer.class作为消息ID。 VALUE_SERIALIZER_CLASS_CONFIG是一个Kafka序列化程序类,我们将其设置为JsonSerializer.class作为消息主体。

要创建消息,首先,我们需要配置一个ProducerFactory,该工厂设置创建Kafka Producer实例的策略。 然后,我们需要一个KafkaTemplate,它包装一个Producer实例,并提供使用数据传输对象“ BusinessEntity ”将消息发送到Kafka主题的便捷方法。

生产者服务

在Kafka Producer服务类中, @ Service注释表示带注释的类是“服务”。 在此类中,我们实现了将消息发送到Kafka代理的方法,在application.properties中预定义的标头上声明了topic属性。

package com.BusinessEntityManagementSystem.kafka;import ...@Service
public class KafkaProducer {@Autowiredprivate KafkaTemplate<String, BusinessEntity> kafkaTemplate;@Value("${statistics.kafka.topic}")String kafkaTopic;public void send(BusinessEntity payload) {Message<BusinessEntity> message = MessageBuilder.withPayload(payload).setHeader(KafkaHeaders.TOPIC, kafkaTopic).build();kafkaTemplate.send(message);}
}

消费者API

在Consumer中,我们需要添加适当的Deserializer,该Deserializer可以将JSON byte []转换为Java Object。 要设置它,我们需要使用config和带有@components注释的类,当使用基于注释的配置和类路径扫描时,它们将自动检测此类以进行依赖项注入。

消费者配置

同样,当我们指定KEY_SERIALIZER_CLASS_CONFIG,VALUE_SERIALIZER_CLASS_CONFIG来序列化生产者发布的消息时,我们还需要通知Spring Kafka有关反序列化的常量值,例如KEY_DESERIALIZER_CLASS_CONFIG和VALUE_DESERIALIZER_CLASS_CONFIG。 除了上面引用的常量之外,我们还指定了GROUP_ID_CONFIG和AUTO_OFFSET_RESET_CONFIG作为最早的常量,从而允许使用者读取代理中最后插入的消息。

要启用Kafka侦听器,我们使用@EnableKafka批注。 这注释了由AbstractListenerContainerFactory在后台创建的端点。 KafkaListenerContainerFactory负责为特定端点创建侦听器容器。 它可以检测容器中任何受Spring管理的bean上的KafkaListener批注。

作为典型的实现, ConcurrentKafkaListenerContainerFactory提供了基础MessageListenerContainer支持的必要配置选项。

package com.BusinessStatisticsUnitFiles;import ...@Configuration
@EnableKafka
public class KafkaConsumerConfig {@Value("${spring.kafka.bootstrap-servers}")private String bootstrapServers;@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, JsonDeserializer.class);props.put(ConsumerConfig.GROUP_ID_CONFIG, "statistics-BusinessStatisticsUnitFiles-group");props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");return props;}@Beanpublic ConsumerFactory<String, BusinessEntity> consumerFactory() {return new DefaultKafkaConsumerFactory<>(consumerConfigs(),new StringDeserializer(),new JsonDeserializer<>(BusinessEntity.class, false));}@Beanpublic ConcurrentKafkaListenerContainerFactory<String, BusinessEntity> kafkaListenerContainerFactory() {ConcurrentKafkaListenerContainerFactory<String, BusinessEntity> factory =new ConcurrentKafkaListenerContainerFactory<>();factory.setConsumerFactory(consumerFactory());return factory;}
}

在消费者工厂,我们可以禁用标题的使用。 现在,这可以通过将新JsonDeserializer <>(BusinessEntity.class,false))中的第二个参数设置为false来实现 。 这使使用者可以信任来自任何程序包的消息。

消费者“服务”

为了使用消息,有必要像上面一样配置ConsumerFactory和KafkaListenerContainerFactory。 一旦这些bean在Spring bean工厂中可用,就可以使用@KafkaListener注释配置基于POJO的使用者。

在用@KafkaListener注释的类中, @ KafkaHandler还需要将方法标记为Kafka消息侦听器的目标。 重要的是要了解,当消息到达时,选择的方法取决于有效负载类型。 该类型与单个非注释参数匹配,或与@Payload注释的参数匹配。 绝不能有歧义-系统必须能够根据有效载荷类型选择恰好一种方法。

package com.BusinessStatisticsUnitFiles.kafka;import ...@Component
public class KafkaConsumer {@AutowiredIBusinessEntityRepository businessEntityRepository;private static final Logger LOG = LoggerFactory.getLogger(BusinessEntity.class);@KafkaListener(topics = "${statistics.kafka.topic.create.entity}", groupId = "statistics-BusinessEntityManagementSystem-group")@KafkaHandlerpublic void receiveCreatedEntity(@Payload BusinessEntity data,@Headers MessageHeaders headers) {businessEntityRepository.save(RetrieveConsumerFromReceivedProducerObject.Binding(new BusinessEntityModel(), data));}
}

@Payload批注将方法参数绑定到消息的有效负载。 它还可以用于将有效负载与方法调用相关联。 有效负载可以通过MessageConverter传递,以将其从具有特定MIME类型的序列化形式转换为与目标方法参数匹配的Object。 用@Payload注释的类是“ BusinessEntity” DTO。

Spring Boot还支持使用侦听器中的@Headers批注检索一个或多个消息头。 可以为一个主题实现多个侦听器,每个侦听器具有不同的组ID。 此外,一个消费者可以收听来自各种主题的消息。

您可能已经注意到,我们创建的主题建筑只有一个分区。 但是,对于具有多个分区的主题, @ KafkaListener可以显式订阅具有初始偏移量的主题的特定分区。

Application.properties

最后但并非最不重要的一点是,在我们的配置中,我们指定一些与生产者和消费者之间的通信行为有关的值。

生产者/消费者

在每个Producer和Consumer API上,我们都使用spring.kafka.bootstrap-servers = localhost:9092定义了我们希望微服务连接的Kafka集群。 同样,有必要定义主题名称以产生和接收消息,密钥以及组ID。

...
## Application.properties Kafka config
spring.kafka.bootstrap-servers=localhost:9092
statistics.kafka.topic=test
statistics.kafka.key=test
statistics.kafka.topic.create.entity=test
spring.kafka.producer.group-id=statistics-BusinessStatisticsUnitFiles-group
spring.kafka.template.default-topic=test
...

准备Kafka和Zookeeper进行集成测试

下面定义的步骤演示了如何在Windows 10操作系统上运行和测试Kafka。

下载带有嵌入式Zookeeper的Kafka

  1. 下载Kafka二进制文件 。 这篇文章基于Kafka 2.3.1,因此我们假设您正在下载Scala 2.12的2.3.1版本。
  2. 解压缩kafka_2.12-2.3.1.tgz文件。

设置zookeeper.properties

为了使其正常工作,我们需要更改Zookeeper数据目录的位置。
打开kafka \ config \ zookeeper.properties文件,然后将Zookeeper数据/ log目录位置配置更改为有效的Windows目录位置。

dataDir=C:\\kafka\\zookeeper-logs

设置server.properties

我们还需要对Kafka配置进行一些更改。 打开kafka \ config \ server.properties并将主题默认设置为1。 我们将运行一个单节点Kafka。 另外,为防止Kafka创建不必要的偏移量,我们将副本指定为1。我们在Windows环境中使用最新的Kafka 2.3.1版本遇到此问题。 这导致Kafka停止,因为内存不足,无法处理在启动服务器的初始阶段自动创建的大量数据。

############################# Log Basics #############################log.dirs=C:\\kafka\\kafka-logs####################### Internal Topic Settings  #####################offsets.topic.replication.factor=1
offsets.topic.num.partitions = 1 
min.insync.replicas=1 
default.replication.factor = 1
...

要完成Kafka配置,请将Kafka bin \ windows目录添加到PATH环境变量中。

创建和执行集成测试

顾名思义,集成测试专注于集成应用程序的不同层,其中不涉及任何模拟。 集成测试需要启动一个容器来执行测试用例。 因此,为此需要一些额外的设置,但是使用spring boot时,使用一些注释和库可以很容易地完成这些步骤。

测试班

第一个注释@RunWith(SpringRunner.class)用于在Spring Boot测试功能和JUnit之间建立桥梁。 SpringRunner.class在测试中全面支持Spring上下文加载和Bean的依赖项注入。 @SpringBootTest通过SpringApplication创建ApplicationContext测试,这些测试将在我们的测试中使用。 自嵌入式服务器以来,它将引导整个容器,并创建一个Web环境。

在我们的测试中,我们模仿的是真实的Web环境,将其设置为RANDOM_PORT也会加载WebServerApplicationContext。 嵌入式服务器将启动并在随机端口上进行侦听。

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {BusinessEntityManagementApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class BusinessEntityIntegrationTest {@LocalServerPortprivate int port;@AutowiredTestRestTemplate restTemplate;HttpHeaders headers = new HttpHeaders();

@LocalServerPort批注为我们提供了在运行时分配的注入的HTTP端口。 这是@Value("${local.server.port}")的便捷替代方法。

要访问Spring应用程序中的第三方REST服务,我们使用Spring RestTemplate或TestRestTemplate ,这是一种适合集成测试的便捷替代方法,方法是将其注入我们的测试类中。 通过在项目中使用spring-boot-starter-test依赖项,我们可以在运行时访问“ TestRestTemplate”类。

测试方法

在我们的方法测试中,我们使用“ junit-json-params ”,这是一个Junit 5库,提供注释以从JSON字符串或参数化测试中的文件加载数据。 我们还使用@ParameterizedTest注释对方法进行了注释,以补充下面的库。 它用于表示带注释的方法是参数化测试方法。 该方法不得为私有或静态。 他们还必须通过@ArgumentsSource或相应的组合批注指定至少一个ArgumentsProvider

我们的@ArgumentsSource@ArgumentsSource中的JSON文件@JsonFileSource(resources =“ /business-entity-test-param.json”)。 @JsonFileSource允许您使用类路径中的JSON文件。 它支持单个对象,对象数组和JSON原语。

从文件中检索的JSON对象绑定到方法参数“对象”,该方法将其转换为POJO对象,在本例中为我们的实体模型。

@ParameterizedTest
@JsonFileSource(resources = "/business-entity-test-param.json")
@DisplayName("create business entity with json parameter")
void createBusinessEntity(JsonObject object) throws IOException, URISyntaxException {BusinessEntityModel businessEntityModel;businessEntityModel = new BusinessEntityModel();ObjectMapper mapper = new ObjectMapper();businessEntityModel = mapper.readValue(object.toString(), BusinessEntityModel.class);HttpEntity<BusinessEntityModel> request = new HttpEntity<>(businessEntityModel, headers);try {ResponseEntity<String> response = this.restTemplate.postForEntity(createURLWithPort("/api/businessEntityManagementSystem/v1/businessEntity"), request, String.class);assertAll(() -> assertThat(response.getStatusCodeValue()).isEqualTo(HttpStatus.CREATED.value()),() -> assertThat(response.getHeaders().getLocation().getPath()).contains("/v1"));}catch(HttpClientErrorException ex) {assertAll(() -> Assert.assertEquals(HttpStatus.BAD_REQUEST.value(), ex.getRawStatusCode()),() -> Assert.assertEquals(true, ex.getResponseBodyAsString().contains("Missing request header")));}
}

在安排并执行操作之后,我们断言对其余API的调用是否返回了所需的结果。

运行集成测试

在我们的开发环境中,我们需要确保我们的Kafka和Zookeeper在两个不同的控制台中启动并运行,如图所示

2-发布-订阅

Kafka需要Zookeeper,因此我们将首先使用以下命令启动Zookeeper。

c:\kafka>.\bin\windows\zookeeper-server-start.bat .\config\zookeeper.properties

它应该启动Zookeeper服务器。 最小化命令窗口,并让Zookeeper在该窗口中运行。 启动一个新的命令窗口,并使用以下命令启动Kafka Broker。

c:\kafka>.\bin\windows\kafka-server-start.bat .\config\server.properties

接下来,我们将按照我们的想法运行Consumer API,或者将其部署在任何兼容的Web服务器中。

最后,我们可以将测试类作为JUnit测试执行。 它将按正常方式启动服务器并部署API。 然后它将执行测试。 您可以在“ JUnit”选项卡中验证测试。

结论

在本文中,我们看到了如何使用发布-订阅模式以可响应的方式在两个不同的微服务之间使用可定制格式频繁,立即,可靠和异步地共享数据,并通过在不同层中的不同层进行集成测试来对其进行验证。端到端场景。

参考文献

[1] Kafka 2.3文档 ;


[2] Gregor Hohpe,Bobby Woolf,企业集成模式设计,构建和部署消息解决方案,2003年;


[3] 适用于Apache Kafka 2.3.3的Spring 。

翻译自: https://www.javacodegeeks.com/2019/11/microservices-in-publish-subscribe-communication-using-apache-kafka-as-a-messaging-systems-and-validated-through-integration-test.html

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

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

相关文章

LINUX系统无线网频繁断开_Ubuntu系统安装amp;amp;解决WiFi不可用

写系统安装的文章太多太多了&#xff0c;我为何还要写哪&#xff1f; 因为文章太多太多了&#xff0c;乍一看各种操作猛如虎&#xff0c;实际上可能对你没有一点的帮助。好多文章只是讲解了如何安装ubuntu系统&#xff0c;对于安装后遇到的问题只字不提&#xff0c;笔者决定写一…

return两个返回值_LeetCode 第四题 寻找两个有序数组的中位数

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数&#xff0c;并且要求算法的时间复杂度为 O(log(m n))。你可以假设 nums1 和 nums2 不会同时为空。示例 1:nums1 [1, 3]nums2 [2]​则中位数是 2.0示例 2:nums1 [1, 2]nums2 [3, 4]​则中…

intellij 使用_使用IntelliJ书签

intellij 使用这是有关IntelliJ的精美书签功能的快速帖子。 IntelliJ使您可以为单行代码添加书签。 将某行添加为书签后&#xff0c;您可以使用多种方法直接跳回该行。 因此&#xff0c;最好在您经常使用的代码位置添加书签。 要创建一个新书签&#xff0c;只需在代码编辑器中…

[即将举行的网络研讨会]对Kubernetes进行故障排除:您需要具备的7个关键组件

如果您没有听说过&#xff0c;那么容器正在吞噬整个世界。 这种转变正在改变我们在开发&#xff0c;交付和维护应用程序方面所知的一切&#xff0c;尤其是在解决错误方面。 有这么多动人的东西&#xff0c;让您难以发现潜伏在基于Kubernetes的应用程序中的关键问题。 传统的故…

php能打开.shp文件吗,shp文件是什么格式的

shape文件由ESRI开发&#xff0c;一个ESRI的shape文件包括一个主文件&#xff0c;一个索引文件&#xff0c;和一个dBASE表。其中主文件的后缀就是【.shp】。本文操作环境&#xff1a;Windows7系统&#xff0c;Dell G3电脑。shape文件由ESRI开发&#xff0c;一个ESRI(Environmen…

成为Java流大师–第5部分:将联接的数据库表转换为流

是否可以将联接的数据库表转换为Java Stream&#xff1f; 答案是肯定的。 既然我们已经多次提出这个问题&#xff0c;我们决定写另一篇动手实验文章&#xff0c;解释如何执行更高级的Stream Joins。 因此&#xff0c;这里是第六篇中的第五篇&#xff0c;后面还有一个GitHub存储…

mysql数据库java链接,java链接MySQL数据库方法

第一步&#xff1a;安装MySQL这步我就很少说了&#xff0c;点击去看看怎么安装吧。html第二步&#xff1a;建立数据库安装好以后&#xff0c;咱们来建立一个数据库&#xff0c;一个表。(代码以下)。//建立数据库 test&#xff1b;//在数据库中建立表 user//插入一条数据create …

matlab虚线分格线,虚线实线网格线……一分钟看懂路面标志线,不再被扣分!

黄色实线黄色实线用来区分不同方向的车道&#xff0c;一般画在马路正中间&#xff0c;车道多的路面上就是双黄线&#xff0c;车道少的路面上则用单黄线。而无论单黄线还是双黄线&#xff0c;均严格禁止车辆跨越&#xff0c;因此压线行驶、超车或者掉头等都是不允许的。黄色虚线…

python 判断列表为空_Python 判断列表为空

原博文 2020-06-05 12:38 − https://mp.weixin.qq.com/s?__bizMzU2MDQwOTU0MA&mid2247483845&idx1&sndaf1d3661b4e6b6a15dbe40c7f9c0e14&chksmfc093f6ecb7eb678c22e3... 相关推荐 2019-09-28 21:13 − Python python是一种跨平台的计算机程序设计语言&#x…

clodeblocks debug断点调试_idea debug调试————简单常用,适合初学者

背景&#xff1a;在现在的开发中&#xff0c;如果不会debug&#xff0c;那么将会给我们的开发带来很大的困扰&#xff0c;如果仅仅是依靠日志信息去查问题&#xff0c;将会大大增加我们解决问题的难度&#xff0c;下面说一下idea开发工具下的简单debug。适用人群&#xff1a;ja…

bigdecimal判断等于0_vue2.0源码用到的工具函数,12个简易的复用函数,看看有多简单...

戎马&#xff1a;https://segmentfault.com/a/11900000196796381. 创建一个被冻结的空对象export const emptyObject Object.freeze({ }) 一旦创建不能给这个对象添加任何属性。2. 判断是否是 undefined 或 nullfunction isUndef (v) { return v undefined || v null}在源码…

告诉我们您想要什么,我们将做到:消费者驱动的合同测试消息传递

相当早以前&#xff0c;我们从REST&#xff08;ful&#xff09; Web API的角度讨论了消费者驱动的合同测试 &#xff0c;尤其是将其投射到Java&#xff08; JAX-RS 2.0规范&#xff09;的角度。 可以公平地说&#xff0c;至少在公共API方面&#xff0c; REST仍在Web API领域占据…

宝塔面板php降级,宝塔面板6.8.8降级到5.9.1的方案教程

有朋友问起&#xff0c;6.8版本用的不习惯&#xff0c;而且缺少5.9版本的nginx过滤器&#xff0c;而且6.8版本许多功能阉割的厉害&#xff1a;服务器状态中的 连接管理、进程管理 也都被阉割&#xff0c;5.9版本是可以在面板中查看服务器进程管理的&#xff0c;如图&#xff1a…

c++矩阵连乘的动态规划算法并输出_「Javascript算法设计」× 动态规划与回溯算法...

目录&#xff1a;分而治之算法动态规划回溯算法分而治之算法分而治之算法是算法设计的一种方式&#xff0c;它将一个问题分成多个和原问题相似的小问题&#xff0c;递归解决小问题&#xff0c;再将解决方式合并以解决原来的问题&#xff08;例如快速排序&#xff0c;二分搜索等…

背包问题九讲_背包问题

背包问题九讲我发现背包问题既棘手又有趣。 我敢肯定&#xff0c;如果您正在访问此页面&#xff0c;您已经知道了问题说明&#xff0c;但是只是为了完成本章&#xff1a; 问题&#xff1a; 给定一个最大容量为W和N的背包&#xff0c;每个背包都有自己的值和重量&#xff0c;将…

随机森林的特征 是放回抽样么_机器学习超详细实践攻略(10):随机森林算法详解及小白都能看懂的调参指南...

一、什么是随机森林前面我们已经介绍了决策树的基本原理和使用。但是决策树有一个很大的缺陷&#xff1a;因为决策树会非常细致地划分样本&#xff0c;如果决策树分得太多细致&#xff0c;会导致其在训练集上出现过拟合&#xff0c;而如果决策树粗略地划分样本&#xff0c;又不…

http端口_PhpStorm 修改默认端口号63342

PhpStorm 修改默认端口号63342​blog.csdn.net关键词PhpStorm phpStorm phpstorm 修改默认端口号63342 8080 80步骤1.打开Settings2. Build, Execution, Deployment→Deployment3.点击添加&#xff0c;选择In place起一个名字&#xff08;可以随便起&#xff09;在Web server U…

rds mysql 磁盘空间,RDS MySQL 空间问题的原因和解决

other_size- 系统文件和临时文件使用空间data_size- 数据文件使用空间binlog_size- Binlog 文件占用空间注&#xff1a;获取实例诊断报告的步骤请参考如何访问RDS 实例诊断报告。2. 解决RDS 实例支持单独升级磁盘空间&#xff0c;升级磁盘空间是解决空间问题的有效方式之一。下…

微信小程序 全局变量异步函数_微信小程序【生命周期】

小程序分为应用、页面和组件三个部分&#xff0c;所以小程序的生命周期涉及以下应用的生命周期页面的生命周期组件的声明周期应用的生命周期对页面生命周期的影响应用的生命周期App() 函数用来注册一个小程序。接受一个 Object 参数&#xff0c;其指定小程序的生命周期回调等。…

Java / Spring:如何快速生成整个数据库CRUD REST API

随着时间的流逝&#xff0c;Spring框架已成为Java中使用最广泛的Web开发框架之一&#xff0c;这一点已变得显而易见。 在接下来的十年之际&#xff0c;Spring最受欢迎的模块Spring Boot刚刚进行了重大更新。 新的Spring Boot版本“ 2.2.0”和年份“ 2020”几乎完美匹配。 因此…