从0到1搞一波dubbo

1、为什么需要dubbo?(为了解决什么问题?)

 

 

 

架构演变

1 单一应用架构

2 应用和数据库单独部署

3 应用和数据库集群部署

4 数据库压力变大,读写分离

5 使用缓存技术加快速度

6 数据库分库分表

7 应用分为不同的类型拆分

应用之间的关系已经十分复杂,产生了以下问题:

  • 当服务越来越多,服务 URL 配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
  • 服务间依赖关系复杂,应用的启动顺序复杂、应用的架构关系复杂
  • 服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?

 

2、Dubbo是什么?(dubbo技术架构)

 

节点角色:

节点

角色说明

Provider

暴露服务的服务提供方

Consumer

调用远程服务的服务消费方

Registry

服务注册与发现的注册中心

Monitor

统计服务的调用次数和调用时间的监控中心

Container

服务运行容器

Dubbo架构简单来说其实是生产者-消费者模型。进一步在这种模型上,加上了注册中心和监控中心,用于管理提供方提供的url,以及管理整个过程。

发布订阅过程:

  • 启动容器,加载,运行服务提供者
  • 服务提供者在启动时,在注册中心发布注册自己提供的服务
  • 服务消费者在启动时,在注册中心订阅自己所需的服务

如果考虑失败或变更的情况,就需要考虑下面的过程。

  • 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  • 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  • 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

3、Dubbo如何使用?

3.1 定义服务提供者

新建provider提供者模块,定义如下接口:

/**

 * xml方式服务提供者接口

 */

public interface ProviderService {

 

    String SayHello(String word);

}

实现类

/**

 * xml方式服务提供者实现类

 */

public class ProviderServiceImpl implements ProviderService{

 

    public String SayHello(String word) {

        return word;

    }

}

3.2 服务暴露

导入maven依赖

<?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.test</groupId>

    <artifactId>dubbo-provider</artifactId>

    <version>1.0-SNAPSHOT</version>

 

    <dependencies>

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>3.8.1</version>

            <scope>test</scope>

        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>dubbo</artifactId>

            <version>2.6.6</version>

        </dependency>

        <dependency>

            <groupId>org.apache.zookeeper</groupId>

            <artifactId>zookeeper</artifactId>

            <version>3.4.10</version>

        </dependency>

        <dependency>

            <groupId>com.101tec</groupId>

            <artifactId>zkclient</artifactId>

            <version>0.5</version>

        </dependency>

        <dependency>

            <groupId>io.netty</groupId>

            <artifactId>netty-all</artifactId>

            <version>4.1.32.Final</version>

        </dependency>

        <dependency>

            <groupId>org.apache.curator</groupId>

            <artifactId>curator-framework</artifactId>

            <version>2.8.0</version>

        </dependency>

        <dependency>

            <groupId>org.apache.curator</groupId>

            <artifactId>curator-recipes</artifactId>

            <version>2.8.0</version>

        </dependency>

 

    </dependencies>

</project>

进行服务暴露:暴露接口(xml 配置方法)

首先,在项目 resource 目录下创建 META-INF.spring 包,然后再创建 provider.xml 文件,

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

 

    <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->

    <dubbo:application name="provider" owner="cp">

        <dubbo:parameter key="qos.enable" value="true"/>

        <dubbo:parameter key="qos.accept.foreign.ip" value="false"/>

        <dubbo:parameter key="qos.port" value="55555"/>

    </dubbo:application>

 

    <dubbo:monitor protocol="registry"/>

 

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->

    <!--<dubbo:registry address="N/A"/>-->

    <dubbo:registry address="N/A" />

 

    <!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http-->

    <dubbo:protocol name="dubbo" port="20880"/>

 

    <!--服务发布的配置,需要暴露的服务接口-->

    <dubbo:service

            interface="com.dubbo.provider.service.ProviderService"

            ref="providerService"/>

 

    <!--Bean bean定义-->

    <bean id="providerService" class="com.dubbo.provider.service.ProviderServiceImpl"/>

</beans>

发布接口:通过 ClassPathXmlApplicationContext 拿到我们刚刚配置好的 xml ,然后调用 context.start() 方法启动

 

package com.dubbo.provider;

 

import com.alibaba.dubbo.config.ApplicationConfig;

import com.alibaba.dubbo.config.ProtocolConfig;

import com.alibaba.dubbo.config.RegistryConfig;

import com.alibaba.dubbo.config.ServiceConfig;

import com.alibaba.dubbo.container.Main;

import com.dubbo.provider.service.ProviderService;

import com.dubbo.provider.service.ProviderServiceImpl;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

import java.io.IOException;

 

/**

 * xml方式启动

 *

 */

public class App

{

    public static void main( String[] args ) throws IOException {

        //加载xml配置文件启动

        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/provider.xml");

        context.start();

        System.in.read(); // 按任意键退出

    }

}

3.2 定义消费消费者

新建消费者consumer模块,先通过点对点方式:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

 

    <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->

    <dubbo:application name="consumer" owner="cp"/>

 

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->

    <!--点对点的方式-->

    <dubbo:registry address="N/A" />

    <!--<dubbo:registry address="zookeeper://localhost:2181" check="false"/>-->

 

    <!--生成一个远程服务的调用代理-->

    <!--点对点方式-->

    <dubbo:reference id="providerService"

                     interface="com.dubbo.provider.service.ProviderService"

                     url="dubbo://localhost:20880/com.dubbo.provider.service.ProviderService"/>

 

    <!--<dubbo:reference id="providerService"

                     interface="com.dubbo.provider.service.ProviderService"/>-->

 

</beans>

导入maven依赖(同服务端类似)

<?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.test</groupId>

    <artifactId>dubbo-consumer</artifactId>

    <version>1.0-SNAPSHOT</version>

 

    <dependencies>

        <dependency>

            <groupId>com.test</groupId>

            <artifactId>dubbo-provider</artifactId>

            <version>1.0-SNAPSHOT</version>

        </dependency>

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>3.8.1</version>

            <scope>test</scope>

        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>dubbo</artifactId>

            <version>2.6.6</version>

        </dependency>

        <dependency>

            <groupId>org.apache.zookeeper</groupId>

            <artifactId>zookeeper</artifactId>

            <version>3.4.10</version>

        </dependency>

        <dependency>

            <groupId>com.101tec</groupId>

            <artifactId>zkclient</artifactId>

            <version>0.5</version>

        </dependency>

        <dependency>

            <groupId>io.netty</groupId>

            <artifactId>netty-all</artifactId>

            <version>4.1.32.Final</version>

        </dependency>

        <dependency>

            <groupId>org.apache.curator</groupId>

            <artifactId>curator-framework</artifactId>

            <version>2.8.0</version>

        </dependency>

        <dependency>

            <groupId>org.apache.curator</groupId>

            <artifactId>curator-recipes</artifactId>

            <version>2.8.0</version>

        </dependency>

    </dependencies>

</project>

调用服务

package com.dubbo.consumer;

 

import com.alibaba.dubbo.config.ApplicationConfig;

import com.alibaba.dubbo.config.ReferenceConfig;

import com.alibaba.dubbo.config.RegistryConfig;

import com.dubbo.provider.service.ProviderService;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

import java.io.IOException;

 

/**

 * xml的方式调用

 *

 */

public class App

{

    public static void main( String[] args ) throws IOException {

 

        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("consumer.xml");

        context.start();

        ProviderService providerService = (ProviderService) context.getBean("providerService");

        String str = providerService.SayHello("hello");

        System.out.println(str);

        System.in.read();

 

    }

}

3.4 加入zookeeper作为注册中心

在前面的操作中没有使用任何注册中心,用一种直连的方式进行。实际都是使用 dubbo + zookeeper 的方式,使用 zookeeper 作为注册中心,这里介绍 zookeeper 作为注册中心的使用方法。对前面的案例进行改造:

3.4.1 服务提供者修改

修改provider.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

 

    <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->

    <dubbo:application name="provider" owner="cp">

        <dubbo:parameter key="qos.enable" value="true"/>

        <dubbo:parameter key="qos.accept.foreign.ip" value="false"/>

        <dubbo:parameter key="qos.port" value="55555"/>

    </dubbo:application>

 

    <dubbo:monitor protocol="registry"/>

 

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->

    <!--<dubbo:registry address="N/A"/>-->

    <dubbo:registry address="zookeeper://localhost:2181" check="false"/>

 

    <!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http-->

    <dubbo:protocol name="dubbo" port="20880"/>

 

    <!--服务发布的配置,需要暴露的服务接口-->

    <dubbo:service

            interface="com.dubbo.provider.service.ProviderService"

            ref="providerService"/>

 

    <!--Bean bean定义-->

    <bean id="providerService" class="com.dubbo.provider.service.ProviderServiceImpl"/>

 

</beans>

3.4.2 服务消费者修改

修改 consumer.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

 

    <!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->

    <dubbo:application name="consumer" owner="cp"/>

 

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->

    <!--点对点的方式-->

    <!--<dubbo:registry address="N/A" />-->

    <dubbo:registry address="zookeeper://localhost:2181" check="false"/>

 

    <!--生成一个远程服务的调用代理-->

    <!--点对点方式-->

    <!--<dubbo:reference id="providerService"

                     interface="com.dubbo.provider.service.ProviderService"

                     url="dubbo://192.168.234.1:20880/com.dubbo.provider.service.ProviderService"/>-->

 

    <dubbo:reference id="providerService"

                     interface="com.dubbo.provider.service.ProviderService"/>

 

</beans>

总结:加入zookeeper和直接点对点方式的区别就是: dubbo 发布的 url 注册到了 zookeeper,消费端从 zookeeper 消费,zookeeper 相当于一个中介,给消费者提供服务。

3.5注解配置方式

前面使用xml文件配置方式,这里使用注解配置方式,现在微服务都倾向于这种方式,这也是以后发展的趋势, 0配置是以后的趋势。那么如何对 dubbo 使用注解的方式呢?

3.5.1 服务提供者注解配置

接口:

package com.dubbo.provider.service.annotation;

 

/**

 * 注解方式接口

 */

public interface ProviderServiceAnnotation {

    String SayHelloAnnotation(String word);

}

实现类

package com.dubbo.provider.service.annotation;

 

import com.alibaba.dubbo.config.annotation.Service;

 

/**

 * 注解方式实现类

 */

@Service(timeout = 5000)

public class ProviderServiceImplAnnotation implements ProviderServiceAnnotation{

 

    public String SayHelloAnnotation(String word) {

        return word;

    }

}

1@Service 用来配置 Dubbo 的服务提供方。

2、通过 Spring  Java Config 的技术(@Configuration)和 annotation 扫描(@EnableDubbo)来发现、组装、并向外提供 Dubbo 的服务。

package com.dubbo.provider.configuration;

 

import com.alibaba.dubbo.config.ApplicationConfig;

import com.alibaba.dubbo.config.ProtocolConfig;

import com.alibaba.dubbo.config.ProviderConfig;

import com.alibaba.dubbo.config.RegistryConfig;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

 

/**

 * 注解方式配置

 */

@Configuration

@EnableDubbo(scanBasePackages = "com.dubbo.provider.service.annotation")

public class DubboConfiguration {

 

    @Bean // #1 服务提供者信息配置

    public ProviderConfig providerConfig() {

        ProviderConfig providerConfig = new ProviderConfig();

        providerConfig.setTimeout(1000);

        return providerConfig;

    }

 

    @Bean // #2 分布式应用信息配置

    public ApplicationConfig applicationConfig() {

        ApplicationConfig applicationConfig = new ApplicationConfig();

        applicationConfig.setName("dubbo-annotation-provider");

        return applicationConfig;

    }

 

    @Bean // #3 注册中心信息配置

    public RegistryConfig registryConfig() {

        RegistryConfig registryConfig = new RegistryConfig();

        registryConfig.setProtocol("zookeeper");

        registryConfig.setAddress("localhost");

        registryConfig.setPort(2181);

        return registryConfig;

    }

 

    @Bean // #4 使用协议配置,这里使用 dubbo

    public ProtocolConfig protocolConfig() {

        ProtocolConfig protocolConfig = new ProtocolConfig();

        protocolConfig.setName("dubbo");

        protocolConfig.setPort(20880);

        return protocolConfig;

    }

}

 

分析:通过 @EnableDubbo 指定在com.dubbo.provider.service.annotation 下扫描所有标注有 @Service 的类。

通过 @Configuration 将 DubboConfiguration 中所有的 @Bean 通过 Java Config 的方式组装出来并注入给 Dubbo 服务,也就是标注有 @Service 的类。这其中就包括了:

ProviderConfig:服务提供方配置

ApplicationConfig:应用配置

RegistryConfig:注册中心配置

ProtocolConfig:协议配置

启动服务

package com.dubbo.provider;

 

import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;

import com.dubbo.provider.configuration.DubboConfiguration;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import sun.applet.Main;

 

import java.io.IOException;

 

/**

 * 注解启动方式

 */

public class AppAnnotation {

 

    public static void main(String[] args) throws IOException {

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DubboConfiguration.class);

        context.start();

        System.in.read();

    }

}

3.5.2 服务消费者注解配置

引用服务

package com.dubbo.consumer.Annotation;

 

import com.alibaba.dubbo.config.annotation.Reference;

import com.dubbo.provider.service.annotation.ProviderServiceAnnotation;

import org.springframework.stereotype.Component;

 

/**

 * 注解方式的service

 */

@Component("annotatedConsumer")

public class ConsumerAnnotationService {

 

    @Reference

    private ProviderServiceAnnotation providerServiceAnnotation;

 

    public String doSayHello(String name) {

        return providerServiceAnnotation.SayHelloAnnotation(name);

    }

}

引入依赖

<dependency>

          <groupId>com.test</groupId>

            <artifactId>dubbo-provider</artifactId>

            <version>1.0-SNAPSHOT</version>

        </dependency>

组装服务端消费者

package com.dubbo.consumer.configuration;

 

import com.alibaba.dubbo.config.ApplicationConfig;

import com.alibaba.dubbo.config.ConsumerConfig;

import com.alibaba.dubbo.config.RegistryConfig;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

 

import java.util.HashMap;

import java.util.Map;

 

/**

 * 注解配置类

 */

@Configuration

@EnableDubbo(scanBasePackages = "com.dubbo.consumer.Annotation")

@ComponentScan(value = {"com.dubbo.consumer.Annotation"})

public class ConsumerConfiguration {

    @Bean // 应用配置

    public ApplicationConfig applicationConfig() {

        ApplicationConfig applicationConfig = new ApplicationConfig();

        applicationConfig.setName("dubbo-annotation-consumer");

        Map<String, String> stringStringMap = new HashMap<String, String>();

        stringStringMap.put("qos.enable","true");

        stringStringMap.put("qos.accept.foreign.ip","false");

        stringStringMap.put("qos.port","33333");

        applicationConfig.setParameters(stringStringMap);

        return applicationConfig;

    }

 

    @Bean // 服务消费者配置

    public ConsumerConfig consumerConfig() {

        ConsumerConfig consumerConfig = new ConsumerConfig();

        consumerConfig.setTimeout(3000);

        return consumerConfig;

    }

 

    @Bean // 配置注册中心

    public RegistryConfig registryConfig() {

        RegistryConfig registryConfig = new RegistryConfig();

        registryConfig.setProtocol("zookeeper");

        registryConfig.setAddress("localhost");

        registryConfig.setPort(2181);

        return registryConfig;

    }

}

发起调用

package com.dubbo.consumer;

 

import com.dubbo.consumer.Annotation.ConsumerAnnotationService;

import com.dubbo.consumer.configuration.ConsumerConfiguration;

import com.dubbo.provider.service.ProviderService;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

import java.io.IOException;

 

/**

 * 注解方式启动

 *

 */

public class AppAnnotation

{

    public static void main( String[] args ) throws IOException {

 

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);

        context.start(); // 启动

        ConsumerAnnotationService consumerAnnotationService = context.getBean(ConsumerAnnotationService.class);

        String hello = consumerAnnotationService.doSayHello("annotation"); // 调用方法

        System.out.println("result: " + hello); // 输出结果

 

    }

}

3.6 主要使用场景:

3.6.1 启动时检查

Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 `check="true"

3.6.2 集群容错

集群模式

说明

使用方法

Failover Cluster

失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。

cluster="xxx" xxx:集群模式名称 ,例如cluster="failover"

Failfast Cluster

快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

 

Failsafe Cluster

失败安全,出现异常时,直接忽略。

 

Failback Cluster

失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

 

Forking Cluster

并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。

 

Broadcast Cluster

广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。

 

3.6.3 直连服务提供者

直连就是点对点方式,绕过注册中心。在开发及测试环境下,只测试指定服务提供者,只需要直接连接服务端的地即可,这种方式简单。

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

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

相关文章

前端学习(1734):前端系列javascript之添加动画

<template><view class"content"><!-- 状态栏 --><view v-if"list.length ! 0" class"todo-header"><!-- 状态栏的左侧 --><view class"todo-header__left"><text class"active-text&quo…

android146 360 病毒查杀

<?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:orientatio…

24 | 二叉树基础(下):有了如此高效的散列表,为什么还需要二叉树?

这节学习一种特殊的二叉树—二叉查找树。它最大的特点是支持动态数据集合的快速插入、删除、查找操作。但是散列表也是支持这些操作的&#xff0c;并且散列表的这些操作比二叉查找树更高效&#xff0c;时间复杂度是 O(1)。 问题引入 既然有高效的散列表&#xff0c;二叉树的地…

25 | 红黑树(上):为什么工程中都用红黑树这种二叉树?

问题引入 二叉查找树在频繁的动态更新过程中&#xff0c;可能会出现树的高度远大于 log2n 的情况&#xff0c;从而导致各个操作的效率下降。极端情况下&#xff0c;二叉树会退化为链表&#xff0c;时间复杂度会退化到 O(n)。要解决这个复杂度退化的问题&#xff0c;需要设计一…

Rabbitmq如何设置优先级队列?如何限流?如何重试?如何处理幂等性?

优先级队列 方式一&#xff1a;可以通过RabbitMQ管理界面配置队列的优先级属性&#xff0c;如下图的x-max-priority 方式二&#xff1a;代码设置 Map<String,Object> args new HashMap<String,Object>(); args.put("x-max-priority", 10); channel.que…

【Qt】Qt之进程间通信(Windows消息)【转】

简述 通过上一节的了解&#xff0c;我们可以看出进程通信的方式很多&#xff0c;今天分享下如何利用Windows消息机制来进行不同进程间的通信。 简述效果发送消息 自定义类型与接收窗体发送数据接收消息 设置标题重写nativeEvent效果 发送消息 自定义类型与接收窗体 包含所需库&…

启动nginx服务报错Job for nginx.service failed because the control process exited with error code.

nginx使用service nginx restart报错 启动nginx服务时如果遇到这个错误 Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details. 可能原因: 1、配…

27 | 递归树:如何借助树来求解递归算法的时间复杂度?

目的 借助递归树来分析递归算法的时间复杂度 递归树 递归的思想就是将大问题分解为小问题来求解&#xff0c;然后再将小问题分解为小小问题。这样一层一层地分解&#xff0c;直到问题的数据规模被分解得足够小&#xff0c;不用继续递归分解为止。 如果我们把这个一层一层的…

28 | 堆和堆排序:为什么说堆排序没有快速排序快?

如何理解“堆” 堆排序是一种原地的、时间复杂度为 O(nlogn) 的排序算法 堆的两个特点&#xff1a; 一颗完全二叉树堆中每个节点都必须大于等于&#xff08;或者小于等于&#xff09;其左右子节点的值&#xff1b; 对于每个节点的值都大于等于子树中每个节点值的堆&#xff…

29 | 堆的应用:如何快速获取到Top 10最热门的搜索关键词?

为什么评价算法性能是根据时间和空间复杂度&#xff0c;而不是别的参数&#xff1f;是因为计算机结构是冯诺依曼体系&#xff0c;除了输入输出设备和控制器&#xff0c;就剩下运算器和存储器了 问题引入 搜索引擎的热门搜索排行榜功能是如何实现的&#xff1f;搜索引擎每天会…

多线程——线程间的同步通信

1、概要 线程间的相互作用&#xff1a;线程之间需要一些协调通信&#xff0c;来共同完成一件任务。线程间的协调通信主要通过wait方法和notify方法来完成。因为wait和notify方法定义在Object类中&#xff0c;因此会被所有的类所继承。这些方法都是final的&#xff0c;即它们都是…