【博学谷学习记录】超强总结,用心分享 。Dubbo相关知识。

一.Dubbo的介绍

  2011年10月27日,阿里巴巴开源了自己的SOA服务化治理方案的核心框架Dubbo,服务治理和SOA的设计理念开始逐渐在国内软件行业中落地,并被广泛应用。

  在企业中有两种开发思路,第一种是基于SOA思想,将传统单一应用拆分为web消费者模块和service提供者模块,基于Dubbo通信。第二种是辅助Springcloud架构提升效率,Dubbo基于TCP传输层协议,效率更高。可以替换Feign,提升高并发压力

 

 

 

 

二.Dubbo框架

 

 

 

   服务提供者通过注册服务信息到Nacos注册中,消费者通过订阅服务提供者的信息,然后服务消费者对服务提供者进行远程调用,在这一系列行为中,都是在监控中心的监控下进行的。

 具体的详细步骤为:

  1.服务提供者在启动时,向注册中心注册自己提供的服务。

  2.服务消费者在启动时,向注册中心订阅自己所需要的服务

  3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长链接推送变更数据给消费者。

  4.服务消费者,从提供者地址列表中,基于负均衡算法,选择提供者进行调用。

  5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

三、应用Dubbo

  1.导入依赖

 <!--dubbo的起步依赖-->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.8</version>
    </dependency>

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-registry-nacos</artifactId>
        <version>2.7.8</version>
    </dependency>

  2.实现类中添加注解

@DubboService
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    //根据id查询用户名称
    public String queryUsername(Long id) {
        return userMapper.findById(id).getUsername();
    }
}

  3.yml配置文件

dubbo:
  protocol:
    name: dubbo
    port: 20881
  registry:
    address: nacos://127.0.0.1:8848
  scan:
    base-packages: cn.itcast.user.service

  4.引导类

@MapperScan("cn.itcast.user.mapper")
@SpringBootApplication
public class UserProviderApplication {

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

}

  5.序列化

    两个机器传输数据,如何传输java对象?

      在RPC通信时,往往采用二进制数据格式,故需要对对象进行序列化处理

  6.总结

    1).Dubbo的服务调用与暴露

      在服务实现类上通过@DUbboService暴露服务

      在消费者端通过@DubboReference引用服务

    2).Dubbo中传输对象

      在RPC框架中,往往通过TCP协议进行数据传输,因此对象需要进行序列化Serializable

    3).在实际开发中往往将接口和实体类抽取到公共模块user-api,然后在各自的模块中引入功能模块

四、高级特性

   1.启动检查

    为了保障服务的正常可用,Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时抛出异常。

 

  

 

 

     在正常开发中,会启动,但是我们在日常的测试中会将其关闭,在配置文件中将其关闭即可   

dubbo:
  consumer:
    check: false

    2.多版本

      在正式系统中,为了保证系统可用性和更好的并发性,往往通过集群部署。

      Dubbo提供了提供者多版本的支持,平滑处理项目功能升级部署

      使用灰度发布:当出现新功能时,会让一部分用户先使用新功能,用户反馈没问题时,再将所有用户迁移到新功能。

(1)user-provider定义新的服务实现类UserServiceImpl2,指定版本

    

@DubboService(version = “2.0.0”)
public class UserServiceImpl2 implements UserService {
    …………
}

(2)user-consumer消费者调用时,指定版本调用

@RestController
@RequestMapping("/user")
public class UserController {
    //引用远程服务
    @DubboReference(version = "2.0.0")
    private UserService userService;    
    ………
}

    3.超时与重试

      服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一直等待下去。大量的请求都在同时请求服务消费者,会造成线程的大量堆积,势必会造成雪崩

      dubbo利用超时机制来解决这个问题

      若超时时间较短,当网络波动时请求就会失败,Dubbo通过重试机制避免此类问题的发生

      如果只是查询的话,可以使用,但是保存操作不建议使用,因为保存操作一次,会发送三个请求。

在消费yml文件中设置,就相当于全局

      

dubbo:
  registry:
    address: nacos://127.0.0.1:8848
  consumer:
    check: false
    retries: 0

  在controller中设置,相当于局部

@DubboReference(version = "2.0.0", retries = 0)
private UserService userService;
    4.负载均衡

    在集群部署时,Dubbo提供了4中负载均衡策略,帮助消费者找到最有提供者并调用

    Random:按权重随机,默认值。按权重设置随机概率

    RoundRobin:按权重轮询

    LeastActive:最少活跃调用数,相同活跃数随机

    ConsistentHash:一致性Hash,相同参数的请求总是发到同一提供者

@DubboReference(version = "2.0.0", retries = 0,loadbalance = "Random")
private UserService userService;

五、SpringCloud整合Dubbo

  为什么需要Dubbo

    Feign基于Http协议(应用层),http协议就是对tcp协议的封装,由于做了深层次的封装,所以效率低,在高并发场景下性能不够理想,容易成为性能瓶颈

    Dubbo框架的通信协议采用TCP协议(数据传输层)

    Dubbo框架的通信协议采用RPC协议,属于传输层协议

    Dubbo默认通过Netty构造TCP长链接的方式进行通信,性能较高

    使用SpringCloud整合Dubbo,强强联合

 

   1.入门案例

    抽取接口

 

package cn.itcast.dubbo.api;


import cn.itcast.dubbo.domain.User;

public interface UserService {

    User queryById(Long id);
}

项目依赖

父工程加入SpringCloud Alibaba依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.5.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

 

消费者和提供者引入nacos注册中心和Dubbo依赖

<!--nacos注册中心的依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!--springcloud alibaba dubbo依赖   -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>

<dependency>
    <groupId>cn.itcast</groupId>
    <artifactId>dubbo-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
服务提供者
  
修改UserService实现UserApi接口。并使用@DubboService注解替换@Service对外暴露dubbo服务
package cn.itcast.user.service;

import cn.itcast.dubbo.api.UserService;
import cn.itcast.dubbo.domain.User;
import cn.itcast.user.mapper.UserMapper;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

@DubboService
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    public User queryById(Long id) {
        return userMapper.findById(id);
    }
}

在application.yml中添加配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/dubbo-demo?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: user-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
#配置dubbo,注册中心,暴露的端口和协议,dubbo注解的包扫描
dubbo:
  protocol:
    name: dubbo
    port: 20881
  registry:
    address: spring-cloud://localhost   #使用SpringCloud中的注册中心
  scan:
    base-packages: cn.itcast.user.service  #dubbo中包扫描

  服务消费者

    在OrderController中引入dubbo服务。调用UserService查询用户

import cn.itcast.dubbo.api.UserService;
import cn.itcast.dubbo.domain.Order;
import cn.itcast.dubbo.domain.User;
import cn.itcast.order.service.OrderService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @DubboReference
    private UserService userService;

    @GetMapping("{orderId}")
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        //根据id查询订单
        Order order = orderService.queryOrderById(orderId);
        //获取用户id
        Long userId = order.getUserId();
        //查询用户
        User user = userService.queryById(userId);
        //设置用户对象
        order.setUser(user);
        // 根据id查询订单并返回
        return order;
    }
}

 

    在Order-service的模块中添加dubbo配置

  

spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
#dubbo配置
dubbo:
  registry:
    address: spring-cloud://localhost  #使用cloud的注册中心
  consumer:
    check: false   #dubbo默认有启动检查
    retries: 0     #dubbo内置的重试机制

 

  

 

posted @ 2022-10-03 16:51  LINwenguan  阅读(43)  评论(0编辑  收藏  举报