0
点赞
收藏
分享

微信扫一扫

dubbo学习笔记

王老师说 2022-04-14 阅读 33
dubborpc

尚硅谷DUBBO笔记


学习链接:https://www.bilibili.com/video/BV1ns411c7jV?spm_id_from=333.337.search-card.all.click

一、MAVEN工程

公共接口 gmall-interface

接口包含bean对象,service接口

例如

Provider

包含接口的实现类,不包含接口,接口写在公共API中

接口和Bean对象的引入在pom.xml中引入实现

<dependency>
    <groupId>com.atguigu.gmall</groupId>
    <artifactId>gmall-interface</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

引入dubbo依赖

<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.6.2</version>
</dependency>

编写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">

    <!--    1.指定当前服务/应用的名字(同样的服务名字相同,不要和别的服务器同名 -->
    <dubbo:application name="userserviceprovider"></dubbo:application>

    <!--    2/指定注册中心的位置-->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry>
    <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>

    <!--    3.指定通信规则(通信协议和通信端口)-->
    <dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>

    <!--    4.暴露服务 ref:指向服务的真正的实现对象-->
    <dubbo:service interface="com.atguigu.gmall.service.UserService"
                   ref="userServiceImpl"></dubbo:service>

    <bean id="userServiceImpl" class="com.atguigu.gmall.service.impl.UserServiceImpl"></bean>
</beans>

实现类无需做改动,正常完成

public class UserServiceImpl implements UserService {

    public List<UserAddress> getUserAddressList(String userId) {
        System.out.println("UserServiceImpl.....old...");
        // TODO Auto-generated method stub
        UserAddress address1 = new UserAddress(1, "北京市昌平区宏福科技园综合楼3层", "1", "李老师", "010-56253825", "Y");
        UserAddress address2 = new UserAddress(2, "深圳市宝安区西部硅谷大厦B座3层(深圳分校)", "1", "王老师", "010-56253825", "N");
        /*try {
			Thread.sleep(4000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
        return Arrays.asList(address1,address2);
    }

}

Consumer

包含接口的实现类,不包含接口,接口写在公共的API中

接口和Bean对象的引入在pom.xml中引入实现

<dependency>
    <groupId>com.atguigu.gmall</groupId>
    <artifactId>gmall-interface</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.6.2</version>
</dependency>

编写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"
       xmlns:context="http://www.springframework.org/schema/context"
       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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--    扫描包注解-->
    <context:component-scan base-package="com.atguigu.gmall.service.impl"></context:component-scan>

    <dubbo:application name="userserviceprovider"></dubbo:application>

    <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry>

    <!--    声明需要调用的远程服务的接口:生成远程服务代理-->
    <dubbo:reference interface="com.atguigu.gmall.service.UserService"
                     id="userService" check="false">
    </dubbo:reference>
</beans>

实现类

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    UserService userService;

    public List<UserAddress> initOrder(String userId) {
        System.out.println("用户id,"+userId);
        //    1、查询用户的收货地址
        List<UserAddress> addressList = userService.getUserAddressList(userId);
        return  addressList;
    }
}

二、SPRINBG-BOOT工程

github网址:https://github.com/apache/dubbo-spring-boot-project

依赖位置

公共接口

UserAddress

public class UserAddress implements Serializable {

    private Integer id;
    private String userAddress; //用户地址
    private String userId; //用户id
    private String consignee; //收货人
    private String phoneNum; //电话号码
    private String isDefault; //是否为默认地址    Y-是     N-否

    public UserAddress() {
        super();
        // TODO Auto-generated constructor stub
    }

    public UserAddress(Integer id, String userAddress, String userId, String consignee, String phoneNum,
                       String isDefault) {
        super();
        this.id = id;
        this.userAddress = userAddress;
        this.userId = userId;
        this.consignee = consignee;
        this.phoneNum = phoneNum;
        this.isDefault = isDefault;
    }

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUserAddress() {
        return userAddress;
    }
    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public String getConsignee() {
        return consignee;
    }
    public void setConsignee(String consignee) {
        this.consignee = consignee;
    }
    public String getPhoneNum() {
        return phoneNum;
    }
    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }
    public String getIsDefault() {
        return isDefault;
    }
    public void setIsDefault(String isDefault) {
        this.isDefault = isDefault;
    }

}

OrderService

public interface OrderService {

    public List<UserAddress> initOrder(String userId);
}

UserService

public interface UserService {
    /**
	 * 按照用户id返回所有的收货地址
	 * @param userId
	 * @return
	 */
    public List<UserAddress> getUserAddressList(String userId);

}

Provider

pom.xml

<!-- Dubbo Spring Boot Starter -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.8</version>
</dependency>

<dependency>
    <groupId>com.atguigu.gmall</groupId>
    <artifactId>gmall-interface</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

application.properties

dubbo.application.name=user-service-provider
dubbo.registry.address=127.0.0.1:2181
dubbo.registry.protocol=zookeeper

dubbo.protocol.name=dubbo
dubbo.protocol.port=20881

dubbo.monitor.protocol=registry

实现类

@DubboService注解的作用:暴露服务,这样就不用在xml文件中配置。

@DubboService
@Service
public class UserServiceImpl implements UserService {

    public List<UserAddress> getUserAddressList(String userId) {
        System.out.println("UserServiceImpl.....old...");
        // TODO Auto-generated method stub
        UserAddress address1 = new UserAddress(1, "北京市昌平区宏福科技园综合楼3层", "1", "李老师", "010-56253825", "Y");
        UserAddress address2 = new UserAddress(2, "深圳市宝安区西部硅谷大厦B座3层(深圳分校)", "1", "王老师", "010-56253825", "N");
        return Arrays.asList(address1,address2);
    }

}

springboot主程序

@EnableDubbo注解的作用:开启基于注解的dubbo功能

@EnableDubbo //开启基于注解的dubbo功能
@SpringBootApplication
public class BootUserServiceProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(BootUserServiceProviderApplication.class, args);
    }

}

Consumer

springboot勾选spring web,导入web相关的依赖

<dependency>
    <groupId>com.atguigu.gmall</groupId>
    <artifactId>gmall-interface</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

<!-- Dubbo Spring Boot Starter -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.8</version>
</dependency>

application.properties

server.port=8081

dubbo.application.name=consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.monitor.protocol=registry

实现类

@DubboReference注解的作用:引用服务

@Service
public class OrderServiceImpl implements OrderService {

    //@Autowired
    @DubboReference
    UserService userService;

    public List<UserAddress> initOrder(String userId) {
        System.out.println("用户id,"+userId);
        //    1、查询用户的收货地址
        List<UserAddress> addressList = userService.getUserAddressList(userId);
        return  addressList;
    }
}

控制器

@Controller
public class OderController {

    @Autowired
    OrderService orderService;

    @ResponseBody
    @RequestMapping("/initOrder")
    public List<UserAddress> initOrder(@RequestParam("uid")String userId){
        return orderService.initOrder(userId);

    }
}

springboot主程序

@EnableDubbo
@SpringBootApplication
public class BootOrderServiceConsumerApplication {

   public static void main(String[] args) {
        SpringApplication.run(BootOrderServiceConsumerApplication.class, args);
    }
}

支持

面向接口代理的高性能RPC调用

只能负载均衡

服务自动注册与发现

高度可拓展能力

运行流量调度

可视化的服务治理和运维

工作原理

三、启动zookeeper

第一次启动会缺少zoo.config

需要将zoo_sample.cfg复制一份改名为zoo.cfg

打开zoo.cfg 修改配置

打开zkServer

启动成功

启动zkCli服务器

四、启动dubbo管理控制台

前提: 打开zookeeper

进入dubbo github网站

https://github.com/apache/dubbo

切换至master-0.2.0

检查该文件中resources目录下的application.properties文件的配置

相同的话,跳到dubbo-admin文件夹目录,在该页面打开cmd ,mvn clean package生成target文件

复制target中的jar包

放在自己想放的目录下,并在该目录下使用cmd命令行运行

java -jar dubbo-admin-0.0.1-SNAPSHOT.jar

浏览器打开localhost:7001

登录账号 root 密码 root

dubbo 2.6是jar包 25.以前是war包

五 、案例

UserService 比较常用,总不能一直把UserService和bean放到别的module中,所以分包

为了使得orderservice调用方法,使用dubbo改造

springboot整合

springboot 暴露服务

用注解来配置

@DubboService 暴露服务

主程序中开启 @EnableDubbo

启动的时候出现了错误,提示缺少包,加入依赖

中间也因为加入依赖等级太高而失败,注意zoo版本和这个的匹配

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>2.12.0</version>
</dependency>

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>2.12.0</version>
</dependency>

使用接口用使用注解的方式

@DubboReference

三大步

1、导入dubbo

2、application.properties中写入dubbo配置

3、暴露服务使用 @DubboService注解 消费服务使用@Reference注入

六 、配置

1、配置优先级

2、启动检查

官方文档:https://dubbo.apache.org/zh/docs/advanced/preflight-check/

正常情况下,当注册中心没有提供者时,启动消费者,消费者程序就会报错。

启动检查便是来解决这个问题的。

  • 默认情况下,check=“true”
  • 关闭启动检查,check=“false”,消费者跳过检查提供者,只有在调用的时候才去注册中心检查服务

示例:

在xml文件中设置false,为一种服务配置

配置所有的服务都不检查

dubbo:consumer的其他配置

官方文档:https://dubbo.apache.org/zh/docs/references/xml/dubbo-consumer/

主程序

package com.atguigu.gmall;

import com.atguigu.gmall.service.OrderService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class MainApplication {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("consumer.xml");
        System.out.println("调用完成");
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行结果为 调用完成

如果不设置check=false ,则报错

设置check=false的方式

springboot中 @DubboReference(version = 1.0.0 , check = false)

3、超时&配置覆盖关系

解决问题:消费方使用提供方的方法,可能提供方的方法要使用很长时间,如果很长时间都没返回,导致大量线程阻塞,会引起性能下降

可以指定超时属性,如果没有反应,就立即终止,不让线程阻塞

超时说明

  • 单位毫秒
  • 未设置,默认值时1000ms,即1s

消费者配置超时

配置优先级

xml配置官方文档:https://dubbo.apache.org/zh/docs/references/configuration/xml/

  • 精准优先:方法级优先,接口级次之,全局配置再次之。
  • 消费者设置优先:如果级别一样,则消费方优先,提供方次之。

消费者方法 > 提供者方法 > 消费者接口 > 提供者接口 > 消费者全局 > 提供者全局

4、重试次数

说明

retries=“”,重试次数,不包含第一次调用,0代表不重试

原则

​ 幂等函数设置重试次数【查询、删除、修改,即每次运行都是相同的效果】

​ 非幂等函数不能设置重置次数【新增】

多个提供方

当有多个提供方提供相同的功能的时候,如果重试失败,会换下一次提供方,默认时轮询

5、多版本

官方文档:https://dubbo.apache.org/zh/docs/advanced/multi-versions/

作用

实现灰度发布

实现方式

提供方写多个实现类,并配置版本号

提供方

版本1配置

版本2配置

消费方

调用版本1 version=“1.0.0”

调用版本2 version=“2.0.0”

随机调用版本 *

6、本地存根

官方文档:https://dubbo.apache.org/zh/docs/advanced/local-stub/

7、与Springboot整合的三种方式

1)、导入dubbo-starter,在application.properties配置属性,使用@Service【暴露服务】使用@Reference【引用服务】

前提:开启注解的dubbo功能

​ 1、在启动程序中写@EnableDubbo

​ 2、或者在配置中写 dubbo.scan.base-packages=com.atguigu.gmall

2)、保留dubbo xml配置文件

方法:

​ 导入dubbo-starter。使用@ImportResource导入dubbo配置文件即可

目的:

​ 实现方法级的精准配置

3)使用注解API的方式

​ 将每一个组件手动创建到容器中

API配置官方文档:https://dubbo.apache.org/zh/docs/references/configuration/api/

注解配置官方文档:https://dubbo.apache.org/zh/docs/references/configuration/annotation/

(建议看API文档

七、高可用

高可用:通过设计,减少系统不能提供服务的时间

1、zookeeper宕机和Dubbo直连

问题:

​ 1)zookeeper宕机了,消费者还能不能调用服务提供者?

​ 能,因为有本地缓存保持通讯

​ 2)没有zookeeper,可以调用服务提供者吗?

​ 可以,dubbo可以直连服务提供者

2、负载均衡模式

官方文档:https://dubbo.apache.org/zh/docs/advanced/loadbalance/

缺省为 random 随机调用

1)基于权重的随即负载均衡机制

根据权重值得到每个Provider的概率,进行有概率的调用

2)基于权重的轮询负载均衡机制

根据权重,分配每个provider的概率,并通过轮询的方式科学地实现概率

3)最少活跃数-负载均衡机制

根据上一次provider的反应速度,选择最快的provider

4)一致性hash-负载均衡机制

根据哈希结果进入,

消费端设置

轮询机制配置

加权轮询配置

​ 消费者 @Reference(loadbalance=“random”)

​ 1) 静态设置 在提供者注解中设置@Service(weight= “”)

​ 2) 动态设置 在控制台

3、服务降级

当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。

可以通过服务降级功能临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。

方法

在消费者配置

屏蔽:消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。

容错:消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。

4、服务容错&Hystrix

集群容错文档:https://dubbo.apache.org/zh/docs/advanced/fault-tolerent-strategy/

​ 缺省为 failover 重试

集群容错模式

方式

整合hystrix

1、配置spring-cloud-starter-netflix-hystrix

针对 消费者 和 提供者

spring boot官方提供了对hystrix的集成,直接在pom.xml里加入依赖:

<dependency>          
    <groupId>org.springframework.cloud</groupId>       
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>         	 	 <version>1.4.4.RELEASE</version>     
</dependency>  

然后在Application类上增加@EnableHystrix来启用hystrix starter:

@SpringBootApplication  
@EnableHystrix  
public class ProviderApplication  {     
2、配置Provider端

在Dubbo的Provider上增加@HystrixCommand配置,这样子调用就会经过Hystrix代理。

@Service(version = "1.0.0")  
public class  HelloServiceImpl implements HelloService {   
 @HystrixCommand(commandProperties =
   {@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
    @HystrixProperty(name ="execution.isolation.thread.timeoutInMilliseconds", value =  "2000") })    
    @Override
    public String sayHello(String name) 
    {   // System.out.println("async  provider received: " + name);      
        // return "annotation: hello,  " + name;      
        throw new  RuntimeException("Exception to show hystrix enabled.");    
    }  
}  


3、配置Consumer端

对于Consumer端,则可以增加一层method调用,并在method上配置@HystrixCommand。当调用出错时,会走到fallbackMethod = "reliable"的调用里。

@Reference(version =  "1.0.0")    
private HelloService demoService;     

@HystrixCommand(fallbackMethod = "reliable")    
public String doSayHello(String name) {      
   return demoService.sayHello(name);    }   

public String reliable(String name) 
   { return "hystrix fallback  value";}  

原理

待补充…

举报

相关推荐

0 条评论