Dubbo服务方消费方通信案例

news2024/11/15 11:18:39

文章目录

    • Maven_服务方
    • Maven_服务消费方
    • 测试通信
    • 使用注册中心自动找服务
    • 设置超时时间
    • 重试次数
    • 单独设置某个方法不可重试
    • 处理多版本的问题
    • 本地存根策略
    • 负载均衡策略
    • Dubbo高可用
    • 服务降级
    • 服务降级实现方式

Maven_服务方

  1. pom文件,注意依赖的版本。

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <spring.version>5.0.6.RELEASE</spring.version>
    </properties>
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.11.0.GA</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven </groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8002</port>
                    <path>/</path>
                </configuration>
                <executions>
                    <execution>
                        <!-- 打包完成后,运行服务 -->
                        <phase>package</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    
  2. 服务方提供接口

    public interface HelloService {
        String sayHello(String name);
    }
    
  3. 服务方接口实现类 :一定要特别注意这个Service注解,这是dubbo的Service注解

    @com.alibaba.dubbo.config.annotation.Service
    public class HelloServiceImpl implements HelloService {
    	@Override
    	public String sayHello(String name) {
    		return "Hello," + name + "!!!";
    	}
    }
    
  4. 服务方的配置文件Spring.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">
        <!--1.服务提供方在zookeeper中的“别名”-->
        <dubbo:application name="dubbo-server"/>
        <!--2.注册中心的地址-->
        <dubbo:registry address="zookeeper://192.168.88.128:2181"/>
        <!--3.扫描类(将什么包下的类作为服务提供类)-->
        <dubbo:annotation package="service.impl"/>
    </beans>
    
  5. 服务方的web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
             id="WebApp_ID" version="3.1">
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/spring.xml</param-value>
        </context-param>
    </web-app>
    

Maven_服务消费方

  1. 消费方的pom文件和服务方的一致,但是需要修改tomcat的端口为8002

  2. 消费方的Controller

    @RestController
    public class HelloAction {
    	// 注意这个注解,这也是 dubbo提供的注解
        @com.alibaba.dubbo.config.annotation.Reference
        private HelloService helloService;
    
        @RequestMapping("hello")
        @ResponseBody
        public String hello(String name) {
            return helloService.sayHello(name);
        }
    }
    
  3. 消费方的接口:controller中要依赖HelloService,所以我们创建一个接口,但是消费方不需要实现这个接口,因为让服务方会提供这个接口的服务!

    public interface HelloService {
    	String sayHello(String name);
    }
    
  4. 消费方的web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
    		 http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
             id="WebApp_ID" version="3.1">
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring/spring.xml</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    

测试通信

  1. 先启动服务方,再启动消费方,访问http://localhost:8002/hello?name=james,注意看服务方提供的接口:

    @com.alibaba.dubbo.config.annotation.Service
    public class HelloServiceImpl implements HelloService {
    	@Override
    	public String sayHello(String name) {
    		return "Hello," + name + "!!!";
    	}
    }
    

使用注册中心自动找服务

  1. 分别修改dubbo-server和dubbo-consumer的spring.xml,

    <!-- 让监控 去注册中心 自动找服务 -->
    <dubbo:monitor protocol="registry"/>
    

设置超时时间

  1. 由于网络或服务端不可靠,会导致调用过程中出现不确定的阻塞状态(超时)

  2. 为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间

  3. 在服务提供方的spring中添加如下配置:

    <!--设置超时时间为2秒,默认为1-->
    <dubbo:provider timeout="2000"/>
    
  4. 模拟的网络延迟进行测试:

    @com.alibaba.dubbo.config.annotation.Service
    public class HelloServiceImpl implements HelloService {
    	@Override
    	public String sayHello(String name) {
    		try {
    			Thread.sleep(3000);
    		}catch (Exception e){
    			e.printStackTrace();
    		}
    		return "Hello," + name + "!!!";
    	}
    }
    
  5. 因为超时设置2秒,而模拟的网络延迟有3秒,超出时限,报错。

PS:配置原则:

  1. dubbo推荐在Provider上尽量多配置Consumer端属性:
  2. 作服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试次数,等等
  3. 在Provider配置后,Consumer不配置则会使用Provider的配置值,即Provider配置可以作消费者的缺省值。

重试次数

  1. 当出现失败,自动切换并重试其它服务器,dubbo重试的缺省值是2次,可以自行设置

  2. 在provider提供方配置:

    <!-- 消费方连接第1次不算,再来重试3次,总共重试4-->
    <dubbo:provider timeout="2000" retries="3"/>
    
    @com.alibaba.dubbo.config.annotation.Service
    public class HelloServiceImpl implements HelloService {
    	@Override
    	public String sayHello(String name) {
    	System.out.println("=============被调用 1 次===============");
    		try {
    			Thread.sleep(3000);
    		}catch (Exception e){
    			e.printStackTrace();
    		}
    		return "Hello," + name + "!!!";
    	}
    }
    
  3. 不是所有的方法都适合设置重试次数

    1. 幂等方法:适合(当参数一样,无论执行多少次,结果是一样的,例如:查询,修改)
    2. 非幂等方法:不适合(当参数一样,执行结果不一样,例如:删除,添加)

单独设置某个方法不可重试

  1. 提供方接口添加sayNo()方法并实现

    public interface HelloService {
    	String sayHello( String name );
    	String sayNo();
    }
    
    @com.alibaba.dubbo.config.annotation.Service
    public class HelloServiceImpl implements HelloService {
    	@Override
    	public String sayHello(String name) {
    	System.out.println("=============被调用 1 次===============");
    		try {
    			Thread.sleep(3000);
    		}catch (Exception e){
    			e.printStackTrace();
    		}
    		return "Hello," + name + "!!!";
    	}
    	public String sayNo() {
    		System.out.println("-------no被调用一次-------");
    		return "no!";
    	}
    }
    
  2. 消费方接口添加sayNo()方法声明

    public interface HelloService {
    	String sayHello( String name );
    	String sayNo();
    }
    
  3. 消费方controller

    @RestController
    public class HelloAction {
        @com.alibaba.dubbo.config.annotation.Reference
        private HelloService helloService;
    
        @RequestMapping("hello")
        @ResponseBody
        public String hello(String name) {
            return helloService.sayHello(name);
        }
    
        @GetMapping("no")
        @ResponseBody
        public String no() {
            return helloService.sayNo();
        }
    }
    
  4. 消费方配置方法重试次数

    <dubbo:reference interface="service.HelloService" id="helloService">
    	<dubbo:method name="sayHello" retries="3"/>
    	<dubbo:method name="sayNo" retries="0"/> <!-- 不重试 -->
    </dubbo:reference>
    

处理多版本的问题

  1. 一个接口,多个(版本的)实现类,可以使用定义版本的方式引入

  2. 为HelloService接口定义两个实现类,提供者修改配置:

    <dubbo:service interface="service.HelloService" class="service.impl.HelloServiceImpl01" version="1.0.0"/>
    <dubbo:service interface="service.HelloService" class="service.impl.HelloServiceImpl02" version="2.0.0"/>
    
  3. 消费者就可以根据version的版本,选择具体的服务版本

<dubbo:reference loadbalance="roundrobin"  interface="service.HelloService" id="helloService" version="2.0.0">
    <dubbo:method name="sayHello" retries="3"/>
    <dubbo:method name="sayNo" retries="0"/> <!-- 不重试 -->
</dubbo:reference>
  1. 当消费者的版本修改为 version="*",那么就会随机调用服务提供者的版本

本地存根策略

  1. 目前的通信案例所有的操作全都是 消费者发起,由服务提供者执行,这样会让提供者承担所有压力,一些功能消费者完全能够胜,把合法的参数再发送给提供者执行,效率高了,提供者也没那么累了,这就是本地存根

  2. 简单来讲,先在消费者处理一些业务逻辑,再调用提供者的过程,就是“本地存根”

  3. 本地存根”代码实现肯定在 消费者,创建一个HelloServiceStub类并且实现HelloService接口,并且必须使用构造方法的方式注入

    public class HelloServiceStub implements HelloService {
    	private HelloService helloService;
    	// 注入HelloService
    	public HelloServiceStub(HelloService helloService) {
    		this.helloService = helloService;
    	}
    	
    	public String sayHello(String name) {
    		System.out.println("本地存根数据验证。。。");
    		if(!StringUtils.isEmpty(name)){
    			return helloService.sayHello(name);
    		}
    			return "i am sorry!";
    		}
    		
    	public String sayNo() {
    		return helloService.sayNo();
    	}
    }
    
  4. 修改消费者配置:

    <dubbo:reference interface="service.HelloService" id="helloService"
    version="1.0.0" stub="service.impl.HelloServiceStub">
    	<dubbo:method name="sayHello" retries="3"/>
    	<dubbo:method name="sayNo" retries="0"/>
    </dubbo:reference>
    

负载均衡策略

  1. 负载均衡(Load Balance), 其实就是将请求分摊到多个操作单元上进行执行,从而共同完成工作任务。
  2. 简单的说,好多台服务器,不能总是让一台服务器干活,应该“雨露均沾”
  3. dubbo一共提供4种策略,缺省为 random 随机分配调用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以使用管理端修改权重

在这里插入图片描述

Dubbo高可用

  1. zookeeper注册中心宕机,还可以消费dubbo暴露的服务
    1. 监控中心宕掉不影响使用,只是丢失部分采样数据
    2. 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
    3. 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
    4. 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
    5. 服务提供者无状态,任意一台宕掉后,不影响使用
    6. 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

服务降级

  1. 服务降级,就是根据实际的情况和流量,对一些服务有策略的停止或换种简单的方式处理,从而释放服务器的资源来保证核心业务的正常运行

为什么要服务降级?

  1. 为什么要使用服务降级,这是防止分布式服务发生雪崩效应。
  2. 雪崩效应就是蝴蝶效应,当一个请求发生超时,一直等待着服务响应,那么在高并发情况下,很多请求都是因为这样一直等着响应,直到服务资源耗尽产生宕机,而宕机之后会导致分布式其他服务调用该宕机的服务也会出现资源耗尽宕机,这样下去将导致整个分布式服务都瘫痪,这就是雪崩。

服务降级实现方式

  1. 在 管理控制台配置服务降级:屏蔽和容错
  2. 屏蔽:mock=force:return+null 表示消费方对该服务的方法调用都 直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
  3. 容错:mock=fail:return+null 表示消费方对该服务的方法调用在 失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。在这里插入图片描述

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

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

相关文章

《无线电发射设备管理规定》解读

2022年12月22日&#xff0c;工业和信息化部公布了《无线电发射设备管理规定》&#xff08;工业和信息化部令第57号&#xff0c;以下简称《规定》&#xff09;。为了更好地理解和执行《规定》&#xff0c;工业和信息化部产业政策与法规司负责同志对《规定》进行了解读。 问题一 …

7.卷积神经网络

7.卷积神经网络 目录 从全连接层到卷积图像卷积 互相关运算&#xff08;手撕卷积&#xff09;卷积层图像中目标的边缘检测学习卷积核 填充和步幅 填充Padding步幅stride 多输入多输出通道 多输入通道多输出通道11 卷积层总结 池化层 最大池化层和平均池化层填充和步幅多个通道…

Matlab 与 Excel 文件的交互

事实上&#xff0c;excel可以解决绝大多数的建模问题&#xff0c;只不过&#xff0c;更加复杂。。。而且难以操作。。。其实可以看看excel的 功能还是很多的不过嘛 术业有专攻的 有专攻的多主体 NetLogo仿真 Comsol 。。。Excel 文件写入向量与张量的excel写入xlswrite(<pat…

JTAG 基础和svf specification介绍

参考&#xff1a; https://www.youtube.com/watch?vUuDf3q5aBjM https://zh.m.wikipedia.org/zh-cn/JTAG浅谈dft之boundary scan JTAG: Joint Test Action Group是开发IEEE 1149.1的工作组&#xff0c;1149.1定义了一个测试开发版上芯片的标准。现在变成了芯片的一个最常见…

yolov5增加iou loss,无痛涨点trick

yolo无痛涨点trick&#xff0c;简单实用 先贴一张最近一篇论文的结果 后来的几种iou的消融实验结果在一定程度上要优于CIoU&#xff0c;最新的WIoU暂时还没复现。 本文将在yolov5的基础上增加SIoU&#xff0c;EIoU&#xff0c;Focal-XIoU&#xff08;X为C,D,G,E,S等&#xff09…

使用Kindling 观测 Kubernetes 应用网络连接状态

kindling介绍&#xff1a; Kindling 解决的是&#xff0c;在不入侵应用的前提下&#xff0c;如何观测网络的问题&#xff0c;其功能主要是通过暴露内核事件来实现观测。如果主机内核版本高于 4.14&#xff0c;可以使用 eBPF 模块&#xff1b;如果主机内核是低版本&#xff0c;…

多级缓存实现

多级缓存实现1.什么是多级缓存2.JVM进程缓存2.1.导入案例2.2.初识Caffeine2.3.实现JVM进程缓存2.3.1.需求2.3.2.实现3.Lua语法入门3.1.初识Lua3.1.HelloWorld3.2.变量和循环3.2.1.Lua的数据类型3.2.2.声明变量3.2.3.循环3.3.条件控制、函数3.3.1.函数3.3.2.条件控制3.3.3.案例4…

俯卧撑计数 opencv-python + mediapipe

分享一个国外的趣味项目&#xff0c;可以计数&#xff0c;也可以完善进行动作是打分&#xff0c;确定标准程度 原文链接&#xff1a;https://aryanvij02.medium.com/push-ups-with-python-mediapipe-open-a544bd9b4351 程序原理介绍 在新加坡军队中&#xff0c;有一种测试叫做…

程序股票交易接口怎么撤单?

在程序股票交易接口的开发基础上&#xff0c;还能增加一个撤单的委托模块&#xff0c;因为程序股票交易接口的开发不单单是委托下单&#xff0c;那照样也能撤单&#xff0c;这两种的开发原理上&#xff0c;都不冲突&#xff0c;有的股票接口需要计算多种算法&#xff0c;算起来…

CNCAP2021法规adas功能场景

CNCAP2021法规adas功能场景概述功能介绍试验场景概述 C-NCAP是中国汽车技术研究中心于2006年3月2日正式发布的首版中国新车评价规程。中国新车评价规程每三年进行一次规程改版&#xff0c;最新的是2021版本。本文只针对cncap2021主动安全场景进行梳理。 功能介绍 1、AEB(Aut…

vue2低代码平台搭建(三)组件间交互的实现

前言 大家好,我是L丶Y,我们在上一篇文章中主要介绍了低代码平台的页面设计器相关的一些功能原理,打通了页面设计器顶部操作栏、左侧组件列表,中间画布、右侧属性配置四个部分的关系。能够实现组件列表的展示、组件到画布的拖动,属性配置修改对组件渲染效果影响,并说明了…

Picgo配置Bilibili图床

Picgo 配置Bilibili 图床 picgo-plugin-bilibili 为 PicGo 开发的一款插件&#xff0c;新增了B站图床 图床。 使用用户动态的图片上传API。填写SESSDATA即可&#xff0c;获取方式在下面。 文章目录Picgo 配置Bilibili 图床在线安装获取B站SESSDATA图片样式解决B站防盗链&#…

隐函数及参数方程求导——“高等数学”

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰的内容是隐函数求导和参数方程求导&#xff0c;下面&#xff0c;就让我们进入求导数的世界吧 一、隐函数的导数 二、隐函数求导 三、由参数方程确定的函数的导数 四、相关变化率 一、隐函数的导数 要想知道隐函数…

官宣:计算中间件 Apache Linkis 正式毕业成为 Apache 顶级项目

Apache 软件基金会&#xff08;ASF&#xff09;孵化器于2022年12月03日&#xff0c;通过了 Apache Linkis 计算中间件项目的孵化毕业投票。2023年01月18日&#xff0c;Apache 软件基金会官方宣布 Apache Linkis 顺利毕业&#xff0c;成为 Apache 顶级项目&#xff08;TLP&#…

泊松分布的计算方式

如果都要计算泊松分布了&#xff0c;那么就默认你知道泊松分布的基本知识了&#xff0c;我这里只介绍如何计算&#xff0c;我是用的Excel直接套用公式计算的&#xff0c;如果想在代码里用&#xff0c;我的实现方式是&#xff0c;先用Excel把值全部求出来&#xff0c;然后做成ma…

开组会写论文必备工具清单

来源&#xff1a;投稿 作者&#xff1a;卷舒 编辑&#xff1a;学姐 公式工具 https://www.latexlive.com/ snip这个工具也与之类似&#xff0c;但是需要安装&#xff0c;且有50个的限制。 这是一个LaTeX公式在线编辑器。提供了各类快捷符号及公式模板。在输入区域尝试LaTeX公…

创建SpringBoot工程

目录 一、官网创建 1、进入spring官网&#xff1a;Spring | Home 2、点击Spring Boot&#xff0c;滑倒最下面&#xff0c;点击Spring initializr 3&#xff0c;创建Spring Boot工程&#xff0c;版本选2.多的&#xff0c;高版本配置可能会出现问题&#xff0c;jdk选你电脑上装…

训练营day15

层序遍历 10 226.翻转二叉树 101.对称二叉树 2 102.二叉树的层序遍历 力扣题目链接 给你一个二叉树&#xff0c;请你返回其按 层序遍历 得到的节点值。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 接下来我们再来介绍二叉树的另一种遍历方式&#x…

Java面试题二-并发编程、IO、设计模式、通信/网络、JVM

本文目录如下&#xff1a;Java面试题(二)四、并发编程线程和进程的区别&#xff1f;守护线程是什么&#xff1f;创建线程有哪几种方式&#xff1f;线程有哪些状态&#xff1f;sleep() 和 wait() 有什么区别&#xff1f;线程的sleep()方法和yield()方法有什么区别&#xff1f;线…

KVM虚拟机安装Virtio驱动

KVM虚拟机安装Virtio驱动KVM服务器上配置Virtio驱动ISO文件Windows实例安装Virtio驱动Linux实例安装kvm驱动(一般不需要)KVM服务器上配置Virtio驱动ISO文件 参考&#xff1a;https://www.ibm.com/docs/zh/cloud-orchestrator/2.5.0.1?topicimages-installing-virtio-driver-k…