企業級SpringBoot與Dubbo的並用

 

技術文章第一時間送達!php

 

 

SpringBoot愈來愈熱門以致於達到爛大街可見的程度,而Dubbo這個基於二進制的微服務框架又捐獻給Apache孵化,若是不會如何使用那麼是否是很很差意思呢?java

此次從公司的項目中抽一個小列子來熟悉下若是從零構建,至於深刻了解->傳送門:Dubbo官方中文手冊git

版本:

  • Springboot2.xweb

  • Double2.6spring

  • Zk3.4.14apache

  • JDK8api

這裏就不介紹Dubbo了緩存

zookeepr安裝

下載去官網查找穩定的版本進行使用:安全

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

先在服務器上安裝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提供了四種負載均衡策略,分別是:

一、Random LoadBalance 按權重的隨機負載均衡,也是dubbo默認的負載均衡策略

二、RoundRobin LoadBalance 按權重的輪詢負載均衡,即在輪詢的基礎上添加了權重的策略

三、LeastActive LoadBalance 最少活躍調用數,相同活躍數的隨機訪問,活躍數指調用先後的計數差即響應時間的長短;這種策略可使響應慢的提供者收到的請求較少,大大提供系統性能

四、ConsistentHash LoadBalance 一致性哈希;相同參數的請求老是發到同一提供者

負載均衡的配置:@Reference(loadbalance = "roundrobin"),loadbalance 的值即爲四種負載均衡的名稱,所有小寫

在集羣調用失敗時,Dubbo 提供了多種容錯方案,缺省爲 failover 重試。下面列舉dubbo支持的容錯策略:

一、Failover Cluster:失敗自動切換,當出現失敗,重試其它服務器。一般用於讀操做,但重試會帶來更長延遲。可經過 retries="XXX" 來設置重試次數(不含第一次)。

二、Failfast Cluster:快速失敗,只發起一次調用,失敗當即報錯。一般用於非冪等性的寫操做,好比新增記錄。

三、Failsafe Cluster:失敗安全,出現異常時,直接忽略。一般用於寫入審計日誌等操做。

四、Failback Cluster:失敗自動恢復,後臺記錄失敗請求,定時重發。一般用於消息通知操做。

五、Forking Cluster:並行調用多個服務器,只要一個成功即返回。一般用於實時性要求較高的讀操做,但須要浪費更多服務資源。可經過 forks="2" 來設置最大並行數。

六、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是導出不了文件而報錯,至於文件下載也同樣可是相信通常都會有單獨的文件服務器。

看完本文有收穫?請轉發分享給更多人

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

相關文章
相關標籤/搜索