1. 程式人生 > >使用Redis為註冊中心的Dubbo微服務架構(基於SpringBoot)

使用Redis為註冊中心的Dubbo微服務架構(基於SpringBoot)


title: 使用Redis為註冊中心的Dubbo微服務架構(基於SpringBoot)
date: 2019-07-30 14:06:29
categories:

  • 架構
    author: mrzhou
    tags:
  • SpringBoot
  • redis
  • Dubbo
  • 微服務
  • RPC

前言

Dubbo作為一款高效能的RPC框架,已經在大多數一線IT企業中得到了廣泛的使用,今天我們也來試一試。為了儘可能的少寫程式碼,讓程式簡單明瞭,我們基於SpringBoot來搭建。
雖然Dubbo推薦使用zk作為註冊中心,今天我們換換Redis試試。

需求分解

本專案只是為了講解Dubbo與Redis的使用,所以將業務儘可能地簡化,我們的消費方呼叫服務提供方獲取一個簡單的使用者資訊。

將業務進行分解:

  • 介面定義(user-common)
  • 服務提供方(user-provider)
  • 服務消費方(user-consumer)

介面專案

原則上該專案其實只是介面定義部分就可以了,其實什麼依賴都可以不需要,只是為了少寫程式碼,這裡引入了lombok,然後將該專案打包釋出到maven倉庫即可。
pom.xml

<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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cn.miw.dubbo</groupId>
    <artifactId>common</artifactId>
    <version>0.0.1</version>
    <dependencies>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

介面定義
UserService.java

package cn.miw.dubbo.api;

import cn.miw.dubbo.model.User;

public interface UserService {
    User findById(Integer id);
}

實體定義
User.java

package cn.miw.dubbo.model;

import java.io.Serializable;

import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class User implements Serializable{

    private static final long serialVersionUID = -7001216319830050312L;
    private Integer id;
    private String name;
    private int age;
    
}

服務提供方專案

在該專案中實現具體的服務處理邏輯並完成註冊中心註冊的過程,該專案可以整合一些成熟的orm框架,這裡為了簡單演示,其實現只是簡單地建立一個物件返回即可。

  • 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 http://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.1.1.RELEASE</version>
        <relativePath />
    </parent>
    <groupId>cn.miw.dubbo</groupId>
    <artifactId>user-provider</artifactId>
    <version>0.0.1</version>
    <packaging>jar</packaging>
    <name>demo</name>
    <description>server</description>

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

    <dependencies>
        <!-- 引入通用專案 -->
        <dependency>
            <groupId>cn.miw.dubbo</groupId>
            <artifactId>common</artifactId>
            <version>0.0.1</version>
        </dependency>
        <!-- Dubbo需要的第三方包 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!-- Redis 支援包 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <!-- Dubbo starter -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>
        <!-- Redis starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        
    </dependencies>

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

</project>

這是一個SpringBoot專案,我們需要使用redis作為註冊中心,所以引入了相關的starter及支援包,再加入Dubbo的starter和支援包。

先看看功能的具體簡單實現,這裡需要注意的是@Service註解,這是使用的dubbo中的註解,通過這個註解即實現了具體服務層在註冊中心的流程過程,所以還需要@Component來加持,讓其能夠被Spring管理。

  • UserServiceImpl.java
package cn.miw.dubbo.server.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

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

import cn.miw.dubbo.api.UserService;
import cn.miw.dubbo.model.User;

@Service(version = "1.0")
@Component
public class UserServiceImpl implements UserService {
    
    private static Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Override
    public User findById(Integer id) {
        log.info("接收到的ID:{}",id);
        User user = new User();
        user.setAge(10+id*2);
        user.setName("張三"+id);
        user.setId(id);
        return user;
    }
}

再看看啟動類,也非常簡單,只是增加了@EnableDubbo註解即可,由於該專案並非web專案,所以增加了一句java System.in.read();,讓其保持執行狀態。

  • ServerApp.java
package cn.miw.dubbo.server;

import java.io.IOException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

@SpringBootApplication
@EnableDubbo
public class ServerApp {

    public static void main(String[] args) throws IOException {
        SpringApplication.run(ServerApp.class, args);
        System.in.read();
    }

}

再來看看配置。這裡指出了註冊中心redis的位置,並指明瞭提供服務所使用的協議為dubbo協議,服務埠為:12345

  • application.yml

dubbo:
  application:
    id: user-provider
    name: user-provider    
    qosEnable: true
    qosPort: 22223
  registry:
    address: redis://root:[email protected]:6379

  protocol:
    name: dubbo
    port: 12345    
    
spring:
  application:
    name: user-provider    

服務呼叫方專案

這個專案的依賴僅比服務提供方多了一個web專案的依賴

  • 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 http://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.1.1.RELEASE</version>
        <relativePath />
    </parent>
    <groupId>cn.miw.dubbo</groupId>
    <artifactId>consumer</artifactId>
    <version>0.0.1</version>
    <packaging>war</packaging>
    <name>user-consumer</name>
    <description>consumer</description>

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

    <dependencies>
        <!-- Dubbo及redis通用部分 開始 -->
        <dependency>
            <groupId>cn.miw.dubbo</groupId>
            <artifactId>common</artifactId>
            <version>0.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- Dubbo及redis通用部分 結束 -->

        <!-- Web專案 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

    </dependencies>

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

</project>

為了儘可能簡單實現我們只有一個java檔案

  • ConsumerApp.java
package cn.miw.dubbo.consumer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

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

import cn.miw.dubbo.api.UserService;

@SpringBootApplication
@EnableDubbo
@RestController
public class ConsumerApp {

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

    @Reference(version = "1.0")
    UserService userService;
    
    private static Logger log = LoggerFactory.getLogger(ConsumerApp.class);
    
    @GetMapping("/")
    public Object index(Integer id) {
        log.info("輸入的ID:{},{}",id,(id==null)?0:id);
        return userService.findById((id==null)?0:id);
    }
}

配置檔案

  • application.yml
dubbo:
  application:
    id: user-consumer
    name: user-consumer        
    qosEnable: false
    qosPort: 22224
  registry:
    address: redis://root:[email protected]:6379
  consumer:
    timeout: 3000

    
spring:
  application:
    name: user-consumer    

注意事項

  • 由於common專案是其他兩個專案都需要使用的,請先編譯釋出到自己的maven倉庫,如果都在同一臺電腦上開發,只需要install到本地倉庫即可,如果是多臺電腦或者小組開發請釋出到自己小組的私有倉庫;
  • 在啟動服務消費方前請先啟動服務提供方,可以多臺電腦同時執行服務提供方專案;
  • 啟動消費方 通過瀏覽器訪問 http://localhost:8080/ 檢視結果。也可以啟動多個消費方,看看在多個服務方執行的情況下分別呼叫的是哪一臺的服務。

結語

這樣拆分後,各其實其實都很簡單,具體開發中,各專案只需要處理自己相關業務程式碼即可,不需要考慮更多,可以讓每一個專案都可以完成得更好,並且不影響其他模組的功能,讓開發和部署維護都能夠更方便