整合SpringBoot+Dubbo(Zookeeper)+redis(Linux)+mybatis的简易项目框架
s使用dubbo大体分为三大部分暴露的API接口(dubbo-interface-API)服务的提供者(dubbo-service-provider)服务的消费者(dubbo-service-consumer)下面是实现细节1.对外暴露的API接口(dsubbo-interface-API)对于接口工程的创建 使用了maven 但没使用任何骨架目录结构为一个实体类和一个服务接口实体类的创建要注意实
springboot整合使用dubbo大体分为三大部分
暴露的API接口(dubbo-interface-API)
服务的提供者(dubbo-service-provider)
服务的消费者(dubbo-service-consumer)
还有就是部署在Linux的Redis服务
下面是实现细节
1.对外暴露的API接口(dubbo-interface-API)
对于接口工程的创建 使用了maven 但没使用任何骨架
目录结构为一个实体类和一个服务接口
实体类的创建要注意实现对象的序列化 (实现Serializable 接口)
public class Student implements Serializable {
private static final long serialVersionUID = 1245946014621298931L;
private Integer id;
private String name;
private int age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public interface StudentService {
Student queryStudent(String name);
int addStudent(Student student);
}
2.服务的提供者(dubbo-service-provider)
对于服务的提供者 这里创建使用了maven的spring Initializr 添加了一大部分的springboot起步依赖
(mysql驱动 mybatis框架 redis驱动等起步依赖)
2.1 处理pom文件
对于<暴露接口工程/dubbo/zookeeper>的依赖还需要手动添加
<!--公共项目的依赖-->
<dependency>
<groupId>XXXXXX.XXXXXX</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0.0</version>
</dependency>
<!--dubbo起步依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<!--zookeeper依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.8</version>
<type>pom</type>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
框架自动生成pom文件中的一些内容
2.2编写StudentDao接口
StudentDao接口来写业务的查询和添加功能
public interface StudentDao {
Student selectStudentByName(@Param("name")String name);
int insertStudent(Student student);
}
@Param("name"):mybatis框架-->使用注解传参
在java代码中把数据内容传入到对应的mapper文件的sql语句中
2.3处理mybatis.xml 文件
实现Dao接口的映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--指定dao接口的全限定名称-->
<mapper namespace="xxx.xxxxxxx.Dao.StudentDao">
<select id="selectStudentByName" resultType="com.xxxxxx.model.Student">
select * from student where name=#{name}
</select>
<insert id="insertStudent">
insert into student(name ,age) values(#{name},#{age})
</insert>
</mapper>
2.4处理StudentServer接口的实现类---StudentServerImpl
@DubboService(interfaceClass = StudentService.class,version = "1.0",timeout = 5000)
public class StudentServiceImpl implements StudentService {
@Resource
private RedisTemplate redisTemplate;
@Resource
private StudentDao studentDao;
/**
*
* @param student
* @return int
* 初始值:0
* 添加成功:1
* 姓名已存在:2
* 姓名不能为空:3
*/
@Override
public int addStudent(Student student) {
int result = 0;
if(student.getName() != null){
Student stu =studentDao.selectStudentByName(student.getName());
//应该是student不应该是student.getName() 不然会空指针
if(stu.getName() != null){
result = 2;
}else{
result =studentDao.insertStudent(student);
}
}else {
result = 3;
}
return result;
}
//查询时会出现缓存穿透的现象
@Override
public Student queryStudent(String name) {
//对键值分别序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Student.class));
Student student = null;
final String USER_KEY="STUDENT:";
if(name != null){
String key = USER_KEY + name;
student = (Student) redisTemplate.opsForValue().get(key);
System.out.println("从redis查数据" + student);
if(student == null){
student = studentDao.selectStudentByName(name);
System.out.println("从数据库查数据" + student);
if(student != null){
redisTemplate.opsForValue().set(key,student);
}else {
redisTemplate.opsForValue().set(key,Student.defaultStudent());
}
}
}
return student;
}
}
@DubboService(interfaceClass = StudentService.class,version = "1.0",timeout = 5000) 实现dubbo服务 设置需要的暴露的公共项目 版本号 超时等属性 @Resource:private RedisTemplate redisTemplate; 使用redis需要的注解 通过RedisTemplate封装好的各种方法来操作Redis 进行序列化 反序列化等 @Resource:private StudentDao studentDao; spring实现自动注入
2.5处理application.properties文件
#配置dubbo
spring.application.name=dubbo-provider
dubbo.scan.base-packages=xxx.xxxxxxx.service
dubbo.registry.address=zookeeper://localhost:2181
#配置redis
#redis部署在Linux上 使用虚拟机的ip 未使用密码
spring.redis.host=192.168.xxx.xxx
spring.redis.port=6379
#配置mybatis
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#配置mysql数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=xxxx
mybatis.mapper-locations=classpath:mapper/*.xml ---->通过主配置文件使mybatis找到mapper文件的位置 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl 配置mybatis的日志 这里直接配置输出在控制台上
2.6 处理springboot主启动项
@SpringBootApplication
@EnableDubbo
@MapperScan(basePackages = "com.xxxxxx.Dao")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@SpringBootApplication 使用springboot核心注解(复合注解) @EnableDubbo 启用dubbo服务 @MapperScan(basePackages = "com.xxxxxx.Dao") (使用mybatis时 把Dao接口与java文件分开存储) 使用注解对包进行扫描 ---->通过springboot主类找到接口位置
3.服务的消费者(dubbo-service-consumer)
提供者提供了接口 消费者就要调用服务提供者提供的接口服务
3.1处理pom文件
作为dubbo的消费者 这里的pom文件只需要手动添加一个dubbo的依赖和接口的依赖即可
3.2处理application.properties文件
#指定端口号
server.port=8081
server.servlet.context-path=/test
#配置dubbo
spring.application.name=dubbo-consumer
dubbo.scan.base-packages="com.xxxxxxx.controller"
dubbo.registry.address=zookeeper://localhost:2181
配置文件指定了服务的端口号和服务上下文的资源路径
使用到了dubbo的zookeeper注册中心服务
3.3处理前端控制层的DubboController
@RestController
public class DubboController {
@DubboReference(interfaceClass = StudentService.class,version = "1.0")
private StudentService studentService;
@PostMapping("/student/add")
public String addStudent(Student student){
String message = "处理";
int result = studentService.addStudent(student);
if(result == 1){
message="添加成功:"+student.getName();
}else if (result == 2){
message="用户信息已存在";
}else if(result == 3){
message ="用户不能为空";
}
return "添加结果:" + message;
}
@GetMapping("/student/query")
public String queryStudent(String name){
String message = "";
Student student = null;
if(name != null){
student = studentService.queryStudent(name);
if(student != null){
message = "学生信息为:" + student.toString();
}else {
message = "未查询到信息!";
}
}else{
message = "查询到信息不能为空!";
}
return message;
}
}
@RestController(复合注解):
RESTful风格的注解 表示@Controller与@ResponseBody的组合,在类的上面使用@RestController , 表示当前类者的所有方法都加入了 @ResponseBody
@DubboReference(interfaceClass = StudentService.class,version = "1.0"):
实现dubbo服务 调用暴露的公共项目 版本号 等属性
@PostMapping("/student/add")
RESTful风格的注解 表示支持post请求方式 ,等同于 @RequestMapping( method=RequestMethod.POST)
@GetMapping("/student/query")
RESTful风格的注解 表示支持的get请求方式, 等同于 @RequestMapping( method=RequestMethod.GET)
4.zookeeper + Redis + Linux
4.1启动zookeeper
三大模块写完之后启动zookeeper 执行bin目录下的zkServer.cmd文件 启动zookeeper服务
4.2启动Linux与Redis服务
Linux选择了部署在虚拟机上 虚拟机软件使用的是VMware Linux系统为CentOS
通过(redis-server)命令启动redis服务 同时也指定了配置文件启动+后台启动 (redis.conf &)
服务启动之后通过(ps -mf|grep redis)来查看Redis服务是否执行
4.2.2关闭了Linux防火墙
因为不是本地在使用redis服务 所以我先关闭了Linux防火墙
(CentOS7这个版本的防火墙默认使用的是firewall 与之前的版本Centos 6.x使用iptables不一样)
通过 (systemctl status firewalld) 查看防火墙状态 (service firewalld stop) 关闭防火墙
4.2.3再给redis.conf配置文件中配置一些重要信息
第一点:指定输出的日志文件
通过vim编辑器 (vim redis.conf)打开redis.conf文件 再使用(:/log)文件进行关键字查找 指定日志输出的文件 这里指定了redis-log.log文件作为日志输出文件
第二点:修改redis的默认bind地址
因为连接Redis服务不是在本地 所以需要修改bind地址(默认为127.0.0.1 限制了只有本地连接 所以软件连接不上)
可以直接把这行注释掉或者改成0.0.0.0
第三点:关闭redis的保护模式
Redis默认的保护模式protected-mod 为yes 改为no
(或者可以为redis设置密码 但是Redis便捷高效的特点不建议这么做)
(第四点:指定Redis服务的端口号)
在前面配置的application.properties配置文件中配置了Redis的端口号 如果不是默认端口号6379 需要自行更改
配置信息与防火墙全部设置好后 Redis服务即可成功部署在Linux系统上了
5.测试结果
先启动了zookeeper和Linux上的redis
再从idea中先启动provider的服务在启动consumer服务
打开postman进行测试
使用postman进行了两次测试查询 从idea的日志可以看出第一次查询是先从redis缓存中查数据没查到 又去数据库中查数据找到后返回了结果
第二次查询就直接从redis缓存中查到了数据 减少了数据库的压力 发挥出了redis的效果
更多推荐
所有评论(0)