使用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/ 檢視結果。也可以啟動多個消費方,看看在多個服務方執行的情況下分別呼叫的是哪一臺的服務。
結語
這樣拆分後,各其實其實都很簡單,具體開發中,各專案只需要處理自己相關業務程式碼即可,不需要考慮更多,可以讓每一個專案都可以完成得更好,並且不影響其他模組的功能,讓開發和部署維護都能夠更方便