SpringCloud+Dubbo3 = 王炸 !

spring cloud alibaba-dubbo3 rpc运行原理 Dubbo3 相较于 Dubbo2,适配了现代微服务架构的需求,尤其是在协议、跨语言支持和服务治理方面做出了显著提升。通过引入。 阅读详情

前言

全链路异步化的大趋势来了

随着业务的发展,微服务应用的流量越来越大,使用到的资源也越来越多。

在微服务架构下,大量的应用都是 SpringCloud 分布式架构,这种架构总体上是全链路同步模式。

全链路同步模式不仅造成了资源的极大浪费,并且在流量发生激增波动的时候,受制于系统资源而无法快速的扩容。

全球后疫情时代,降本增效是大背景。如何降本增效?

可以通过技术升级,全链路同步模式 ,升级为 全链路异步模式。

先回顾一下全链路同步模式架构图

全链路同步模式 ,如何升级为 全链路异步模式, 就是一个一个 环节的异步化。

40岁老架构师,持续深化自己的3高架构知识宇宙,当然首先要去完成一次牛逼的全链路异步模式 微服务实操,下面是尼恩的实操过程、效果、压测数据(性能足足提升10倍多)。

全链路异步模式改造 具体的内容,请参考尼恩的深度文章:全链路异步,让你的 SpringCloud 性能优化10倍+

并且,上面的文章,作为尼恩 全链路异步的架构知识,收录在《尼恩Java面试宝典》V51版的架构专题中

注:本文以 PDF 持续更新,最新Java 架构笔记、面试题 的PDF文件,请后台私信【笔记】获取!

SpringCloud + Dubbo 完成 RPC 异步

高并发时代来了, 各大项目有越来越强烈的诉求,全链路异步, 是性能优化的一个杀手锏。

全链路异步核心环境,就是RPC的异步化。

使用Dubbo来替换Feign,足足可以提升10倍性能。

所以,SpringCloud + Dubbo RPC 的集成 是一个比较刚性的需求。

有小伙伴查招聘网站,发现很多需要有SpringCloud + Dubbo 的集成经验,刚好印证了这点。

接下来,尼恩一步一步带着大家,来做一下 SpringCloud + Dubbo RPC 的集成实验+性能测试。

见证一下奇迹: 使用Dubbo 提升10倍的性能。

Dubbo3应用的宏观架构

Dubbo3应用架构,如下图所示:

从上面的图中,整体的的Dubbo的Rpc框架中,核心的组件有:

  • config-center 配置中心,接下来使用 nacos
  • Consumer消费端, 业务服务,使用Dubbo SDK 完成服务发现
  • Provider服务提供端,业务服务,使用Dubbo SDK 完成服务注册
  • Registry注册中心 配置中心,接下来使用 nacos

Dubbo3 应用架构的核心组件

两大部分:

  • 一个Dubbo SDK
  • 三中心

Dubbo SDK

Dubbo SDK作为模块,被微服务所引入和依赖。跟随着微服务组件被部署在分布式集群各个位置,实现各个微服务组件间的协作,主要是服务的注册、服务的发现

三中心

Dubbo3包含一些中心化组件,主要有3个,这包括:

  • 注册中心协调Consumer消费者与Provider服务提供者之间的地址注册与发现。
  • 配置中心存储Dubbo启动阶段的全局配置,保证配置的跨环境共享与全局一致性负责服务治理规则(路由规则、动态配置等)的存储与推送。
  • 元数据中心接收Provider服务端上报的服务接口元数据,为Admin等控制台提供运维能力(如服务测试、接口文档等)作为服务发现机制的补充,提供额外的接口/方法级别配置信息的同步能力,相当于注册中心的额外扩展。

以上三个中心,由Nacos组件承担,

所以在下面的实操中,无论dubbo-Provider还是dubbo-consumer,配置文件中都是这么配置的:

dubbo:
  scan:
    base-packages: com.crazymaker.cloud.dubbo
  application:
    name:  ${spring.application.name}
  protocol:
    name: dubbo
    port: -1
  registry:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    parameters:
      namespace: dubbo
      group: DUBBO_GROUP
  config-center:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    group: DUBBO_GROUP
  metadata-report:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    group: DUBBO_GROUP
复制代码

SpringBoot整合Dubbo3.0基础准备

阿里早已把dubbo捐赠给了Apache,现在dubbo由Apache在维护更新,dubbo也已经成了Apache下的顶级项目。

SpringCloud+Nacos+Dubbo3.0

版本说明

  • SpringCloud:Hoxton.SR8
  • SpringCloudAlibaba:2.2.3.RELEASE
  • SpringBoot:2.3.4.RELEASE
  • Nacos:2.0.3
  • Dubbo:3.0.7

项目结构介绍

1、dubbo的依赖的坐标

Maven 依赖的坐标是Apache官方最新的3.0.4坐标。

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-bom</artifactId>
    <version>${dubbo.version}</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
复制代码

如果使用的老版本的Dubbo,比如下面的这些依赖, 现在需要去掉啦

<dependency>
    <groupId>com.alibaba.spring.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.0.0</version>
</dependency>

<dependency>
    <groupId>io.dubbo.springboot</groupId>
    <artifactId>spring-boot-starter-dubbo</artifactId>
    <version>1.0.0</version>
</dependency>
复制代码

2、 注册中心的依赖的坐标

老的项目采用zookeeper为注册中心,当然,咱们的电脑里的虚拟机,其实都已经安装好zookeeper服务器,并已经启动。

所以,如果要使用ZK,对于咱们技术自由圈(疯狂创客圈的新名字)的小伙伴来说,也是非常方便的。

但是SpringCloud项目上一般使用的注册中,不是appolo,不是eureka,而是nacos。

现在Dubbo也支持nacos, 所以我们使用Nacos作为注册中心

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-registry-nacos</artifactId>
    <version>${dubbo.version}</version>
    <exclusions>
        <exclusion>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
        </exclusion>
    </exclusions>

    <type>pom</type>
</dependency>
复制代码

这里有个版本兼容性的bug,尼恩稍微花了一点点时间,才解决这个问题。

具体的话,视频中给大家详细说一下。

SpringBoot整合Dubbo3.0大致步骤

  • SpringBoot 项目创建
  • Dubbo 服务提供方实现
  • Dubbo 服务消费方实现
  • 自定义Filter拦截所有消费请求
  • 自定义LoadBalance完成特殊场景负载均衡

模块结构

接下来演示下整合的模块结构,注意,是Springcloud 项目的老项目升级,

不是一个全新的项目,很多老的代码,要复用的

所以,就是在原来的crazy-SpringCloud 微服务项目上改造

但是这里仅仅演示 dubbo,所以,在原理的 脚手架里边,增加了两个子模块,

注意: 模块里边,并没有去掉原来的SpringCloud OpenFeign 的RPC调用, 而是两种RPC 调用共存。

方便后续在业务中快速运用,完整结构如下:

  1. consumer,服务消费方模块;
  2. provider,服务提供方模块;
  3. 统一定义服务接口和实体类,被其他工程模块引用;

consumer,服务消费方模块\ provider,服务提供方模块;如下图

统一定义服务接口和实体类,被其他工程模块引用; 所以,这个之前fegin 的RPC 接口,现在接着给Dubbo用。

Dubbo微服务注册发现的相关配置

  • 命名空间隔离
  • 微服务注册中心配置

命名空间隔离

在nacos 的命名空间, 用来做 dubbo 的命名空间隔离

首先创建nacos的命名空间

命名id 是要用到的, 这里需要填写,

主要,不要自动生产

微服务yml配置

微服务 yml 配置, yml配置 dubbo nacos 命名空间

dubbo:
  scan:
	base-packages: xxx
  protocol:
    name: dubbo
    port: -1
  # 注册中心配置
  registry:
    address: nacos://xxx
 	parameters:
   		namespace: dubbo
    group: DUBBO_GROUP

dubbo:
  application:
    name:  ${spring.application.name}
  protocol:
    name: dubbo
    port: -1
  registry:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    parameters:
      namespace: dubbo
      group: DUBBO_GROUP
  config-center:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    group: DUBBO_GROUP
  metadata-report:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    group: DUBBO_GROUP
复制代码

common-service 模块

服务接口 进行利旧 复用

还是之前的 UserClient 老接口,open fegn注解都不去掉

package com.crazymaker.springcloud.user.info.remote.client;

import com.crazymaker.springcloud.common.dto.UserDTO;
import com.crazymaker.springcloud.common.result.RestOut;
import com.crazymaker.springcloud.standard.config.FeignConfiguration;
import com.crazymaker.springcloud.user.info.remote.fallback.UserClientFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Feign 客户端接口
 * @description: 用户信息 远程调用接口
 * @date 2019年7月22日
 */

@FeignClient(value = "uaa-provider",
        configuration = FeignConfiguration.class,
//        fallback = UserClientFallback.class,
        fallbackFactory = UserClientFallbackFactory.class,
        path = "/uaa-provider/api/user")
public interface UserClient
{
      /**
     * 远程调用 RPC 方法:获取用户详细信息
     * @param userId 用户 Id
     * @return 用户详细信息
     */
    @RequestMapping(value = "/detail/v1", method = RequestMethod.GET)
    RestOut<UserDTO> detail(@RequestParam(value = "userId") Long userId);

    @RequestMapping(value = "/hello/v1", method = RequestMethod.GET)
    public String hello(@RequestParam(value = "name") String name);
}
复制代码

服务提供者实操:dubbo-provider 服务

pom依赖

<!-- dubbo -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-registry-nacos</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>nacos-client</artifactId>
            <groupId>com.alibaba.nacos</groupId>
        </exclusion>
    </exclusions>
</dependency>

<!-- dubbo starter -->

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>${nacos-client-verson}</version>
</dependency>
复制代码

服务实现类

package com.crazymaker.cloud.dubbo.demo.sevice;

import com.crazymaker.springcloud.common.dto.UserDTO;
import com.crazymaker.springcloud.common.result.RestOut;
import com.crazymaker.springcloud.user.info.remote.client.UserClient;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Component;

@DubboService
@Component

public class UserClientDubboService implements UserClient {
    @Override
    public RestOut<UserDTO> detail(Long userId) {
        UserDTO dto=new UserDTO();
        dto.setUserId(userId);
        dto.setNickname(" dubbo rpc test");
        return RestOut.success(dto).setRespMsg("操作成功");
    }

    @Override
    public String hello(String name) {
        return "from dubbo provider : 你好,"+name;
    }
}
复制代码

dubbo和Feign的一个不同

  • dubbo的服务发布和暴露,直接在 service 层加上注解 ,就完成了

比如:上面的案例中,加上一个类级别的 注解,就可以 暴露这个服务接口 @DubboService

  • 而 Feign 的服务接口发布,是在 @Controller 层完成的。

相对来说,比 使用 Dubbo 更为笨重

Provider的Dubbo+Nacos配置文件

spring:
  security:
    enabled: false
  application:
    name: dubbo-provider-demo


server:
  port: 28088
  servlet:
    context-path: /dubbo-provider-demo

#### 暴露端点
management:
  endpoints:
    web:
      base-path: "/actuator"  # 配置 Endpoint 的基础路径
      exposure:
        include: '*'  #在yaml 文件属于关键字,所以需要加引号
  endpoint:
    logfile:
      # spring boot admin  client不配置日志文件路径(同时配置logback-spring.xml对应的日志输出配置,否则无法输出日志),
      # 控制台上的Logging模块下的Logfile会报错:Fetching logfile failed.Request failed with status code 404
      external-file: ${log_dubbo_provider_demo_path_full:C:/logs/dubbo-provider-demo/logs/output.log}
      enabled: true
    health:
      show-details: always
    # 未配置/注释 以下内容
#  boot:
#    admin:
#      context-path: consumer
  metrics:
    tags:
      application:  ${spring.application.name}
    export:
      prometheus:
        enabled: true
        step: 1m
        descriptions: true

dubbo:
  scan:
    base-packages: com.crazymaker.cloud.dubbo
  application:
    name:  ${spring.application.name}
  protocol:
    name: dubbo
    port: -1
  registry:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    parameters:
      namespace: dubbo
      group: DUBBO_GROUP
  config-center:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    group: DUBBO_GROUP
  metadata-report:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    group: DUBBO_GROUP
复制代码

启动类 加上@EnableDubbo 注解

package com.crazymaker.cloud.dubbo.demo.starter;

import com.crazymaker.springcloud.common.util.IpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.net.Inet4Address;
import java.util.Optional;

@EnableSwagger2
@EnableDiscoveryClient
@Slf4j
@EnableDubbo

@SpringBootApplication(scanBasePackages =
        {
                "com.crazymaker.cloud.dubbo.demo",
        }
)


public class DubboProviderApplication {
    public static void main(String[] args) {
        try {
            ConfigurableApplicationContext applicationContext = SpringApplication.run(DubboProviderApplication.class, args);

            Environment env = applicationContext.getEnvironment();
            String port = env.getProperty("server.port");
            String name = env.getProperty("spring.application.name");

            String path = env.getProperty("server.servlet.context-path");
            if (StringUtils.isBlank(path)) {
                path = "";
            }
            Optional<Inet4Address> ip = IpUtil.getLocalIp4Address();

          log.info("\n----------------------------------------------------------\n\t" +
                    name.toUpperCase() + " is running! Access URLs:\n\t" +
                    "Local: \t\thttp://" + ip.get() + ":" + port + path + "/\n\t" +
                    "swagger-ui: \thttp://" + ip.get() + ":" + port + path + "/swagger-ui.html\n\t" +
                    "actuator: \thttp://" + ip.get() + ":" + port + path + "/actuator/info\n\t" +
                    "----------------------------------------------------------");

        } catch (Exception e) {
            log.error("服务启动报错", e);

        }
    }
}
复制代码

启动、体验Provider

打包之后,在 咱们优雅的虚拟机centos8中,优雅的启动一下,

来一个优雅的启动命令

[root@centos1 work]# cd dubbo-provider-demo-1.0-SNAPSHOT/bin/
[root@centos1 bin]# sh ./deploy.sh start
PORT:28088
JVM:-server -Xms512m -Xmx2048m
nohup java -server -Xms512m -Xmx2048m -Dserver.port=28088   -jar /work/dubbo-provider-demo-1.0-SNAPSHOT/lib/dubbo-provider-demo-1.0-SNAPSHOT.jar com.crazymaker.cloud.dubbo.demo.starter.DubboProviderApplication  &
 log file : /work/logs/dubbo-provider-demo-1.0-SNAPSHOT/output.log
复制代码

太爽................. 有个vagrant+Centos 开发环境, 开发Java应用,爽到不要不要的

关键是: 在这个虚拟机 box 文件中,尼恩给大家预装了K8S 云原生环境,大家一键导入省了N多麻烦。基于这个环境, 下一步咱们就开始 “左手大数据、右手云原生” 的高端实操

继续看,屏幕的下面,下面还有swagger体验地址

使用这个地址,可以在浏览器开起Swagger -UI 的界面

http:///cdh1:28088/dubbo-provider-demo/swagger-ui.html

开启之后的效果,但是,这个和dubbo没有关系

因为dubbo的服务并没有在swagger ui 展示

在Nacos查看Dubbo服务的注册情况

通过nacos,可以看到 dubbo的服务啦

具体的细节,咱们后面讲dubbo视频的时候,再说

这里先把性能优化起来

服务消费者实操:dubbo-consumer 服务

consumer模块

消费者实现类

package com.crazymaker.cloud.dubbo.demo.consumer.controller;

import com.crazymaker.springcloud.common.dto.UserDTO;
import com.crazymaker.springcloud.common.result.RestOut;
import com.crazymaker.springcloud.user.info.remote.client.UserClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
@Api(tags = "Dubbo-RPC  完成远程调用")
public class UserConsumerController {


    //注入  @DubboReference 注解配置 所配置的 EchoClient 客户端Feign实例
     @DubboReference(loadbalance = "groupLoadBalance")
    private UserClient userService;

    //用户详情
    @ApiOperation(value = "用户详情接口")
    @RequestMapping(value = "/detail/v1", method = RequestMethod.GET)
    RestOut<UserDTO> detail(@RequestParam(value = "userId", required = true)Long userId) {
        RestOut<UserDTO> ret = userService.detail(userId);
        return ret;
    }
}
复制代码

消费者Dubbo+Nacos配置文件

spring:
  security:
    enabled: false
  application:
    name: dubbo-consumer-demo
#http://cdh1:18081/dubbo-consumer-demo/swagger-ui.html

server:
  port: 18081
  servlet:
    context-path: /dubbo-consumer-demo

#### 暴露端点
management:
  endpoints:
    web:
      base-path: "/actuator"  # 配置 Endpoint 的基础路径
      exposure:
        include: '*'  #在yaml 文件属于关键字,所以需要加引号
  endpoint:
    health:
      show-details: always
  metrics:
    tags:
      application: ${spring.application.name}
#  boot:
#    admin:
#      context-path: consumer

dubbo:
  scan:
    base-packages: com.crazymaker.cloud.dubbo
  application:
    name:  ${spring.application.name}
  protocol:
    name: dubbo
    port: -1
  registry:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    parameters:
      namespace: dubbo
      group: DUBBO_GROUP
  config-center:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    group: DUBBO_GROUP
  metadata-report:
    address: nacos://${NACOS_SERVER:cdh1:8848}
    username: nacos
    password: nacos
    group: DUBBO_GROUP
复制代码

启动类 加上@EnableDubbo 注解

package com.crazymaker.cloud.dubbo.demo.consumer.starter;

import com.crazymaker.springcloud.common.util.IpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.net.Inet4Address;
import java.util.Optional;

@EnableSwagger2
@EnableDiscoveryClient
@Slf4j
@EnableDubbo

@SpringBootApplication(
        scanBasePackages =
                {
                        "com.crazymaker.cloud.dubbo.demo",
                        "com.crazymaker.springcloud.standard"
                },
        exclude = {SecurityAutoConfiguration.class,
                //排除db的自动配置
                DataSourceAutoConfiguration.class,
                DataSourceTransactionManagerAutoConfiguration.class,
                HibernateJpaAutoConfiguration.class,
                SecurityAutoConfiguration.class,
                ManagementWebSecurityAutoConfiguration.class,
                //排除redis的自动配置
                RedisAutoConfiguration.class,
                RedisRepositoriesAutoConfiguration.class})
//启动Feign
@EnableFeignClients(basePackages =
        {"com.crazymaker.cloud.dubbo.demo.consumer.client"})
public class DubboConsumerApplication {

    public static void main(String[] args) {
        try {
            ConfigurableApplicationContext applicationContext = SpringApplication.run(DubboConsumerApplication.class, args);

            Environment env = applicationContext.getEnvironment();
            String port = env.getProperty("server.port");
            String name = env.getProperty("spring.application.name");

            String path = env.getProperty("server.servlet.context-path");
            if (StringUtils.isBlank(path)) {
                path = "";
            }
            Optional<Inet4Address> ip = IpUtil.getLocalIp4Address();

            log.info("\n----------------------------------------------------------\n\t" +
                    name.toUpperCase() + " is running! Access URLs:\n\t" +
                    "Local: \t\thttp://" + ip.get() + ":" + port + path + "/\n\t" +
                    "swagger-ui: \thttp://" + ip.get() + ":" + port + path + "/swagger-ui.html\n\t" +
                    "actuator: \thttp://" + ip.get() + ":" + port + path + "/actuator/info\n\t" +
                    "----------------------------------------------------------");

        } catch (Exception e) {
            log.error("服务启动报错", e);

        }
    }
}
复制代码

启动、体验 Consumer

打包之后,在 咱们优雅的虚拟机 centos8 中,优雅的启动一下,

来一个优雅的启动命令

[root@centos1 bin]# cd ../../dubbo-consumer-demo-1.0-SNAPSHOT/bin/
[root@centos1 bin]# sh ./deploy.sh start
PORT:18081
JVM:-server -Xms512m -Xmx2048m
nohup java -server -Xms512m -Xmx2048m -Dserver.port=18081   -jar /work/dubbo-consumer-demo-1.0-SNAPSHOT/lib/dubbo-consumer-demo-1.0-SNAPSHOT.jar com.crazymaker.cloud.dubbo.demo.consumer.starter.DubboConsumerApplication  &
nohup: appending output to 'nohup.out'
复制代码

太爽................. 有个vagrant+Centos 开发环境, 开发Java应用,爽到不要不要的

关键是: 在这个虚拟机 box 文件中,尼恩给大家预装了K8S 云原生环境,大家一键导入省了N多麻烦。

下一步,基于这个环境, 咱们就开始 “左手大数据、右手云原生” 的高端实操

继续看,屏幕的下面,下面还有swagger体验地址

使用这个地址,可以在浏览器开起Swagger -UI 的界面

http:///10.0.2.15:18081/dubbo-consumer-demo/swagger-ui.html

注意,要修改一下 host,修改之后为

http://cdh1:18081/dubbo-consumer-demo/swagger-ui.html

Feign 和Dubbo 两大RPC调用 并存的效果,如下:

在Nacos查看Dubbo服务的注册情况

通过nacos,可以看到 dubbo的服务的消费者啦

具体的细节,咱们后面讲dubbo视频的时候,再说

这里先把性能优化起来

性能的对比测试

然后进行了性能的对比验证

dubbo 的压测数据

wrk -t8 -c200 -d30s --latency  http://cdh1:18081/dubbo-consumer-demo/user/detail/v1?userId=1

[root@centos1 src]# wrk -t8 -c200 -d30s --latency  http://cdh1:18081/dubbo-consumer-demo/user/detail/v1?userId=1
Running 30s test @ http://cdh1:18081/dubbo-consumer-demo/user/detail/v1?userId=1
  8 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    30.10ms   45.68ms 644.45ms   95.43%
    Req/Sec     1.12k   465.63     2.36k    66.87%
  Latency Distribution
     50%   18.94ms
     75%   28.43ms
     90%   46.21ms
     99%  283.56ms
  264316 requests in 30.07s, 148.47MB read
Requests/sec:   8788.96
Transfer/sec:      4.94MB
复制代码

feign 的压测数据

wrk -t8 -c200 -d30s --latency  http://cdh1:18081/dubbo-consumer-demo/echo/variable/11

[root@centos1 src]# wrk -t8 -c200 -d30s --latency  http://cdh1:18081/dubbo-consumer-demo/echo/variable/11
Running 30s test @ http://cdh1:18081/dubbo-consumer-demo/echo/variable/11
  8 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   321.50ms  294.59ms   2.00s    61.77%
    Req/Sec    87.18     43.39   232.00     67.00%
  Latency Distribution
     50%  309.06ms
     75%  503.06ms
     90%  687.99ms
     99%    1.21s
  20495 requests in 30.10s, 7.64MB read
  Socket errors: connect 0, read 0, write 0, timeout 49
Requests/sec:    680.90
Transfer/sec:    259.99KB
复制代码

从数据来看, dubbo rpc 是feign rpc 性能10倍

Dubbo比Feign高10倍以上的本质

Dubbo比Feign高10倍以上的本质,不是在于应用层的协议,和传输格式

面试的时候,太多的小伙伴被问到: Dubbo比Feign性能高,说说原因。

小伙伴首先回答的是:

Dubbo 是TCP 层的传输协议,Feign是应用层 的HTTP传输协议,所以性能低。

这个答案不是本质原因,HTTP是有些冗余的头部报文,但是不至于差10倍。能差0.5倍,就已经顶天了。

差10倍的原因:是 同步链路 与异步链路 的 区别。

或者说:Dubbo比Feign高10倍以上的本质,是RPC 调用异步化

RPC 调用主要的框架有:

特点是:

  • feign 是同步IO 、阻塞模式的同步 RPC框架
  • dubbo 是基于Netty的非阻塞IO + Reactor 反应堆线程模型的 异步RPC框架

异步RPC 调用,等待upstream 上游 response 返回时,线程不处于block 状态

作为微服务架构中数据流量最大的一部分,RPC 调用异步化的收益巨大;

dubbo 的异步RPC,仅仅 SpringCloud 微服务全链路 异步的一个环节, SpringCloud 全链路 异步有5个以上的环节。

有关 微服务全链路 异步高性能改造,请参考尼恩的深度文章:

全链路异步,让你的 SpringCloud 性能优化10倍+

高并发、云原生、大数据时代,很多组件都是 全异步的、响应式的。

大家一定要掌握全链路异步的底层原理,掌握好 响应式编程的底层原理和实操,为 “左手大数据、右手云原生” 做好技术准备。

Dubbo 与 SpringCloud 的通信 Openfeign的区别

1、协议支持方面

  • Feign更加优雅简单。
  • Feign是通过REST API实现的远程调用,基于Http传输协议,服务提供者需要对外暴露Http接口供消费者调用,服务粒度是http接口级的。
  • 很多文章说:通过短连接的方式进行通信,不适合高并发的访问。
  • 尼恩纠错: Feign 并不是短链接,而是长连接
  • Dubbo方式更灵活。
  • Dubbo是通过RPC调用实现的远程调用,支持多传输协议(Dubbo、Rmi、http、redis等等),可以根据业务场景选择最佳的方式,非常灵活。
  • 默认的Dubbo协议:利用Netty,TCP传输,单一、异步、长连接,适合数据量小、高并发和服务提供者远远少于消费者的场景。Dubbo通过TCP长连接的方式进行通信,服务粒度是方法级的。

2、通信性能方面

  • Feign基于Http传输协议,底层实现是rest。在高并发场景下性能不够理想。
  • Dubbo框架的通信协议采用RPC协议,属于传输层协议,提升了交互的性能,保持了长连接,高性能。

3、线程模型方面

  • Feign使用的是阻塞式的线程模型, 在请求和响应直之间, IO线程是阻塞的,死等到超时。
  • Dubbo使用的是异步非阻塞式的线程模型(Netty的Reactor反应器), 在请求和响应直之间, IO线程是非阻塞的,有限的线程,可以处理大量的请求。

这点是性能的核心。

SpringCloud + Dubbo RPC 的集成的价值

高并发时代来了, 各大项目有越来越强烈的诉求,全链路异步, 是性能优化的一个杀手锏。

使用Dubbo来替换Feign,足足可以提升10倍性能。

所以,SpringCloud + Dubbo RPC 的集成 是一个比较刚性的需求。

有小伙伴查招聘网站,发现很多需要有SpringCloud + Dubbo 的集成经验,刚好印证了这点。

强烈建议大家,做一下 SpringCloud + Dubbo RPC 的集成,在同一个微服务下,同时使用了Feign + Dubbo。

提示:很多小伙伴来找我改简历,但是发现一点漂亮的技术亮点都没有,如果确实找不到亮点,可以把这个实操做一下,写入简历,作为亮点。如果确实不清楚怎么写入简历,可以来找尼恩进行简历指导。保证 脱胎换骨、金光闪闪、天衣无缝。

SpringCloudAlibaba基础实战(Dubbo+Nacos 服务注册与发现篇) 微服务服务注册与发现简单实战 阅读详情

相关推荐

SpringCloud微服务集成Dubbo

Apache Dubbo 是一款易用、高性能的 WEB 和 RPC 框架,同时为构建企业级微服务提供服务发现、流量治理、可观测、认证鉴权等能力、工具与最佳实践。用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力, 利用 Dubbo 提供的丰富服务治理特性,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。

xdpcxq的专栏 1191

Dubbo(一):Dubbo 3.0

在服务注册领域,市面上有两种模型,一种是应用级注册(),一种是接口级注册,在Spring Cloud中,一个应用是一个微服务,而在Dubbo2.7中,一个接口是一个微服务。Spring Cloud在进行服务注册时,是把应用名以及应用所在服务器的IP地址和应用所绑定的端口注册到注册中心,相当于key是应用名,value是ip+port,Dubbo2.7中,是把接口名以及对应应用的IP地址和所绑定的端口注册到注册中心,相当于key是接口名,value是ip+port。.........

Men-DD 3095

springCloud之Dubbo

将Dubbo集成至SpringCloud主要是替换Ribbo或者Feign实现远程调用。

weixin_43956070的博客 956

SpringCloud与Dubbo的比较

SpringCloud与Dubbo的比较及异同点

程序大视界 11万+

【微服务】springcloud整合dubbo3使用nacos作为注册中心

springcloud整合dubbo3使用nacos作为注册中心

congge 3331

STM32+EC800M-CN 4G模块数据透传踩坑实录:从AT指令调试到花生壳内网穿透

本文详细介绍了STM32与移远EC800M-CN 4G模块的数据透传实现过程,包括硬件连接、AT指令调试、TCP连接建立以及花生壳内网穿透配置。通过实战案例和代码示例,帮助开发者快速解决4G通信模块在物联网应用中的常见问题,提升数据传输稳定性。

weixin_42715608的博客 320

SpringCloud 整合 Dubbo

Dubbo有两种使用方式: 1、基于SOA的思想,将一个单体架构拆分为web层和Services层,然后web和services借助Dubbo框架进行数据交互。 2、SpringCloud 整合Dubbo。

一切总会归于平淡 9053

【AI智能体】图像处理-生成营销 Banner 图

生成营销 Banner 图是一款用于制作营销图片的智能体,它可以根据指定的营销活动内容,快速生成活动 Banner 图片,降低活动运营成本、提高制图效率。

AI创变工坊,和1000万新个体创业者一起成长!愿大家都能跟上时代的洪流,不被社会淘汰,愿大家的生活工作收入都能具备竞争力! 1175

SpringCloud 与 Dubbo 的区别详解

SpringCloud 是一个用于构建云原生应用的框架集合,它为开发者提供了一套完整的工具链,用于快速搭建分布式系统。SpringCloud 基于SpringBoot提供了丰富的组件,如配置管理、服务注册与发现、断路器等采用声明式的编程模型,易于上手与 SpringBoot 无缝集成,开箱即用适用于各种部署环境,如本地、云端等Dubbo是阿里巴巴开源的一个高性能、轻量级的 RPC 框架。它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

py0007的博客 3821

【大模型】SpringBoot整合LangChain4j实现RAG检索实战详解

SpringBoot整合LangChain4j实现RAG检索实战详解

congge 1万+

14 硬件工程师笔面试高频考点真题解析——逻辑门

逻辑门是数字电路的基本单元,实现布尔运算(如与、或、非、异或等)。OC门(集电极开路)和OD门(漏极开路)需外接上拉电阻,支持“线与”逻辑,适用于I2C总线等场景,避免推挽输出并联导致的短路问题。三态门具有高、低、高阻三种状态,用于总线分时复用。推挽输出因内置上下管,禁止并联,否则会引发电源短路。三者区别在于:推挽驱动强但不可并联;OC/OD需上拉,支持线与;三态门通过使能控制实现高阻隔离,适用于共享总线设计。

XU157303764的博客 1901

面试Dubbo ,却问我和Springcloud有什么区别?

提到Dubbo,很多人都并不陌生,也是这些年来的热点面试内容。笔者也有很深的印象,在n年前的一场面试中,面试官问了一个问题:请至少说出Dubbo的六个包名,笔者当时虽然看过部分源码,但从未关注过包名,内心五味杂陈,当场就懵了。当然了,除开这种角度奇怪的提问,Dubbo也有一些看起来比较"正常"的面试题,比如著名的:Dubbo 和 Springcloud 有什么区别?

战斧的博客 7922

移动机器人路径规划中噪声环境下的鲁棒性测试仿真

设计一个二维或三维环境模型,包括静态障碍物和可能存在的动态障碍物。

amy_mhd的博客 125

spring boot、SpringCloud、Dubbo

什么是SpringCloud? 什么是SpringBoot? 以及两者关系? springboot和Dubbo的区别? 微服务框架如何进行选型? SpringCloud核心组件架构?

qq_41889508的博客 1万+

国网DLT698.45协议——采集系统、数据交换(三)

物理层规定了通信单元或其他终端设备与多功能电表的通信接口,接口的物理与电气特性。常见的物理层传输方式有对于RS485、红外、载波通信等通信信道。将数据包装成可传输的帧格式。1、根据通信配置参数完成端口的初始化配置,通信状态初始化为准备接收状态,初始化相关计数器及缓冲区指针。2、链路层及控制子模块负责通信数据的收发控制,各类超时问题的处理。无通信数据接收时,定时初始化通信端口。3、完成协议帧的解析及应答。

一个bug是bug,多个bug能work 8050

Onnxruntime之YOLOP部署过程记录

魔改YoloP部署过程记录

如果想成为中心,那么就到中心去吧。 1924

SpringCloud之Dubbo

Apache Dubbo 是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。由于dubbo是针对二进制处理,所以效率最高。

m0_56512023的博客 1165

猫群优化算法(CSO)详解:从生物灵感到智能优化

猫群优化算法(CSO)是一种模拟猫科动物行为的群体智能优化算法。该算法基于猫的两种主要行为模式:搜寻状态(全局探索)和跟踪状态(局部开发)。CSO通过混合率(MR)动态调整两种模式的比例,实现探索与开发的平衡。算法核心包括搜寻模式的变异操作和跟踪模式的速度-位移模型,具有收敛性能好、全局搜索能力强等特点。相比传统优化算法,CSO在高维复杂问题中表现优异,已成功应用于函数优化、图像处理等多个领域。算法性能受混合率、变化域等参数影响,自适应参数策略可进一步提升优化效果。

qq_42212808的博客 617

SpringCloud与Dubbo的区别

1.SpringCloud与Dubbo的区别 两者都是现在主流的微服务框架,但却存在不少差异: 初始定位不同:SpringCloud定位为微服务架构下的一站式解决方案;Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用和治理 生态环境不同:SpringCloud依托于Spring平台,具备更加完善的生态体系;而Dubbo一开始只是做RPC远程调用,生态相对匮乏,现在逐渐丰富起来。 调用方式:SpringCloud是采用Http协议做远程调用,接口一般是Rest...

年少青山的博客 4041

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

SpringCloud 与 Dubbo的区别

SpringCloud和Dubbo都是现在主流的微服务架构从技术维度上,其实SpringCloud远远的超过Dubbo,Dubbo本身只是实现了服务治理,而SpringCloud现在以及有21个子项目,以后还会更多,所以其实很多人都会说Dubbo和SpringCloud是不公平的,但是由于RPC以及注册中心元数据等原因,在技术选型的时候我们只能二者选其一,所以我们常常为用他俩来对比服务的调用方式,而。

2401_87878486的博客 3005

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

上一篇: 第七篇|Flink Table API&SQL编程指南之时间属性(3)
下一篇: 当面试官问我ArrayList和LinkedList哪个更占空间时,我这么答让他眼前一亮
wrr-cat
博客等级 码龄9年 128粉丝 302原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值