栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 前沿技术 > 大数据 > 其他

基于springboot+dubbo+zookeeper+redis实现微服架构搭建

其他 更新时间:发布时间: 百科书网 趣学号
        前言:了解微服务架构入门简介 1.运行原理
  • Provider:暴露服务的服务提供方
  • Consumer:调用远程服务的服务消费方
  • Registry:提供注册与调用服务的注册中心
  • Monitor:统计服务的调用次数和调用时间的监控中心
  • Container:服务运行容器,例如spring容器

  1. 服务容器负责启动,加载,运行服务提供者。
  2. 服务提供者在启动时,向注册中心注册自己提供的服务。
  3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
  4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心Monitor。

 2.所需的工具软件
  • Zookeeper:Dubbo建议使用Zookeeper作为服务的注册中心
  • redis(window版)
  • redis-desktop-manager:redis的可视化管理,相当于sqlyog
  • dubbo-war:可视化监控中心
  • postpan:用于做接口请求测试,无论是前端,后台还是测试人员,都可以用 postman 来测试接口,用起来非常方便。
  • student_info:  用到的数据库


 ——————————————————开始搭建————————————————————

3. 创建通用项目——common 3-1.用maven创建:

 3-2.所需的依赖:也是提供者与消费所需的模块
        
            junit
            junit
            4.11
            test
        
        
            log4j
            log4j
            1.2.17
        
3-2.创建实体类:pojo

        编写通用的实体类,用于给其他项目模块使用

        Student类:

package cn.common.pojo;

import java.io.Serializable;
import java.util.Date;


public class Student implements Serializable {
    private static final long serialVersionUID = 212298760094457193L;
    
    private Integer id;
    
    private String sname;
    
    private Date birthday;
    
    private String gender;
    
    private String telephone;
    
    private String email;
    
    private Integer classid;

    
    private String cname;

    //get已set方法已省略

}

        Classes 类:

package cn.common.pojo;

import java.io.Serializable;


public class Classes implements Serializable {
    private static final long serialVersionUID = -39827967746559332L;
    
    private Integer id;
    
    private String cname;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

}
3-3.RPC接口

        这是一个通用的接口,用于给其他模块和项目调用,也是通用项目中的service

        CommonStudentService:

package cn.common.service;

import cn.common.pojo.Student;

import java.util.List;

public interface CommonStudentService {
    
    List findAllStudeng();
}

到这里路通用项目已经简单搭建完成,实际项目中还有很多,根据业务需求进行编写

3-4.最后使用maven将通用项目打成jar包,在其他项目中进行引入

依赖所在的路径: 

打成jar包后的依赖坐标就是通用项目的pom.xml

        
            org.example
            student_common
            1.0-SNAPSHOT
        

4.创建提供者——Provider 4-1.使用idea创建springboot项目——版本2.0.0.RELEASE

4-2.导入依赖 
        
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            com.alibaba
            fastjson
            1.2.75
        
        
        
            com.alibaba.spring.boot
            dubbo-spring-boot-starter
            2.0.0
        
        
            com.101tec
            zkclient
            0.10
        
        
        
            org.example
            student_common
            1.0-SNAPSHOT
        
        
        
            org.junit.jupiter
            junit-jupiter-api
            test
        
4-3.配置文件application.properties
#端口号,可以直接在这里进行修改
server.port=8081
#配置连接数据库的相关参数
spring.datasource.url=jdbc:mysql://localhost:3306/student_info?characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#配置mybatis的映射文件的位置
mybatis.mapper-locations=classpath:mapper
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value.toString());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value.toString(), time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    
    public long getExpireTime(String key){
        long time = redisTemplate.getExpire(key);
        return time;
    }

    
    public String getValue(String key) {
        String result = null;
        try {
            ValueOperations valueOps = redisTemplate.opsForValue();
            result = valueOps.get(key);
            log.info("[REDIS] Get k-v key={}, value={}", key, result);
        } catch (Exception e) {
            log.error("[REDIS--ERROR]-->getValue(String key)错误:{}", e);
        }
        return result;
    }

    
    public Map multiGetValue(List keys) {
        Map results = null;
        try {
            ValueOperations valueOps = redisTemplate.opsForValue();
            List values = valueOps.multiGet(keys);
            results = new HashMap<>(16);
            if (!CollectionUtils.isEmpty(values) && !keys.isEmpty()) {
                for (int i = 0; i < keys.size(); i++) {
                    String fieldName = keys.get(i);
                    String fieldValue = values.get(i);
                    // 如果对应的字段为null,则不需要放入
                    if (!StringUtils.isEmpty(fieldValue)) {
                        results.put(fieldName, fieldValue);
                    }
                }
            }
            log.info("[REDIS] Get Map map=%s", results);
        } catch (Exception e) {
            log.error("[REDIS--ERROR] Get Map map=%s", results);
        }

        return results;
    }

    

    public void delete(Collection keys) {
        try {
            redisTemplate.delete(keys);
            log.info("[REDIS] Delete keys=%s", keys);
        } catch (Exception e) {
            log.error("[REDIS] Delete keys=%s", keys);
        }
    }

    
    public void delete(String key) {
        try {
            redisTemplate.delete(key);
            log.info("[REDIS] Delete key=%s", key);
        } catch (Exception e) {
            log.error("[REDIS] Delete key=%s", key);
        }
    }

    
    public List getList(String key, long start, long end){
        List result = null;
        try {
            ListOperations opsForList = redisTemplate.opsForList();
            result = opsForList.range(key, start, end);
            log.info("[REDIS] getList list key=%s,result=%s", key, result);
        } catch (Exception e) {
            log.error("[REDIS] getList list key=%s,result=%s", key, result);
        }
        return result;
    }

    
    public void leftPushList(String key, List list) {
        try {
            ListOperations opsForList = redisTemplate.opsForList();
            opsForList.leftPushAll(key ,list);
            log.info("[REDIS] leftPush list key=%s,value=%s", key, list);
        } catch (Exception e) {
            log.error("[REDIS] leftPush list key=%s,value=%s", key, list);
        }
    }

    public  T getJson(String key, Class entityClass) {
        try {
            String value = getValue(key);
            if (StringUtils.isEmpty(value)) {
                return null;
            }
            return JSON.parseObject(value, entityClass);
        } catch (Exception e) {
            log.error("从redis获取json对象失败:%s,异常信息为: %s", key, e.getMessage());
        }
        return null;
    }


}

        ---StudentProviderService类:实现的是通用项目common中的service接口

        注意:

                这里的@Service是com.alibaba.dubbo.config.annotation里面的

                所以还需要加@Component用于给spring管理

package cn.example.provider.service;

import cn.common.pojo.Student;
import cn.common.service.CommonStudentService;
import cn.example.provider.mapper.StudentProviderMapper;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.List;
@Component
@Service(interfaceClass = CommonStudentService.class)
public class StudentProviderService implements CommonStudentService {
    @Autowired
    private StudentProviderMapper spm;
    @Autowired
    private RedisService rs;

    @Override
    public List findAllStudeng() {
        List studentList = null;
        //先去redis中获取数据
        String studentInfo = rs.getValue("student_info");
        //判断redis是否有缓存数据
        if (StringUtils.isEmpty(studentInfo)||studentInfo.equals("null")){
            //如果没有缓存数据,就去mysql数据库中查询,并存入redis中
            studentList = spm.getAllStudent();
            //转json格式存入redis
            String jsonString = JSON.toJSonString(studentList);
            rs.set("student_info",jsonString,-1);
        }else {
            //如果有就直接取出
            String jsonString = rs.getValue("student_info");
            studentList = JSONObject.parseArray(jsonString,Student.class);
        }
        return studentList;
    }
}
4-7.在启动类上添加@EnableDubboConfiguration注解                 在com.alibaba.dubbo.spring.boot.annotation包下,开启dubbo框架

 4-8.启动zookeepr如图(提供的安装包中有使用说明)

 4-9.启动provider项目,看是否能够正常启动成功,并在zookeeper中开放服务接口

        如果服务项目能够正常启动,并且在zookeeper中也有变化,说明应该是没问题的:


5.创建消费者——Consumer 5-1.使用idea创建springboot项目

        创建时只需要添加web依赖

 5-2.添加外部依赖坐标

        统一springboot的版本:2.0.0.RELEASE

        
        
            com.alibaba.spring.boot
            dubbo-spring-boot-starter
            2.0.0
        
        
            com.101tec
            zkclient
            0.10
        
        
        
            org.example
            student_common
            1.0-SNAPSHOT
        
        
            org.junit.jupiter
            junit-jupiter-api
            test
        
5-3.编写配置文件
#端口号,可以直接在这里进行修改
server.port=8082
#配置注册地址
#当前服务者的名字
spring.application.name=student_consumer
#zookeeper注册地址
spring.dubbo.registry=zookeeper://127.0.0.1:2181
#注册协议
spring.dubbo.protocol=dubbo
#不需要开放端口号,因为消费者是用来调提供者的
#spring.dubbo.port=20803

#第一个设置就是使用24小时的时间格式;第二个设置就是设置时区为东八区
spring.jackson.default-property-inclusion=NON_NULL
spring.jackson.time-zone=GMT+8
#设置日期格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
5-4.编写service接口

        这里的service接口与common中的service接口内容相同,但它只起到规范的作用,而在下面的service实现类中调用的依然是通用common项目中的service,然后common中的service调用的是提供者中provider的service实现类

package cn.example.consumer.service;

import cn.common.pojo.Student;

import java.util.List;

public interface StudentConsumerService {
    List findAllStudent();
}
5-5.编写service的实现类

        这里service实现类中调用的依然是通用common项目中的service接口,然后common中的service接口引用的是提供者中provider的service实现类,所以最终运行的是在provider中的业务

package cn.example.consumer.service.impl;

import cn.common.pojo.Student;
import cn.common.service.CommonStudentService;
import cn.example.consumer.service.StudentConsumerService;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

import java.util.List;
@Service
public class StudentConsumerServiceImpl implements StudentConsumerService {
    @Reference //引用common中提供的service接口
    private CommonStudentService commonStudentService;

    @Override
    public List findAllStudent() {
        return commonStudentService.findAllStudeng();
    }
}
5-6.编写controller
package cn.example.consumer.controller;

import cn.common.pojo.Student;
import cn.example.consumer.service.StudentConsumerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class StudentController {

    @Autowired
    private StudentConsumerService scs;
    //查询所有学生信息
    @RequestMapping("/findAllStudent")
    public List findAllStudent(){
        return scs.findAllStudent();
    }
}
5-7.在启动类上添加@EnableDubboConfiguration注解          在com.alibaba.dubbo.spring.boot.annotation包下,开启dubbo框架

 5-8.启动当前项目Consumer
  • 前提是先启动provider和zookeeper
  • 安装好提供的postman,打开进行测试

 接着打开redis-desktop-manager查看redis中是否存入数据:

  •  db15是我们在provider项目中的配置文件配置 Redis配置 #数据库索引 0-15中设置的是15
  •   这里的key是我们自己定义,实际开发中会有具体的规范         

 到这里说明我们基于springboot+dubbo+zookeeper+redis搭建的微服架构是没问题的,这也是最基础比较简单的

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/279347.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号