Spring Boot中使用Dubbo
高并发下Redis会出现的问题:
- 缓存穿透
- 缓存雪崩
- 热点缓存
一、定义commons工程11-dubboCommons
(1) 创建工程
创建Maven的Java工程,并命名为11-dubboCommons
(2) 定义pom文件
-
<groupId>com.abc</groupId>
-
<artifactId>11-dubboCommons</artifactId>
-
<version>1.0-SNAPSHOT</version>
-
-
<properties>
-
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-
<maven.compiler.source>1.8</maven.compiler.source>
-
<maven.compiler.target>1.8</maven.compiler.target>
-
</properties>
-
-
<dependencies>
-
<dependency>
-
<groupId>org.projectlombok</groupId>
-
<artifactId>lombok</artifactId>
-
<version>1.18.4</version>
-
<scope>provided</scope>
-
</dependency>
-
</dependencies>
(3) 定义实体类
(4) 定义业务接口
(5) 将工程安装到本地库
运行Maven的install命令,将工程安装到本地版本库,以备其它工程使用
二、定义提供者11-provider-springboot
(1) 创建工程
创建一个Spring Boot工程,并重命名为11-provider-springboot
(2) 定义pom文件
A、添加dubbo与spring boot整合依赖
B、添加zkClient依赖
C、其它依赖
- dubboCommons依赖
- spring boot与redis整合依赖
- mybatis与spring boot整合依赖
- 数据源Druid依赖
- mysql驱动依赖
- slf4j-log4j12依赖
- spring-boot-starter-web依赖
-
<groupId>com.abc</groupId>
-
<artifactId>11-provider-springboot</artifactId>
-
<version>0.0.1-SNAPSHOT</version>
-
-
<parent>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-parent</artifactId>
-
<version>2.1.5.RELEASE</version>
-
<relativePath/> <!-- lookup parent from repository -->
-
</parent>
-
-
<properties>
-
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-
<java.version>1.8</java.version>
-
</properties>
-
-
<dependencies>
-
<!--dubbo与spring boot整合依赖-->
-
<dependency>
-
<groupId>com.alibaba.spring.boot</groupId>
-
<artifactId>dubbo-spring-boot-starter</artifactId>
-
<version>2.0.0</version>
-
</dependency>
-
<!-- zk客户端依赖:zkclient -->
-
<dependency>
-
<groupId>com.101tec</groupId>
-
<artifactId>zkclient</artifactId>
-
<version>0.10</version>
-
</dependency>
-
<dependency>
-
<groupId>com.abc</groupId>
-
<artifactId>11-dubboCommons</artifactId>
-
<version>1.0-SNAPSHOT</version>
-
</dependency>
-
<!--Spring Boot与Redis整合依赖-->
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-data-redis</artifactId>
-
</dependency>
-
<!--mybatis与Spring Boot整合依赖-->
-
<dependency>
-
<groupId>org.mybatis.spring.boot</groupId>
-
<artifactId>mybatis-spring-boot-starter</artifactId>
-
<version>1.3.2</version>
-
</dependency>
-
<!--数据源Druid依赖-->
-
<dependency>
-
<groupId>com.alibaba</groupId>
-
<artifactId>druid</artifactId>
-
<version>1.1.10</version>
-
</dependency>
-
<!--MySQL驱动依赖-->
-
<dependency>
-
<groupId>mysql</groupId>
-
<artifactId>mysql-connector-java</artifactId>
-
<version>5.1.47</version>
-
</dependency>
-
<dependency>
-
<groupId>org.slf4j</groupId>
-
<artifactId>slf4j-log4j12</artifactId>
-
<version>1.7.25</version>
-
<scope>test</scope>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-web</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-test</artifactId>
-
<scope>test</scope>
-
</dependency>
-
</dependencies>
-
-
<build>
-
<plugins>
-
<plugin>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-maven-plugin</artifactId>
-
</plugin>
-
</plugins>
-
-
<resources>
-
<!--注册dao包下mybatis映射文件为资源目录-->
-
<resource>
-
<directory>src/main/java</directory>
-
<includes>
-
<include>**/*.xml</include>
-
</includes>
-
</resource>
-
</resources>
-
</build>
(3) 定义Service实现类
-
import com.abc.bean.Employee;
-
import com.abc.dao.EmployeeDao;
-
import com.alibaba.dubbo.config.annotation.Service;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.cache.annotation.CacheEvict;
-
import org.springframework.cache.annotation.Cacheable;
-
import org.springframework.data.redis.core.BoundValueOperations;
-
import org.springframework.data.redis.core.RedisTemplate;
-
import org.springframework.stereotype.Component;
-
import org.springframework.transaction.annotation.Transactional;
-
-
import java.util.concurrent.TimeUnit;
-
-
@Service // Dubbo的注解 <dubbo:service/>
-
@Component
-
public class EmployeeServiceImpl implements EmployeeService {
-
@Autowired
-
private EmployeeDao dao;
-
@Autowired
-
private RedisTemplate<Object, Object> redisTemplate;
-
-
// 当有对象插入时会清空realTimeCache缓存空间
-
@CacheEvict(value="realTimeCache", allEntries = true)
-
@Transactional(rollbackFor = Exception.class)
-
@Override
-
public void addEmployee(Employee employee) {
-
dao.insertEmployee(employee);
-
}
-
-
// 一旦有了查询结果,则会将此结果写入到realTimeCache缓存
-
// key是employee_加上方法参数
-
@Cacheable(value = {"realTimeCache"}, key = "'employee_'+#id")
-
@Override
-
public Employee findEmployeeById(int id) {
-
// 从DB查询
-
System.out.println("从DB查询id = " + id);
-
return dao.selectEmployeeById(id);
-
}
-
-
private volatile Object count;
-
// 双重检测锁机制解决Reids的热点缓存问题
-
@Override
-
public Integer findEmployeeCount() {
-
// 获取Redis操作对象
-
BoundValueOperations<Object, Object> ops = redisTemplate.boundValueOps("count");
-
// 从缓存获取数据
-
count = ops.get();
-
if(count == null) {
-
synchronized (this) {
-
count = ops.get();
-
if(count == null) {
-
System.out.println("从DB中查询");
-
// 从DB中查询
-
count = dao.selectEmployeeCount();
-
// 将查询结果存放到Redis
-
ops.set(count, 10, TimeUnit.SECONDS);
-
}
-
}
-
}
-
return (Integer) count;
-
}
-
}
(4) 定义Dao接口
(5) 定义映射文件
(6) 修改启动类
在启动类上必须要添加@EnableDubboConfiguration注解,开启Dubbo的自动配置功能
(7) 修改主配置文件
-
server:
-
port: 8888
-
-
mybatis:
-
# 注册mybatis中实体类的别名
-
type-aliases-package: com.abc.bean
-
# 注册映射文件
-
mapper-locations: classpath:com/abc/dao/*.xml
-
-
spring:
-
# 注册数据源
-
datasource:
-
# 指定数据源类型为Druid
-
type: com.alibaba.druid.pool.DruidDataSource
-
driver-class-name: com.mysql.jdbc.Driver
-
url: jdbc:mysql:///test?useUnicode=true&characterEncoding=utf8
-
username: root
-
password: root
-
-
# 连接Redis服务器
-
redis:
-
host: 39.97.176.160
-
port: 6379
-
-
# 连接Redis高可有集群
-
# redis:
-
# sentinel:
-
# master: mymaster
-
# nodes:
-
# - sentinelOS1:26379
-
# - sentinelOS2:26379
-
# - sentinelOS3:26379
-
-
# 配置缓存
-
cache:
-
type: redis # 指定缓存类型
-
cache-names: realTimeCache # 指定缓存区域名称
-
-
-
# 功能等价于spring-boot配置文件中的<dubbo:application/>
-
application:
-
name: 11-provider-springboot
-
# 指定zk注册中心
-
dubbo:
-
registry: zookeeper://39.97.176.160:2181
-
# zk集群作注册中心
-
# registry: zookeeper://zkOS1:2181?backup=zkOS2:2181,zkOS3:2181
三、定义消费者11-consumer-springboot
(1) 创建工程
创建一个Spring Boot工程,并重命名为11-consumer-springboot
(2) 定义pom文件
- dubbo与spring boot整合依赖
- zkClient依赖
- dubboCommons依赖
- JSP引擎jasper依赖
- slf4j-log4j12依赖
- spring-boot-starter-web依赖
(3) 修改主配置文件
-
spring:
-
# 功能等价于spring-dubbo配置文件中的<dubbo:application/>
-
application:
-
name: 11-consumer-springboot
-
# 指定zk注册中心
-
dubbo:
-
registry: zookeeper://39.97.176.160:2181
-
# zk集群作注册中心
-
# registry: zookeeper://zkOS1:2181?backup=zkOS2:2181,zkOS3:2181
(4) 创建index.jsp页面
在src/main/webapp目录下定义index.jsp文件
(5) 定义处理器
-
package com.abc.controller;
-
-
import com.abc.bean.Employee;
-
import com.abc.service.EmployeeService;
-
import com.alibaba.dubbo.config.annotation.Reference;
-
import org.springframework.stereotype.Controller;
-
import org.springframework.ui.Model;
-
import org.springframework.web.bind.annotation.PathVariable;
-
import org.springframework.web.bind.annotation.PostMapping;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.ResponseBody;
-
-
@Controller
-
@RequestMapping("/consumer/employee")
-
public class SomeController {
-
-
// @Autowired
-
@Reference // Dubbo的注解 <dubbo:reference />
-
private EmployeeService employeeService;
-
-
@PostMapping("/register")
-
public String someHandle(Employee employee, Model model) {
-
employeeService.addEmployee(employee);
-
model.addAttribute("employee", employee);
-
return "/welcome.jsp";
-
}
-
-
@RequestMapping("/find/{id}")
-
@ResponseBody
-
public Employee findHandle(@PathVariable("id") int id) {
-
return employeeService.findEmployeeById(id);
-
}
-
-
@RequestMapping("/count")
-
@ResponseBody
-
public Integer countHandle() {
-
return employeeService.findEmployeeCount();
-
}
-
-
}
(6) 定义welcome.jsp页面
(7) 修改入口类
四、测试
当有对象插入时会清空realTimeCache缓存空间
一旦有了查询结果,则会将此结果写入到realTimeCache缓存
http://localhost:8080/index.jsp 首页
Spring Boot中使用Dubbo的更多相关文章
- Dubbo在Spring和Spring Boot中的使用
一.在Spring中使用Dubbo 1.Maven依赖 <dependency> <groupId>com.alibaba</groupId> <artifa ...
- spring boot中的声明式事务管理及编程式事务管理
这几天在做一个功能,具体的情况是这样的: 项目中原有的几个功能模块中有数据上报的功能,现在需要在这几个功能模块的上报之后生成一条消息记录,然后入库,在写个接口供前台来拉取消息记录. 看到这个需求,首先 ...
- Spring Boot 中如何支持异步方法
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...
- spring boot(三):Spring Boot中Redis的使用
spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...
- Spring Boot中的事务管理
原文 http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...
- Spring Boot中的注解
文章来源:http://www.tuicool.com/articles/bQnMra 在Spring Boot中几乎可以完全弃用xml配置文件,本文的主题是分析常用的注解. Spring最开始是为了 ...
- 在Spring Boot中使用Https
本文介绍如何在Spring Boot中,使用Https提供服务,并将Http请求自动重定向到Https. Https证书 巧妇难为无米之炊,开始的开始,要先取得Https证书.你可以向证书机构申请证书 ...
- Spring Boot中使用Swagger2构建强大的RESTful API文档
由于Spring Boot能够快速开发.便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API.而我们构建RESTful API的目的通常都是由于多终端的原因,这 ...
- springboot(十一):Spring boot中mongodb的使用
mongodb是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居多.由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoDB 因配置 ...
随机推荐
- Python之模块导入(不看会后悔系列)
看到这个标题猜想大家内心OS: 什么辣鸡水文,划走划走~ 别急有干货! 静态导入(照顾新人) 假设现在有两个文件a,b在不同目录,b文件想引用a文件中的函数: # test_module/sub_mo ...
- springboot入门之版本依赖和自动配置原理
前言 Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that ...
- ucharts tooltip弹窗自定义换行
这个东西吧,也许是因为菜,看了3小时,下面给出解决方案 1. 找到源码下面的这个文件 2. 增加绿色方框中的代码 3.组件调用的时候有一个opts属性 :opts="{ extra: { t ...
- MySQL统计总数就用count(*),别花里胡哨的《死磕MySQL系列 十》
有一个问题是这样的统计数据总数用count(*).count(主键ID).count(字段).count(1)那个效率高. 先说结论,不用那么花里胡哨遇到统计总数全部使用count(*). 但是有很多 ...
- Python科普系列——类与方法(上篇)
欢迎来到新的系列,up又开新坑了~~ 实际上,Python作为一门易用性见长的语言,看上去简单,却仍然有很多值得一说的内容,因此这个系列会把Python中比较有意思的地方也给科普一遍.而另一方面,关于 ...
- Python基础(序列化)
#pickling import pickle,json # d = dict(name='傻狗1',age=300,score=100) # d1 = pickle.dumps(d)#pickle. ...
- Django 小实例S1 简易学生选课管理系统 5 实现注册功能
Django 小实例S1 简易学生选课管理系统 第5节--实现注册功能 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 本文涉及到的新的额外知识点: ...
- jenkins bat删除指定路径下的文件及文件夹
最近在用jenkins集成,生成allure测试报告,但是每次生成的allure测试报告,都是上一次执行的痕迹.比如这次我只运行了100个用例,结果显示运行2000条,上一次运行的用例,时间也涵括了上 ...
- Android——ViewHolder的作用与用法
转载至:https://www.cnblogs.com/wugu-ren/p/6106379.htmlViewHolder通常出现在适配器里,为的是listview滚动的时候快速设置值,而不必每次都重 ...
- 【Java】运行时Java对象在内存中是如何存储的?
翻译自这一篇文章 我们知道函数在内存中实现为一个活动记录的栈.我们也知道Java方法在JVM栈区中实现为一个帧栈而Java对象是在堆区进行分配的. Java对象在堆内存中是怎样的呢?一旦对象保存在内存 ...