【Java】springboot整合dubbo

前言

本文使用 springboot2.x 来整合dubbo

dubbo工作原理

  • 服务启动的时候,provider和consumer根据配置信息,连接到注册中心register,分别向注册中心注册和订阅服务
  • register根据服务订阅关系,返回provider信息到consumer,同时consumer会把provider信息缓存到本地。如果信息有变更,consumer会收到来自register的推送
  • consumer生成代理对象,同时根据负载均衡策略,选择一台provider,同时定时向monitor记录接口的调用次数和时间信息
  • 拿到代理对象之后,consumer通过代理对象发起接口调用
  • provider收到请求后对数据进行反序列化,然后通过代理调用具体的接口实现

dubbo负载均衡策略

  • 加权随机:假设我们有一组服务器 servers = [A, B, C],他们对应的权重为 weights = [5, 3, 2],权重总和为10。现在把这些权重值平铺在一维坐标值上,[0, 5) 区间属于服务器 A,[5, 8) 区间属于服务器 B,[8, 10) 区间属于服务器 C。接下来通过随机数生成器生成一个范围在 [0, 10) 之间的随机数,然后计算这个随机数会落到哪个区间上就可以了。
  • 最小活跃数:每个服务提供者对应一个活跃数 active,初始情况下,所有服务提供者活跃数均为0。每收到一个请求,活跃数加1,完成请求后则将活跃数减1。在服务运行一段时间后,性能好的服务提供者处理请求的速度更快,因此活跃数下降的也越快,此时这样的服务提供者能够优先获取到新的服务请求。
  • 一致性hash:通过hash算法,把provider的invoke和随机节点生成hash,并将这个 hash 投射到 [0, 2^32 - 1] 的圆环上,查询的时候根据key进行md5然后进行hash,得到第一个节点的值大于等于当前hash的invoker。

【Java】springboot整合dubbo

  • 加权轮询:比如服务器 A、B、C 权重比为 5:2:1,那么在8次请求中,服务器 A 将收到其中的5次请求,服务器 B 会收到其中的2次请求,服务器 C 则收到其中的1次请求。

创建项目

创建父工程

打开 idea 点击 File>New>Project 选择Spring Initializr >JDK版本>Next 并创建好父工程 springboot-dubbo-parent,并删除 src ,.gitignore,HELP.md,mvnwmvnw.cmd 目录

父工程 pom 依赖:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<packaging>pom</packaging>

<modules>

<module>springboot-dubbo-public-api-service</module>

<module>springboot-dubbo-api-member-service-impl</module>

<module>springboot-dubbo-order-web</module>

</modules>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.4.1</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<groupId>com.baba.wlb</groupId>

<artifactId>springboot-dubbo-parent</artifactId>

<version>1.0-SNAPSHOT</version>

<name>springboot-dubbo-parent</name>

<description>Demo project for Spring Boot</description>

<properties>

<java.version>1.8</java.version>

</properties>

<dependencies>

<!--springboot 整合web组件-->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

<dependency>

<groupId>com.alibaba.boot</groupId>

<artifactId>dubbo-spring-boot-starter</artifactId>

<version>0.2.0</version>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

<configuration>

<excludes>

<exclude>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

</exclude>

</excludes>

</configuration>

</plugin>

</plugins>

</build>

</project>

子模块工程

  • springboot-dubbo-public-api-service:通用Api接口类,只有接口和Entity类。

    springboot-dubbo-api-member-service:为具体的会员接口类,在springboot-dubbo-public-api-service模块下面

  • springboot-dubbo-api-member-service-impl:member接口的实现类,依赖于 springboot-dubbo-api-member-service member接口模块。

  • springboot-dubbo-order-web :order模块依赖于于member接口模块,调用member模块接口。

依照上面的依赖关系构建好项目目录结构如下:

【Java】springboot整合dubbo


springboot-dubbo-api-member-service中新建接口:IMemberService.java

package com.baba.wlb.member;

/**

* @Author wulongbo

* @Date 2021/1/5 19:36

* @Version 1.0

*/

public interface IMemberService {

// 会员接口

String getUser();

}

目录结构以及pom依赖如下:
【Java】springboot整合dubbo


springboot-dubbo-api-member-service-impl中新建接口的实现类 MemberServiceImpl.java

package com.baba.wlb.member.impl;

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

import com.baba.wlb.member.IMemberService;

import org.springframework.beans.factory.annotation.Value;

/**

* @Author wulongbo

* @Date 2021/1/5 19:39

* @Version 1.0

*/

@Service

public class MemberServiceImpl implements IMemberService {

@Value("${dubbo.protocol.port}")

private String dubboPort;

// 1.dubbo服务发布的时候采用dubbo 注解方式,使用 dubbo @Service注解 进行发布服务

// 2.dubbo 提供的 @Service 将该接口的实现注册到注册中心上去

// 3.spring 的 @Service 将该类注入到spring容器中

@Override

public String getUser() {

System.out.println("订单服务调用会员服务...dubbo服务端口号:" + dubboPort);

return "订单服务调用会员服务...dubbo服务端口号:" + dubboPort;

}

}

再新建 MemberApplication.java 启动类:

package com.baba.wlb.member.impl;

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

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

/**

* @Author wulongbo

* @Date 2021/1/5 19:52

* @Version 1.0

*/

@EnableDubbo

@SpringBootApplication

public class MemberApplication {

public static void main(String[] args) {

SpringApplication.run(MemberApplication.class,args);

}

}

application.yml配置类:

##服务器端口号

server:

port: 8083

##dubbo 注册到注册中心的名称

dubbo:

application:

name: member

##采用协议方式和端口号

protocol:

## 常用协议:dubbo,http,webService等

name: dubbo

## 发布dubbo端口号为20880

port: 20880

registry:

## dubbo注册中心地址 zookeeper地址

address: zookeeper://39.102.56.91:2181

scan:

## 实现类扫包范围(可以省略,dubbo会自动扫 带了@Service的类)

base-packages: com.baba.wlb.member.impl.MemberServiceImpl

目录结构以及pom依赖如下:
【Java】springboot整合dubbo


springboot-dubbo-order-web中新建业务类 OrderController.java

package com.baba.wlb.controller;

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

import com.baba.wlb.member.IMemberService;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**

* @Author wulongbo

* @Date 2021/1/5 20:01

* @Version 1.0

*/

@RestController

public class OrderController {

// @Reference 提供 获取调用服务

@Reference

private IMemberService imemberService;

@RequestMapping("/orderToMember")

public String orderToMember() {

return imemberService.getUser();

}

}

OrderApplication.java启动类:

package com.baba.wlb.controller;

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

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

/**

* @Author wulongbo

* @Date 2021/1/5 20:05

* @Version 1.0

*/

@EnableDubbo

@SpringBootApplication

public class OrderApplication {

public static void main(String[] args) {

SpringApplication.run(OrderApplication.class,args);

}

}

application.yml配置类:

##服务器端口号

server:

port: 8084

##dubbo 注册到注册中心的名称

dubbo:

application:

name: order

registry:

## dubbo注册中心地址 zookeeper地址

address: zookeeper://39.102.56.91:2181

consumer:

timeout:

目录结构以及pom依赖如下:
【Java】springboot整合dubbo

启动项目

启动生产者

启动 MemberApplication.java
勾选 Allow paraller run 允许我们并行运行,这样我们就不用新建两个启动类:
【Java】springboot整合dubbo
修改 application.ymlprot8085 dubbo端口号修改为20881
再启动一个生产者
【Java】springboot整合dubbo
查看 dubbo admin 上生产者:
【Java】springboot整合dubbo

启动consumer

启动 OrderApplication.java
【Java】springboot整合dubbo
查看 dubbo admin 上consumer:
【Java】springboot整合dubbo

Postman接口测试

打开postman 并访问:localhost:8084/orderToMember
我们每点击一次send 请求,会轮询我们两个生产者服务。
【Java】springboot整合dubbo
如果是随机可以在 dubbo admin 上配置负载均衡策略
【Java】springboot整合dubbo

至此springboot整合dubbo就完成了!

以上是 【Java】springboot整合dubbo 的全部内容, 来源链接: utcz.com/a/94543.html

回到顶部