SpringBoot2整合dubbo及负载均衡策略简易范例
dubbo需要基于zookeeper,这里zookeeper版本号为3.6.2,JDK版本1.8.0_161
先附上demo源码地址
https://gitee.com/tong_2019/springboot-dubbo-demo
项目目录结构大概如下
一、api
api只有一个接口,PortService
PortService.java
package service;
public interface PortService {
String getPort();
}
修改pom.xml,方便后期api往生产者和消费者里面打包用
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot-dubbo-demo</artifactId>
<groupId>com</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<!-- 这里加groupId和version,名字随意,方面后面打包用 -->
<groupId>com</groupId>
<artifactId>api</artifactId>
<version>1.0</version>
</project>
二、生产者provider
这是个springboot项目,先上pom.xml
pom.xml,这里项目测试运行是没有问题,但是后期部署需要把api打好的jar打到生产者和消费者的springboot项目里面去,这个在随后的文章我会写一下,如何把jar包打到war或者jar的springboot项目
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 包含PortService的api -->
<dependency>
<groupId>com</groupId>
<artifactId>api</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
然后项目配置文件
application.properties
server.port=8091
#应用配置,用于配置当前生产者和消费者应用信息
spring.dubbo.application.name=dubbo-provider
#注册中心配置,用于配置连接注册中心相关信息。
spring.dubbo.registry.protocol=zookeeper
#配置zookeeper,如使用集群则192.168.26.101|192.168.26.102:2181|192.168.26.103:2181
#或者192.168.153.130:2181,192.168.153.131:2181,192.168.153.131:2182
#或者192.168.153.130\:2181,192.168.153.131\:2181,192.168.153.131\:2182
spring.dubbo.registry.address=127.0.0.1:2181
#协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。
spring.dubbo.protocol.name=dubbo
#使用分布式可修改不同节点的端口,如20881、20882、20883等
spring.dubbo.protocol.port=20880
#服务暴露的Service所在的package
spring.dubbo.scan=com.example.provider.service
#负载均衡策略,常用有以下几种:轮询roundrobin,随机random,最少活跃数leastActive
spring.dubbo.provider.loadbalance=roundrobin
再来实现类
这里PortServiceImpl.java用于实现api接口,我这里输出一下调用的生产者的port信息,用于之后组分布式测试用,区分是调用的哪个生产者
package com.example.provider.service;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import service.PortService;
//dubbo注解,暴露服务,注意Service注解引用的是dubbo
@Service
@Component
public class PortServiceImpl implements PortService {
@Value("${server.port}")
private String port;
@Override
public String getPort() {
StringBuilder sb = new StringBuilder();
sb.append("<<<<<<<<<< PROVIDER_PORT = ");
sb.append(port);
sb.append(" >>>>>>>>>>");
return sb.toString();
}
}
ProviderApplication.java,注意添加了dubbo自动配置注解
package com.example.provider;
import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//开启dubbo的自动配置
@EnableDubboConfiguration
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
三、消费者consumer
项目结构:
还是先pom
pom.xml
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>consumer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 包含PortService的api -->
<dependency>
<groupId>com</groupId>
<artifactId>api</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
项目配置文件application.properties
server.port=8081
#应用配置,用于配置当前生产者和消费者应用信息
spring.dubbo.application.name=dubbo-consumer
#注册中心配置,用于配置连接注册中心相关信息。
spring.dubbo.registry.protocol=zookeeper
#配置zookeeper,如使用集群则192.168.26.101|192.168.26.102:2181|192.168.26.103:2181
#或者192.168.153.130:2181,192.168.153.131:2181,192.168.153.131:2182
#或者192.168.153.130\:2181,192.168.153.131\:2181,192.168.153.131\:2182
spring.dubbo.registry.address=127.0.0.1:2181
#负载均衡策略,常用有以下几种:轮询roundrobin,随机random,最少活跃数leastActive
spring.dubbo.consumer.loadbalance=roundrobin
控制器PortController.java
package com.example.consumer.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import service.PortService;
@RestController
public class PortController {
//Reference注解,启动消费者之前需要先启动zookeeper和生产者
@Reference
private PortService portService;
@GetMapping(value = "/getPort")
public String getPort() {
return portService.getPort();
}
}
启动类ConsumerApplication.java,同样注意使用了dubbo自动配置的注解
package com.example.consumer;
import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//开启dubbo的自动配置
@EnableDubboConfiguration
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
四、测试一
启动顺序zookeeper => 生产者provider => 消费者consumer
我们这里使用dubbo-admin 2.7查看和管理服务,具体dubbo-admin安装和使用见我之前的文章
启动完成后浏览器输入下面url访问消费者控制器
http://localhost:8081/getServicePort
这里8081是消费者,调用了8091的生产者
五、api打包到springboot发布
springboot项目项目发布有jar和war两种方式,直接这样打包,api的jar包是不会被打入项目中的,发布运行时会因为缺少对应的api依赖包导致服务启动失败,这时我们需要修改一下pom.xml,在修改之前先把api打成jar包,可以进入api文件夹
执行mvn package或者
点击package执行打包,在target下面生产jar文件,然后在生产者和消费者的resource目录下各新建一个lib文件夹,把这个生成的api的jar包复制到消费者的resource里面的lib和生产者的resource里面的lib里
springboot如果是jar包打包方式,需要将生产者和消费者的pom.xml中的
<dependency>
<groupId>com</groupId>
<artifactId>api</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
替换为
<dependency>
<groupId>com</groupId>
<artifactId>api</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/api-1.0.jar</systemPath>
</dependency>
之后将
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
替换为
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
然后打包即可
修改后的provider生产者pom.xml
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 包含PortService的api -->
<dependency>
<groupId>com</groupId>
<artifactId>api</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/api-1.0.jar</systemPath>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
</project>
修改后的消费者pom.xml
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>consumer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 包含PortService的api -->
<dependency>
<groupId>com</groupId>
<artifactId>api</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/api-1.0.jar</systemPath>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
</project>
如果是打成war包除了修改api引用lib为
<dependency>
<groupId>com</groupId>
<artifactId>api</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/api-1.0.jar</systemPath>
</dependency>
之外还需要修改pom.xml里面的build,将
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
替换为:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<targetPath>BOOT-INF/lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<targetPath>BOOT-INF/classes/</targetPath>
</resource>
</resources>
<!--设置maven-war-plugins插件,否则外部依赖无法打进war包 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>${project.basedir}/src/main/resources/lib</directory>
<targetPath>WEB-INF/lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
以上完成以后,PortServiceImpl的引用发生了变化,变为引用本地lib中的jar包了,如果打包报错,修改一下引用lib中的jar即可
然后生产者和消费者分别打包即可,我这里用的jar方式
打包过程中出现点小插曲,出现maven Input length = 1 -> [Help 1]的报错,提示应该是编码问题,之后去掉了application.properties的中文注释,打包后测试成功
六、负载均衡策略测试
这里我用的是roundrobin也就是轮询,在application.properties中配置,除此之外常用的还有随机random,最少活跃数leastActive等,具体可以看官方文档
假设有三个服务节点node1、node2和node3,复制provider生产者三份,建立node1、2、3三个文件夹,每个文件夹把provider复制进去同时新建一个config文件夹,如下图
三个节点相同,在三个节点的config中各新建application.properties
修改配置文件,这样新配置文件配置会优先选用,并弃用jar打包中内置的配置文件
node1配置文件
server.port=8091
#应用配置,用于配置当前生产者和消费者应用信息
spring.dubbo.application.name=dubbo-provider
#注册中心配置,用于配置连接注册中心相关信息。
spring.dubbo.registry.protocol=zookeeper
#配置zookeeper,如使用集群则192.168.26.101|192.168.26.102:2181|192.168.26.103:2181
#或者192.168.153.130\:2181,192.168.153.131\:2181,192.168.153.131\:2182
spring.dubbo.registry.address=127.0.0.1:2181
#协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。
spring.dubbo.protocol.name=dubbo
#使用分布式可修改不同节点的端口,如20881、20882、20883等
spring.dubbo.protocol.port=20880
#服务暴露的Service所在的package
spring.dubbo.scan=com.example.provider.service
#负载均衡策略,常用有以下几种:轮询roundrobin,随机random,最少活跃数leastActive
spring.dubbo.provider.loadbalance=roundrobin
node2
server.port=8092
#应用配置,用于配置当前生产者和消费者应用信息
spring.dubbo.application.name=dubbo-provider
#注册中心配置,用于配置连接注册中心相关信息。
spring.dubbo.registry.protocol=zookeeper
#配置zookeeper,如使用集群则192.168.26.101|192.168.26.102:2181|192.168.26.103:2181
#或者192.168.153.130\:2181,192.168.153.131\:2181,192.168.153.131\:2182
spring.dubbo.registry.address=127.0.0.1:2181
#协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。
spring.dubbo.protocol.name=dubbo
#使用分布式可修改不同节点的端口,如20881、20882、20883等
spring.dubbo.protocol.port=20881
#服务暴露的Service所在的package
spring.dubbo.scan=com.example.provider.service
#负载均衡策略,常用有以下几种:轮询roundrobin,随机random,最少活跃数leastActive
spring.dubbo.provider.loadbalance=roundrobin
node3
server.port=8093
#应用配置,用于配置当前生产者和消费者应用信息
spring.dubbo.application.name=dubbo-provider
#注册中心配置,用于配置连接注册中心相关信息。
spring.dubbo.registry.protocol=zookeeper
#配置zookeeper,如使用集群则192.168.26.101|192.168.26.102:2181|192.168.26.103:2181
#或者192.168.153.130\:2181,192.168.153.131\:2181,192.168.153.131\:2182
spring.dubbo.registry.address=127.0.0.1:2181
#协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。
spring.dubbo.protocol.name=dubbo
#使用分布式可修改不同节点的端口,如20881、20882、20883等
spring.dubbo.protocol.port=20882
#服务暴露的Service所在的package
spring.dubbo.scan=com.example.provider.service
#负载均衡策略,常用有以下几种:轮询roundrobin,随机random,最少活跃数leastActive
spring.dubbo.provider.loadbalance=roundrobin
启动dubbo-admin 2.7查看注册的服务
这里默认的权重是100,当服务器配置有高低区别时,可适当调整权重
重复刷新可以看到轮询每一个节点,输出的是节点的端口号
未完待续
本文地址:https://blog.csdn.net/weixin_38424881/article/details/109801889