使用Redis為注冊(cè)中心的Dubbo微服務(wù)架構(gòu)(基于SpringBoot)


title: 使用Redis為注冊(cè)中心的Dubbo微服務(wù)架構(gòu)(基于SpringBoot)
date: 2019-07-30 14:06:29
categories:

  • 架構(gòu)
    author: mrzhou
    tags:
  • SpringBoot
  • redis
  • Dubbo
  • 微服務(wù)
  • RPC

前言

Dubbo作為一款高性能的RPC框架,已經(jīng)在大多數(shù)一線IT企業(yè)中得到了廣泛的使用,今天我們也來(lái)試一試。為了盡可能的少寫代碼,讓程序簡(jiǎn)單明了,我們基于SpringBoot來(lái)搭建。
雖然Dubbo推薦使用zk作為注冊(cè)中心,今天我們換換Redis試試。

需求分解

本項(xiàng)目只是為了講解Dubbo與Redis的使用,所以將業(yè)務(wù)盡可能地簡(jiǎn)化,我們的消費(fèi)方調(diào)用服務(wù)提供方獲取一個(gè)簡(jiǎn)單的用戶信息。
將業(yè)務(wù)進(jìn)行分解:

  • 接口定義(user-common)
  • 服務(wù)提供方(user-provider)
  • 服務(wù)消費(fèi)方(user-consumer)

接口項(xiàng)目

原則上該項(xiàng)目其實(shí)只是接口定義部分就可以了,其實(shí)什么依賴都可以不需要,只是為了少寫代碼,這里引入了lombok,然后將該項(xiàng)目打包發(fā)布到maven倉(cāng)庫(kù)即可。
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);
}

實(shí)體定義
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;
    
}

服務(wù)提供方項(xiàng)目

在該項(xiàng)目中實(shí)現(xiàn)具體的服務(wù)處理邏輯并完成注冊(cè)中心注冊(cè)的過(guò)程,該項(xiàng)目可以集成一些成熟的orm框架,這里為了簡(jiǎn)單演示,其實(shí)現(xiàn)只是簡(jiǎn)單地創(chuàng)建一個(gè)對(duì)象返回即可。

  • 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>
        <!-- 引入通用項(xiàng)目 -->
        <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>

這是一個(gè)SpringBoot項(xiàng)目,我們需要使用redis作為注冊(cè)中心,所以引入了相關(guān)的starter及支持包,再加入Dubbo的starter和支持包。

先看看功能的具體簡(jiǎn)單實(shí)現(xiàn),這里需要注意的是@Service注解,這是使用的dubbo中的注解,通過(guò)這個(gè)注解即實(shí)現(xiàn)了具體服務(wù)層在注冊(cè)中心的流程過(guò)程,所以還需要@Component來(lái)加持,讓其能夠被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;
    }
}

再看看啟動(dòng)類,也非常簡(jiǎn)單,只是增加了@EnableDubbo注解即可,由于該項(xiàng)目并非web項(xiàng)目,所以增加了一句java System.in.read();,讓其保持運(yùn)行狀態(tài)。

  • 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();
    }

}

再來(lái)看看配置。這里指出了注冊(cè)中心redis的位置,并指明了提供服務(wù)所使用的協(xié)議為dubbo協(xié)議,服務(wù)端口為:12345

  • application.yml

dubbo:
  application:
    id: user-provider
    name: user-provider    
    qosEnable: true
    qosPort: 22223
  registry:
    address: redis://root:pass@192.168.0.116:6379

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

服務(wù)調(diào)用方項(xiàng)目

這個(gè)項(xiàng)目的依賴僅比服務(wù)提供方多了一個(gè)web項(xiàng)目的依賴

  • 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通用部分 結(jié)束 -->

        <!-- Web項(xiàng)目 -->
        <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>

為了盡可能簡(jiǎn)單實(shí)現(xiàn)我們只有一個(gè)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:pass@192.168.0.116:6379
  consumer:
    timeout: 3000

    
spring:
  application:
    name: user-consumer    

注意事項(xiàng)

  • 由于common項(xiàng)目是其他兩個(gè)項(xiàng)目都需要使用的,請(qǐng)先編譯發(fā)布到自己的maven倉(cāng)庫(kù),如果都在同一臺(tái)電腦上開發(fā),只需要install到本地倉(cāng)庫(kù)即可,如果是多臺(tái)電腦或者小組開發(fā)請(qǐng)發(fā)布到自己小組的私有倉(cāng)庫(kù);
  • 在啟動(dòng)服務(wù)消費(fèi)方前請(qǐng)先啟動(dòng)服務(wù)提供方,可以多臺(tái)電腦同時(shí)運(yùn)行服務(wù)提供方項(xiàng)目;
  • 啟動(dòng)消費(fèi)方 通過(guò)瀏覽器訪問 http://localhost:8080/ 查看結(jié)果。也可以啟動(dòng)多個(gè)消費(fèi)方,看看在多個(gè)服務(wù)方運(yùn)行的情況下分別調(diào)用的是哪一臺(tái)的服務(wù)。

結(jié)語(yǔ)

這樣拆分后,各其實(shí)其實(shí)都很簡(jiǎn)單,具體開發(fā)中,各項(xiàng)目只需要處理自己相關(guān)業(yè)務(wù)代碼即可,不需要考慮更多,可以讓每一個(gè)項(xiàng)目都可以完成得更好,并且不影響其他模塊的功能,讓開發(fā)和部署維護(hù)都能夠更方便。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容