18

企业级 SpringBoot 与 Dubbo 的并用

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzU2NjIzNDk5NQ%3D%3D&%3Bmid=2247488120&%3Bidx=1&%3Bsn=873d3ff8a9ed7020ed2240624e6fb3b3
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

点击上方 匠心零度 ,选择“ 设为星标

做积极的人,而不是积极废人

NZ3uuiQ.jpg!web

作者:SimpleWu

cnblogs.com/SimpleWu/p/10833555.html

SpringBoot 和 Dubbo 又能碰撞出什么火花呢?我们来看看企业级 SpringBoot 与 Dubbo 的并用。

版本:

  • Springboot2.x

  • Double2.6

  • Zk3.4.14

  • JDK8

这里就不介绍Dubbo了,不了解的可以看这里:

https://www.cnblogs.com/SimpleWu/p/9769797.html

zookeepr安装

下载去官网查找稳定的版本进行使用:

http://www.apache.org/dyn/closer.cgi/zookeeper/

先在服务器上安装zookeeper。

cd /usr/local/src/
#下载
sudo wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz
#解压
tar -zxvf zookeeper-3.4.14.tar.gz
#修改配置文件名称
mv conf/zoo_sample.cfg zoo.cfg
#启动zk
./bin/zkServer.sh start
#出现以下字样代表启动成功,默认端口2181
Starting zookeeper ... STARTED

SpringBoot2.x整合Dubbo

父工程搭建(pom工程)

<groupId>com.simple.springboot</groupId>
<artifactId>yun-double</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>yun-double</name>
<description>double</description>

<!--统一管理依赖版本-->
<properties>
<java.version>1.8</java.version>
<double.version>2.0.0</double.version>
<zkclient.version>0.10</zkclient.version>
</properties>

<!-- 依赖于SpringBoot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/>
</parent>

<!--依赖定义-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${double.version}</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>${zkclient.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

创建公共接口工程common

该工程用于存储服务层接口,以减少代码的冗余。

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.simple.springboot</groupId>
<artifactId>yun-double</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>

<groupId>com.simple.springboot</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>

<name>common</name>
<description>公共接口</description>

创建公共接口

public interface UserService {

String getUserById(int id);

}

创建服务提供者(provider)

Pom文件

<modelVersion>4.0.0</modelVersion>

<groupId>com.simple.springboot</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>provider</name>
<description>生产者</description>


<parent>
<groupId>com.simple.springboot</groupId>
<artifactId>yun-double</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>

<dependencies>
<!-- SpringBoot快速启动Duubbo -->
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- Zk客户端依赖 -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<!-- 排除依赖里的日志 -->
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>

<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>

<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 导入公共接口依赖 -->
<dependency>
<groupId>com.simple.springboot</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

在pom文件中我们需要引入Dubbo,Zk客户端并且引入公共接口工程

application.properties配置文件

#dubbo.application.name 应用名称
#dubbo.registry.address 注册中心地址
#dubbo.protocol.name 协议名称
#dubbo.protocol.port 协议端口
#dubbo.scan dubbo 服务类包目录
#server.port=8080
spring.application.name=user-pro
dubbo.application.name=user-provider1
dubbo.registry.address=zookeeper://192.168.197.133:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880

在这里dubbo.application.name应用名称一定不能重复

实现UserService

@Component
@Service(timeout = 10000,interfaceClass = UserService.class)
public class UserServiceImpl implements UserService {

@Override
public String getUserById(int id) {
if(id == 1) {
return "SimpleWu";
}else {
return "Apache Dubbo";
}
}
}

@Service 这个注解使用的不是Spring里面的,而是com.alibaba.dubbo.config.annotation.Service

  • timeout 配置超时时间

  • interfaceClass 接口类

  • version 服务版本,如果配置了服务版本在消费端引用也必须一样,具体等会说

创建启动类

在该工程中我们不需要引入Web模块浪费端口号,只需要这样写启动类

@EnableDubbo
@EnableDubboConfiguration
@DubboComponentScan("com.simple.springboot.provider.common.impl")
public class ProviderApplication {

public static void main(String[] args) {
SpringApplication app = new SpringApplication(ProviderApplication.class);
app.run(args);
//dubbo Main独立运行,脱离web容器
Main.main(args);
}

}
  • @EnableDubbo 启动Dubbo功能

  • @EnableDubboConfiguration 启动Duubbo配置

  • @DubboComponentScan 扫描提供者实现类

创建服务消费者(consumer)

POM文件

<modelVersion>4.0.0</modelVersion>


<groupId>com.simple.springboot</groupId>
<artifactId>consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>


<name>consumer</name>
<description>消费者</description>

<parent>
<groupId>com.simple.springboot</groupId>
<artifactId>yun-double</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- SpringBoot快速启动Duubbo -->
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- Zk客户端依赖 -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<!-- 排除依赖里的日志 -->
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>

<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>

<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 导入公共接口依赖 -->
<dependency>
<groupId>com.simple.springboot</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

在这个工程中我们是需要依赖Web的,不然咋访问呢

编写Application.properties配置文件

spring.application.name=user-con
server.port=8080
dubbo.application.name=user-consumer
dubbo.registry.address=zookeeper://192.168.197.133:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#dubbo.scan=com.simple.springboot.provider.common.impl

在这里dubbo.application.name应用名称一定不能重复,dubbo.scan 该配置指向应该是要和服务提供方一致

编写Controller

@RestController
public class UserController {

//timeout 可以不指定,如果提供则有填写但是version一定要指定 不然会找不到服务 直连需要加url="dubbo://localhost:20880"
@Reference
private UserService userService;

@GetMapping("/dubbo/user/{id}")
public String getUserById(@PathVariable int id){
return userService.getUserById(id);
}
}

在这里是使用@Reference去发现服务而不是@Autowired去注入Bean,@Reference 里面可以配置version,timeout超时时间

如果需要Dubbo直连url="dubbo://localhost:20880"

dubbo提供了四种负载均衡策略,分别是:

1、Random LoadBalance 按权重的随机负载均衡,也是dubbo默认的负载均衡策略

2、RoundRobin LoadBalance 按权重的轮询负载均衡,即在轮询的基础上添加了权重的策略

3、LeastActive LoadBalance 最少活跃调用数,相同活跃数的随机访问,活跃数指调用前后的计数差即响应时间的长短;这种策略可以使响应慢的提供者收到的请求较少,大大提供系统性能

4、ConsistentHash LoadBalance 一致性哈希;相同参数的请求总是发到同一提供者

负载均衡的配置:@Reference(loadbalance = "roundrobin"),loadbalance 的值即为四种负载均衡的名称,全部小写

在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。下面列举dubbo支持的容错策略:

1、Failover Cluster:失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="XXX" 来设置重试次数(不含第一次)。

2、Failfast Cluster:快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

3、Failsafe Cluster:失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

4、Failback Cluster:失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

5、Forking Cluster:并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。

6、Broadcast Cluster:广播调用所有提供者,逐个调用,任意一台报错则报错 [2]。通常用于通知所有提供者更新缓存或日志等本地资源信息。

配置如下:@Reference(cluster = "failsafe")这里表示使用失败安全的容错策略

编写启动类

/**
* @author:SimpleWu
* @date: 2019-05-08
*/

@EnableDubbo
@SpringBootApplication
@EnableDubboConfiguration
@DubboComponentScan("com.simple.springboot.provider.common.impl")
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class,args);
}
}

然后直接就可以访问成功了。

如果不想使用注解扫描可以使用properties进行配置

#dubbo.scan=com.simple.springboot.provider.common.impl

参考代码:

https://gitlab.com/450255266/code/tree/master/SpringBoot/dubbo/yun-double

注意事项:

Dubbo是一个二进制的Rpc框架在传输数据过程中,实体类必须经过序列化。

在使用poi导出功能时一定不能把response传到Service层,否则传输到Service是导出不了文件而报错,至于文件下载也一样但是相信一般都会有单独的文件服务器。

END

如果读完觉得有收获的话,欢迎点【好看】,关注【匠心零度】,查阅更多精彩历史!!!

nmqYriz.gif

让我“ 好看 ”  bYreamJ.gif


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK