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ù)都能夠更方便。